Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"start:server:dev": "yarn workspace @bfc/server start:dev",
"runtime": "cd ../runtime/dotnet/azurewebapp && dotnet build && dotnet run",
"test": "yarn typecheck && jest",
"test:watch": "jest --watch",
"test:watch": "yarn typecheck jest --watch",
"test:coverage": "yarn test --coverage --no-cache --forceExit --reporters=default",
"test:integration": "cypress run --browser edge",
"test:integration:start-server": "node scripts/e2e.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
openBotProject,
createProject,
saveProjectAs,
saveTemplateId,
fetchStorages,
fetchFolderItemsByPath,
setCreationFlowStatus,
Expand Down Expand Up @@ -81,9 +80,12 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {

const openBot = async (botFolder) => {
const projectId = await openBotProject(botFolder);
setCreationFlowStatus(CreationFlowStatus.CLOSE);
const mainUrl = `/bot/${projectId}/dialogs/Main`;
navigateTo(mainUrl);
if (projectId) {
setCreationFlowStatus(CreationFlowStatus.CLOSE);
const mainUrl = `/bot/${projectId}/dialogs/Main`;

navigateTo(mainUrl);
}
};

const handleCreateNew = async (formData, templateId: string) => {
Expand Down Expand Up @@ -125,7 +127,6 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
createFolder={createFolder}
focusedStorageFolder={focusedStorageFolder}
path="create/:templateId"
saveTemplateId={saveTemplateId}
updateFolder={updateFolder}
onCurrentPathUpdate={updateCurrentPath}
onDismiss={handleDismiss}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ interface DefineConversationProps
onDismiss: () => void;
onCurrentPathUpdate: (newPath?: string, storageId?: string) => void;
onGetErrorMessage?: (text: string) => void;
saveTemplateId?: (templateId: string) => void;
focusedStorageFolder: StorageFolder;
}

Expand Down
11 changes: 6 additions & 5 deletions Composer/packages/client/src/pages/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { CreationFlowStatus } from '../../constants';
import { dispatcherState } from '../../recoilModel';
import { navigateTo } from '../../utils';
import { botNameState, projectIdState } from '../../recoilModel/atoms/botState';
import { recentProjectsState, templateProjectsState, templateIdState } from '../../recoilModel/atoms/appState';
import { recentProjectsState, templateProjectsState } from '../../recoilModel/atoms/appState';
import { ToolBar, IToolBarItem } from '../../components/ToolBar/ToolBar';

import * as home from './styles';
Expand Down Expand Up @@ -58,7 +58,6 @@ const tutorials = [
];

const Home: React.FC<RouteComponentProps> = () => {
const templateId = useRecoilValue(templateIdState);
const templateProjects = useRecoilValue(templateProjectsState);
const botName = useRecoilValue(botNameState);
const recentProjects = useRecoilValue(recentProjectsState);
Expand All @@ -69,8 +68,10 @@ const Home: React.FC<RouteComponentProps> = () => {

const onClickRecentBotProject = async (path) => {
const projectId = await openBotProject(path);
const mainUrl = `/bot/${projectId}/dialogs/Main`;
navigateTo(mainUrl);
if (projectId) {
const mainUrl = `/bot/${projectId}/dialogs/Main`;
navigateTo(mainUrl);
}
};

const onItemChosen = async (item) => {
Expand Down Expand Up @@ -130,7 +131,7 @@ const Home: React.FC<RouteComponentProps> = () => {
},
onClick: () => {
setCreationFlowStatus(CreationFlowStatus.SAVEAS);
navigate(`projects/${projectId}/${templateId}/save`);
navigate(`projects/${projectId}/save`);
},
},
align: 'left',
Expand Down
5 changes: 0 additions & 5 deletions Composer/packages/client/src/recoilModel/atoms/appState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,6 @@ export const runtimeSettingsState = atom<{
},
});

export const templateIdState = atom<string>({
key: getFullyQualifiedKey('templateId'),
default: '',
});

export const botEndpointsState = atom<any>({
key: 'botEndpoints',
default: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@
import { CallbackInterface, useRecoilCallback } from 'recoil';
import debounce from 'lodash/debounce';

import {
appUpdateState,
announcementState,
onboardingState,
creationFlowStatusState,
applicationErrorState,
} from '../atoms/appState';
import { appUpdateState, announcementState, onboardingState, creationFlowStatusState } from '../atoms/appState';
import { AppUpdaterStatus, CreationFlowStatus } from '../../constants';
import OnboardingState from '../../utils/onboardingStorage';
import { StateError, AppUpdateState } from '../../recoilModel/types';

import { setError } from './shared';

export const applicationDispatcher = () => {
const setAppUpdateStatus = useRecoilCallback<[AppUpdaterStatus, string | undefined], Promise<void>>(
({ set, snapshot: { getPromise } }: CallbackInterface) => async (
Expand Down Expand Up @@ -104,8 +100,8 @@ export const applicationDispatcher = () => {
);

const setApplicationLevelError = useRecoilCallback<[StateError | undefined], void>(
({ set }: CallbackInterface) => (errorObj: StateError | undefined) => {
set(applicationErrorState, errorObj);
(callbackHelpers: CallbackInterface) => (errorObj: StateError | undefined) => {
setError(callbackHelpers, errorObj);
}
);

Expand Down
47 changes: 24 additions & 23 deletions Composer/packages/client/src/recoilModel/dispatchers/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import luFileStatusStorage from '../../utils/luFileStatusStorage';
import { DialogSetting } from '../../recoilModel/types';
import settingStorage from '../../utils/dialogSettingStorage';
import filePersistence from '../persistence/FilePersistence';
import { navigateTo } from '../../utils';

import {
skillManifestsState,
Expand All @@ -38,10 +39,14 @@ import {
recentProjectsState,
templateProjectsState,
runtimeTemplatesState,
templateIdState,
applicationErrorState,
} from './../atoms';
import { logMessage } from './../dispatchers/shared';
import { logMessage, setError } from './../dispatchers/shared';

const handleProjectFailure = (callbackHelpers: CallbackInterface, ex) => {
callbackHelpers.set(botOpeningState, false);
setError(callbackHelpers, ex);
};

const checkProjectUpdates = async () => {
const workers = [filePersistence, lgWorker, luWorker];
Expand Down Expand Up @@ -143,12 +148,11 @@ export const projectDispatcher = () => {
...currentRecentProjects,
});
} catch (ex) {
// TODO: Handle exceptions
logMessage(callbackHelpers, `Error removing recent project: ${ex}`);
}
};

const setOpenPendingStatusasync = async (callbackHelpers: CallbackInterface) => {
const setOpenPendingStatusAsync = async (callbackHelpers: CallbackInterface) => {
const { set } = callbackHelpers;
set(botOpeningState, true);
await checkProjectUpdates();
Expand All @@ -157,21 +161,26 @@ export const projectDispatcher = () => {
const openBotProject = useRecoilCallback<[string, string?], Promise<string>>(
(callbackHelpers: CallbackInterface) => async (path: string, storageId = 'default') => {
try {
await setOpenPendingStatusasync(callbackHelpers);
await setOpenPendingStatusAsync(callbackHelpers);
const response = await httpClient.put(`/projects/open`, { path, storageId });
await initBotState(callbackHelpers, response.data);
return response.data.id;
} catch (ex) {
callbackHelpers.set(botOpeningState, false);
removeRecentProject(callbackHelpers, path);
handleProjectFailure(callbackHelpers, ex);
}
}
);

const fetchProjectById = useRecoilCallback<[string], Promise<void>>(
(callbackHelpers: CallbackInterface) => async (projectId: string) => {
const response = await httpClient.get(`/projects/${projectId}`);
await initBotState(callbackHelpers, response.data);
try {
const response = await httpClient.get(`/projects/${projectId}`);
await initBotState(callbackHelpers, response.data);
} catch (ex) {
handleProjectFailure(callbackHelpers, ex);
navigateTo('/home');
}
}
);

Expand All @@ -184,7 +193,7 @@ export const projectDispatcher = () => {
schemaUrl?: string
) => {
try {
await setOpenPendingStatusasync(callbackHelpers);
await setOpenPendingStatusAsync(callbackHelpers);
const response = await httpClient.post(`/projects`, {
storageId: 'default',
templateId,
Expand All @@ -199,9 +208,8 @@ export const projectDispatcher = () => {
}
await initBotState(callbackHelpers, response.data);
return projectId;
} catch (error) {
callbackHelpers.set(botOpeningState, false);
logMessage(callbackHelpers, error.message);
} catch (ex) {
handleProjectFailure(callbackHelpers, ex);
}
}
);
Expand Down Expand Up @@ -235,7 +243,7 @@ export const projectDispatcher = () => {
const saveProjectAs = useRecoilCallback<[string, string, string, string], Promise<string>>(
(callbackHelpers: CallbackInterface) => async (projectId, name, description, location) => {
try {
await setOpenPendingStatusasync(callbackHelpers);
await setOpenPendingStatusAsync(callbackHelpers);
const response = await httpClient.post(`/projects/${projectId}/project/saveAs`, {
storageId: 'default',
name,
Expand All @@ -244,10 +252,9 @@ export const projectDispatcher = () => {
});
await initBotState(callbackHelpers, response.data);
return response.data.id;
} catch (error) {
//TODO: error handling
callbackHelpers.set(botOpeningState, false);
logMessage(callbackHelpers, error.message);
} catch (ex) {
handleProjectFailure(callbackHelpers, ex);
logMessage(callbackHelpers, ex.message);
}
}
);
Expand All @@ -258,7 +265,6 @@ export const projectDispatcher = () => {
const response = await httpClient.get(`/projects/recent`);
set(recentProjectsState, response.data);
} catch (ex) {
// TODO: Handle exceptions
set(recentProjectsState, []);
logMessage(callbackHelpers, `Error in fetching recent projects: ${ex}`);
}
Expand Down Expand Up @@ -294,10 +300,6 @@ export const projectDispatcher = () => {
}
);

const saveTemplateId = useRecoilCallback(({ set }) => async (templateId: string) => {
set(templateIdState, templateId);
});

const fetchTemplates = useRecoilCallback<[], Promise<void>>((callbackHelpers: CallbackInterface) => async () => {
try {
const response = await httpClient.get(`/assets/projectTemplates`);
Expand Down Expand Up @@ -352,7 +354,6 @@ export const projectDispatcher = () => {
createProject,
deleteBotProject,
saveProjectAs,
saveTemplateId,
fetchTemplates,
fetchProjectById,
fetchRecentProjects,
Expand Down
23 changes: 22 additions & 1 deletion Composer/packages/client/src/recoilModel/dispatchers/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
// Licensed under the MIT License.

import { CallbackInterface } from 'recoil';
import formatMessage from 'format-message';

import { logEntryListState } from '../atoms/appState';
import { logEntryListState, applicationErrorState } from '../atoms/appState';

export enum ConsoleMsgLevel {
Error,
Expand All @@ -29,3 +30,23 @@ export const logMessage = ({ set }: CallbackInterface, message: string, level =
}
set(logEntryListState, (logEntries) => [...logEntries, message]);
};

export const setError = (callbackHelpers: CallbackInterface, payload) => {
// if the error originated at the server and the server included message, use it...
if (payload?.status === 409) {
callbackHelpers.set(applicationErrorState, {
status: 409,
message: formatMessage(
'This version of the content is out of date, and your last change was rejected. The content will be automatically refreshed.'
),
summary: formatMessage('Modification Rejected'),
});
} else {
if (payload?.response?.data?.message) {
callbackHelpers.set(applicationErrorState, payload.response.data);
} else {
callbackHelpers.set(applicationErrorState, payload);
}
}
logMessage(callbackHelpers, `Error: ${JSON.stringify(payload)}`);
};