Skip to content

Commit

Permalink
Implement Move
Browse files Browse the repository at this point in the history
  • Loading branch information
cwhitten committed Mar 8, 2020
1 parent 8cd8859 commit 42164f7
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 25 deletions.
4 changes: 2 additions & 2 deletions Composer/packages/client/src/ShellApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,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,8 +110,8 @@ const shellApi: ShellApi = {
return apiClient.apiCall('removeLuIntent', { id, intentName });
},

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

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 @@ -251,6 +251,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 @@ -309,7 +321,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) : {}),
...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 @@ -73,7 +73,7 @@ export interface ShellApi {
addLuIntent: (id: string, intent: LuIntentSection | null) => Promise<void>;
updateLuIntent: (id: string, intentName: string, intent: LuIntentSection | null) => 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

0 comments on commit 42164f7

Please sign in to comment.