diff --git a/Composer/cypress/integration/NotificationPage.spec.ts b/Composer/cypress/integration/NotificationPage.spec.ts index 4db76bb819..07c1090f1c 100644 --- a/Composer/cypress/integration/NotificationPage.spec.ts +++ b/Composer/cypress/integration/NotificationPage.spec.ts @@ -34,7 +34,7 @@ context('Notification Page', () => { cy.findByTestId('LeftNav-CommandBarButtonNotifications').click(); cy.findByTestId('notifications-table-view').within(() => { - cy.findAllByText('__testtodobotwithluissample.en-us.lu').should('exist').first().dblclick(); + cy.findAllByText('__TestToDoBotWithLuisSample.en-us.lu').should('exist').first().dblclick(); }); cy.findAllByText('__TestToDoBotWithLuisSample').should('exist'); diff --git a/Composer/cypress/integration/ToDoBot.spec.ts b/Composer/cypress/integration/ToDoBot.spec.ts index 4625c90421..0cbe207bfe 100644 --- a/Composer/cypress/integration/ToDoBot.spec.ts +++ b/Composer/cypress/integration/ToDoBot.spec.ts @@ -5,8 +5,6 @@ context('ToDo Bot', () => { before(() => { cy.visit('/home'); cy.createBot('TodoSample'); - cy.findByTestId('WelcomeModalCloseIcon').click(); - cy.findByText('Yes').click(); }); it('can open the main dialog', () => { diff --git a/Composer/packages/server/src/models/bot/botProject.ts b/Composer/packages/server/src/models/bot/botProject.ts index 766deba83c..3090957ba4 100644 --- a/Composer/packages/server/src/models/bot/botProject.ts +++ b/Composer/packages/server/src/models/bot/botProject.ts @@ -94,6 +94,12 @@ export class BotProject implements IBotProject { return files; } + public get rootDialogId() { + const mainDialogFile = this.dialogFiles.find((file) => !file.relativePath.includes('/')); + + return Path.basename(mainDialogFile?.name ?? '', '.dialog'); + } + public get formDialogSchemaFiles() { const files: FileInfo[] = []; this.files.forEach((file) => { @@ -350,24 +356,20 @@ export class BotProject implements IBotProject { public updateBotInfo = async (name: string, description: string, preserveRoot = false) => { const mainDialogFile = this.dialogFiles.find((file) => !file.relativePath.includes('/')); if (!mainDialogFile) return; - const botName = name.trim().toLowerCase(); + + const botName = name.trim(); + const { relativePath } = mainDialogFile; const content = JSON.parse(mainDialogFile.content); - if (!content.$designer) return; - const oldDesigner = content.$designer; - let newDesigner; - if (oldDesigner && oldDesigner.id) { - newDesigner = { - ...oldDesigner, - name, - description, - }; - } else { - newDesigner = getNewDesigner(name, description); - } - content.$designer = newDesigner; - content.id = name; - const updatedContent = autofixReferInDialog(botName, JSON.stringify(content, null, 2)); + + const { $designer } = content; + + content.$designer = $designer?.id ? { ...$designer, name, description } : getNewDesigner(botName, description); + + content.id = preserveRoot ? Path.basename(mainDialogFile.name, '.dialog') : botName; + + const updatedContent = autofixReferInDialog(content.id, JSON.stringify(content, null, 2)); + await this._updateFile(relativePath, updatedContent); for (const botProjectFile of this.botProjectFiles) { @@ -434,7 +436,7 @@ export class BotProject implements IBotProject { this._validateFileContent(name, content); const botName = this.name; const defaultLocale = this.settings?.defaultLanguage || defaultLanguage; - const relativePath = defaultFilePath(botName, defaultLocale, filename); + const relativePath = defaultFilePath(botName, defaultLocale, filename, this.rootDialogId); const file = this.files.get(filename); if (file) { throw new Error(`${filename} dialog already exist`); diff --git a/Composer/packages/server/src/models/bot/botStructure.ts b/Composer/packages/server/src/models/bot/botStructure.ts index 71518baf26..c4dce265bf 100644 --- a/Composer/packages/server/src/models/bot/botStructure.ts +++ b/Composer/packages/server/src/models/bot/botStructure.ts @@ -77,7 +77,12 @@ export const parseFileName = (name: string, defaultLocale: string) => { export const isRecognizer = (fileName: string) => fileName.endsWith('.lu.dialog') || fileName.endsWith('.qna.dialog'); export const isCrossTrainConfig = (fileName: string) => fileName.endsWith('cross-train.config.json'); -export const defaultFilePath = (botName: string, defaultLocale: string, filename: string): string => { +export const defaultFilePath = ( + botName: string, + defaultLocale: string, + filename: string, + rootDialogId = '' +): string => { const BOTNAME = botName.toLowerCase(); const CommonFileId = 'common'; @@ -86,8 +91,8 @@ export const defaultFilePath = (botName: string, defaultLocale: string, filename // now recognizer extension is .lu.dialog or .qna.dialog if (isRecognizer(filename)) { - const isRoot = filename.startsWith(botName.toLowerCase()); - const dialogId = filename.slice(0, filename.indexOf('.')); + const dialogId = filename.split('.')[0]; + const isRoot = filename.startsWith(botName) || (rootDialogId && filename.startsWith(rootDialogId)); if (isRoot) { return templateInterpolate(BotStructureTemplate.recognizer, { RECOGNIZERNAME: filename, @@ -170,14 +175,15 @@ export const defaultFilePath = (botName: string, defaultLocale: string, filename // when create/saveAs bot, serialize entry dialog/lg/lu export const serializeFiles = async (fileStorage, rootPath, botName, preserveRoot = false) => { const entryPatterns = [ - templateInterpolate(BotStructureTemplate.lg, { LOCALE: '*', BOTNAME: '*' }), - templateInterpolate(BotStructureTemplate.lu, { LOCALE: '*', BOTNAME: '*' }), - templateInterpolate(BotStructureTemplate.qna, { LOCALE: '*', BOTNAME: '*' }), templateInterpolate(BotStructureTemplate.dialogSchema, { BOTNAME: '*' }), templateInterpolate(BotStructureTemplate.botProject, { BOTNAME: '*' }), ]; + if (!preserveRoot) { entryPatterns.push(templateInterpolate(BotStructureTemplate.entry, { BOTNAME: '*' })); + entryPatterns.push(templateInterpolate(BotStructureTemplate.lg, { LOCALE: '*', BOTNAME: '*' })); + entryPatterns.push(templateInterpolate(BotStructureTemplate.lu, { LOCALE: '*', BOTNAME: '*' })); + entryPatterns.push(templateInterpolate(BotStructureTemplate.qna, { LOCALE: '*', BOTNAME: '*' })); } for (const pattern of entryPatterns) {