diff --git a/Composer/packages/client/src/components/AppComponents/MainContainer.tsx b/Composer/packages/client/src/components/AppComponents/MainContainer.tsx
index 70ebc52202..58600cd13c 100644
--- a/Composer/packages/client/src/components/AppComponents/MainContainer.tsx
+++ b/Composer/packages/client/src/components/AppComponents/MainContainer.tsx
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
/** @jsx jsx */
import { jsx, css } from '@emotion/core';
+import { Router } from '@reach/router';
import { NotificationContainer } from '../Notifications/NotificationContainer';
@@ -17,7 +18,9 @@ const main = css`
export const MainContainer = () => {
return (
-
+
+
+
diff --git a/Composer/packages/client/src/components/AppComponents/SideBar.tsx b/Composer/packages/client/src/components/AppComponents/SideBar.tsx
index 3e6f00c4f7..c0028aeb86 100644
--- a/Composer/packages/client/src/components/AppComponents/SideBar.tsx
+++ b/Composer/packages/client/src/components/AppComponents/SideBar.tsx
@@ -9,6 +9,7 @@ import formatMessage from 'format-message';
import { IconButton } from 'office-ui-fabric-react/lib/Button';
import { FocusZone } from 'office-ui-fabric-react/lib/FocusZone';
import { TooltipHost, DirectionalHint } from 'office-ui-fabric-react/lib/Tooltip';
+import { RouteComponentProps } from '@reach/router';
import { resolveToBasePath } from '../../utils/fileUtil';
import { BASEPATH } from '../../constants';
@@ -64,7 +65,7 @@ const divider = (isExpand: boolean) => css`
// -------------------- SideBar -------------------- //
-export const SideBar = () => {
+export const SideBar: React.FC
= () => {
const [sideBarExpand, setSideBarExpand] = useState(false);
const { topLinks, bottomLinks } = useLinks();
diff --git a/Composer/packages/client/src/pages/design/CommandBar.tsx b/Composer/packages/client/src/pages/design/CommandBar.tsx
index 5967dc84f5..70a1fc5320 100644
--- a/Composer/packages/client/src/pages/design/CommandBar.tsx
+++ b/Composer/packages/client/src/pages/design/CommandBar.tsx
@@ -16,15 +16,17 @@ import {
dispatcherState,
rootBotProjectIdSelector,
currentDialogState,
+ designPageLocationState,
} from '../../recoilModel';
import { undoFunctionState } from '../../recoilModel/undo/history';
import { undoStatusSelectorFamily } from '../../recoilModel/selectors/undo';
import { DiagnosticsHeader } from '../../components/DiagnosticsHeader';
import TelemetryClient from '../../telemetry/TelemetryClient';
-type CommandBarProps = { dialogId?: string; projectId: string };
+type CommandBarProps = { projectId: string };
-const CommandBar: React.FC = ({ dialogId, projectId }) => {
+const CommandBar: React.FC = React.memo(({ projectId }) => {
+ const { dialogId } = useRecoilValue(designPageLocationState(projectId));
const currentDialog = useRecoilValue(currentDialogState({ dialogId, projectId }));
const { undo, redo, clearUndo } = useRecoilValue(undoFunctionState(projectId));
const rootProjectId = useRecoilValue(rootBotProjectIdSelector) ?? projectId;
@@ -185,6 +187,6 @@ const CommandBar: React.FC = ({ dialogId, projectId }) => {
);
-};
+});
export default CommandBar;
diff --git a/Composer/packages/client/src/pages/design/DesignPage.tsx b/Composer/packages/client/src/pages/design/DesignPage.tsx
index 1f6deaa7cd..49c474e7dd 100644
--- a/Composer/packages/client/src/pages/design/DesignPage.tsx
+++ b/Composer/packages/client/src/pages/design/DesignPage.tsx
@@ -22,8 +22,9 @@ import Modals from './Modals';
const DesignPage: React.FC> = (
props
) => {
- const { dialogId, projectId = '', skillId, location } = props;
- useEmptyPropsHandler(projectId, location, skillId, dialogId);
+ const { projectId = '', skillId, location } = props;
+
+ useEmptyPropsHandler(projectId, location, skillId, props.dialogId);
const { setPageElementState } = useRecoilValue(dispatcherState);
const onMeasuredSizesChanged = (sizes: SplitMeasuredSizes) => {
@@ -43,9 +44,9 @@ const DesignPage: React.FC
-
+
-
+
diff --git a/Composer/packages/client/src/pages/design/PropertyPanel.tsx b/Composer/packages/client/src/pages/design/PropertyPanel.tsx
index e9a0b7653d..cd7580239e 100644
--- a/Composer/packages/client/src/pages/design/PropertyPanel.tsx
+++ b/Composer/packages/client/src/pages/design/PropertyPanel.tsx
@@ -26,7 +26,7 @@ type PropertyViewProps = {
isSkill: boolean;
};
-const PropertyPanel: React.FC = ({ projectId = '', isSkill = false }) => {
+const PropertyPanel: React.FC = React.memo(({ projectId = '', isSkill = false }) => {
const schemas = useRecoilValue(schemasState(projectId));
const focusPath = useRecoilValue(focusPathState(projectId));
const undoVersion = useRecoilValue(undoVersionState(projectId));
@@ -58,6 +58,6 @@ const PropertyPanel: React.FC = ({ projectId = '', isSkill =
)}
);
-};
+});
export default PropertyPanel;
diff --git a/Composer/packages/client/src/pages/design/SideBar.tsx b/Composer/packages/client/src/pages/design/SideBar.tsx
index e04dd214ac..36bb2fac26 100644
--- a/Composer/packages/client/src/pages/design/SideBar.tsx
+++ b/Composer/packages/client/src/pages/design/SideBar.tsx
@@ -65,9 +65,10 @@ const parseTriggerId = (triggerId: string | undefined): number | undefined => {
return parseInt(indexString);
};
-type SideBarProps = { dialogId: string; projectId: string };
+type SideBarProps = { projectId: string };
-const SideBar: React.FC = ({ dialogId, projectId }) => {
+const SideBar: React.FC = React.memo(({ projectId }) => {
+ const { dialogId, selected: encodedSelected } = useRecoilValue(designPageLocationState(projectId));
const currentDialog = useRecoilValue(currentDialogState({ dialogId, projectId }));
const dialogs = useRecoilValue(dialogsSelectorFamily(projectId));
const projectDialogsMap = useRecoilValue(projectDialogsMapSelector);
@@ -75,7 +76,6 @@ const SideBar: React.FC = ({ dialogId, projectId }) => {
const undoFunction = useRecoilValue(undoFunctionState(projectId));
const rootProjectId = useRecoilValue(rootBotProjectIdSelector);
const { commitChanges } = undoFunction;
- const designPageLocation = useRecoilValue(designPageLocationState(projectId));
const {
removeDialog,
@@ -93,7 +93,7 @@ const SideBar: React.FC = ({ dialogId, projectId }) => {
const skillUsedInBotsMap = useRecoilValue(skillUsedInBotsSelector);
const selected = decodeDesignerPathToArrayPath(
dialogs.find((x) => x.id === dialogId)?.content,
- designPageLocation.selected || ''
+ encodedSelected || ''
);
const setTriggerModalInfo = useSetRecoilState(triggerModalInfoState);
@@ -287,6 +287,6 @@ const SideBar: React.FC = ({ dialogId, projectId }) => {
/>
);
-};
+});
export default SideBar;
diff --git a/Composer/packages/client/src/pages/design/VisualEditor.tsx b/Composer/packages/client/src/pages/design/VisualEditor.tsx
index 74ffc7a710..430652d915 100644
--- a/Composer/packages/client/src/pages/design/VisualEditor.tsx
+++ b/Composer/packages/client/src/pages/design/VisualEditor.tsx
@@ -10,7 +10,7 @@ import get from 'lodash/get';
import VisualDesigner from '@bfc/adaptive-flow';
import { useRecoilValue } from 'recoil';
import { useFormConfig, useShellApi } from '@bfc/extension-client';
-import cloneDeep from 'lodash/cloneDeep';
+import clone from 'lodash/clone';
import grayComposerIcon from '../../images/grayComposerIcon.svg';
import { dispatcherState, dialogsSelectorFamily, schemasState, designPageLocationState } from '../../recoilModel';
@@ -77,20 +77,18 @@ const VisualEditor: React.FC = (props) => {
const formConfig = useFormConfig();
const overridedSDKSchema = useMemo(() => {
if (!dialogId) return {};
-
- const sdkSchema = cloneDeep(schemas.sdk?.content ?? {});
- const sdkDefinitions = sdkSchema.definitions;
-
+ const sdkSchema = schemas.sdk?.content ?? {};
+ const sdkDefinitions = clone(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;
+ const sdkOptions = sdkDefinitions[$kind];
+ if (formOptions && sdkOptions) {
+ sdkDefinitions[$kind] = { ...sdkOptions, title: formOptions.label };
}
});
- return sdkSchema;
+ return { ...sdkSchema, definitions: sdkDefinitions };
}, [formConfig, schemas, dialogId]);
-
useEffect(() => {
const dialog = dialogs.find((d) => d.id === dialogId);
const visible = dialog ? get(dialog, 'triggers', []).length === 0 : false;
diff --git a/Composer/packages/client/src/pages/design/VisualPanel.tsx b/Composer/packages/client/src/pages/design/VisualPanel.tsx
index 45065e888b..aa28fc6e5a 100644
--- a/Composer/packages/client/src/pages/design/VisualPanel.tsx
+++ b/Composer/packages/client/src/pages/design/VisualPanel.tsx
@@ -29,19 +29,18 @@ import VisualEditorWrapper from './VisualEditorWrapper';
type VisualPanelProps = {
projectId: string;
- dialogId?: string;
};
-const VisualPanel: React.FC = ({ projectId, dialogId }) => {
+const VisualPanel: React.FC = React.memo(({ projectId }) => {
+ const { dialogId, selected: encodedSelected } = useRecoilValue(designPageLocationState(projectId));
const userSettings = useRecoilValue(userSettingsState);
const currentDialog = useRecoilValue(currentDialogState({ dialogId, projectId }));
const schemas = useRecoilValue(schemasState(projectId));
const { isRemote: isRemoteSkill } = useRecoilValue(projectMetaDataState(projectId));
- const designPageLocation = useRecoilValue(designPageLocationState(projectId));
const { updateDialog, navTo } = useRecoilValue(dispatcherState);
- const selected = decodeDesignerPathToArrayPath(currentDialog?.content, designPageLocation.selected || '');
+ const selected = decodeDesignerPathToArrayPath(currentDialog?.content, encodedSelected || '');
const [dialogJsonVisible, setDialogJsonVisibility] = useState(false);
const [warningIsVisible, setWarningIsVisible] = useState(true);
@@ -50,7 +49,7 @@ const VisualPanel: React.FC = ({ projectId, dialogId }) => {
if (!warningIsVisible) {
setWarningIsVisible(true);
}
- }, [dialogId, designPageLocation]);
+ }, [dialogId, encodedSelected]);
const pluginConfig: PluginConfig = useMemo(() => {
const sdkUISchema = schemas?.ui?.content ?? {};
@@ -100,6 +99,6 @@ const VisualPanel: React.FC = ({ projectId, dialogId }) => {
)}
);
-};
+});
export default VisualPanel;