Skip to content

Commit

Permalink
chore: migrate SendActivity, BeginDialog, ReplaceDialog to uischema (#…
Browse files Browse the repository at this point in the history
…1840)

* render fallback node

* fix the problem in a more schema-driven way

* revert unnecessary changes

* extend builtin props: id, data, onEvent

* migrate widget ActionCard to new base props

* retire DefaultRenderer

* make ActivityRenderer a widget

* make 'icon' customizable

* update sdk demp

* register 'SendActivity' in uischema

* drive ReplaceDialog, BeginDialog

* fix lint

* render BeginDialog, ReplaceDialog with UISchemaRenderer

* leverage fabric <Link /> as dialog ref
  • Loading branch information
yeze322 authored and a-b-r-o-w-n committed Jan 13, 2020
1 parent a255210 commit a8c348e
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const DemoMaps = {

class Demo extends Component {
state = {
selectedItem: DemoMaps.VisualEditorDemo.key,
selectedItem: DemoMaps.VisualSDKDemo.key,
};

renderNav() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { seedNewDialog, SDKTypes } from '@bfc/shared';

import { renderSDKType } from '../../../src/schema/uischemaRenderer';
import { UISchemaRenderer } from '../../../src/schema/uischemaRenderer';
import { EdgeMenu } from '../../../src/components/menus/EdgeMenu';
import { JsonBlock } from '../components/json-block';

Expand All @@ -14,13 +14,17 @@ export class VisualSDKDemo extends Component {

seedInitialActions() {
const initialTypes = [
SDKTypes.SendActivity,
SDKTypes.EditArray,
SDKTypes.InitProperty,
SDKTypes.SetProperties,
SDKTypes.SetProperty,
SDKTypes.DeleteProperties,
SDKTypes.DeleteProperty,
SDKTypes.BeginDialog,
SDKTypes.EndDialog,
SDKTypes.RepeatDialog,
SDKTypes.ReplaceDialog,
SDKTypes.CancelAllDialogs,
SDKTypes.EmitEvent,
];
Expand Down Expand Up @@ -58,7 +62,9 @@ export class VisualSDKDemo extends Component {
}}
/>
</div>
<div className="action-preview--visual">{renderSDKType(action)}</div>
<div className="action-preview--visual">
<UISchemaRenderer id={`actions[${index}]`} data={action} onEvent={() => null} />
</div>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export * from './steps/ActivityRenderer';
export * from './steps/BeginDialog';
export * from './steps/ReplaceDialog';
export * from './steps/ChoiceInput';
export * from './steps/TextInput';
export * from './steps/BotAsks';
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,20 @@ import { ObiTypes } from '../../constants/ObiTypes';
import { AttrNames } from '../../constants/ElementAttributes';
import { NodeRendererContext } from '../../store/NodeRendererContext';
import { SelectionContext } from '../../store/SelectionContext';
import {
BeginDialog,
ReplaceDialog,
ActivityRenderer,
ChoiceInput,
BotAsks,
UserInput,
InvalidPromptBrick,
} from '../nodes/index';
import { ChoiceInput, BotAsks, UserInput, InvalidPromptBrick } from '../nodes/index';
import { ConditionNode } from '../nodes/steps/ConditionNode';
import { ForeachDetail } from '../nodes/steps/ForeachDetail';
import { ForeachPageDetail } from '../nodes/steps/ForeachPageDetail';
import { NodeProps, defaultNodeProps } from '../nodes/nodeProps';
import { UISchemaRenderer } from '../../schema/uischemaRenderer';

const rendererByObiType = {
[ObiTypes.BeginDialog]: BeginDialog,
[ObiTypes.ConditionNode]: ConditionNode,
[ObiTypes.ForeachDetail]: ForeachDetail,
[ObiTypes.ForeachPageDetail]: ForeachPageDetail,
[ObiTypes.ReplaceDialog]: ReplaceDialog,
[ObiTypes.SendActivity]: ActivityRenderer,
[ObiTypes.BeginDialog]: UISchemaRenderer,
[ObiTypes.ReplaceDialog]: UISchemaRenderer,
[ObiTypes.SendActivity]: UISchemaRenderer,
[ObiTypes.ChoiceInputDetail]: ChoiceInput,
[ObiTypes.BotAsks]: BotAsks,
[ObiTypes.UserAnswers]: UserInput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,38 @@
// Licensed under the MIT License.

import { SDKTypes } from '@bfc/shared';
import React from 'react';

import { ActionCard } from '../widgets/ActionCard';
import { ActivityRenderer } from '../widgets/ActivityRenderer';
import { DialogRefCard } from '../widgets/DialogRefCard';
import { ElementIcon } from '../utils/obiPropertyResolver';
import { ObiColors } from '../constants/ElementColors';

import { UISchema } from './uischema.types';

export const uiSchema: UISchema = {
default: {
'ui:widget': ActionCard,
},
[SDKTypes.SendActivity]: {
'ui:widget': ActivityRenderer,
field: 'activity',
icon: ElementIcon.MessageBot,
colors: {
theme: ObiColors.BlueMagenta20,
icon: ObiColors.BlueMagenta30,
},
},
[SDKTypes.BeginDialog]: {
'ui:widget': DialogRefCard,
dialog: data => data.dialog,
},
[SDKTypes.ReplaceDialog]: {
'ui:widget': DialogRefCard,
dialog: data => data.dialog,
getRefContent: data => dialogRef => <>Switch to {dialogRef}</>,
},
[SDKTypes.EditArray]: {
'ui:widget': ActionCard,
content: data => `${data.changeType} {${data.itemsProperty || '?'}}`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { generateSDKTitle } from '@bfc/shared';
import get from 'lodash/get';

import { NodeEventTypes } from '../constants/NodeEventTypes';
import { ElementIcon } from '../utils/obiPropertyResolver';
import { NodeMenu } from '../components/menus/NodeMenu';
import { FormCard } from '../components/nodes/templates/FormCard';
import { useLgTemplate } from '../utils/hooks';
import { WidgetContainerProps } from '../schema/uischema.types';
import { ObiColors } from '../constants/ElementColors';

export interface ActivityRenderer extends WidgetContainerProps {
/** indicates which field contains lg activity. ('activity', 'prompt', 'invalidPropmt'...) */
field: string;
icon: ElementIcon;
colors?: {
theme: string;
icon: string;
};
}

const DefaultThemeColor = {
theme: ObiColors.BlueMagenta20,
icon: ObiColors.BlueMagenta30,
};

export const ActivityRenderer: React.FC<ActivityRenderer> = ({
id,
data,
onEvent,
field,
icon = ElementIcon.MessageBot,
colors = DefaultThemeColor,
}) => {
const designerId = get(data, '$designer.id');
const activityTemplate = get(data, field, '');

const templateText = useLgTemplate(activityTemplate, designerId);
const nodeColors = { themeColor: colors.theme, iconColor: colors.icon };

return (
<FormCard
header={generateSDKTitle(data)}
label={templateText}
icon={icon}
corner={<NodeMenu id={id} onEvent={onEvent} />}
nodeColors={nodeColors}
onClick={() => {
onEvent(NodeEventTypes.Focus, { id });
}}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

/** @jsx jsx */
import { jsx } from '@emotion/core';
import { generateSDKTitle } from '@bfc/shared';
import get from 'lodash/get';
import { Link } from 'office-ui-fabric-react/lib/Link';

import { FormCard } from '../components/nodes/templates/FormCard';
import { WidgetContainerProps, WidgetComponent } from '../schema/uischema.types';
import { ObiColors } from '../constants/ElementColors';
import { NodeEventTypes } from '../constants/NodeEventTypes';
import { NodeMenu } from '../components/menus/NodeMenu';

export interface DialogRefCardProps extends WidgetContainerProps {
dialog: string | object;
getRefContent?: (dialogRef: JSX.Element) => JSX.Element;
colors?: {
theme: string;
icon: string;
};
}

const DefaultCardColor = {
theme: ObiColors.AzureGray3,
icon: ObiColors.AzureGray2,
};

export const DialogRefCard: WidgetComponent<DialogRefCardProps> = ({
id,
data,
onEvent,
dialog,
getRefContent,
colors = DefaultCardColor,
}) => {
const header = generateSDKTitle(data);
const nodeColors = { themeColor: colors.theme, iconColor: colors.icon };
const calleeDialog = typeof dialog === 'object' ? get(dialog, '$ref') : dialog;
const dialogRef = (
<Link
onClick={e => {
e.stopPropagation();
onEvent(NodeEventTypes.OpenDialog, { caller: id, callee: calleeDialog });
}}
>
{calleeDialog}
</Link>
);
return (
<FormCard
header={header}
corner={<NodeMenu id={id} onEvent={onEvent} />}
label={typeof getRefContent === 'function' ? getRefContent(dialogRef) : dialogRef}
nodeColors={nodeColors}
onClick={() => onEvent(NodeEventTypes.Focus, { id })}
/>
);
};

0 comments on commit a8c348e

Please sign in to comment.