Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
11 changes: 10 additions & 1 deletion Composer/packages/client/src/ShellApi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useContext, useRef, useMemo } from 'react';
import React, { useEffect, useContext, useRef, useMemo, useState } from 'react';
import { debounce, isEqual, get } from 'lodash';

import { parseLgTemplate, checkLgContent, updateTemplateInContent } from '../src/store/action/lg';
Expand Down Expand Up @@ -65,6 +65,10 @@ const shellNavigator = (shellPage: string, opts: { id?: string } = {}) => {
};

export const ShellApi: React.FC = () => {
// HACK: `onSelect` should actually change some states
// TODO: (leilei, ze) fix it when refactoring shell state management.
const [, forceUpdate] = useState();

const { state, actions } = useContext(StoreContext);
const { dialogs, schemas, lgFiles, luFiles, designPageLocation, focusPath, breadcrumb } = state;
const updateDialog = actions.updateDialog;
Expand Down Expand Up @@ -101,6 +105,7 @@ export const ShellApi: React.FC = () => {
apiClient.registerApi('navTo', navTo);
apiClient.registerApi('onFocusEvent', focusEvent);
apiClient.registerApi('onFocusSteps', focusSteps);
apiClient.registerApi('onSelect', onSelect);
apiClient.registerApi('shellNavigate', ({ shellPage, opts }) => shellNavigator(shellPage, opts));
apiClient.registerApi('isExpression', ({ expression }) => isExpression(expression));
apiClient.registerApi('createDialog', () => {
Expand Down Expand Up @@ -308,5 +313,9 @@ export const ShellApi: React.FC = () => {
actions.focusTo(dataPath);
}

function onSelect(ids) {
forceUpdate(ids);
}

return null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ const shellApi = {
return apiClient.apiCall('onFocusSteps', { subPaths });
},

onSelect: (ids: string[]) => {
return apiClient.apiCall('onSelect', { ids });
},

shellNavigate: (shellPage, opts = {}) => {
return apiClient.apiCall('shellNavigate', { shellPage, opts });
},
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/client/src/messenger/FrameAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const VisualEditorAPI = (() => {

return {
hasElementFocused: () => visualEditorFrameAPI.invoke('hasElementFocused'),
hasElementSelected: () => visualEditorFrameAPI.invoke('hasElementSelected'),
hasElementSelected: () => visualEditorFrameAPI.invoke('hasElementSelected').catch(() => false),
copySelection: () => visualEditorFrameAPI.invoke('copySelection'),
cutSelection: () => visualEditorFrameAPI.invoke('cutSelection'),
deleteSelection: () => visualEditorFrameAPI.invoke('deleteSelection'),
Expand Down
16 changes: 9 additions & 7 deletions Composer/packages/client/src/pages/design/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,15 @@ function DesignPage(props) {
}
};

VisualEditorAPI.hasElementSelected()
.then(selected => {
setNodeOperationAvailability(selected);
})
.catch(() => {
setNodeOperationAvailability(false);
});
useEffect(() => {
// HACK: wait until visual editor finish rerender.
// TODO: (ze) expose visual editor store to Shell and (leilei) intercept store events.
setTimeout(() => {
VisualEditorAPI.hasElementSelected().then(selected => {
setNodeOperationAvailability(selected);
});
}, 100);
});

const toolbarItems = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const ObiEditor: FC<ObiEditorProps> = ({
onFocusSteps,
onOpen,
onChange,
onSelect,
}): JSX.Element | null => {
let divRef;

Expand Down Expand Up @@ -159,11 +160,10 @@ export const ObiEditor: FC<ObiEditorProps> = ({
} else {
setKeyBoardStatus('normal');
}
}, [focusedId, selectionContext]);

useEffect(() => {
onChange(data);
}, [selectionContext]);
// Notify container at every selection change.
onSelect(selectionContext.selectedIds);
}, [focusedId, selectionContext]);

useEffect(
(): void => {
Expand Down Expand Up @@ -309,6 +309,7 @@ ObiEditor.defaultProps = {
onFocusEvent: () => {},
onOpen: () => {},
onChange: () => {},
onSelect: () => {},
};

interface ObiEditorProps {
Expand All @@ -321,4 +322,5 @@ interface ObiEditorProps {
onFocusEvent: (eventId: string) => any;
onOpen: (calleeDialog: string, callerId: string) => any;
onChange: (newDialog: any) => any;
onSelect: (selection: any) => any;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const VisualDesigner: React.FC<VisualDesignerProps> = ({
}

const data = dataCache.current;
const { navTo, onFocusEvent, onFocusSteps, saveData, getLgTemplates, removeLgTemplate } = shellApi;
const { navTo, onFocusEvent, onFocusSteps, onSelect, saveData, getLgTemplates, removeLgTemplate } = shellApi;

const focusedId = Array.isArray(focusedSteps) && focusedSteps[0] ? focusedSteps[0] : '';

Expand Down Expand Up @@ -63,6 +63,7 @@ const VisualDesigner: React.FC<VisualDesignerProps> = ({
onFocusEvent={onFocusEvent}
onOpen={(x, rest) => navTo(x, rest)}
onChange={x => saveData(x)}
onSelect={onSelect}
/>
</div>
</NodeRendererContext.Provider>
Expand All @@ -87,6 +88,7 @@ VisualDesigner.defaultProps = {
navTo: () => {},
onFocusEvent: (eventId: string) => {},
onFocusSteps: (stepIds: string[]) => {},
onSelect: (ids: string[]) => {},
saveData: () => {},
},
};
Expand Down