Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: add Support For Segmented Assets #191

Merged
merged 5 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions plugins/auto-scroll/react/src/__tests__/plugin.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { makeFlow } from '@player-ui/make-flow';
import {
actionTransform,
inputTransform,
infoTransform,
} from '@player-ui/reference-assets-plugin';
import { Info, Action, Input } from '@player-ui/reference-assets-plugin-react';
import { CommonTypesPlugin } from '@player-ui/common-types-plugin';
Expand Down Expand Up @@ -108,6 +109,7 @@ describe('auto-scroll plugin', () => {
new AssetTransformPlugin([
[{ type: 'action' }, actionTransform],
[{ type: 'input' }, inputTransform],
[{ type: 'info' }, infoTransform],
]),
new CommonTypesPlugin(),
new AutoScrollManagerPlugin({
Expand Down Expand Up @@ -145,6 +147,7 @@ describe('auto-scroll plugin', () => {
new AssetTransformPlugin([
[{ type: 'action' }, actionTransform],
[{ type: 'input' }, inputTransform],
[{ type: 'info' }, infoTransform],
]),
new CommonTypesPlugin(),
new AutoScrollManagerPlugin({
Expand Down Expand Up @@ -202,6 +205,7 @@ describe('auto-scroll plugin', () => {
new AssetTransformPlugin([
[{ type: 'action' }, actionTransform],
[{ type: 'input' }, inputTransform],
[{ type: 'info' }, infoTransform],
]),
new CommonTypesPlugin(),
new AutoScrollManagerPlugin({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { runTransform } from '@player-ui/asset-testing-library';
import { infoTransform } from '..';

describe('info transform', () => {
it('populates segmentedActions', () => {
const ref = runTransform('info', infoTransform, {
id: 'generated-flow',
views: [
{
id: 'info-view',
type: 'info',
title: {
asset: {
id: 'info-title',
type: 'text',
value: 'Info Title',
},
},
actions: [
{
asset: {
id: 'next-action',
value: 'Next',
type: 'action',
label: {
asset: {
id: 'next-action-label',
type: 'text',
value: 'Continue',
},
},
},
},
{
asset: {
id: 'prev-action',
value: 'Prev',
type: 'action',
label: {
asset: {
id: 'next-action-label',
type: 'text',
value: 'Back',
},
},
},
},
],
},
],
data: {},
navigation: {
BEGIN: 'FLOW_1',
FLOW_1: {
startState: 'VIEW_1',
VIEW_1: {
state_type: 'VIEW',
ref: 'info-view',
transitions: {
'*': 'END_Done',
},
},
END_Done: {
state_type: 'END',
outcome: 'done',
},
},
},
});
expect(ref.current?.segmentedActions).toStrictEqual({
next: [
{
asset: {
id: 'next-action',
label: {
asset: {
id: 'next-action-label',
type: 'text',
value: 'Continue',
},
},
type: 'action',
value: 'Next',
},
},
],
prev: [
{
asset: {
id: 'prev-action',
label: {
asset: {
id: 'next-action-label',
type: 'text',
value: 'Back',
},
},
type: 'action',
value: 'Prev',
},
},
],
});
});
it('does not populate segmentedActions', () => {
const ref = runTransform('info', infoTransform, {
id: 'generated-flow',
views: [
{
id: 'info-view',
type: 'info',
title: {
asset: {
id: 'info-title',
type: 'text',
value: 'Info Title',
},
},
},
],
data: {},
navigation: {
BEGIN: 'FLOW_1',
FLOW_1: {
startState: 'VIEW_1',
VIEW_1: {
state_type: 'VIEW',
ref: 'info-view',
transitions: {
'*': 'END_Done',
},
},
END_Done: {
state_type: 'END',
outcome: 'done',
},
},
},
});
expect(ref.current?.segmentedActions).toBeUndefined();
});
});
1 change: 1 addition & 0 deletions plugins/reference-assets/core/src/assets/info/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './transform';
export * from './types';
38 changes: 38 additions & 0 deletions plugins/reference-assets/core/src/assets/info/transform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { TransformFunction } from '@player-ui/player';
import type { AssetWrapper } from '@player-ui/player';
import type { InfoAsset, InfoAssetTransform } from './types';
import type { ActionAsset } from '../action/types';
import { isBackAction } from '../action/transform';

/**
* This transform should add segmentedActions to the info asset.
* Segmented actions display side by side in larger viewports. Segmented Actions is an object of next and prev actions
*/
export const infoTransform: TransformFunction<InfoAsset, InfoAssetTransform> = (
infoAsset
) => {
const actions = infoAsset?.actions;
const segmentedActions = actions?.reduce(
(segmentedActionsArray, action) => {
segmentedActionsArray[
isBackAction(action.asset as ActionAsset) ? 'prev' : 'next'
].push(action as AssetWrapper<ActionAsset>);
return segmentedActionsArray;
},
{ next: [], prev: [] } as {
/**
* next is an array of next actions
*/
next: Array<AssetWrapper<ActionAsset>>;
/**
* prev is an array of prev actions
*/
prev: Array<AssetWrapper<ActionAsset>>;
}
);

return {
...infoAsset,
segmentedActions,
};
};
17 changes: 17 additions & 0 deletions plugins/reference-assets/core/src/assets/info/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { AssetWrapper, Asset } from '@player-ui/player';
import type { ActionAsset } from '../action/types';

export interface InfoAsset extends Asset<'info'> {
/** The string value to show */
Expand All @@ -13,3 +14,19 @@ export interface InfoAsset extends Asset<'info'> {
/** List of actions to show at the bottom of the page */
actions?: Array<AssetWrapper>;
}

export interface InfoAssetTransform extends InfoAsset {
/**
* This is an array of next and prev actions
*/
segmentedActions?: {
/**
* Array of next actions
*/
mercillo marked this conversation as resolved.
Show resolved Hide resolved
next: Array<AssetWrapper<ActionAsset>>;
/**
* Array of prev actions
*/
prev: Array<AssetWrapper<ActionAsset>>;
};
}
3 changes: 2 additions & 1 deletion plugins/reference-assets/core/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Player, PlayerPlugin } from '@player-ui/player';
import { AssetTransformPlugin } from '@player-ui/asset-transform-plugin';
import { inputTransform, actionTransform } from './assets';
import { inputTransform, actionTransform, infoTransform } from './assets';

/**
* A plugin to add transforms for the reference assets
Expand All @@ -13,6 +13,7 @@ export class ReferenceAssetsPlugin implements PlayerPlugin {
new AssetTransformPlugin([
[{ type: 'action' }, actionTransform],
[{ type: 'input' }, inputTransform],
[{ type: 'info' }, infoTransform],
])
);
}
Expand Down
14 changes: 14 additions & 0 deletions plugins/reference-assets/mocks/info/info-basic.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@
}
}
}
},
{
"asset": {
"id": "prev-action",
"value": "Prev",
"type": "action",
"label": {
"asset": {
"id": "next-action-label",
"type": "text",
"value": "Back"
}
}
}
}
]
}
34 changes: 5 additions & 29 deletions plugins/reference-assets/react/src/assets/info/Info.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import React from 'react';
import type {
ActionAsset,
InfoAsset,
} from '@player-ui/reference-assets-plugin';
import { isBackAction } from '@player-ui/reference-assets-plugin';
import type { InfoAssetTransform } from '@player-ui/reference-assets-plugin';
import { ReactAsset } from '@player-ui/react';
import {
ButtonGroup,
Expand All @@ -13,29 +9,9 @@ import {
Stack,
HStack,
} from '@chakra-ui/react';
import type { AssetWrapper } from '@player-ui/react';

/** The info view type is used to show information to the user */
export const Info = (props: InfoAsset) => {
const segmentedActions = React.useMemo(() => {
if (!props.actions?.length) {
return;
}

return props.actions?.reduce(
(memo, next) => {
memo[isBackAction(next.asset as ActionAsset) ? 'prev' : 'next'].push(
next as AssetWrapper<ActionAsset>
);
return memo;
},
{ prev: [], next: [] } as {
prev: Array<AssetWrapper<ActionAsset>>;
next: Array<AssetWrapper<ActionAsset>>;
}
);
}, [props.actions]);

export const Info = (props: InfoAssetTransform) => {
return (
<Box minW={{ base: undefined, md: 'md' }}>
<Stack gap="10">
Expand All @@ -51,15 +27,15 @@ export const Info = (props: InfoAsset) => {
)}
<Box>{props.primaryInfo && <ReactAsset {...props.primaryInfo} />}</Box>
<Stack gap="4">
{segmentedActions && <Divider />}
{props?.segmentedActions && <Divider />}
<HStack justifyContent="space-between">
<ButtonGroup spacing="6">
{segmentedActions?.prev?.map((a) => (
{props?.segmentedActions?.prev?.map((a) => (
<ReactAsset key={a.asset.id} {...a} />
))}
</ButtonGroup>
<ButtonGroup spacing="6">
{segmentedActions?.next?.map((a) => (
{props?.segmentedActions?.next?.map((a) => (
<ReactAsset key={a.asset.id} {...a} />
))}
</ButtonGroup>
Expand Down