diff --git a/plugins/auto-scroll/react/src/__tests__/plugin.test.tsx b/plugins/auto-scroll/react/src/__tests__/plugin.test.tsx index d1f2582f9..338c54636 100644 --- a/plugins/auto-scroll/react/src/__tests__/plugin.test.tsx +++ b/plugins/auto-scroll/react/src/__tests__/plugin.test.tsx @@ -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'; @@ -108,6 +109,7 @@ describe('auto-scroll plugin', () => { new AssetTransformPlugin([ [{ type: 'action' }, actionTransform], [{ type: 'input' }, inputTransform], + [{ type: 'info' }, infoTransform], ]), new CommonTypesPlugin(), new AutoScrollManagerPlugin({ @@ -145,6 +147,7 @@ describe('auto-scroll plugin', () => { new AssetTransformPlugin([ [{ type: 'action' }, actionTransform], [{ type: 'input' }, inputTransform], + [{ type: 'info' }, infoTransform], ]), new CommonTypesPlugin(), new AutoScrollManagerPlugin({ @@ -202,6 +205,7 @@ describe('auto-scroll plugin', () => { new AssetTransformPlugin([ [{ type: 'action' }, actionTransform], [{ type: 'input' }, inputTransform], + [{ type: 'info' }, infoTransform], ]), new CommonTypesPlugin(), new AutoScrollManagerPlugin({ diff --git a/plugins/reference-assets/core/src/assets/info/__tests__/transform.test.ts b/plugins/reference-assets/core/src/assets/info/__tests__/transform.test.ts new file mode 100644 index 000000000..e08268324 --- /dev/null +++ b/plugins/reference-assets/core/src/assets/info/__tests__/transform.test.ts @@ -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(); + }); +}); diff --git a/plugins/reference-assets/core/src/assets/info/index.ts b/plugins/reference-assets/core/src/assets/info/index.ts index fcb073fef..d08fa9a65 100644 --- a/plugins/reference-assets/core/src/assets/info/index.ts +++ b/plugins/reference-assets/core/src/assets/info/index.ts @@ -1 +1,2 @@ +export * from './transform'; export * from './types'; diff --git a/plugins/reference-assets/core/src/assets/info/transform.ts b/plugins/reference-assets/core/src/assets/info/transform.ts new file mode 100644 index 000000000..b507ed6bb --- /dev/null +++ b/plugins/reference-assets/core/src/assets/info/transform.ts @@ -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 +) => { + const actions = infoAsset?.actions; + const segmentedActions = actions?.reduce( + (segmentedActionsArray, action) => { + segmentedActionsArray[ + isBackAction(action.asset as ActionAsset) ? 'prev' : 'next' + ].push(action as AssetWrapper); + return segmentedActionsArray; + }, + { next: [], prev: [] } as { + /** + * next is an array of next actions + */ + next: Array>; + /** + * prev is an array of prev actions + */ + prev: Array>; + } + ); + + return { + ...infoAsset, + segmentedActions, + }; +}; diff --git a/plugins/reference-assets/core/src/assets/info/types.ts b/plugins/reference-assets/core/src/assets/info/types.ts index cfbd5d927..61a50d88b 100644 --- a/plugins/reference-assets/core/src/assets/info/types.ts +++ b/plugins/reference-assets/core/src/assets/info/types.ts @@ -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 */ @@ -13,3 +14,19 @@ export interface InfoAsset extends Asset<'info'> { /** List of actions to show at the bottom of the page */ actions?: Array; } + +export interface InfoAssetTransform extends InfoAsset { + /** + * This is an array of next and prev actions + */ + segmentedActions?: { + /** + * Array of next actions + */ + next: Array>; + /** + * Array of prev actions + */ + prev: Array>; + }; +} diff --git a/plugins/reference-assets/core/src/plugin.ts b/plugins/reference-assets/core/src/plugin.ts index 816e5841d..8b6563931 100644 --- a/plugins/reference-assets/core/src/plugin.ts +++ b/plugins/reference-assets/core/src/plugin.ts @@ -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 @@ -13,6 +13,7 @@ export class ReferenceAssetsPlugin implements PlayerPlugin { new AssetTransformPlugin([ [{ type: 'action' }, actionTransform], [{ type: 'input' }, inputTransform], + [{ type: 'info' }, infoTransform], ]) ); } diff --git a/plugins/reference-assets/mocks/info/info-basic.json b/plugins/reference-assets/mocks/info/info-basic.json index 35f02d0b9..889505996 100644 --- a/plugins/reference-assets/mocks/info/info-basic.json +++ b/plugins/reference-assets/mocks/info/info-basic.json @@ -22,6 +22,20 @@ } } } + }, + { + "asset": { + "id": "prev-action", + "value": "Prev", + "type": "action", + "label": { + "asset": { + "id": "next-action-label", + "type": "text", + "value": "Back" + } + } + } } ] } \ No newline at end of file diff --git a/plugins/reference-assets/react/src/assets/info/Info.tsx b/plugins/reference-assets/react/src/assets/info/Info.tsx index 446b16517..efe422fd0 100644 --- a/plugins/reference-assets/react/src/assets/info/Info.tsx +++ b/plugins/reference-assets/react/src/assets/info/Info.tsx @@ -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, @@ -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 - ); - return memo; - }, - { prev: [], next: [] } as { - prev: Array>; - next: Array>; - } - ); - }, [props.actions]); - +export const Info = (props: InfoAssetTransform) => { return ( @@ -51,15 +27,15 @@ export const Info = (props: InfoAsset) => { )} {props.primaryInfo && } - {segmentedActions && } + {props?.segmentedActions && } - {segmentedActions?.prev?.map((a) => ( + {props?.segmentedActions?.prev?.map((a) => ( ))} - {segmentedActions?.next?.map((a) => ( + {props?.segmentedActions?.next?.map((a) => ( ))}