Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Move #2206

Merged
merged 10 commits into from
Mar 12, 2020
4 changes: 2 additions & 2 deletions Composer/packages/client/src/ShellApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,9 @@ export const ShellApi: React.FC = () => {
apiClient.registerApi('onSelect', onSelect);
apiClient.registerApi('onCopy', onCopy);
apiClient.registerApi('isExpression', ({ expression }) => isExpression(expression));
apiClient.registerApi('createDialog', () => {
apiClient.registerApi('createDialog', actionsSeed => {
return new Promise(resolve => {
actions.createDialogBegin((newDialog: string | null) => {
actions.createDialogBegin(actionsSeed, (newDialog: string | null) => {
resolve(newDialog);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ const shellApi: ShellApi = {
return apiClient.apiCall('removeLuIntent', { id, intentName });
},

updateRegExIntent: (id, intentName, pattern) => {
return apiClient.apiCall('updateRegExIntent', { id, intentName, pattern });
createDialog: actions => {
return apiClient.apiCall('createDialog', { actions });
},

createDialog: () => {
return apiClient.apiCall('createDialog');
updateRegExIntent: (id, intentName, pattern) => {
return apiClient.apiCall('updateRegExIntent', { id, intentName, pattern });
},

validateExpression: expression => {
Expand Down
1 change: 1 addition & 0 deletions Composer/packages/client/src/messenger/FrameAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const VisualEditorAPI = (() => {
hasElementSelected: () => visualEditorFrameAPI.invoke('hasElementSelected').catch(() => false),
copySelection: () => visualEditorFrameAPI.invoke('copySelection'),
cutSelection: () => visualEditorFrameAPI.invoke('cutSelection'),
moveSelection: () => visualEditorFrameAPI.invoke('moveSelection'),
deleteSelection: () => visualEditorFrameAPI.invoke('deleteSelection'),
};
})();
14 changes: 13 additions & 1 deletion Composer/packages/client/src/pages/design/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,18 @@ function DesignPage(props) {
align: 'left',
disabled: !nodeOperationAvailable,
},
{
type: 'action',
text: formatMessage('Move'),
buttonProps: {
iconProps: {
iconName: 'Share',
},
onClick: () => VisualEditorAPI.moveSelection(),
},
align: 'left',
disabled: !nodeOperationAvailable,
},
{
type: 'action',
text: formatMessage('Delete'),
Expand Down Expand Up @@ -313,7 +325,7 @@ function DesignPage(props) {

async function onSubmit(data: { name: string; description: string }) {
const content = { ...getNewDesigner(data.name, data.description), generator: `${data.name}.lg` };
const seededContent = seedNewDialog('Microsoft.AdaptiveDialog', content.$designer, content);
const seededContent = seedNewDialog('Microsoft.AdaptiveDialog', content.$designer, content, state.actionsSeed);
await actions.createDialog({ id: data.name, content: seededContent });
}

Expand Down
3 changes: 2 additions & 1 deletion Composer/packages/client/src/store/action/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ export const updateDialog: ActionCreator = undoable(
updateDialogBase
);

export const createDialogBegin: ActionCreator = ({ dispatch }, onComplete) => {
export const createDialogBegin: ActionCreator = ({ dispatch }, { actions }, onComplete) => {
dispatch({
type: ActionTypes.CREATE_DIALOG_BEGIN,
payload: {
actionsSeed: actions,
onComplete,
},
});
Expand Down
1 change: 1 addition & 0 deletions Composer/packages/client/src/store/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const initialState: State = {
lgFiles: [],
schemas: { editor: {} },
luFiles: [],
actionsSeed: [],
designPageLocation: {
dialogId: '',
focused: '',
Expand Down
4 changes: 3 additions & 1 deletion Composer/packages/client/src/store/reducer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ const removeDialog: ReducerFunc = (state, { response }) => {
return state;
};

const createDialogBegin: ReducerFunc = (state, { onComplete }) => {
const createDialogBegin: ReducerFunc = (state, { actionsSeed, onComplete }) => {
state.showCreateDialogModal = true;
state.actionsSeed = actionsSeed;
state.onCreateDialogComplete = onComplete;
return state;
};
Expand All @@ -105,6 +106,7 @@ const createDialogSuccess: ReducerFunc = (state, { response }) => {
state.luFiles = response.data.luFiles;
state.lgFiles = response.data.lgFiles;
state.showCreateDialogModal = false;
state.actionsSeed = [];
delete state.onCreateDialogComplete;
return state;
};
Expand Down
1 change: 1 addition & 0 deletions Composer/packages/client/src/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export interface State {
showCreateDialogModal: boolean;
isEnvSettingUpdated: boolean;
settings: DialogSetting;
actionsSeed: any;
onCreateDialogComplete?: (dialogId: string | null) => void;
toStartBot: boolean;
currentUser: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const DialogSelectWidget: React.FC<BFDWidgetProps> = props => {
if (option) {
if (option.key === ADD_DIALOG) {
setComboboxTitle(formatMessage('Create a new dialog'));
formContext.shellApi.createDialog().then(newDialog => {
formContext.shellApi.createDialog({ actions: [] }).then(newDialog => {
if (newDialog) {
onChange(newDialog);
setTimeout(() => formContext.shellApi.navTo(newDialog), 500);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export enum NodeEventTypes {
InsertEvent = 'event.data.insert-event',
CopySelection = 'event.data.copy-selection',
CutSelection = 'event.data.cut-selection',
MoveSelection = 'event.data.move-selection',
DeleteSelection = 'event.data.delete-selection',
AppendSelection = 'event.data.paste-selection--keyboard',
InsertSelection = 'event.data.paste-selection--menu',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { jsx } from '@emotion/core';
import { useContext, FC, useEffect, useState, useRef } from 'react';
import { MarqueeSelection, Selection } from 'office-ui-fabric-react/lib/MarqueeSelection';
import { deleteAction, deleteActions, LgTemplateRef, LgMetaData } from '@bfc/shared';
import querystring from 'query-string';
import { SDKTypes } from '@bfc/shared';

import { NodeEventTypes } from '../constants/NodeEventTypes';
import { KeyboardCommandTypes, KeyboardPrimaryTypes } from '../constants/KeyboardCommandTypes';
Expand Down Expand Up @@ -37,6 +39,7 @@ export const ObiEditor: FC<ObiEditorProps> = ({
onClipboardChange,
onOpen,
onChange,
onCreateDialog,
onSelect,
undo,
redo,
Expand Down Expand Up @@ -140,6 +143,30 @@ export const ObiEditor: FC<ObiEditorProps> = ({
onClipboardChange(cutData);
};
break;
case NodeEventTypes.MoveSelection:
handler = e => {
const copiedActions = copyNodes(data, e.actionIds);
onCreateDialog(copiedActions).then(d => {
const startIndex = e.actionIds[0].indexOf('actions[');
const position = parseInt(e.actionIds[0][startIndex + 8]);
const deleteResult = deleteNodes(data, e.actionIds, nodes =>
deleteActions(nodes, deleteLgTemplates, deleteLuIntents)
);
const queryString = querystring.parseUrl(parent.location.href);
const insertResult = insert(
deleteResult,
`${queryString.query.selected}.actions`,
position,
SDKTypes.BeginDialog,
{
dialog: d,
}
);
onChange(insertResult);
});
onFocusSteps([]);
};
break;
case NodeEventTypes.DeleteSelection:
handler = e => {
const dialog = deleteNodes(data, e.actionIds, nodes =>
Expand Down Expand Up @@ -239,6 +266,8 @@ export const ObiEditor: FC<ObiEditorProps> = ({
dispatchEvent(NodeEventTypes.CopySelection, { actionIds: getClipboardTargetsFromContext() });
(window as any).cutSelection = () =>
dispatchEvent(NodeEventTypes.CutSelection, { actionIds: getClipboardTargetsFromContext() });
(window as any).moveSelection = () =>
dispatchEvent(NodeEventTypes.MoveSelection, { actionIds: getClipboardTargetsFromContext() });
(window as any).deleteSelection = () =>
dispatchEvent(NodeEventTypes.DeleteSelection, { actionIds: getClipboardTargetsFromContext() });

Expand Down Expand Up @@ -352,6 +381,7 @@ interface ObiEditorProps {
focusedEvent: string;
onFocusEvent: (eventId: string) => any;
onClipboardChange: (actions: any[]) => void;
onCreateDialog: (actions: any[]) => Promise<string>;
onOpen: (calleeDialog: string, callerId: string) => any;
onChange: (newDialog: any) => any;
onSelect: (ids: string[]) => any;
Expand Down
2 changes: 2 additions & 0 deletions Composer/packages/extensions/visual-designer/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const VisualDesigner: React.FC<VisualDesignerProps> = ({
onSelect,
onCopy,
saveData,
createDialog,
updateLgTemplate,
getLgTemplates,
copyLgTemplate,
Expand Down Expand Up @@ -97,6 +98,7 @@ const VisualDesigner: React.FC<VisualDesignerProps> = ({
focusedEvent={focusedEvent}
onFocusEvent={onFocusEvent}
onClipboardChange={onCopy}
onCreateDialog={createDialog}
onOpen={x => navTo(x)}
onChange={x => saveData(x)}
onSelect={onSelect}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ export function deleteNodes(inputDialog, nodeIds: string[], callbackOnRemovedDat
return dialog;
}

export function insert(inputDialog, path, position, $type) {
export function insert(inputDialog, path, position, $type, extra = {}) {
const dialog = cloneDeep(inputDialog);
const current = get(dialog, path, []);
const newStep = {
$type,
...seedNewDialog($type, { name: generateSDKTitle({ $type }) }),
...seedNewDialog($type, { name: generateSDKTitle({ $type }) }, extra),
};

const insertAt = typeof position === 'undefined' ? current.length : position;
Expand Down
30 changes: 16 additions & 14 deletions Composer/packages/lib/shared/src/dialogFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ const initialInputDialog = {
};

const initialDialogShape = {
[SDKTypes.AdaptiveDialog]: {
[SDKTypes.AdaptiveDialog]: seededActions => ({
$type: SDKTypes.AdaptiveDialog,
triggers: [
{
$type: SDKTypes.OnBeginDialog,
...getNewDesigner('BeginDialog', ''),
actions: [...seededActions],
},
],
},
[SDKTypes.OnConversationUpdateActivity]: {
}),
[SDKTypes.OnConversationUpdateActivity]: () => ({
$type: 'Microsoft.OnConversationUpdateActivity',
actions: [
{
Expand All @@ -55,16 +56,16 @@ const initialDialogShape = {
],
},
],
},
[SDKTypes.SendActivity]: {
}),
[SDKTypes.SendActivity]: () => ({
activity: '',
},
[SDKTypes.AttachmentInput]: initialInputDialog,
[SDKTypes.ChoiceInput]: initialInputDialog,
[SDKTypes.ConfirmInput]: initialInputDialog,
[SDKTypes.DateTimeInput]: initialInputDialog,
[SDKTypes.NumberInput]: initialInputDialog,
[SDKTypes.TextInput]: initialInputDialog,
}),
[SDKTypes.AttachmentInput]: () => initialInputDialog,
[SDKTypes.ChoiceInput]: () => initialInputDialog,
[SDKTypes.ConfirmInput]: () => initialInputDialog,
[SDKTypes.DateTimeInput]: () => initialInputDialog,
[SDKTypes.NumberInput]: () => initialInputDialog,
[SDKTypes.TextInput]: () => initialInputDialog,
};

export function getNewDesigner(name: string, description: string) {
Expand Down Expand Up @@ -137,7 +138,8 @@ export const deleteActions = (
export const seedNewDialog = (
$type: string,
designerAttributes: Partial<DesignerAttributes> = {},
optionalAttributes: object = {}
optionalAttributes: object = {},
seededActions: unknown[] = []
): object => {
return {
$type,
Expand All @@ -146,7 +148,7 @@ export const seedNewDialog = (
...designerAttributes,
},
...seedDefaults($type),
...(initialDialogShape[$type] || {}),
...(initialDialogShape[$type] ? initialDialogShape[$type](seededActions) : {}),
yeze322 marked this conversation as resolved.
Show resolved Hide resolved
...optionalAttributes,
};
};
2 changes: 1 addition & 1 deletion Composer/packages/lib/shared/src/types/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export interface ShellApi {
updateLuIntent: (id: string, intentName: string, intent: LuIntentSection | null) => Promise<void>;
updateRegExIntent: (id: string, intentName: string, pattern: string) => Promise<void>;
removeLuIntent: (id: string, intentName: string) => Promise<void>;
createDialog: () => Promise<string>;
createDialog: (actions: any) => Promise<string>;
validateExpression: (expression?: string) => Promise<boolean>;
// TODO: fix these types
addCoachMarkRef: any;
Expand Down