diff --git a/Composer/packages/adaptive-flow/__tests__/adaptive-flow-renderer/adaptive/AdaptiveDialog.test.tsx b/Composer/packages/adaptive-flow/__tests__/adaptive-flow-renderer/adaptive/AdaptiveDialog.test.tsx
index 7e86d9de73..c588d5329e 100644
--- a/Composer/packages/adaptive-flow/__tests__/adaptive-flow-renderer/adaptive/AdaptiveDialog.test.tsx
+++ b/Composer/packages/adaptive-flow/__tests__/adaptive-flow-renderer/adaptive/AdaptiveDialog.test.tsx
@@ -37,7 +37,7 @@ describe('', () => {
activeTrigger="triggers[0]"
dialogData={dialog}
dialogId="test"
- schema={uischema}
+ uischema={uischema}
widgets={widgets}
onEvent={() => null}
/>
diff --git a/Composer/packages/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx b/Composer/packages/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx
index 50dad3bc4c..70885e352a 100644
--- a/Composer/packages/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx
+++ b/Composer/packages/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx
@@ -7,7 +7,7 @@ import createCache from '@emotion/cache';
import React, { useRef, useMemo, useEffect } from 'react';
import isEqual from 'lodash/isEqual';
import formatMessage from 'format-message';
-import { DialogFactory } from '@bfc/shared';
+import { DialogFactory, SchemaDefinitions } from '@bfc/shared';
import { useShellApi, JSONSchema7, FlowUISchema, FlowWidget } from '@bfc/extension-client';
import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection';
@@ -171,7 +171,8 @@ const VisualDesigner: React.FC = ({ onFocus, onBlur, schema
NodeWrapper: VisualEditorNodeWrapper,
ElementWrapper: VisualEditorElementWrapper,
}}
- schema={{ ...schemaFromPlugins, ...customFlowSchema }}
+ sdkschema={schema?.definitions as SchemaDefinitions}
+ uischema={{ ...schemaFromPlugins, ...customFlowSchema }}
widgets={widgetsFromPlugins}
onEvent={(eventName, eventData) => {
divRef.current?.focus({ preventScroll: true });
diff --git a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/adaptive/AdaptiveDialog.tsx b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/adaptive/AdaptiveDialog.tsx
index c95b098491..d30b1015d9 100644
--- a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/adaptive/AdaptiveDialog.tsx
+++ b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/adaptive/AdaptiveDialog.tsx
@@ -5,7 +5,7 @@
import { jsx } from '@emotion/core';
import { FC, Fragment } from 'react';
import get from 'lodash/get';
-import { FlowEditorWidgetMap, FlowUISchema } from '@bfc/extension-client';
+import { FlowEditorWidgetMap, FlowUISchema, SchemaDefinitions } from '@bfc/extension-client';
import { EditorEventHandler } from '../constants/NodeEventTypes';
import { RendererContext, DefaultRenderers, RendererContextData } from '../contexts/RendererContext';
@@ -30,10 +30,14 @@ export interface AdaptiveDialogProps {
onEvent: EditorEventHandler;
/** UI schema to define how to render a sdk $kind */
- schema: FlowUISchema;
+ uischema: FlowUISchema;
/** All available widgets to render a node */
widgets: FlowEditorWidgetMap;
+
+ /** SDK schema to define the data model of a sdk $kind */
+ sdkschema?: SchemaDefinitions;
+
renderers?: Partial;
}
@@ -42,7 +46,8 @@ export const AdaptiveDialog: FC = ({
dialogData,
activeTrigger,
onEvent,
- schema = builtinSchema,
+ sdkschema,
+ uischema = builtinSchema,
widgets = builtinWidgets,
renderers = {},
}): JSX.Element => {
@@ -55,7 +60,8 @@ export const AdaptiveDialog: FC = ({
({
widgets: {},
schemaProvider: new WidgetSchemaProvider({ default: { widget: () => null } }),
+ sdkschema: {},
});
diff --git a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/utils/visual/widgetRenderer.tsx b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/utils/visual/widgetRenderer.tsx
index 4734ab1d65..78d9dcd3fb 100644
--- a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/utils/visual/widgetRenderer.tsx
+++ b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/utils/visual/widgetRenderer.tsx
@@ -2,22 +2,12 @@
// Licensed under the MIT License.
import React from 'react';
-import { BaseSchema } from '@bfc/shared';
-import { FlowEditorWidgetMap, FlowWidget, FlowWidgetProp, WidgetEventHandler } from '@bfc/extension-client';
+import { FlowEditorWidgetMap, FlowWidget, FlowWidgetProp, WidgetContainerProps } from '@bfc/extension-client';
import { Boundary } from '../../models/Boundary';
import { evaluateWidgetProp, ActionContextKey } from '../expression/widgetExpressionEvaluator';
-export interface UIWidgetContext {
- /** The uniq id of current schema data. Usually a json path. */
- id: string;
-
- /** Declarative json with a $kind field. */
- data: BaseSchema;
-
- /** Handle UI events */
- onEvent: WidgetEventHandler;
-
+export interface UIWidgetContext extends WidgetContainerProps {
/** Report widget boundary */
onResize: (boundary: Boundary) => void;
}
diff --git a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/ActionHeader/ActionHeader.tsx b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/ActionHeader/ActionHeader.tsx
index 1fdeda32e0..875defdb0a 100644
--- a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/ActionHeader/ActionHeader.tsx
+++ b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/ActionHeader/ActionHeader.tsx
@@ -35,6 +35,7 @@ export interface ActionHeaderProps extends WidgetContainerProps {
export const ActionHeader: WidgetComponent = ({
id,
data,
+ adaptiveSchema,
onEvent,
title = '',
disableSDKTitle,
@@ -48,7 +49,7 @@ export const ActionHeader: WidgetComponent = ({
const textCSS = disabled ? DisabledHeaderTextCSS : HeaderTextCSS(colors.color);
const iconColor = disabled ? DisabledIconColor : colors.icon;
- const headerContent = disableSDKTitle ? title : generateSDKTitle(data, title);
+ const headerContent = disableSDKTitle ? title : generateSDKTitle(adaptiveSchema, data, title);
const { NodeMenu } = useContext(RendererContext);
const menuNode =
diff --git a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/AdaptiveAction.tsx b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/AdaptiveAction.tsx
index 4d95e75566..29ecf057a9 100644
--- a/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/AdaptiveAction.tsx
+++ b/Composer/packages/adaptive-flow/src/adaptive-flow-renderer/widgets/AdaptiveAction.tsx
@@ -13,13 +13,14 @@ import { RendererContext } from '../contexts/RendererContext';
import { ElementMeasurer } from '../components/ElementMeasurer';
export const StepRenderer: FC = ({ id, data, onEvent, onResize }): JSX.Element => {
- const { widgets, schemaProvider } = useContext(SchemaContext);
+ const { widgets, schemaProvider, sdkschema } = useContext(SchemaContext);
const { NodeWrapper } = useContext(RendererContext);
const $kind = get(data, '$kind', '');
const widgetSchema = schemaProvider.get($kind);
+ const adaptiveSchema = get(sdkschema, $kind, {});
- const content = renderUIWidget(widgetSchema, widgets, { id, data, onEvent, onResize });
+ const content = renderUIWidget(widgetSchema, widgets, { id, data, adaptiveSchema, onEvent, onResize });
if (widgetSchema.nowrap) {
return content;
}
diff --git a/Composer/packages/client/src/pages/design/VisualEditor.tsx b/Composer/packages/client/src/pages/design/VisualEditor.tsx
index 708cf47a29..86a7424a73 100644
--- a/Composer/packages/client/src/pages/design/VisualEditor.tsx
+++ b/Composer/packages/client/src/pages/design/VisualEditor.tsx
@@ -3,13 +3,14 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
-import React, { useCallback, useState, useEffect } from 'react';
+import React, { useCallback, useState, useEffect, useMemo } from 'react';
import formatMessage from 'format-message';
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
import get from 'lodash/get';
import VisualDesigner from '@bfc/adaptive-flow';
import { useRecoilValue } from 'recoil';
-import { useShellApi } from '@bfc/extension-client';
+import { useFormConfig, useShellApi } from '@bfc/extension-client';
+import cloneDeep from 'lodash/cloneDeep';
import grayComposerIcon from '../../images/grayComposerIcon.svg';
import {
@@ -72,6 +73,21 @@ const VisualEditor: React.FC = (props) => {
const addRef = useCallback((visualEditor) => onboardingAddCoachMarkRef({ visualEditor }), []);
+ const formConfig = useFormConfig();
+ const overridedSDKSchema = useMemo(() => {
+ const sdkSchema = cloneDeep(schemas.sdk?.content ?? {});
+ const sdkDefinitions = sdkSchema.definitions;
+
+ // Override the sdk.schema 'title' field with form ui option 'label' field
+ // to make sure the title is consistent with Form Editor.
+ Object.entries(formConfig).forEach(([$kind, formOptions]) => {
+ if (formOptions && sdkDefinitions[$kind]) {
+ sdkDefinitions[$kind].title = formOptions?.label;
+ }
+ });
+ return sdkSchema;
+ }, [formConfig, schemas]);
+
useEffect(() => {
const dialog = dialogs.find((d) => d.id === dialogId);
const visible = get(dialog, 'triggers', []).length === 0;
@@ -88,7 +104,7 @@ const VisualEditor: React.FC = (props) => {
>
diff --git a/Composer/packages/extension-client/src/types/flowSchema.ts b/Composer/packages/extension-client/src/types/flowSchema.ts
index 172bb57965..b10223e05e 100644
--- a/Composer/packages/extension-client/src/types/flowSchema.ts
+++ b/Composer/packages/extension-client/src/types/flowSchema.ts
@@ -2,7 +2,7 @@
// Licensed under the MIT License.
import { FC, ComponentClass } from 'react';
-import { BaseSchema, SDKKinds } from '@botframework-composer/types';
+import { BaseSchema, JSONSchema7, SDKKinds } from '@botframework-composer/types';
export type FlowEditorWidgetMap = { [widgetName: string]: WidgetComponent };
export enum FlowSchemaBuiltinKeys {
@@ -25,9 +25,18 @@ export type WidgetComponent = FC | ComponentC
export type WidgetEventHandler = (eventName: string, eventData?: any) => void;
export interface WidgetContainerProps {
+ /** The uniq id of current schema data. Usually a json path. */
id: string;
+
+ /** Declarative json with a $kind field. */
data: BaseSchema;
+
+ /** Declarative json's schema from bot-builder sdk. */
+ adaptiveSchema: JSONSchema7;
+
+ /** UI events handler */
onEvent: WidgetEventHandler;
+
[propKey: string]: any;
}
diff --git a/Composer/packages/lib/shared/src/viewUtils.ts b/Composer/packages/lib/shared/src/viewUtils.ts
index abb556db04..7dd0e83d39 100644
--- a/Composer/packages/lib/shared/src/viewUtils.ts
+++ b/Composer/packages/lib/shared/src/viewUtils.ts
@@ -3,9 +3,8 @@
import get from 'lodash/get';
import formatMessage from 'format-message';
-import { SDKKinds } from '@botframework-composer/types';
+import { JSONSchema7, SDKKinds } from '@botframework-composer/types';
-import { conceptLabels as conceptLabelsFn } from './labelMap';
import { PromptTab, PromptTabTitles } from './promptTabs';
export const PROMPT_TYPES = [
@@ -188,13 +187,13 @@ const truncateSDKType = ($kind) => (typeof $kind === 'string' ? $kind.replace('M
* Title priority: $designer.name > title from sdk schema > customize title > $kind suffix
* @param customizedTitile customized title
*/
-export function generateSDKTitle(data, customizedTitle?: string, tab?: PromptTab) {
+export function generateSDKTitle(sdkschema: JSONSchema7, data, customizedTitle?: string, tab?: PromptTab) {
const $kind = get(data, '$kind');
- const titleFromShared = get(conceptLabelsFn(), [$kind, 'title']);
+ const titleFromSDKSchema = get(sdkschema, 'title');
const titleFrom$designer = get(data, '$designer.name');
const titleFrom$kind = truncateSDKType($kind);
- const title = titleFromShared || titleFrom$designer || customizedTitle || titleFrom$kind;
+ const title = titleFrom$designer || titleFromSDKSchema || customizedTitle || titleFrom$kind;
if (tab) {
return `${PromptTabTitles} (${title})`;
}