diff --git a/Composer/cypress/integration/NavigateUrls.spec.ts b/Composer/cypress/integration/NavigateUrls.spec.ts index 99bb4916fd..3ccbe1c001 100644 --- a/Composer/cypress/integration/NavigateUrls.spec.ts +++ b/Composer/cypress/integration/NavigateUrls.spec.ts @@ -12,7 +12,7 @@ context('Navigate Url', () => { }); it('should open Define Conversations window from a url', () => { - cy.visit('/projects/create/TodoSample'); + cy.visit('/projects/create/dotnet/conversationalCore'); cy.get('[data-testid="NewDialogName"]').should('be.visible'); }); diff --git a/Composer/packages/client/__tests__/components/CreationFlowV2/CreateOptions/index.test.tsx b/Composer/packages/client/__tests__/components/CreationFlowV2/CreateOptions/index.test.tsx index 3cc2d52b16..138b3307e5 100644 --- a/Composer/packages/client/__tests__/components/CreationFlowV2/CreateOptions/index.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlowV2/CreateOptions/index.test.tsx @@ -12,7 +12,6 @@ describe('', () => { const handleCreateNextMock = jest.fn(); const handleJumpToOpenModal = jest.fn(); const handleFetchReadMeMock = jest.fn(); - const handleFetchTemplatesMock = jest.fn(); const templates = [ { @@ -34,7 +33,6 @@ describe('', () => { return renderWithRecoil( ; - -const CreationFlow: React.FC = (props: CreationFlowProps) => { +const CreationFlow: React.FC = () => { const { fetchTemplatesV2, fetchRecentProjects, diff --git a/Composer/packages/client/src/components/CreationFlow/v2/CreateBot.tsx b/Composer/packages/client/src/components/CreationFlow/v2/CreateBot.tsx index 096011541b..b8d7bb8b71 100644 --- a/Composer/packages/client/src/components/CreationFlow/v2/CreateBot.tsx +++ b/Composer/packages/client/src/components/CreationFlow/v2/CreateBot.tsx @@ -118,7 +118,6 @@ type CreateBotProps = { location?: WindowLocation | undefined; onDismiss: () => void; onNext: (templateName: string, templateLanguage: string, urlData?: string) => void; - fetchTemplates: (feedUrls?: string[]) => Promise; fetchReadMe: (moduleName: string) => {}; }; diff --git a/Composer/packages/client/src/components/CreationFlow/v2/CreateOptions.tsx b/Composer/packages/client/src/components/CreationFlow/v2/CreateOptions.tsx index 3f7a601f7c..9100532816 100644 --- a/Composer/packages/client/src/components/CreationFlow/v2/CreateOptions.tsx +++ b/Composer/packages/client/src/components/CreationFlow/v2/CreateOptions.tsx @@ -30,7 +30,6 @@ type CreateOptionsProps = { onDismiss: () => void; onNext: (templateName: string, templateLanguage: string, urlData?: string) => void; onJumpToOpenModal: (search?: string) => void; - fetchTemplates: (feedUrls?: string[]) => Promise; fetchReadMe: (moduleName: string) => {}; } & RouteComponentProps<{}>; @@ -38,7 +37,7 @@ export function CreateOptionsV2(props: CreateOptionsProps) { const [isOpenOptionsModal, setIsOpenOptionsModal] = useState(false); const [option, setOption] = useState('Create'); const [isOpenCreateModal, setIsOpenCreateModal] = useState(false); - const { templates, onDismiss, onNext, onJumpToOpenModal, fetchTemplates, fetchReadMe } = props; + const { templates, onDismiss, onNext, onJumpToOpenModal, fetchReadMe } = props; const [showNodeModal, setShowNodeModal] = useState(false); const userHasNode = useRecoilValue(userHasNodeInstalledState); @@ -128,7 +127,6 @@ export function CreateOptionsV2(props: CreateOptionsProps) { = () => { /> = (props) => { createNewBotV2, openProject, addExistingSkillToBotProject, - fetchTemplatesV2, fetchReadMe, } = useRecoilValue(dispatcherState); @@ -65,7 +64,6 @@ export const CreationModal: React.FC = (props) => { const fetchResources = async () => { await fetchStorages(); - fetchTemplatesV2(); }; useEffect(() => { @@ -169,7 +167,6 @@ export const CreationModal: React.FC = (props) => { import('./pages/botProject/BotProjec const Diagnostics = React.lazy(() => import('./pages/diagnostics/Diagnostics')); const ExtensionsPage = React.lazy(() => import('./pages/extensions/ExtensionsPage')); const Publish = React.lazy(() => import('./pages/publish/Publish')); -const BotCreationFlowRouter = React.lazy(() => import('./components/CreationFlow/CreationFlow')); +// const BotCreationFlowRouter = React.lazy(() => import('./components/CreationFlow/CreationFlow')); const BotCreationFlowRouterV2 = React.lazy(() => import('./components/CreationFlow/v2/CreationFlow')); const FormDialogPage = React.lazy(() => import('./pages/form-dialog/FormDialogPage')); @@ -102,9 +102,9 @@ const Routes = (props) => { - + - + diff --git a/Composer/packages/server/src/controllers/asset.ts b/Composer/packages/server/src/controllers/asset.ts index 9d048db6d0..fd20068fc8 100644 --- a/Composer/packages/server/src/controllers/asset.ts +++ b/Composer/packages/server/src/controllers/asset.ts @@ -62,7 +62,7 @@ export async function getProjTemplatesV2(req: any, res: any) { templates = templates.concat(await getNpmTemplates()); } - const sortedTemplateList = sortTemplates(templates); + const sortedTemplateList = await sortTemplates(templates); // return templates res.status(200).json(sortedTemplateList); diff --git a/Composer/packages/server/src/utility/__tests__/creation.test.ts b/Composer/packages/server/src/utility/__tests__/creation.test.ts index 7deff6fae7..723158cef8 100644 --- a/Composer/packages/server/src/utility/__tests__/creation.test.ts +++ b/Composer/packages/server/src/utility/__tests__/creation.test.ts @@ -3,7 +3,12 @@ import { BotTemplate } from '@bfc/shared'; -import { sortTemplates, templateSortOrder } from '../creation'; +import { sortTemplates, defaultSortOrder } from '../creation'; + +jest.mock('../../models/asset/assetManager', () => ({ + getRawGithubFileContent: jest.fn(), + AssetManager: jest.fn(), +})); describe('templateSort', () => { const templates: BotTemplate[] = [ @@ -82,8 +87,8 @@ describe('templateSort', () => { it('should return sorted templates per sortOrder obj', async () => { // note - the list in templates has to include all the same items in creation.ts - const sortedTemplateList = sortTemplates(templates); - templateSortOrder.forEach((templateSortEntry, index) => { + const sortedTemplateList = await sortTemplates(templates); + defaultSortOrder.forEach((templateSortEntry, index) => { if ( templates.findIndex((temp) => { temp.id === templateSortEntry.generatorName; diff --git a/Composer/packages/server/src/utility/creation.ts b/Composer/packages/server/src/utility/creation.ts index 7dd748b9a2..d4c8443162 100644 --- a/Composer/packages/server/src/utility/creation.ts +++ b/Composer/packages/server/src/utility/creation.ts @@ -4,9 +4,12 @@ import { BotTemplate, QnABotTemplateId } from '@bfc/shared'; import union from 'lodash/union'; -export const templateSortOrder = [ +import logger from '../logger'; +import AssetService from '../services/asset'; + +export const defaultSortOrder = [ { generatorName: '@microsoft/generator-bot-empty', displayName: 'Blank bot' }, - { generatorName: '@microsoft/generator-bot-conversational-core', displayName: 'Basic conversational bot' }, + { generatorName: '@microsoft/generator-bot-conversational-core', displayName: 'Basic bot' }, { generatorName: '@microsoft/generator-bot-assistant-core', displayName: 'Basic assistant' }, { generatorName: '@microsoft/generator-bot-enterprise-assistant', displayName: 'Enterprise assistant' }, { generatorName: '@microsoft/generator-bot-people', displayName: 'People' }, @@ -14,11 +17,23 @@ export const templateSortOrder = [ { generatorName: QnABotTemplateId, displayName: 'QnAMaker bot' }, ]; -export const sortTemplates = (templates: BotTemplate[]): BotTemplate[] => { +export const sortTemplates = async (templates: BotTemplate[]): Promise => { let sortedTemplateList: BotTemplate[] = []; + let sortOrder = defaultSortOrder; + try { + const templateSortOrder = await AssetService.manager.getRawGithubFileContent( + 'microsoft', + 'BotFramework-Composer', + 'main', + 'templates.json' + ); + const templateSortOrderObj = JSON.parse(templateSortOrder); + sortOrder = templateSortOrderObj && templateSortOrderObj?.length > 0 ? templateSortOrderObj : defaultSortOrder; + } catch (err) { + logger(JSON.stringify(err, Object.getOwnPropertyNames(err))); + } - // Sort incoming template array and reassign display name based on sort list - templateSortOrder.forEach((tempSortEntry, index) => { + sortOrder.forEach((tempSortEntry) => { const templateIndex = templates.findIndex((template) => { return template.id === tempSortEntry.generatorName; }); diff --git a/templates.json b/templates.json new file mode 100644 index 0000000000..acd2cf2ef1 --- /dev/null +++ b/templates.json @@ -0,0 +1,9 @@ +[ + { "generatorName": "@microsoft/generator-bot-empty", "displayName": "Blank bot" }, + { "generatorName": "@microsoft/generator-bot-conversational-core", "displayName": "Basic conversational bot" }, + { "generatorName": "@microsoft/generator-bot-assistant-core", "displayName": "Basic assistant" }, + { "generatorName": "@microsoft/generator-bot-enterprise-assistant", "displayName": "Enterprise assistant" }, + { "generatorName": "@microsoft/generator-bot-people", "displayName": "People" }, + { "generatorName": "@microsoft/generator-bot-calendar", "displayName": "Calendar" }, + { "generatorName": "QnASample", "displayName": "QnAMaker bot" } +]