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
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
import { ProjectTemplate } from '@bfc/shared';
import { NeutralColors } from '@uifabric/fluent-theme';

import { DialogCreationCopy, EmptyBotTemplateId } from '../../constants';
import { DialogCreationCopy, EmptyBotTemplateId, QnABotTemplateId } from '../../constants';
import { DialogWrapper, DialogTypes } from '../DialogWrapper';

// -------------------- Styles -------------------- //
Expand Down Expand Up @@ -98,6 +98,7 @@ const content = css`

const optionKeys = {
createFromScratch: 'createFromScratch',
createFromQnA: 'createFromQnA',
createFromTemplate: 'createFromTemplate',
};

Expand Down Expand Up @@ -146,6 +147,10 @@ export function CreateOptions(props) {
routeToTemplate = currentTemplate;
}

if (option === optionKeys.createFromQnA) {
routeToTemplate = QnABotTemplateId;
}

if (props.location && props.location.search) {
routeToTemplate += props.location.search;
}
Expand Down Expand Up @@ -226,6 +231,13 @@ export function CreateOptions(props) {
text: formatMessage('Create from scratch'),
onRenderField: SelectOption,
},
{
ariaLabel: formatMessage('Create from QnA') + (option === optionKeys.createFromQnA ? ' selected' : ''),
key: optionKeys.createFromQnA,
'data-testid': 'Create from QnA',
text: formatMessage('Create new knowledge base from FAQ, URL or PDF'),
onRenderField: SelectOption,
},
{
ariaLabel: formatMessage('Create from template') + (option === optionKeys.createFromTemplate ? ' selected' : ''),
key: optionKeys.createFromTemplate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// TODO: Remove path module
import Path from 'path';

import React, { useEffect, useRef, Fragment } from 'react';
import React, { useEffect, useRef, Fragment, useState } from 'react';
import { RouteComponentProps, Router, navigate } from '@reach/router';
import { useRecoilValue } from 'recoil';

Expand All @@ -16,8 +16,10 @@ import {
templateProjectsState,
storagesState,
focusedStorageFolderState,
localeState,
} from '../../recoilModel';
import Home from '../../pages/home/Home';
import ImportQnAFromUrlModal from '../../pages/qna/ImportQnAFromUrlModal';

import { CreateOptions } from './CreateOptions';
import { OpenProject } from './OpenProject';
Expand All @@ -38,15 +40,18 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
updateCurrentPathForStorage,
updateFolder,
saveTemplateId,
importQnAFromUrl,
} = useRecoilValue(dispatcherState);
const creationFlowStatus = useRecoilValue(creationFlowStatusState);
const projectId = useRecoilValue(projectIdState);
const templateProjects = useRecoilValue(templateProjectsState);
const storages = useRecoilValue(storagesState);
const focusedStorageFolder = useRecoilValue(focusedStorageFolderState);
const locale = useRecoilValue(localeState);
const currentStorageIndex = useRef(0);
const storage = storages[currentStorageIndex.current];
const currentStorageId = storage ? storage.id : 'default';
const [formData, setFormData] = useState({ name: '' });

useEffect(() => {
if (storages && storages.length) {
Expand Down Expand Up @@ -83,13 +88,37 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
};

const handleCreateNew = async (formData, templateId: string) => {
createProject(templateId || '', formData.name, formData.description, formData.location, formData.schemaUrl);
await createProject(templateId || '', formData.name, formData.description, formData.location, formData.schemaUrl);
};

const handleSaveAs = (formData) => {
saveProjectAs(projectId, formData.name, formData.description, formData.location);
};

const handleCreateQnA = async (urls: string[], knowledgeBaseName: string) => {
await handleSubmit(formData, 'QnASample');
for (let i = 0; i < urls.length; i++) {
if (!urls[i]) continue;
await importQnAFromUrl({
id: `${formData.name.toLocaleLowerCase()}.${locale}`,
knowledgeBaseName,
subscriptionKey: '',
url: urls[i],
region: 'westus',
isCreatingBot: true,
});
}
};

const handleSubmitOrImportQnA = async (formData, templateId: string) => {
if (templateId === 'QnASample') {
setFormData(formData);
navigate(`./QnASample/importQnA`);
return;
}
handleSubmit(formData, templateId);
};

const handleSubmit = async (formData, templateId: string) => {
handleDismiss();
switch (creationFlowStatus) {
Expand All @@ -99,7 +128,7 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {

default:
saveTemplateId(templateId);
handleCreateNew(formData, templateId);
await handleCreateNew(formData, templateId);
}
};

Expand All @@ -119,7 +148,7 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
updateFolder={updateFolder}
onCurrentPathUpdate={updateCurrentPath}
onDismiss={handleDismiss}
onSubmit={handleSubmit}
onSubmit={handleSubmitOrImportQnA}
/>
<CreateOptions path="create" templates={templateProjects} onDismiss={handleDismiss} onNext={handleCreateNext} />
<DefineConversation
Expand All @@ -129,7 +158,7 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
updateFolder={updateFolder}
onCurrentPathUpdate={updateCurrentPath}
onDismiss={handleDismiss}
onSubmit={handleSubmit}
onSubmit={handleSubmitOrImportQnA}
/>
<OpenProject
focusedStorageFolder={focusedStorageFolder}
Expand All @@ -138,6 +167,17 @@ const CreationFlow: React.FC<CreationFlowProps> = () => {
onDismiss={handleDismiss}
onOpen={openBot}
/>
<ImportQnAFromUrlModal
isCreatingBot
isMultipleUrlAllowed
isOpen
dialogId={formData.name.toLowerCase()}
isRegionNeeded={false}
isSubscriptionKeyNeeded={false}
path="create/QnASample/importQnA"
onDismiss={handleDismiss}
onSubmit={handleCreateQnA}
/>
</Router>
</Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { RouteComponentProps } from '@reach/router';
import querystring from 'query-string';
import { FontWeights } from '@uifabric/styling';

import { DialogCreationCopy, nameRegex } from '../../constants';
import { DialogCreationCopy, QnABotTemplateId, nameRegex } from '../../constants';
import { DialogWrapper, DialogTypes } from '../DialogWrapper';
import { FieldConfig, useForm } from '../../hooks/useForm';
import { StorageFolder } from '../../recoilModel/types';
Expand Down Expand Up @@ -259,7 +259,7 @@ const DefineConversation: React.FC<DefineConversationProps> = (props) => {
<PrimaryButton
data-testid="SubmitNewBotBtn"
disabled={hasErrors || !writable}
text={formatMessage('OK')}
text={templateId === QnABotTemplateId ? formatMessage('Next') : formatMessage('OK')}
onClick={handleSubmit}
/>
</DialogFooter>
Expand Down
2 changes: 2 additions & 0 deletions Composer/packages/client/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ export const DefaultPublishConfig = {

export const EmptyBotTemplateId = 'EmptyBot';

export const QnABotTemplateId = 'QnASample';

export const nameRegex = /^[a-zA-Z0-9-_]+$/;

export const adaptiveCardJsonBody =
Expand Down
Loading