Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 18d66bd

Browse files
pavolumpavolumMsft
andauthored
feature: Adding VA template custom creation UI (#4176)
* Adding va core template plug in with corresponding plugin build steps * Adding env variable feature flag around VA=Core template * removing unused code that was initially added for custom runtime which has been removed * Added creation UI workspace which is linked to and referenced from client package creation flow, Moved some UI assets to shared UI lib for cross workspace reuse, added creation UI experience for va-core template * Minor styling changes * Cleaning up code for review: Moved to standard styling practices, normalized file content structure, added formatMessage() to UI strings, misc clean up * Cleaning up unused changes * removing bot type tile * removing bot type tile * Making requested PR changes, general clean up, conversion of interfaces to types, adding error catching * Converting props types to intersaction with reach router, adding await back to createProject function * Fixing files to follow repoo linting rules * Changed post creation logic to execute on useEffect as opposed to reliance on await * resolve reentry bug * removing unused function * Fixing linting errors * resolve reentry bug * Fixing reference * Updating react version in creation extension * Updating react version in creation extension * Making PR changes * Fixed non static formatMessage calls * minor syntax refactoring * Refactoring state management for more modular state. Implemented local state relationship to prevent excessive rerenders * Making additional state management changes for better readability and performance. minor clean up of interface and file names * Fixing file naming * Formatting template strings for localization * changing ReachRouter version dpendency to match client reach/router version * update Azure Publish yarn.lock * Updating reach router version and tamplate name Co-authored-by: Patrick Volum <[email protected]>
1 parent 31ec081 commit 18d66bd

33 files changed

+1029
-52
lines changed

Composer/packages/client/__tests__/components/DialogWrapper/index.test.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33

44
import React from 'react';
55
import { render } from '@bfc/test-utils';
6-
7-
import { DialogWrapper, DialogTypes } from '../../../src/components/DialogWrapper';
6+
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
87

98
describe('<DialogWrapper />', () => {
109
const props = {

Composer/packages/client/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@bfc/extension-client": "*",
2626
"@bfc/indexers": "*",
2727
"@bfc/shared": "*",
28+
"@bfc/ui-shared": "*",
2829
"@bfc/ui-plugin-composer": "*",
2930
"@bfc/ui-plugin-cross-trained": "*",
3031
"@bfc/ui-plugin-dialog-schema-editor": "*",
@@ -33,6 +34,7 @@
3334
"@bfc/ui-plugin-prompts": "*",
3435
"@bfc/ui-plugin-select-dialog": "*",
3536
"@bfc/ui-plugin-select-skill-dialog": "*",
37+
"@bfc/ui-plugin-va-creation": "*",
3638
"@emotion/core": "^10.0.27",
3739
"@reach/router": "^1.2.1",
3840
"@uifabric/fluent-theme": "^7.1.107",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
object-assign
3+
(c) Sindre Sorhus
4+
@license MIT
5+
*/
6+
7+
/** @license React v16.13.1
8+
* react.production.min.js
9+
*
10+
* Copyright (c) Facebook, Inc. and its affiliates.
11+
*
12+
* This source code is licensed under the MIT license found in the
13+
* LICENSE file in the root directory of this source tree.
14+
*/
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
object-assign
3+
(c) Sindre Sorhus
4+
@license MIT
5+
*/
6+
7+
/** @license React v0.19.1
8+
* scheduler.production.min.js
9+
*
10+
* Copyright (c) Facebook, Inc. and its affiliates.
11+
*
12+
* This source code is licensed under the MIT license found in the
13+
* LICENSE file in the root directory of this source tree.
14+
*/
15+
16+
/** @license React v16.13.1
17+
* react-dom.production.min.js
18+
*
19+
* Copyright (c) Facebook, Inc. and its affiliates.
20+
*
21+
* This source code is licensed under the MIT license found in the
22+
* LICENSE file in the root directory of this source tree.
23+
*/

Composer/packages/client/src/components/CreateSkillModal.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ import { TextField } from 'office-ui-fabric-react/lib/TextField';
1212
import { useRecoilValue } from 'recoil';
1313
import debounce from 'lodash/debounce';
1414
import { SkillSetting } from '@bfc/shared';
15+
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
1516

1617
import { addSkillDialog } from '../constants';
1718
import httpClient from '../utils/httpUtil';
1819
import { skillsState } from '../recoilModel';
1920

20-
import { DialogWrapper, DialogTypes } from './DialogWrapper';
21-
2221
export interface SkillFormDataErrors {
2322
endpoint?: string;
2423
manifestUrl?: string;

Composer/packages/client/src/components/CreationFlow/CreateOptions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import {
2121
} from 'office-ui-fabric-react/lib/DetailsList';
2222
import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
2323
import { ProjectTemplate } from '@bfc/shared';
24+
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
2425
import { NeutralColors } from '@uifabric/fluent-theme';
2526

2627
import { DialogCreationCopy, EmptyBotTemplateId, QnABotTemplateId } from '../../constants';
27-
import { DialogWrapper, DialogTypes } from '../DialogWrapper';
2828

2929
// -------------------- Styles -------------------- //
3030

Composer/packages/client/src/components/CreationFlow/CreationFlow.tsx

Lines changed: 70 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
// TODO: Remove path module
55
import Path from 'path';
66

7-
import React, { useEffect, useRef, Fragment, useState } from 'react';
7+
import React, { useEffect, useRef, Fragment, useState, useMemo } from 'react';
88
import { RouteComponentProps, Router, navigate } from '@reach/router';
99
import { useRecoilValue } from 'recoil';
10+
import VirtualAssistantCreationModal from '@bfc/ui-plugin-va-creation';
11+
import { PluginConfig, mergePluginConfigs, EditorExtension } from '@bfc/extension-client';
1012

1113
import { CreationFlowStatus } from '../../constants';
1214
import {
@@ -22,6 +24,8 @@ import Home from '../../pages/home/Home';
2224
import ImportQnAFromUrlModal from '../../pages/knowledge-base/ImportQnAFromUrlModal';
2325
import { QnABotTemplateId } from '../../constants';
2426
import { useProjectIdCache } from '../../utils/hooks';
27+
import { useShell } from '../../shell';
28+
import plugins from '../../plugins';
2529

2630
import { CreateOptions } from './CreateOptions';
2731
import { OpenProject } from './OpenProject';
@@ -56,8 +60,8 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
5660
const currentStorageIndex = useRef(0);
5761
const storage = storages[currentStorageIndex.current];
5862
const currentStorageId = storage ? storage.id : 'default';
59-
const [formData, setFormData] = useState({ name: '' });
60-
63+
const [formData, setFormData] = useState({ name: '', description: '', location: '' });
64+
const shellForCreation = useShell('VaCreation', projectId);
6165
useEffect(() => {
6266
if (storages && storages.length) {
6367
const storageId = storage.id;
@@ -67,6 +71,13 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
6771
}
6872
}, [storages]);
6973

74+
// Plugin config for VA creation plug in
75+
const pluginConfig: PluginConfig = useMemo(() => {
76+
const sdkUISchema = {};
77+
const userUISchema = {};
78+
return mergePluginConfigs({ uiSchema: sdkUISchema }, plugins, { uiSchema: userUISchema });
79+
}, []);
80+
7081
const fetchResources = async () => {
7182
// fetchProject use `gotoSnapshot` which will wipe out all state value.
7283
// so here make those methods call in sequence.
@@ -125,12 +136,20 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
125136
handleCreateNew(formData, QnABotTemplateId, urls);
126137
};
127138

128-
const handleSubmitOrImportQnA = async (formData, templateId: string) => {
139+
const handleDefineConversationSubmit = async (formData, templateId: string) => {
140+
// If selected template is qnaSample then route to QNA import modal
129141
if (templateId === 'QnASample') {
130142
setFormData(formData);
131143
navigate(`./QnASample/importQnA`);
132144
return;
133145
}
146+
// If selected template is vaCore then route to VA Customization modal
147+
if (templateId === 'va-core') {
148+
setFormData(formData);
149+
navigate(`./vaCore/customize`);
150+
return;
151+
}
152+
134153
handleSubmit(formData, templateId);
135154
};
136155

@@ -155,40 +174,53 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
155174
return (
156175
<Fragment>
157176
<Home />
158-
<Router>
159-
<DefineConversation
160-
createFolder={createFolder}
161-
focusedStorageFolder={focusedStorageFolder}
162-
path="create/:templateId"
163-
updateFolder={updateFolder}
164-
onCurrentPathUpdate={updateCurrentPath}
165-
onDismiss={handleDismiss}
166-
onSubmit={handleSubmitOrImportQnA}
167-
/>
168-
<CreateOptions path="create" templates={templateProjects} onDismiss={handleDismiss} onNext={handleCreateNext} />
169-
<DefineConversation
170-
createFolder={createFolder}
171-
focusedStorageFolder={focusedStorageFolder}
172-
path=":projectId/:templateId/save"
173-
updateFolder={updateFolder}
174-
onCurrentPathUpdate={updateCurrentPath}
175-
onDismiss={handleDismiss}
176-
onSubmit={handleSubmitOrImportQnA}
177-
/>
178-
<OpenProject
179-
focusedStorageFolder={focusedStorageFolder}
180-
path="open"
181-
onCurrentPathUpdate={updateCurrentPath}
182-
onDismiss={handleDismiss}
183-
onOpen={openBot}
184-
/>
185-
<ImportQnAFromUrlModal
186-
dialogId={formData.name.toLowerCase()}
187-
path="create/QnASample/importQnA"
188-
onDismiss={handleDismiss}
189-
onSubmit={handleCreateQnA}
190-
/>
191-
</Router>
177+
<EditorExtension plugins={pluginConfig} projectId={projectId} shell={shellForCreation}>
178+
<Router>
179+
<DefineConversation
180+
createFolder={createFolder}
181+
focusedStorageFolder={focusedStorageFolder}
182+
path="create/:templateId"
183+
updateFolder={updateFolder}
184+
onCurrentPathUpdate={updateCurrentPath}
185+
onDismiss={handleDismiss}
186+
onSubmit={handleDefineConversationSubmit}
187+
/>
188+
<CreateOptions
189+
path="create"
190+
templates={templateProjects}
191+
onDismiss={handleDismiss}
192+
onNext={handleCreateNext}
193+
/>
194+
<DefineConversation
195+
createFolder={createFolder}
196+
focusedStorageFolder={focusedStorageFolder}
197+
path=":projectId/:templateId/save"
198+
updateFolder={updateFolder}
199+
onCurrentPathUpdate={updateCurrentPath}
200+
onDismiss={handleDismiss}
201+
onSubmit={handleDefineConversationSubmit}
202+
/>
203+
<OpenProject
204+
focusedStorageFolder={focusedStorageFolder}
205+
path="open"
206+
onCurrentPathUpdate={updateCurrentPath}
207+
onDismiss={handleDismiss}
208+
onOpen={openBot}
209+
/>
210+
<ImportQnAFromUrlModal
211+
dialogId={formData.name.toLowerCase()}
212+
path="create/QnASample/importQnA"
213+
onDismiss={handleDismiss}
214+
onSubmit={handleCreateQnA}
215+
/>
216+
<VirtualAssistantCreationModal
217+
formData={formData}
218+
handleCreateNew={handleCreateNew}
219+
path="create/vaCore/*"
220+
onDismiss={handleDismiss}
221+
/>
222+
</Router>
223+
</EditorExtension>
192224
</Fragment>
193225
);
194226
};

Composer/packages/client/src/components/CreationFlow/DefineConversation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { TextField } from 'office-ui-fabric-react/lib/TextField';
1313
import { RouteComponentProps } from '@reach/router';
1414
import querystring from 'query-string';
1515
import { FontWeights } from '@uifabric/styling';
16+
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
1617

1718
import { DialogCreationCopy, QnABotTemplateId, nameRegex } from '../../constants';
18-
import { DialogWrapper, DialogTypes } from '../DialogWrapper';
1919
import { FieldConfig, useForm } from '../../hooks/useForm';
2020
import { StorageFolder } from '../../recoilModel/types';
2121

Composer/packages/client/src/components/CreationFlow/OpenProject.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
88
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
99
import formatMessage from 'format-message';
1010
import { RouteComponentProps } from '@reach/router';
11+
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
1112

1213
import { StorageFolder } from '../../recoilModel/types';
1314
import { DialogCreationCopy } from '../../constants';
14-
import { DialogWrapper, DialogTypes } from '../DialogWrapper';
1515

1616
import { LocationSelectContent } from './LocationSelectContent';
1717
interface OpenProjectProps extends RouteComponentProps<{}> {

Composer/packages/client/src/components/MultiLanguage/AddLanguageModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import { Stack, StackItem } from 'office-ui-fabric-react/lib/Stack';
1414
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
1515
import { Label } from 'office-ui-fabric-react/lib/Label';
1616
import { Dropdown, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
17+
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
1718

18-
import { DialogWrapper, DialogTypes } from '../DialogWrapper';
1919
import { MultiLanguagesDialog } from '../../constants';
2020

2121
import { ILanguageFormData } from './types';

0 commit comments

Comments
 (0)