Skip to content

Commit

Permalink
first round of changes for multi-user support
Browse files Browse the repository at this point in the history
Related to #1918 and #1917
  • Loading branch information
benbrown committed Feb 12, 2020
1 parent e70fa8a commit 8e825c7
Show file tree
Hide file tree
Showing 23 changed files with 181 additions and 77 deletions.
6 changes: 3 additions & 3 deletions Composer/packages/client/src/CreationFlow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function CreationFlow(props) {

const openBot = async botFolder => {
await openBotProject(botFolder);
navigateTo('/dialogs/Main');
navigateTo(`/dialogs/Main`);
handleDismiss();
};

Expand All @@ -123,11 +123,11 @@ export function CreationFlow(props) {
case CreationFlowStatus.NEW_FROM_TEMPLATE:
case CreationFlowStatus.NEW:
handleCreateNew(formData);
navigateTo('/dialogs/Main');
navigateTo(`/dialogs/Main`);
break;
case CreationFlowStatus.SAVEAS:
handleSaveAs(formData);
navigateTo('/dialogs/Main');
navigateTo(`/dialogs/Main`);
break;
default:
setStep(Steps.NONE);
Expand Down
14 changes: 14 additions & 0 deletions Composer/packages/client/src/ShellApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,10 @@ export const ShellApi: React.FC = () => {
const payload = {
id: dialogId,
content: updatedDialog,
projectId: state.projectId,
};
dialogsMap[dialogId] = updatedDialog;
console.log('update dialog from handlevaluechange');
updateDialog(payload);

//make sure focusPath always valid
Expand Down Expand Up @@ -153,10 +155,13 @@ export const ShellApi: React.FC = () => {
if (!file) throw new Error(`lg file ${id} not found`);
if (!templateName) throw new Error(`templateName is missing or empty`);

const projectId = state.projectId;

lgUtil.checkSingleLgTemplate(template);

await updateLgTemplate({
file,
projectId,
templateName,
template,
});
Expand All @@ -171,8 +176,11 @@ export const ShellApi: React.FC = () => {
if (!file) throw new Error(`lg file ${id} not found`);
if (!fromTemplateName || !toTemplateName) throw new Error(`templateName is missing or empty`);

const projectId = state.projectId;

return actions.copyLgTemplate({
file,
projectId,
fromTemplateName,
toTemplateName,
});
Expand All @@ -183,9 +191,11 @@ export const ShellApi: React.FC = () => {
const file = lgFiles.find(file => file.id === id);
if (!file) throw new Error(`lg file ${id} not found`);
if (!templateName) throw new Error(`templateName is missing or empty`);
const projectId = state.projectId;

return actions.removeLgTemplate({
file,
projectId,
templateName,
});
}
Expand All @@ -195,9 +205,11 @@ export const ShellApi: React.FC = () => {
const file = lgFiles.find(file => file.id === id);
if (!file) throw new Error(`lg file ${id} not found`);
if (!templateNames) throw new Error(`templateName is missing or empty`);
const projectId = state.projectId;

return actions.removeLgTemplates({
file,
projectId,
templateNames,
});
}
Expand All @@ -208,6 +220,7 @@ export const ShellApi: React.FC = () => {
const payload = {
id,
content,
projectId: state.projectId,
};

switch ([fileTargetType, fileChangeType].join(',')) {
Expand All @@ -233,6 +246,7 @@ export const ShellApi: React.FC = () => {
const payload = {
id: dialogId,
content: cleanedData,
projectId: state.projectId,
};
updateDialog(payload);
}
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/client/src/TestController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const TestController: React.FC = () => {
try {
const luisConfig = settingsStorage.get(botName) ? settingsStorage.get(botName).luis : null;
if (luisConfig) {
await publishLuis(luisConfig.authoringKey);
await publishLuis(luisConfig.authoringKey, state.projectId);
return true;
} else {
throw new Error('Please Set Luis Config');
Expand Down
8 changes: 5 additions & 3 deletions Composer/packages/client/src/pages/design/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ function DesignPage(props) {
const params = new URLSearchParams(location.search);
setDesignPageLocation({
dialogId: dialogId,
projectId: state.projectId,
selected: params.get('selected'),
focused: params.get('focused'),
breadcrumb: location.state ? location.state.breadcrumb || [] : [],
Expand Down Expand Up @@ -175,6 +176,7 @@ function DesignPage(props) {
const onTriggerCreationSubmit = dialog => {
const payload = {
id: dialog.id,
projectId: state.projectId,
content: dialog.content,
};
const index = get(dialog, 'content.triggers', []).length - 1;
Expand Down Expand Up @@ -317,7 +319,7 @@ function DesignPage(props) {
async function onSubmit(data: { name: string; description: string }) {
const content = getNewDesigner(data.name, data.description);
const seededContent = seedNewDialog('Microsoft.AdaptiveDialog', content.$designer, content);
await actions.createDialog({ id: data.name, content: seededContent });
await actions.createDialog({ id: data.name, content: seededContent, projectId: state.projectId });
}

async function handleDeleteDialog(id) {
Expand All @@ -341,14 +343,14 @@ function DesignPage(props) {
const result = await OpenConfirmModal(title, subTitle, setting);

if (result) {
await removeDialog(id);
await removeDialog(id, state.projectId);
}
}

async function handleDeleteTrigger(id, index) {
const content = deleteTrigger(dialogs, id, index);
if (content) {
await updateDialog({ id, content });
await updateDialog({ id, projectId: state.projectId, content });
const match = /\[(\d+)\]/g.exec(selected);
const current = match && match[1];
if (!current) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const CodeEditor: React.FC<CodeEditorProps> = props => {
const { name, parameters } = template;
const payload = {
file,
projectId: state.projectId,
templateName: name,
template: {
name,
Expand All @@ -113,6 +114,7 @@ const CodeEditor: React.FC<CodeEditorProps> = props => {
const { id } = file;
const payload = {
id,
projectId: state.projectId,
content,
};
actions.updateLgFile(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const TableView: React.FC<TableViewProps> = props => {
const newName = increaseNameUtilNotExist(templates, 'TemplateName');
const payload = {
file,
projectId: state.projectId,
template: {
name: newName,
body: '-TemplateValue',
Expand All @@ -82,6 +83,7 @@ const TableView: React.FC<TableViewProps> = props => {
index => {
const payload = {
file,
projectId: state.projectId,
templateName: templates[index].name,
};

Expand All @@ -96,6 +98,7 @@ const TableView: React.FC<TableViewProps> = props => {
const resolvedName = increaseNameUtilNotExist(templates, `${name}_Copy`);
const payload = {
file,
projectId: state.projectId,
fromTemplateName: name,
toTemplateName: resolvedName,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const LUPage: React.FC<DefineConversationProps> = props => {
const payload = {
id: id, // current opened lu file
content: newContent,
projectId: state.projectId,
};
try {
await actions.updateLuFile(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export const PublishLuis = props => {
// save the settings change to store and persist to server
const newValue = { ...formData, ...result };
delete newValue.errors;
await setSettings(botName, { ...settings, luis: newValue });
await setSettings(state.projectId, botName, { ...settings, luis: newValue });
await onPublish();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const DialogSettings = () => {

const changeEditing = (_, on) => {
setEditing(on);
actions.setEditDialogSettings(on, absHosted ? slot : undefined);
actions.setEditDialogSettings(state.projectId, on, absHosted ? slot : undefined);
};

const slots = [
Expand All @@ -50,13 +50,13 @@ export const DialogSettings = () => {

const changeSlot = (_, option) => {
setSlot(option.key);
actions.setDialogSettingsSlot(editing, option.key);
actions.setDialogSettingsSlot(state.projectId, editing, option.key);
};

const saveChangeResult = result => {
try {
const mergedResult = absHosted ? { ...managedSettings, ...result } : result;
actions.setSettings(botName, mergedResult, absHosted ? slot : undefined);
actions.setSettings(state.projectId, botName, mergedResult, absHosted ? slot : undefined);
} catch (err) {
// eslint-disable-next-line no-console
console.error(err.message);
Expand Down
16 changes: 16 additions & 0 deletions Composer/packages/client/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const Routes = props => {
const shouldRenderDesignPage = useRef(false);

useEffect(() => {
console.log('fetch project');
actions.fetchProject();
}, []);

Expand All @@ -36,6 +37,8 @@ const Routes = props => {
{({ match, navigate, location }) => {
if (match) {
shouldRenderDesignPage.current = true;
// console.log('FETCH PROJECT FOR DIALOG', match.projectId);
// actions.fetchProject(match.projectId);
}

return (
Expand All @@ -47,11 +50,13 @@ const Routes = props => {
{!match && (
<Router basepath={BASEPATH} {...parentProps}>
<Redirect from="/" to={resolveToBasePath(BASEPATH, 'dialogs/Main')} noThrow />
{/* <ProjectRouter path="/bot/:projectId"> */}
<SettingPage path="setting/*" />
<LUPage path="language-understanding/*" />
<Redirect from="language-generation" to="language-generation/common" noThrow />
<LGPage path="language-generation/:fileId/*" />
<Notifications path="notifications" />
{/* </ProjectRouter> */}
<Home path="home" />
<About path="about" />
<NotFound default />
Expand All @@ -65,4 +70,15 @@ const Routes = props => {
);
};

// const ProjectRouter = props => {
// const { actions } = useContext(StoreContext);

// useEffect(() => {
// console.log('FETCH PROJECT!!!', props.projectId);
// actions.fetchProject(props.projectId);
// }, []);

// return <div>{props.children}</div>;
// };

export default Routes;
29 changes: 16 additions & 13 deletions Composer/packages/client/src/store/action/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ const getDiff = (dialogs1: DialogInfo[], dialogs2: DialogInfo[]) => {
}
};

export const removeDialogBase: ActionCreator = async (store, id) => {
export const removeDialogBase: ActionCreator = async (store, id, projectId) => {
try {
const response = await httpClient.delete(`/projects/opened/dialogs/${id}`);
const response = await httpClient.delete(`/projects/opened/dialogs/${projectId}/${id}`);
store.dispatch({
type: ActionTypes.REMOVE_DIALOG,
payload: { response },
Expand All @@ -54,9 +54,9 @@ export const removeDialogBase: ActionCreator = async (store, id) => {
}
};

export const createDialogBase: ActionCreator = async (store, { id, content }) => {
export const createDialogBase: ActionCreator = async (store, { id, content, projectId }) => {
try {
const response = await httpClient.post(`/projects/opened/dialogs`, { id, content });
const response = await httpClient.post(`/projects/opened/dialogs`, { id, content, projectId });
const onCreateDialogComplete = store.getState().onCreateDialogComplete;
if (typeof onCreateDialogComplete === 'function') {
setTimeout(() => onCreateDialogComplete(id));
Expand All @@ -80,28 +80,30 @@ export const removeDialog = undoable(
pickDialog,
async (store: Store, { dialogs }) => {
const target = getDiff(store.getState().dialogs, dialogs);
const projectId = store.getState().projectId;
if (target) {
await createDialogBase(store, target);
await createDialogBase(store, { projectId, ...target });
}
},
(store, { id }) => removeDialogBase(store, id)
(store, { id, projectId }) => removeDialogBase(store, id, projectId)
);

export const createDialog = undoable(
createDialogBase,
pickDialog,
async (store: Store, { dialogs }) => {
const target = getDiff(dialogs, store.getState().dialogs);
const projectId = store.getState().projectId;
if (target) {
await removeDialogBase(store, target.id);
await removeDialogBase(store, target.id, projectId);
}
},
(store, { id, content }) => createDialogBase(store, { id, content })
);

export const debouncedUpdateDialog = debounce(async (store, id, content) => {
export const debouncedUpdateDialog = debounce(async (store, id, projectId, content) => {
try {
await httpClient.put(`/projects/opened/dialogs/${id}`, { id, content });
await httpClient.put(`/projects/opened/dialogs/${id}`, { id, projectId, content });
} catch (err) {
setError(store, {
message: err.response && err.response.data.message ? err.response.data.message : err,
Expand All @@ -112,9 +114,9 @@ export const debouncedUpdateDialog = debounce(async (store, id, content) => {
}
}, 500);

export const updateDialogBase: ActionCreator = (store, { id, content }) => {
store.dispatch({ type: ActionTypes.UPDATE_DIALOG, payload: { id, content } });
debouncedUpdateDialog(store, id, content);
export const updateDialogBase: ActionCreator = (store, { id, projectId, content }) => {
store.dispatch({ type: ActionTypes.UPDATE_DIALOG, payload: { id, projectId, content } });
debouncedUpdateDialog(store, id, projectId, content);
};

export const updateDialog: ActionCreator = undoable(
Expand All @@ -123,7 +125,8 @@ export const updateDialog: ActionCreator = undoable(
if (isEmpty) {
const id = state.designPageLocation.dialogId;
const dialog = state.dialogs.find(dialog => dialog.id === id);
return [{ id, content: dialog ? dialog.content : {} }];
const projectId = state.projectId;
return [{ id, projectId, content: dialog ? dialog.content : {} }];
} else {
return args;
}
Expand Down
Loading

0 comments on commit 8e825c7

Please sign in to comment.