From e5c2ed83bfe9f6da9ae7fc88f0cdcdc59fa3c66b Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Tue, 23 Mar 2021 17:16:40 +0800
Subject: [PATCH 01/55] add skill select profile component
---
.../design/exportSkillModal/constants.tsx | 58 ++++---
.../content/SelectProfile.tsx | 162 ++++++++++++++++++
2 files changed, 200 insertions(+), 20 deletions(-)
create mode 100644 Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 611914dcbc..e4463a03bc 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -20,6 +20,7 @@ import {
SelectManifest,
SelectTriggers,
} from './content';
+import { SelectProfile } from './content/SelectProfile';
export const VERSION_REGEX = /\d\.\d+\.(\d+|preview-\d+)|\d\.\d+/i;
@@ -127,7 +128,7 @@ interface EditorStep {
}
export enum ManifestEditorSteps {
- ENDPOINTS = 'ENDPOINTS',
+ // ENDPOINTS = 'ENDPOINTS',
FETCH_MANIFEST_SCHEMA = 'FETCH_MANIFEST_SCHEMA',
MANIFEST_DESCRIPTION = 'MANIFEST_DESCRIPTION',
MANIFEST_REVIEW = 'MANIFEST_REVIEW',
@@ -135,13 +136,15 @@ export enum ManifestEditorSteps {
SELECT_MANIFEST = 'SELECT_MANIFEST',
SELECT_DIALOGS = 'SELECT_DIALOGS',
SELECT_TRIGGERS = 'SELECT_TRIGGERS',
+ SELECT_PROFILE = 'SELECT_PROFILE',
}
export const order: ManifestEditorSteps[] = [
ManifestEditorSteps.SELECT_MANIFEST,
ManifestEditorSteps.FETCH_MANIFEST_SCHEMA,
ManifestEditorSteps.MANIFEST_DESCRIPTION,
- ManifestEditorSteps.ENDPOINTS,
+ // ManifestEditorSteps.ENDPOINTS,
+ ManifestEditorSteps.SELECT_PROFILE,
ManifestEditorSteps.SELECT_DIALOGS,
ManifestEditorSteps.SELECT_TRIGGERS,
ManifestEditorSteps.MANIFEST_REVIEW,
@@ -207,27 +210,42 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
subText: () => formatMessage('To make your bot available for others as a skill, we need to generate a manifest.'),
validate,
},
- [ManifestEditorSteps.ENDPOINTS]: {
- buttons: [cancelButton, nextButton],
- content: Endpoints,
- editJson: true,
- subText: () =>
- formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
- title: () => formatMessage('Skill endpoints'),
- validate: ({ content, schema }) => {
- const { items, minItems } = schema.properties?.endpoints;
+ // [ManifestEditorSteps.ENDPOINTS]: {
+ // buttons: [cancelButton, nextButton],
+ // content: Endpoints,
+ // editJson: true,
+ // subText: () =>
+ // formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
+ // title: () => formatMessage('Skill endpoints'),
+ // validate: ({ content, schema }) => {
+ // const { items, minItems } = schema.properties?.endpoints;
- if (!content.endpoints || content.endpoints.length < minItems) {
- return { endpoints: formatMessage('Please add at least {minItems} endpoint', { minItems }) };
- }
+ // if (!content.endpoints || content.endpoints.length < minItems) {
+ // return { endpoints: formatMessage('Please add at least {minItems} endpoint', { minItems }) };
+ // }
- const endpointSchema = resolveRef(items, schema.definitions);
- const endpoints = (content.endpoints || []).map((endpoint) =>
- validate({ content: endpoint, schema: endpointSchema })
- );
+ // const endpointSchema = resolveRef(items, schema.definitions);
+ // const endpoints = (content.endpoints || []).map((endpoint) =>
+ // validate({ content: endpoint, schema: endpointSchema })
+ // );
- return endpoints.some((endpoint) => Object.keys(endpoint).length) ? { endpoints } : {};
- },
+ // return endpoints.some((endpoint) => Object.keys(endpoint).length) ? { endpoints } : {};
+ // },
+ // },
+ [ManifestEditorSteps.SELECT_PROFILE]: {
+ buttons: [
+ cancelButton,
+ {
+ primary: true,
+ text: () => formatMessage('Next'),
+ onClick: ({ onNext }) => onNext,
+ },
+ ],
+ editJson: false,
+ content: SelectProfile,
+ subText: () =>
+ formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
+ title: () => formatMessage('Confirm skill endpoints'),
},
[ManifestEditorSteps.MANIFEST_REVIEW]: {
buttons: [
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
new file mode 100644
index 0000000000..bb6960b530
--- /dev/null
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -0,0 +1,162 @@
+import { PublishTarget } from '@bfc/shared';
+import formatMessage from 'format-message';
+import { css, Dropdown, Icon, IDropdownOption, PrimaryButton, TextField, TooltipHost } from 'office-ui-fabric-react';
+import React, { useEffect, useMemo, useState } from 'react';
+import { useRecoilValue } from 'recoil';
+import { settingsState } from '../../../../recoilModel';
+import { PublishTargets } from '../../../botProject/PublishTargets';
+import { iconStyle } from '../../../botProject/runtime-settings/style';
+import Publish from '../../../publish/Publish';
+import { ContentProps } from '../constants';
+
+const styles = {
+ container: css`
+ height: 350px;
+ overflow: auto;
+ `,
+};
+
+const onRenderLabel = (props) => {
+ return (
+
+
+ {' '}
+ {props.label}{' '}
+
+
+
+
+
+ );
+};
+
+export const SelectProfile: React.FC = ({ errors, value, schema, onChange, projectId }) => {
+ const [publishingTargets, setPublishingTargets] = useState([]);
+ const [currentTarget, setCurrentTarget] = useState();
+ const [endpointUrl, setEndpointUrl] = useState();
+ const [appId, setAppId] = useState();
+ const { endpoints, ...rest } = value;
+
+ const updateCurrentProfile = useMemo(
+ () => (_e, option?: IDropdownOption) => {
+ const target = publishingTargets.find((t) => {
+ return t.name === option?.key;
+ });
+ if (target) {
+ setCurrentTarget(target);
+ const config = JSON.parse(target.configuration);
+ setEndpointUrl(`https://${config.hostname}.azurewebsites.net`);
+ setAppId(config.settings.MicrosoftAppId);
+ onChange({
+ endpoints: [
+ {
+ protocol: 'BotFrameworkV3',
+ name: option?.key,
+ endpointUrl: `https://${config.hostname}.azurewebsites.net`,
+ description: '',
+ msAppId: config.settings.MicrosoftAppId,
+ },
+ ],
+ ...rest,
+ });
+ }
+ },
+ [publishingTargets]
+ );
+
+ const isProfileValid = useMemo(
+ () => () => {
+ if (!publishingTargets) {
+ return false;
+ }
+ const filteredProfile = publishingTargets.filter((item) => {
+ const config = JSON.parse(item.configuration);
+ return (
+ config.settings.MicrosoftAppId &&
+ config.hostname &&
+ config.settings.MicrosoftAppId.length > 0 &&
+ config.hostname.length > 0
+ );
+ });
+ return filteredProfile.length > 0;
+ },
+ [publishingTargets]
+ );
+
+ const publishingOptions = useMemo(() => {
+ return publishingTargets.map((t) => ({
+ key: t.name,
+ text: t.name,
+ }));
+ }, [publishingTargets]);
+
+ const settings = useRecoilValue(settingsState(projectId));
+
+ const OnEndpointChange = useMemo(
+ () => (e, newValue) => {
+ setEndpointUrl(newValue);
+ },
+ [setEndpointUrl]
+ );
+
+ const OnAppIdChange = useMemo(
+ () => (e, newValue) => {
+ setAppId(newValue);
+ },
+ [setAppId]
+ );
+
+ useEffect(() => {
+ setPublishingTargets(settings.publishTargets || []);
+ }, [settings]);
+
+ return isProfileValid() ? (
+
+
+
+
+
+ ) : (
+
+ );
+};
From c86693e46a65ea0be281f615c2b94d371f739a1c Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 24 Mar 2021 17:55:41 +0800
Subject: [PATCH 02/55] manifest file cud api
---
.../client/src/utils/manifestFileUtil.ts | 24 ++++++++++
.../server/src/controllers/project.ts | 48 +++++++++++++++++++
.../server/src/models/bot/botProject.ts | 38 ++++++++++++++-
.../server/src/models/bot/botStructure.ts | 9 ++++
Composer/packages/server/src/router/api.ts | 3 ++
5 files changed, 121 insertions(+), 1 deletion(-)
create mode 100644 Composer/packages/client/src/utils/manifestFileUtil.ts
diff --git a/Composer/packages/client/src/utils/manifestFileUtil.ts b/Composer/packages/client/src/utils/manifestFileUtil.ts
new file mode 100644
index 0000000000..ece41cd8f3
--- /dev/null
+++ b/Composer/packages/client/src/utils/manifestFileUtil.ts
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import httpClient from './httpUtil';
+
+export const createManifestFile = async (projectId: string, name: string, content: string) => {
+ const response = await httpClient.post(`/projects/${projectId}/manifest/files`, {
+ name,
+ content,
+ });
+ return response.data;
+};
+
+export const deleteManifestFile = async (projectId: string, name: string) => {
+ await httpClient.delete(`/projects/${projectId}/manifest/files/${name}`);
+};
+
+export const updateManifestFile = async (projectId: string, name: string, content: string) => {
+ const response = await httpClient.put(`/projects/${projectId}/manifest/files/${name}`, {
+ name,
+ content,
+ });
+ return response.data;
+};
diff --git a/Composer/packages/server/src/controllers/project.ts b/Composer/packages/server/src/controllers/project.ts
index f1a9185fcd..47699352e2 100644
--- a/Composer/packages/server/src/controllers/project.ts
+++ b/Composer/packages/server/src/controllers/project.ts
@@ -301,6 +301,51 @@ async function removeFile(req: Request, res: Response) {
}
}
+async function updateManifestFile(req: Request, res: Response) {
+ const projectId = req.params.projectId;
+ const user = await ExtensionContext.getUserFromRequest(req);
+ const currentProject = await BotProjectService.getProjectById(projectId, user);
+ if (currentProject !== undefined) {
+ const lastModified = await currentProject.updateManifestLuFile(req.body.name, req.body.content);
+ res.status(200).json({ lastModified: lastModified });
+ } else {
+ res.status(404).json({
+ message: 'No such bot project opened',
+ });
+ }
+}
+
+async function createManifestFile(req: Request, res: Response) {
+ const projectId = req.params.projectId;
+ const user = await ExtensionContext.getUserFromRequest(req);
+
+ const currentProject = await BotProjectService.getProjectById(projectId, user);
+ if (currentProject !== undefined) {
+ const { name, content } = req.body;
+
+ //dir = id
+ const file = await currentProject.createManifestLuFile(name, content);
+ res.status(200).json(file);
+ } else {
+ res.status(404).json({
+ message: 'No such bot project opened',
+ });
+ }
+}
+
+async function removeManifestFile(req: Request, res: Response) {
+ const projectId = req.params.projectId;
+ const user = await ExtensionContext.getUserFromRequest(req);
+
+ const currentProject = await BotProjectService.getProjectById(projectId, user);
+ if (currentProject !== undefined) {
+ const dialogResources = await currentProject.deleteManifestLuFile(req.params.name);
+ res.status(200).json(dialogResources);
+ } else {
+ res.status(404).json({ error: 'No bot project opened' });
+ }
+}
+
async function getSkill(req: Request, res: Response) {
const projectId = req.params.projectId;
const user = await ExtensionContext.getUserFromRequest(req);
@@ -546,6 +591,9 @@ export const ProjectController = {
updateFile,
createFile,
removeFile,
+ createManifestFile,
+ updateManifestFile,
+ removeManifestFile,
getSkill,
build,
setQnASettings,
diff --git a/Composer/packages/server/src/models/bot/botProject.ts b/Composer/packages/server/src/models/bot/botProject.ts
index 9904623cc6..d97adf30fd 100644
--- a/Composer/packages/server/src/models/bot/botProject.ts
+++ b/Composer/packages/server/src/models/bot/botProject.ts
@@ -32,7 +32,7 @@ import log from '../../logger';
import { BotProjectService } from '../../services/project';
import AssetService from '../../services/asset';
-import { BotStructureFilesPatterns, isCrossTrainConfig } from './botStructure';
+import { BotStructureFilesPatterns, defaultManifestFilePath, isCrossTrainConfig } from './botStructure';
import { Builder } from './builder';
import { IFileStorage } from './../storage/interface';
import { LocationRef, IBuildConfig } from './interface';
@@ -461,6 +461,42 @@ export class BotProject implements IBotProject {
return await this._createFile(relativePath, content);
};
+ public createManifestLuFile = async (name: string, content = '') => {
+ const filename = name.trim();
+ this.validateFileName(filename);
+ this._validateFileContent(name, content);
+ const botName = this.name;
+ const defaultLocale = this.settings?.defaultLanguage || defaultLanguage;
+ const relativePath = defaultManifestFilePath(botName, filename, defaultLocale);
+ const file = this.files.get(filename);
+ if (file) {
+ throw new Error(`${filename} dialog already exist`);
+ }
+ return await this._createFile(relativePath, content);
+ };
+
+ public updateManifestLuFile = async (name: string, content: string): Promise => {
+ const file = this.files.get(name);
+ if (file === undefined) {
+ const { lastModified } = await this.createManifestLuFile(name, content);
+ return lastModified;
+ }
+
+ const relativePath = file.relativePath;
+ this._validateFileContent(name, content);
+ const lastModified = await this._updateFile(relativePath, content);
+ return lastModified;
+ };
+
+ public deleteManifestLuFile = async (name: string) => {
+ const file = this.files.get(name);
+ if (file === undefined) {
+ throw new Error(`no such file ${name}`);
+ }
+ await this._removeFile(file.relativePath);
+ await this._cleanUp(file.relativePath);
+ };
+
public createFiles = async (files) => {
const createdFiles: FileInfo[] = [];
for (const { name, content } of files) {
diff --git a/Composer/packages/server/src/models/bot/botStructure.ts b/Composer/packages/server/src/models/bot/botStructure.ts
index 22814269bb..f6fc6db3da 100644
--- a/Composer/packages/server/src/models/bot/botStructure.ts
+++ b/Composer/packages/server/src/models/bot/botStructure.ts
@@ -10,6 +10,7 @@ const BotStructureTemplate = {
entry: '${BOTNAME}.dialog',
lg: 'language-generation/${LOCALE}/${BOTNAME}.${LOCALE}.lg',
lu: 'language-understanding/${LOCALE}/${BOTNAME}.${LOCALE}.lu',
+ manifestLu: 'manifest/${FILENAME}.${LOCALE}.lu',
qna: 'knowledge-base/en-us/${BOTNAME}.en-us.qna',
sourceQnA: 'knowledge-base/source/${FILENAME}.source.qna',
dialogSchema: '${BOTNAME}.dialog.schema',
@@ -105,6 +106,14 @@ 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 defaultManifestFilePath = (botName: string, fileName: string, locale: string): string => {
+ return templateInterpolate(BotStructureTemplate.manifestLu, {
+ BOTNAME: botName,
+ FILENAME: fileName,
+ LOCALE: locale,
+ });
+};
+
export const defaultFilePath = (
botName: string,
defaultLocale: string,
diff --git a/Composer/packages/server/src/router/api.ts b/Composer/packages/server/src/router/api.ts
index f3ae8d7e4b..7c770c4bd9 100644
--- a/Composer/packages/server/src/router/api.ts
+++ b/Composer/packages/server/src/router/api.ts
@@ -38,6 +38,9 @@ router.delete('/projects/:projectId', ProjectController.removeProject);
router.put('/projects/:projectId/files/:name', ProjectController.updateFile);
router.delete('/projects/:projectId/files/:name', ProjectController.removeFile);
router.post('/projects/:projectId/files', ProjectController.createFile);
+router.put('/projects/:projectId/manifest/files/:name', ProjectController.updateManifestFile);
+router.delete('/projects/:projectId/manifest/files/:name', ProjectController.removeManifestFile);
+router.post('/projects/:projectId/manifest/files', ProjectController.createManifestFile);
router.get('/projects/:projectId/skill/retrieveSkillManifest', ProjectController.getSkill);
router.post('/projects/:projectId/build', ProjectController.build);
router.post('/projects/:projectId/qnaSettings/set', ProjectController.setQnASettings);
From 0873dfc1eb203096cc79d2c13687fd5f0cf1e621 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Thu, 25 Mar 2021 11:45:13 +0800
Subject: [PATCH 03/55] add skill select page and publish logic
---
.../design/exportSkillModal/constants.tsx | 38 ++++----------
.../content/SelectProfile.tsx | 51 ++++++++++++++++---
.../pages/design/exportSkillModal/index.tsx | 48 ++++++++++++++++-
.../src/pages/publish/Notifications.tsx | 16 ++++++
.../client/src/pages/publish/Publish.tsx | 6 ++-
.../client/src/recoilModel/atoms/botState.ts | 6 +++
.../src/recoilModel/dispatchers/project.ts | 10 +++-
7 files changed, 137 insertions(+), 38 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index e4463a03bc..c399deed59 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -143,10 +143,9 @@ export const order: ManifestEditorSteps[] = [
ManifestEditorSteps.SELECT_MANIFEST,
ManifestEditorSteps.FETCH_MANIFEST_SCHEMA,
ManifestEditorSteps.MANIFEST_DESCRIPTION,
- // ManifestEditorSteps.ENDPOINTS,
- ManifestEditorSteps.SELECT_PROFILE,
ManifestEditorSteps.SELECT_DIALOGS,
ManifestEditorSteps.SELECT_TRIGGERS,
+ // ManifestEditorSteps.SELECT_PROFILE,
ManifestEditorSteps.MANIFEST_REVIEW,
ManifestEditorSteps.SAVE_MANIFEST,
];
@@ -210,35 +209,17 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
subText: () => formatMessage('To make your bot available for others as a skill, we need to generate a manifest.'),
validate,
},
- // [ManifestEditorSteps.ENDPOINTS]: {
- // buttons: [cancelButton, nextButton],
- // content: Endpoints,
- // editJson: true,
- // subText: () =>
- // formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
- // title: () => formatMessage('Skill endpoints'),
- // validate: ({ content, schema }) => {
- // const { items, minItems } = schema.properties?.endpoints;
-
- // if (!content.endpoints || content.endpoints.length < minItems) {
- // return { endpoints: formatMessage('Please add at least {minItems} endpoint', { minItems }) };
- // }
-
- // const endpointSchema = resolveRef(items, schema.definitions);
- // const endpoints = (content.endpoints || []).map((endpoint) =>
- // validate({ content: endpoint, schema: endpointSchema })
- // );
-
- // return endpoints.some((endpoint) => Object.keys(endpoint).length) ? { endpoints } : {};
- // },
- // },
[ManifestEditorSteps.SELECT_PROFILE]: {
buttons: [
cancelButton,
{
primary: true,
- text: () => formatMessage('Next'),
- onClick: ({ onNext }) => onNext,
+ text: () => formatMessage('Generate and Publish'),
+ onClick: ({ onNext, generateManifest }) => () => {
+ onNext({ dismiss: true, save: true });
+ generateManifest();
+ // onPublish();
+ },
},
],
editJson: false,
@@ -282,9 +263,8 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
cancelButton,
{
primary: true,
- text: () => formatMessage('Generate'),
- onClick: ({ generateManifest, onNext }) => () => {
- generateManifest();
+ text: () => formatMessage('Next'),
+ onClick: ({ onNext }) => () => {
onNext();
},
},
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index bb6960b530..6d543b8934 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -1,13 +1,19 @@
-import { PublishTarget } from '@bfc/shared';
+import { PublishTarget, SkillManifestFile } from '@bfc/shared';
import formatMessage from 'format-message';
import { css, Dropdown, Icon, IDropdownOption, PrimaryButton, TextField, TooltipHost } from 'office-ui-fabric-react';
import React, { useEffect, useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
-import { settingsState } from '../../../../recoilModel';
+import {
+ botDisplayNameState,
+ currentTargetState,
+ dispatcherState,
+ settingsState,
+ skillManifestsState,
+} from '../../../../recoilModel';
import { PublishTargets } from '../../../botProject/PublishTargets';
import { iconStyle } from '../../../botProject/runtime-settings/style';
import Publish from '../../../publish/Publish';
-import { ContentProps } from '../constants';
+import { ContentProps, VERSION_REGEX } from '../constants';
const styles = {
container: css`
@@ -42,12 +48,37 @@ const onRenderLabel = (props) => {
);
};
-export const SelectProfile: React.FC = ({ errors, value, schema, onChange, projectId }) => {
+export const getManifestId = (
+ botName: string,
+ skillManifests: SkillManifestFile[],
+ { content: { $schema } = {} }: Partial
+): string => {
+ const [version] = VERSION_REGEX.exec($schema) || [''];
+
+ let fileId = version ? `${botName}-${version.replace(/\./g, '-')}-manifest` : `${botName}-manifest`;
+ let i = -1;
+
+ while (skillManifests.some(({ id }) => id === fileId)) {
+ if (i < 0) {
+ fileId = fileId.concat(`-${++i}`);
+ } else {
+ fileId = fileId.substr(0, fileId.lastIndexOf('-')).concat(`-${++i}`);
+ }
+ }
+
+ return fileId;
+};
+
+export const SelectProfile: React.FC = ({ manifest, setSkillManifest, value, onChange, projectId }) => {
const [publishingTargets, setPublishingTargets] = useState([]);
const [currentTarget, setCurrentTarget] = useState();
+ const { updateCurrentTarget } = useRecoilValue(dispatcherState);
const [endpointUrl, setEndpointUrl] = useState();
const [appId, setAppId] = useState();
const { endpoints, ...rest } = value;
+ const { id } = manifest;
+ const botName = useRecoilValue(botDisplayNameState(projectId));
+ const skillManifests = useRecoilValue(skillManifestsState(projectId));
const updateCurrentProfile = useMemo(
() => (_e, option?: IDropdownOption) => {
@@ -56,20 +87,21 @@ export const SelectProfile: React.FC = ({ errors, value, schema, o
});
if (target) {
setCurrentTarget(target);
+ updateCurrentTarget(projectId, target);
const config = JSON.parse(target.configuration);
setEndpointUrl(`https://${config.hostname}.azurewebsites.net`);
setAppId(config.settings.MicrosoftAppId);
onChange({
+ ...rest,
endpoints: [
{
protocol: 'BotFrameworkV3',
name: option?.key,
- endpointUrl: `https://${config.hostname}.azurewebsites.net`,
+ endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
description: '',
msAppId: config.settings.MicrosoftAppId,
},
],
- ...rest,
});
}
},
@@ -122,6 +154,13 @@ export const SelectProfile: React.FC = ({ errors, value, schema, o
setPublishingTargets(settings.publishTargets || []);
}, [settings]);
+ useEffect(() => {
+ if (!id) {
+ const fileId = getManifestId(botName, skillManifests, manifest);
+ setSkillManifest({ ...manifest, id: fileId });
+ }
+ }, []);
+
return isProfileValid() ? (
= ({ onSubmit, onDismiss
const dialogSchemas = useRecoilValue(dialogSchemasState(projectId));
const luFiles = useRecoilValue(luFilesState(projectId));
const qnaFiles = useRecoilValue(qnaFilesState(projectId));
+ const currentTarget = useRecoilValue(currentTargetState(projectId));
const skillManifests = useRecoilValue(skillManifestsState(projectId));
const { updateSkillManifest } = useRecoilValue(dispatcherState);
+ const { publishToTarget, addNotification } = useRecoilValue(dispatcherState);
+ const [showAuthDialog, setShowAuthDialog] = useState(false);
+
+ const pendingNotificationRef = useRef();
+ const showNotificationsRef = useRef>({});
const [editingId, setEditingId] = useState();
const [currentStep, setCurrentStep] = useState(0);
@@ -77,6 +89,28 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
}
};
+ const handleTriggerPublish = async () => {
+ // get token
+
+ let token = '';
+ // TODO: this logic needs to be moved into the Azure publish extensions
+ if (isGetTokenFromUser()) {
+ token = getTokenFromCache('accessToken');
+ } else {
+ let tenant = getTenantIdFromCache();
+ if (!tenant) {
+ const tenants = await AuthClient.getTenants();
+ tenant = tenants?.[0]?.tenantId;
+ setTenantId(tenant);
+ }
+ token = await AuthClient.getARMTokenForTenant(tenant);
+ }
+ console.log(token);
+ const notification = createNotification(getPendingNotificationSkillCardProps());
+ addNotification(notification);
+ await publishToTarget(projectId, currentTarget, {}, null, token);
+ };
+
const handleSave = () => {
if (skillManifest.content && skillManifest.id) {
updateSkillManifest(skillManifest as SkillManifestFile, projectId);
@@ -162,6 +196,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
onDismiss: handleDismiss,
onNext: handleNext,
onSave: handleSave,
+ // onPublish: handleTriggerPublish,
onSubmit,
})}
/>
@@ -171,6 +206,17 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
{editJson && }
+ {showAuthDialog && (
+ {
+ // setDialogHidden(false);
+ }}
+ onDismiss={() => {
+ setShowAuthDialog(false);
+ }}
+ />
+ )}
);
diff --git a/Composer/packages/client/src/pages/publish/Notifications.tsx b/Composer/packages/client/src/pages/publish/Notifications.tsx
index 8802db9da7..0b35dabed5 100644
--- a/Composer/packages/client/src/pages/publish/Notifications.tsx
+++ b/Composer/packages/client/src/pages/publish/Notifications.tsx
@@ -83,3 +83,19 @@ export const getPendingNotificationCardProps = (items: BotStatus[]): CardProps =
),
};
};
+
+export const getPendingNotificationSkillCardProps = (): CardProps => {
+ return {
+ title: '',
+ description: formatMessage(`Publishing skill`),
+ type: 'pending',
+ onRenderCardContent: (props) => (
+
+ ),
+ };
+};
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index 2f8374350d..d74d87178a 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -29,7 +29,11 @@ import { navigateTo } from '../../utils/navigation';
import { PublishDialog } from './PublishDialog';
import { ContentHeaderStyle, HeaderText, ContentStyle, contentEditor } from './styles';
import { BotStatusList } from './BotStatusList';
-import { getPendingNotificationCardProps, getPublishedNotificationCardProps } from './Notifications';
+import {
+ getPendingNotificationCardProps,
+ getPendingNotificationSkillCardProps,
+ getPublishedNotificationCardProps,
+} from './Notifications';
import { PullDialog } from './pullDialog';
import { PublishToolbar } from './PublishToolbar';
import { Bot, BotStatus } from './type';
diff --git a/Composer/packages/client/src/recoilModel/atoms/botState.ts b/Composer/packages/client/src/recoilModel/atoms/botState.ts
index 1a6d4b316f..9bc98f08bc 100644
--- a/Composer/packages/client/src/recoilModel/atoms/botState.ts
+++ b/Composer/packages/client/src/recoilModel/atoms/botState.ts
@@ -17,6 +17,7 @@ import {
QnAFile,
SkillManifestFile,
RecognizerFile,
+ PublishTarget,
} from '@bfc/shared';
import { DirectLineLog } from '@botframework-composer/types/src';
import { atomFamily } from 'recoil';
@@ -312,6 +313,11 @@ export const qnaFilesState = atomFamily({
default: [],
});
+export const currentTargetState = atomFamily({
+ key: getFullyQualifiedKey('currentTarget'),
+ default: {} as PublishTarget,
+});
+
export const jsonSchemaFilesState = atomFamily({
key: getFullyQualifiedKey('jsonSchemaFiles'),
default: [],
diff --git a/Composer/packages/client/src/recoilModel/dispatchers/project.ts b/Composer/packages/client/src/recoilModel/dispatchers/project.ts
index 44072454c3..c957856e51 100644
--- a/Composer/packages/client/src/recoilModel/dispatchers/project.ts
+++ b/Composer/packages/client/src/recoilModel/dispatchers/project.ts
@@ -4,7 +4,7 @@
import formatMessage from 'format-message';
import findIndex from 'lodash/findIndex';
-import { QnABotTemplateId, RootBotManagedProperties } from '@bfc/shared';
+import { PublishTarget, QnABotTemplateId, RootBotManagedProperties } from '@bfc/shared';
import get from 'lodash/get';
import { CallbackInterface, useRecoilCallback } from 'recoil';
@@ -28,6 +28,7 @@ import {
createQnAOnState,
creationFlowTypeState,
currentProjectIdState,
+ currentTargetState,
dispatcherState,
fetchReadMePendingState,
filePersistenceState,
@@ -464,6 +465,12 @@ export const projectDispatcher = () => {
}
);
+ const updateCurrentTarget = useRecoilCallback<[string, PublishTarget], void>(
+ ({ set }: CallbackInterface) => async (projectId: string, currentTarget) => {
+ set(currentTargetState(projectId), currentTarget);
+ }
+ );
+
const saveTemplateId = useRecoilCallback<[string], void>(({ set }: CallbackInterface) => (templateId) => {
if (templateId) {
set(templateIdState, templateId);
@@ -598,6 +605,7 @@ export const projectDispatcher = () => {
saveProjectAs,
fetchProjectById,
fetchRecentProjects,
+ updateCurrentTarget,
setBotStatus,
saveTemplateId,
updateBoilerplate,
From 4d7cc968bb52c911c232e36a32c4abd33e94ab61 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Thu, 25 Mar 2021 15:33:40 +0800
Subject: [PATCH 04/55] folder rename
---
Composer/packages/server/src/models/bot/botStructure.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/server/src/models/bot/botStructure.ts b/Composer/packages/server/src/models/bot/botStructure.ts
index f6fc6db3da..227f2326b1 100644
--- a/Composer/packages/server/src/models/bot/botStructure.ts
+++ b/Composer/packages/server/src/models/bot/botStructure.ts
@@ -10,7 +10,7 @@ const BotStructureTemplate = {
entry: '${BOTNAME}.dialog',
lg: 'language-generation/${LOCALE}/${BOTNAME}.${LOCALE}.lg',
lu: 'language-understanding/${LOCALE}/${BOTNAME}.${LOCALE}.lu',
- manifestLu: 'manifest/${FILENAME}.${LOCALE}.lu',
+ manifestLu: 'manifests/${FILENAME}.${LOCALE}.lu',
qna: 'knowledge-base/en-us/${BOTNAME}.en-us.qna',
sourceQnA: 'knowledge-base/source/${FILENAME}.source.qna',
dialogSchema: '${BOTNAME}.dialog.schema',
From b51339ee48c0650b4c48866f12718997a13edeab Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Thu, 25 Mar 2021 15:56:22 +0800
Subject: [PATCH 05/55] add lu files writing logic
---
.../design/exportSkillModal/constants.tsx | 15 +++---
.../exportSkillModal/generateSkillManifest.ts | 46 +++++++++++++++----
.../pages/design/exportSkillModal/index.tsx | 33 +++++++------
3 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index c399deed59..c022cda263 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -145,9 +145,9 @@ export const order: ManifestEditorSteps[] = [
ManifestEditorSteps.MANIFEST_DESCRIPTION,
ManifestEditorSteps.SELECT_DIALOGS,
ManifestEditorSteps.SELECT_TRIGGERS,
- // ManifestEditorSteps.SELECT_PROFILE,
- ManifestEditorSteps.MANIFEST_REVIEW,
- ManifestEditorSteps.SAVE_MANIFEST,
+ ManifestEditorSteps.SELECT_PROFILE,
+ // ManifestEditorSteps.MANIFEST_REVIEW,
+ // ManifestEditorSteps.SAVE_MANIFEST,
];
const cancelButton: Button = {
@@ -215,14 +215,14 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
{
primary: true,
text: () => formatMessage('Generate and Publish'),
- onClick: ({ onNext, generateManifest }) => () => {
- onNext({ dismiss: true, save: true });
+ onClick: ({ generateManifest, onNext }) => () => {
generateManifest();
+ onNext({ dismiss: true, save: true });
// onPublish();
},
},
],
- editJson: false,
+ editJson: true,
content: SelectProfile,
subText: () =>
formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
@@ -263,8 +263,9 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
cancelButton,
{
primary: true,
- text: () => formatMessage('Next'),
+ text: () => formatMessage('Generate'),
onClick: ({ onNext }) => () => {
+ // generateManifest();
onNext();
},
},
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
index 79a160e931..bfb531d682 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
@@ -2,16 +2,26 @@
// Licensed under the MIT License.
import get from 'lodash/get';
-import { DialogInfo, DialogSchemaFile, ITrigger, SDKKinds, SkillManifestFile, LuFile, QnAFile } from '@bfc/shared';
+import {
+ DialogInfo,
+ DialogSchemaFile,
+ ITrigger,
+ SDKKinds,
+ SkillManifestFile,
+ LuFile,
+ QnAFile,
+ PublishTarget,
+} from '@bfc/shared';
import { JSONSchema7 } from '@bfc/extension-client';
import { Activities, Activity, activityHandlerMap, ActivityTypes, DispatchModels } from './constants';
+import { createManifestFile } from '../../../utils/manifestFileUtil';
const getActivityType = (kind: SDKKinds): ActivityTypes | undefined => activityHandlerMap[kind];
export const isSupportedTrigger = ({ type }: ITrigger) => Object.keys(activityHandlerMap).includes(type as SDKKinds);
-export const generateSkillManifest = (
+export const generateSkillManifest = async (
schema: JSONSchema7,
skillManifest: Partial,
dialogs: DialogInfo[],
@@ -19,7 +29,9 @@ export const generateSkillManifest = (
luFiles: LuFile[],
qnaFiles: QnAFile[],
selectedTriggers: ITrigger[],
- selectedDialogs: Partial[]
+ selectedDialogs: Partial[],
+ currentTarget: PublishTarget,
+ projectId: string
) => {
const {
activities: previousActivities,
@@ -40,7 +52,15 @@ export const generateSkillManifest = (
const triggers = selectedTriggers.map((tr) => get(content, tr.id) as ITrigger).filter(Boolean);
const activities = generateActivities(dialogSchemas, triggers, resolvedDialogs);
- const dispatchModels = generateDispatchModels(schema, dialogs, triggers, luFiles, qnaFiles);
+ const dispatchModels = await generateDispatchModels(
+ schema,
+ dialogs,
+ triggers,
+ luFiles,
+ qnaFiles,
+ currentTarget,
+ projectId
+ );
const definitions = getDefinitions(dialogSchemas, resolvedDialogs);
return {
@@ -99,12 +119,14 @@ export const generateOtherActivities = (kind: SDKKinds): Activities => {
return type ? { [type]: { type } } : {};
};
-export const generateDispatchModels = (
+export const generateDispatchModels = async (
schema: JSONSchema7,
dialogs: DialogInfo[],
selectedTriggers: any[],
luFiles: LuFile[],
- qnaFiles: QnAFile[]
+ qnaFiles: QnAFile[],
+ target: PublishTarget,
+ projectId: string
): { dispatchModels?: DispatchModels } => {
const intents = selectedTriggers.filter(({ $kind }) => $kind === SDKKinds.OnIntent).map(({ intent }) => intent);
const { id: rootId } = dialogs.find((dialog) => dialog?.isRoot) || {};
@@ -123,6 +145,14 @@ export const generateDispatchModels = (
return {};
}
+ const config = JSON.parse(target.configuration);
+ const baseEndpointUrl = `https://${config.hostname}.azurewebsites.net/manifest`;
+
+ for (const rootLuFile of rootLuFiles) {
+ const currentFileName = `skill-${rootLuFile.id}.lu`;
+ await createManifestFile(projectId, currentFileName, rootLuFile.content);
+ }
+
const luLanguages = intents.length
? rootLuFiles.reduce((acc, { empty, id }) => {
const [name, locale] = id.split('.');
@@ -140,7 +170,7 @@ export const generateDispatchModels = (
{
name,
contentType: 'application/lu',
- url: `<${id}.lu url>`,
+ url: `${baseEndpointUrl}/skill-${id}.lu`,
description: '',
},
],
@@ -164,7 +194,7 @@ export const generateDispatchModels = (
{
name,
contentType: 'application/qna',
- url: `<${id}.qna url>`,
+ url: `${baseEndpointUrl}/skill-${id}.qna`,
description: '',
},
],
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index ff403e4a3c..ccbe6054fd 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -25,7 +25,13 @@ import {
import { editorSteps, ManifestEditorSteps, order } from './constants';
import { generateSkillManifest } from './generateSkillManifest';
import { styles } from './styles';
-import { getTenantIdFromCache, getTokenFromCache, isGetTokenFromUser, setTenantId } from '../../../utils/auth';
+import {
+ getTenantIdFromCache,
+ getTokenFromCache,
+ isGetTokenFromUser,
+ isShowAuthDialog,
+ setTenantId,
+} from '../../../utils/auth';
import { AuthClient } from '../../../utils/authClient';
import { createNotification } from '../../../recoilModel/dispatchers/notification';
import { getPendingNotificationCardProps, getPendingNotificationSkillCardProps } from '../../publish/Notifications';
@@ -48,9 +54,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const { updateSkillManifest } = useRecoilValue(dispatcherState);
const { publishToTarget, addNotification } = useRecoilValue(dispatcherState);
const [showAuthDialog, setShowAuthDialog] = useState(false);
-
- const pendingNotificationRef = useRef();
- const showNotificationsRef = useRef>({});
+ const [clickPublish, setclickPublish] = useState(false);
const [editingId, setEditingId] = useState();
const [currentStep, setCurrentStep] = useState(0);
@@ -67,8 +71,8 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const editorStep = order[currentStep];
const { buttons = [], content: Content, editJson, helpLink, subText, title, validate } = editorSteps[editorStep];
- const handleGenerateManifest = () => {
- const manifest = generateSkillManifest(
+ const handleGenerateManifest = async () => {
+ const manifest = await generateSkillManifest(
schema,
skillManifest,
dialogs,
@@ -76,7 +80,9 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
luFiles,
qnaFiles,
selectedTriggers,
- selectedDialogs
+ selectedDialogs,
+ currentTarget,
+ projectId
);
setSkillManifest(manifest);
};
@@ -91,7 +97,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const handleTriggerPublish = async () => {
// get token
-
+ setShowAuthDialog(true);
let token = '';
// TODO: this logic needs to be moved into the Azure publish extensions
if (isGetTokenFromUser()) {
@@ -105,9 +111,8 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
}
token = await AuthClient.getARMTokenForTenant(tenant);
}
- console.log(token);
- const notification = createNotification(getPendingNotificationSkillCardProps());
- addNotification(notification);
+ // const notification = createNotification(getPendingNotificationSkillCardProps());
+ // addNotification(notification);
await publishToTarget(projectId, currentTarget, {}, null, token);
};
@@ -196,7 +201,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
onDismiss: handleDismiss,
onNext: handleNext,
onSave: handleSave,
- // onPublish: handleTriggerPublish,
+ onPublish: handleTriggerPublish,
onSubmit,
})}
/>
@@ -206,9 +211,9 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
{editJson && }
- {showAuthDialog && (
+ {clickPublish && isShowAuthDialog(false) && (
{
// setDialogHidden(false);
}}
From b92eafa3afe73737823485f5352573b5006bf4c4 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Thu, 25 Mar 2021 16:46:03 +0800
Subject: [PATCH 06/55] add redirect to publishing page action
---
.../design/exportSkillModal/constants.tsx | 24 +++++++---
.../exportSkillModal/generateSkillManifest.ts | 16 ++-----
.../pages/design/exportSkillModal/index.tsx | 44 ++++++++++---------
3 files changed, 46 insertions(+), 38 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index c022cda263..627c195b73 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -215,10 +215,10 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
{
primary: true,
text: () => formatMessage('Generate and Publish'),
- onClick: ({ generateManifest, onNext }) => () => {
+ onClick: ({ generateManifest, onNext, onPublish }) => () => {
generateManifest();
onNext({ dismiss: true, save: true });
- // onPublish();
+ onPublish();
},
},
],
@@ -227,6 +227,20 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
subText: () =>
formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
title: () => formatMessage('Confirm skill endpoints'),
+ validate: ({ editingId, id, skillManifests }) => {
+ if (!id || !nameRegex.test(id)) {
+ return { id: formatMessage('Spaces and special characters are not allowed. Use letters, numbers, -, or _.') };
+ }
+
+ if (
+ (typeof editingId === 'undefined' || editingId !== id) &&
+ skillManifests.some(({ id: manifestId }) => manifestId === id)
+ ) {
+ return { id: formatMessage('{id} already exists. Please enter a unique file name.', { id }) };
+ }
+
+ return {};
+ },
},
[ManifestEditorSteps.MANIFEST_REVIEW]: {
buttons: [
@@ -263,9 +277,9 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
cancelButton,
{
primary: true,
- text: () => formatMessage('Generate'),
- onClick: ({ onNext }) => () => {
- // generateManifest();
+ text: () => formatMessage('Next'),
+ onClick: ({ onNext, generateManifest }) => () => {
+ generateManifest();
onNext();
},
},
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
index bfb531d682..1e42f5e8b8 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
@@ -21,7 +21,7 @@ const getActivityType = (kind: SDKKinds): ActivityTypes | undefined => activityH
export const isSupportedTrigger = ({ type }: ITrigger) => Object.keys(activityHandlerMap).includes(type as SDKKinds);
-export const generateSkillManifest = async (
+export const generateSkillManifest = (
schema: JSONSchema7,
skillManifest: Partial,
dialogs: DialogInfo[],
@@ -52,15 +52,7 @@ export const generateSkillManifest = async (
const triggers = selectedTriggers.map((tr) => get(content, tr.id) as ITrigger).filter(Boolean);
const activities = generateActivities(dialogSchemas, triggers, resolvedDialogs);
- const dispatchModels = await generateDispatchModels(
- schema,
- dialogs,
- triggers,
- luFiles,
- qnaFiles,
- currentTarget,
- projectId
- );
+ const dispatchModels = generateDispatchModels(schema, dialogs, triggers, luFiles, qnaFiles, currentTarget, projectId);
const definitions = getDefinitions(dialogSchemas, resolvedDialogs);
return {
@@ -119,7 +111,7 @@ export const generateOtherActivities = (kind: SDKKinds): Activities => {
return type ? { [type]: { type } } : {};
};
-export const generateDispatchModels = async (
+export const generateDispatchModels = (
schema: JSONSchema7,
dialogs: DialogInfo[],
selectedTriggers: any[],
@@ -150,7 +142,7 @@ export const generateDispatchModels = async (
for (const rootLuFile of rootLuFiles) {
const currentFileName = `skill-${rootLuFile.id}.lu`;
- await createManifestFile(projectId, currentFileName, rootLuFile.content);
+ createManifestFile(projectId, currentFileName, rootLuFile.content);
}
const luLanguages = intents.length
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index ccbe6054fd..734806bde9 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -36,6 +36,7 @@ import { AuthClient } from '../../../utils/authClient';
import { createNotification } from '../../../recoilModel/dispatchers/notification';
import { getPendingNotificationCardProps, getPendingNotificationSkillCardProps } from '../../publish/Notifications';
import { AuthDialog } from '../../../components/Auth/AuthDialog';
+import { navigate } from '@reach/router';
interface ExportSkillModalProps {
isOpen: boolean;
@@ -71,8 +72,8 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const editorStep = order[currentStep];
const { buttons = [], content: Content, editJson, helpLink, subText, title, validate } = editorSteps[editorStep];
- const handleGenerateManifest = async () => {
- const manifest = await generateSkillManifest(
+ const handleGenerateManifest = () => {
+ const manifest = generateSkillManifest(
schema,
skillManifest,
dialogs,
@@ -96,24 +97,25 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
};
const handleTriggerPublish = async () => {
+ navigate(`/bot/${projectId}/publish/all`);
// get token
- setShowAuthDialog(true);
- let token = '';
- // TODO: this logic needs to be moved into the Azure publish extensions
- if (isGetTokenFromUser()) {
- token = getTokenFromCache('accessToken');
- } else {
- let tenant = getTenantIdFromCache();
- if (!tenant) {
- const tenants = await AuthClient.getTenants();
- tenant = tenants?.[0]?.tenantId;
- setTenantId(tenant);
- }
- token = await AuthClient.getARMTokenForTenant(tenant);
- }
- // const notification = createNotification(getPendingNotificationSkillCardProps());
- // addNotification(notification);
- await publishToTarget(projectId, currentTarget, {}, null, token);
+ // setShowAuthDialog(true);
+ // let token = '';
+ // // TODO: this logic needs to be moved into the Azure publish extensions
+ // if (isGetTokenFromUser()) {
+ // token = getTokenFromCache('accessToken');
+ // } else {
+ // let tenant = getTenantIdFromCache();
+ // if (!tenant) {
+ // const tenants = await AuthClient.getTenants();
+ // tenant = tenants?.[0]?.tenantId;
+ // setTenantId(tenant);
+ // }
+ // token = await AuthClient.getARMTokenForTenant(tenant);
+ // }
+ // // const notification = createNotification(getPendingNotificationSkillCardProps());
+ // // addNotification(notification);
+ // await publishToTarget(projectId, currentTarget, {}, null, token);
};
const handleSave = () => {
@@ -211,7 +213,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
{editJson && }
- {clickPublish && isShowAuthDialog(false) && (
+ {/* {clickPublish && isShowAuthDialog(false) && (
{
@@ -221,7 +223,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
setShowAuthDialog(false);
}}
/>
- )}
+ )} */}
);
From 45be7cd2399bbc5c66ddb236fba4a5ce4d95f971 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Thu, 25 Mar 2021 16:47:22 +0800
Subject: [PATCH 07/55] change folder name
---
.../src/pages/design/exportSkillModal/generateSkillManifest.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
index 1e42f5e8b8..7d97fdb228 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
@@ -138,7 +138,7 @@ export const generateDispatchModels = (
}
const config = JSON.parse(target.configuration);
- const baseEndpointUrl = `https://${config.hostname}.azurewebsites.net/manifest`;
+ const baseEndpointUrl = `https://${config.hostname}.azurewebsites.net/manifests`;
for (const rootLuFile of rootLuFiles) {
const currentFileName = `skill-${rootLuFile.id}.lu`;
From 97584b1f20f3dc80e603ebff36832415305ef8ba Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Fri, 26 Mar 2021 12:38:29 +0800
Subject: [PATCH 08/55] add lu file parsing and intents filtering
---
.../design/exportSkillModal/constants.tsx | 26 ++++++++--------
.../content/SelectProfile.tsx | 30 +++++++++++--------
.../exportSkillModal/generateSkillManifest.ts | 10 ++++++-
.../pages/design/exportSkillModal/index.tsx | 22 +++++++++-----
4 files changed, 54 insertions(+), 34 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 627c195b73..57986d8164 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -227,20 +227,20 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
subText: () =>
formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
title: () => formatMessage('Confirm skill endpoints'),
- validate: ({ editingId, id, skillManifests }) => {
- if (!id || !nameRegex.test(id)) {
- return { id: formatMessage('Spaces and special characters are not allowed. Use letters, numbers, -, or _.') };
- }
+ // validate: ({ editingId, id, skillManifests }) => {
+ // if (!id || !nameRegex.test(id)) {
+ // return { id: formatMessage('Spaces and special characters are not allowed. Use letters, numbers, -, or _.') };
+ // }
- if (
- (typeof editingId === 'undefined' || editingId !== id) &&
- skillManifests.some(({ id: manifestId }) => manifestId === id)
- ) {
- return { id: formatMessage('{id} already exists. Please enter a unique file name.', { id }) };
- }
+ // if (
+ // (typeof editingId === 'undefined' || editingId !== id) &&
+ // skillManifests.some(({ id: manifestId }) => manifestId === id)
+ // ) {
+ // return { id: formatMessage('{id} already exists. Please enter a unique file name.', { id }) };
+ // }
- return {};
- },
+ // return {};
+ // },
},
[ManifestEditorSteps.MANIFEST_REVIEW]: {
buttons: [
@@ -279,7 +279,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
primary: true,
text: () => formatMessage('Next'),
onClick: ({ onNext, generateManifest }) => () => {
- generateManifest();
+ // generateManifest();
onNext();
},
},
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index 6d543b8934..6d98e76899 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -75,11 +75,11 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const { updateCurrentTarget } = useRecoilValue(dispatcherState);
const [endpointUrl, setEndpointUrl] = useState();
const [appId, setAppId] = useState();
- const { endpoints, ...rest } = value;
- const { id } = manifest;
+ const { id, content } = manifest;
const botName = useRecoilValue(botDisplayNameState(projectId));
const skillManifests = useRecoilValue(skillManifestsState(projectId));
+ const { ...rest } = content;
const updateCurrentProfile = useMemo(
() => (_e, option?: IDropdownOption) => {
const target = publishingTargets.find((t) => {
@@ -91,17 +91,21 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const config = JSON.parse(target.configuration);
setEndpointUrl(`https://${config.hostname}.azurewebsites.net`);
setAppId(config.settings.MicrosoftAppId);
- onChange({
- ...rest,
- endpoints: [
- {
- protocol: 'BotFrameworkV3',
- name: option?.key,
- endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
- description: '',
- msAppId: config.settings.MicrosoftAppId,
- },
- ],
+
+ setSkillManifest({
+ content: {
+ ...rest,
+ endpoints: [
+ {
+ protocol: 'BotFrameworkV3',
+ name: option?.key,
+ endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
+ description: '',
+ msAppId: config.settings.MicrosoftAppId,
+ },
+ ],
+ },
+ id: id,
});
}
},
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
index 7d97fdb228..6393bb15a4 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
@@ -16,6 +16,7 @@ import { JSONSchema7 } from '@bfc/extension-client';
import { Activities, Activity, activityHandlerMap, ActivityTypes, DispatchModels } from './constants';
import { createManifestFile } from '../../../utils/manifestFileUtil';
+import { luIndexer } from '@bfc/indexers';
const getActivityType = (kind: SDKKinds): ActivityTypes | undefined => activityHandlerMap[kind];
@@ -142,7 +143,14 @@ export const generateDispatchModels = (
for (const rootLuFile of rootLuFiles) {
const currentFileName = `skill-${rootLuFile.id}.lu`;
- createManifestFile(projectId, currentFileName, rootLuFile.content);
+ const parsedLuFile = luIndexer.parse(rootLuFile.content, rootLuFile.id, {});
+ const contents = parsedLuFile.intents.map((x) => {
+ if (intents.find((intent) => intent == x.Name) != -1) {
+ return x.Body;
+ }
+ });
+ const mergedContents = contents.join('\n');
+ createManifestFile(projectId, currentFileName, mergedContents);
}
const luLanguages = intents.length
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 734806bde9..102d43d118 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -3,7 +3,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
-import React, { useRef, useState } from 'react';
+import React, { useEffect, useMemo, useRef, useState } from 'react';
import formatMessage from 'format-message';
import { Dialog, DialogFooter, DialogType } from 'office-ui-fabric-react/lib/Dialog';
import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react/lib/Button';
@@ -53,9 +53,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const currentTarget = useRecoilValue(currentTargetState(projectId));
const skillManifests = useRecoilValue(skillManifestsState(projectId));
const { updateSkillManifest } = useRecoilValue(dispatcherState);
- const { publishToTarget, addNotification } = useRecoilValue(dispatcherState);
- const [showAuthDialog, setShowAuthDialog] = useState(false);
- const [clickPublish, setclickPublish] = useState(false);
const [editingId, setEditingId] = useState();
const [currentStep, setCurrentStep] = useState(0);
@@ -63,7 +60,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const [schema, setSchema] = useState({});
const [skillManifest, setSkillManifest] = useState>({});
-
const { content = {}, id } = skillManifest;
const [selectedDialogs, setSelectedDialogs] = useState([]);
@@ -119,8 +115,20 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
};
const handleSave = () => {
- if (skillManifest.content && skillManifest.id) {
- updateSkillManifest(skillManifest as SkillManifestFile, projectId);
+ const manifest = generateSkillManifest(
+ schema,
+ skillManifest,
+ dialogs,
+ dialogSchemas,
+ luFiles,
+ qnaFiles,
+ selectedTriggers,
+ selectedDialogs,
+ currentTarget,
+ projectId
+ );
+ if (manifest.content && manifest.id) {
+ updateSkillManifest(manifest as SkillManifestFile, projectId);
}
};
From 73a802a7844463429f7aa4e71e04f88dbfd9bc5d Mon Sep 17 00:00:00 2001
From: Lu Han <32191031+luhan2017@users.noreply.github.com>
Date: Tue, 23 Mar 2021 11:59:31 +0800
Subject: [PATCH 09/55] Support .lu and .qna for static files
---
runtime/dotnet/azurewebapp/Startup.cs | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/runtime/dotnet/azurewebapp/Startup.cs b/runtime/dotnet/azurewebapp/Startup.cs
index 177bc35b9b..a7b18b6ec0 100644
--- a/runtime/dotnet/azurewebapp/Startup.cs
+++ b/runtime/dotnet/azurewebapp/Startup.cs
@@ -4,6 +4,8 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.AI.Luis;
using Microsoft.Bot.Builder.AI.QnA;
@@ -28,6 +30,7 @@
using Microsoft.BotFramework.Composer.WebAppTemplates.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.FileProviders;
namespace Microsoft.BotFramework.Composer.WebAppTemplates
{
@@ -223,7 +226,21 @@ public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDefaultFiles();
- app.UseStaticFiles();
+
+ // Set up custom content types - associating file extension to MIME type.
+ var provider = new FileExtensionContentTypeProvider();
+ provider.Mappings[".lu"] = "application/lu";
+ provider.Mappings[".qna"] = "application/qna";
+
+ // Expose static files in manifests folder for skill scenarios.
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ FileProvider = new PhysicalFileProvider(
+ Path.Combine(env.WebRootPath, "manifests")),
+ RequestPath = "/manifests",
+ ContentTypeProvider = provider
+ });
+
app.UseNamedPipes(System.Environment.GetEnvironmentVariable("APPSETTING_WEBSITE_SITE_NAME") + ".directline");
app.UseWebSockets();
app.UseRouting()
From b4da411977ba0059bd7ece01635305e652296391 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Tue, 30 Mar 2021 20:33:12 +0800
Subject: [PATCH 10/55] 'notification'
---
.../pages/design/exportSkillModal/index.tsx | 5 +-
.../src/pages/publish/BotStatusList.tsx | 1 +
.../src/pages/publish/Notifications.tsx | 46 +++++++++++++++-
.../client/src/pages/publish/Publish.tsx | 43 +++++++++++++--
.../packages/server/src/locales/en-US.json | 55 +++++++++++++++----
5 files changed, 130 insertions(+), 20 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 49eb6c9292..f6a3d53dbf 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -93,7 +93,10 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
};
const handleTriggerPublish = async () => {
- navigate(`/bot/${projectId}/publish/all`);
+ const filePath = `https://${JSON.parse(currentTarget.configuration).hostname}.azurewebsites.net/manifests/${
+ skillManifest.id
+ }.json`;
+ navigate(`/bot/${projectId}/publish/all?publishTargetName=${currentTarget.name}&url=${filePath}`);
// get token
// setShowAuthDialog(true);
// let token = '';
diff --git a/Composer/packages/client/src/pages/publish/BotStatusList.tsx b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
index 48823b1ac8..7092436f69 100644
--- a/Composer/packages/client/src/pages/publish/BotStatusList.tsx
+++ b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
@@ -142,6 +142,7 @@ export const BotStatusList: React.FC = ({
return (
),
};
};
-export const getPendingNotificationCardProps = (items: BotStatus[]): CardProps => {
+
+export const getSkillPublishedNotificationCardProps = (
+ item: BotStatus,
+ endpoint?: string,
+ manifestName?: string
+): CardProps => {
+ const statusIconStyle = css({
+ margin: '12px 0 0 -1px',
+ width: '12px',
+ height: '12px',
+ fontSize: '12px',
+ color: item.status === 200 ? '#27AE60' : 'rgb(161, 159, 157)',
+ transform: item.status !== 200 ? 'rotate(45deg)' : '',
+ });
+ return {
+ title: '',
+ description:
+ item.status === 200
+ ? formatMessage(`You have successfully published {name} to {publishTarget}`, {
+ name: item.name,
+ publishTarget: item.publishTarget,
+ })
+ : formatMessage(`Publishing {name} to {publishTarget} failed.`, {
+ name: item.name,
+ publishTarget: item.publishTarget,
+ }),
+ type: 'pending',
+ onRenderCardContent: (props) => (
+
+ ),
+ };
+};
+
+export const getPendingNotificationCardProps = (items: BotStatus[], isSkill = false): CardProps => {
+ const description = isSkill
+ ? 'Publishing your skill...'
+ : formatMessage(`Publishing {count} bots`, { count: items.length });
return {
title: '',
- description: formatMessage(`Publishing {count} bots`, { count: items.length }),
+ description,
type: 'pending',
onRenderCardContent: (props) => (
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index 5a0d84bfa6..0ab8b7a3fe 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -8,6 +8,7 @@ import { RouteComponentProps } from '@reach/router';
import formatMessage from 'format-message';
import { useRecoilValue } from 'recoil';
import { PublishResult, PublishTarget } from '@bfc/shared';
+import querystring from 'query-string';
import { dispatcherState, localBotPublishHistorySelector, localBotsDataSelector } from '../../recoilModel';
import { AuthDialog } from '../../components/Auth/AuthDialog';
@@ -32,8 +33,8 @@ import { ContentHeaderStyle, HeaderText, ContentStyle, contentEditor } from './s
import { BotStatusList } from './BotStatusList';
import {
getPendingNotificationCardProps,
- getPendingNotificationSkillCardProps,
getPublishedNotificationCardProps,
+ getSkillPublishedNotificationCardProps,
} from './Notifications';
import { PullDialog } from './pullDialog';
import { PublishToolbar } from './PublishToolbar';
@@ -44,7 +45,15 @@ import {
generateBotStatusList,
deleteNotificationInterval,
} from './publishPageUtils';
-
+import { manifestUrl } from '../design/styles';
+
+const SKILL_PUBLISH_STATUS = {
+ INITIAL: 'inital',
+ WAITING: 'wait for publish',
+ PUBLISHING: 'publishing',
+ PUBLISHED: 'published',
+ CANCEL: 'cancel',
+};
const Publish: React.FC
> = (props) => {
const { projectId = '' } = props;
@@ -124,6 +133,20 @@ const Publish: React.FC {
+ if (publishTargetName && botStatusList.length > 0 && skillPublishStatus === SKILL_PUBLISH_STATUS.INITIAL) {
+ setSkillPublishStatus(SKILL_PUBLISH_STATUS.WAITING);
+ const currentBotStatus = botStatusList.find((bot) => bot.id === projectId);
+ changePublishTarget(publishTargetName, currentBotStatus);
+ setCheckedSkillIds([projectId]);
+ setPublishDialogVisiblity(true);
+ }
+ }, [publishTargetName, botStatusList]);
+
useEffect(() => {
if (currentBotList.length < botList.length) {
// init bot status list for the botProjectData is empty array when first mounted
@@ -198,9 +221,11 @@ const Publish: React.FC {
deleteNotification(resultNotification.id);
@@ -302,10 +327,16 @@ const Publish: React.FC{ botName }"
},
@@ -3362,6 +3389,9 @@
"this_page_contains_detailed_information_about_your_b2b3413b": {
"message": "This Page contains detailed information about your bot. For security reasons, they are hidden by default. To test your bot or publish to Azure, you may need to provide these settings"
},
+ "this_publishing_profile_profilename_is_no_longer_s_eee0f447": {
+ "message": "This publishing profile ({ profileName }) is no longer supported. You are a member of multiple Azure tenants and the profile needs to have a tenant id associated with it. You can either edit the profile by adding the `tenantId` property to it''s configuration or create a new one."
+ },
"this_trigger_type_is_not_supported_by_the_regex_re_dc3eefa2": {
"message": "This trigger type is not supported by the RegEx recognizer. To ensure this trigger is fired, change the recognizer type."
},
@@ -3518,6 +3548,9 @@
"unread_notifications_indicator_e2ca00d5": {
"message": "Unread notifications Indicator"
},
+ "unsupported_publishing_profile_ad088e54": {
+ "message": "Unsupported publishing profile"
+ },
"unused_8d193e3": {
"message": "Unused"
},
From 9c56475bb7983e61601b6423945277d3ee41cf7f Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Wed, 31 Mar 2021 11:11:35 +0800
Subject: [PATCH 11/55] manifest file name
---
Composer/packages/server/src/models/bot/botProject.ts | 3 +--
Composer/packages/server/src/models/bot/botStructure.ts | 5 ++---
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/Composer/packages/server/src/models/bot/botProject.ts b/Composer/packages/server/src/models/bot/botProject.ts
index c877e3f008..14bfdd1ece 100644
--- a/Composer/packages/server/src/models/bot/botProject.ts
+++ b/Composer/packages/server/src/models/bot/botProject.ts
@@ -469,8 +469,7 @@ export class BotProject implements IBotProject {
this.validateFileName(filename);
this._validateFileContent(name, content);
const botName = this.name;
- const defaultLocale = this.settings?.defaultLanguage || defaultLanguage;
- const relativePath = defaultManifestFilePath(botName, filename, defaultLocale);
+ const relativePath = defaultManifestFilePath(botName, filename);
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 227f2326b1..608dcf516f 100644
--- a/Composer/packages/server/src/models/bot/botStructure.ts
+++ b/Composer/packages/server/src/models/bot/botStructure.ts
@@ -10,7 +10,7 @@ const BotStructureTemplate = {
entry: '${BOTNAME}.dialog',
lg: 'language-generation/${LOCALE}/${BOTNAME}.${LOCALE}.lg',
lu: 'language-understanding/${LOCALE}/${BOTNAME}.${LOCALE}.lu',
- manifestLu: 'manifests/${FILENAME}.${LOCALE}.lu',
+ manifestLu: 'manifests/${FILENAME}.lu',
qna: 'knowledge-base/en-us/${BOTNAME}.en-us.qna',
sourceQnA: 'knowledge-base/source/${FILENAME}.source.qna',
dialogSchema: '${BOTNAME}.dialog.schema',
@@ -106,11 +106,10 @@ 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 defaultManifestFilePath = (botName: string, fileName: string, locale: string): string => {
+export const defaultManifestFilePath = (botName: string, fileName: string): string => {
return templateInterpolate(BotStructureTemplate.manifestLu, {
BOTNAME: botName,
FILENAME: fileName,
- LOCALE: locale,
});
};
From 6739924b09d61c68e1851f11ab2b2b5df91fc92c Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Wed, 31 Mar 2021 11:58:05 +0800
Subject: [PATCH 12/55] add skill add callers logic
---
.../design/exportSkillModal/constants.tsx | 51 ++++++-----
.../exportSkillModal/content/AddCallers.tsx | 89 +++++++++++++++++++
.../content/SelectProfile.tsx | 37 +++-----
.../exportSkillModal/generateSkillManifest.ts | 9 +-
.../pages/design/exportSkillModal/index.tsx | 75 +++++++---------
5 files changed, 168 insertions(+), 93 deletions(-)
create mode 100644 Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 57986d8164..a3beae3148 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -21,6 +21,7 @@ import {
SelectTriggers,
} from './content';
import { SelectProfile } from './content/SelectProfile';
+import { AddCallers } from './content/AddCallers';
export const VERSION_REGEX = /\d\.\d+\.(\d+|preview-\d+)|\d\.\d+/i;
@@ -100,6 +101,8 @@ export interface ContentProps {
value: { [key: string]: any };
onChange: (_: any) => void;
projectId: string;
+ callers: string[];
+ setCallers: (callers: string[]) => void;
}
interface Button {
@@ -137,6 +140,7 @@ export enum ManifestEditorSteps {
SELECT_DIALOGS = 'SELECT_DIALOGS',
SELECT_TRIGGERS = 'SELECT_TRIGGERS',
SELECT_PROFILE = 'SELECT_PROFILE',
+ ADD_CALLERS = 'ADD_CALLERS',
}
export const order: ManifestEditorSteps[] = [
@@ -145,6 +149,7 @@ export const order: ManifestEditorSteps[] = [
ManifestEditorSteps.MANIFEST_DESCRIPTION,
ManifestEditorSteps.SELECT_DIALOGS,
ManifestEditorSteps.SELECT_TRIGGERS,
+ ManifestEditorSteps.ADD_CALLERS,
ManifestEditorSteps.SELECT_PROFILE,
// ManifestEditorSteps.MANIFEST_REVIEW,
// ManifestEditorSteps.SAVE_MANIFEST,
@@ -204,7 +209,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.MANIFEST_DESCRIPTION]: {
buttons: [cancelButton, nextButton],
content: Description,
- editJson: true,
+ editJson: false,
title: () => formatMessage('Describe your skill'),
subText: () => formatMessage('To make your bot available for others as a skill, we need to generate a manifest.'),
validate,
@@ -217,30 +222,36 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
text: () => formatMessage('Generate and Publish'),
onClick: ({ generateManifest, onNext, onPublish }) => () => {
generateManifest();
- onNext({ dismiss: true, save: true });
+ onNext();
onPublish();
},
},
],
- editJson: true,
+ editJson: false,
content: SelectProfile,
subText: () =>
formatMessage('We need to define the endpoints for the skill to allow other bots to interact with it.'),
title: () => formatMessage('Confirm skill endpoints'),
- // validate: ({ editingId, id, skillManifests }) => {
- // if (!id || !nameRegex.test(id)) {
- // return { id: formatMessage('Spaces and special characters are not allowed. Use letters, numbers, -, or _.') };
- // }
-
- // if (
- // (typeof editingId === 'undefined' || editingId !== id) &&
- // skillManifests.some(({ id: manifestId }) => manifestId === id)
- // ) {
- // return { id: formatMessage('{id} already exists. Please enter a unique file name.', { id }) };
- // }
-
- // return {};
- // },
+ },
+ [ManifestEditorSteps.ADD_CALLERS]: {
+ buttons: [
+ cancelButton,
+ {
+ primary: true,
+ text: () => formatMessage('Next'),
+ onClick: ({ onNext, onSaveSkill }) => () => {
+ onSaveSkill();
+ onNext();
+ },
+ },
+ ],
+ editJson: false,
+ content: AddCallers,
+ subText: () =>
+ formatMessage(
+ 'Add Microsoft App Ids of bots that can access this skill. You can skip this step and add this information later from the project settings tab.'
+ ),
+ title: () => formatMessage('Which bots are allowed to use this skill?'),
},
[ManifestEditorSteps.MANIFEST_REVIEW]: {
buttons: [
@@ -265,7 +276,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
},
],
content: SelectDialogs,
- editJson: true,
+ editJson: false,
subText: () =>
formatMessage(
'These tasks will be used to generate the manifest and describe the capabilities of this skill to those who may want to use it.'
@@ -285,7 +296,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
},
],
content: SelectTriggers,
- editJson: true,
+ editJson: false,
subText: () =>
formatMessage(
'These tasks will be used to generate the manifest and describe the capabilities of this skill to those who may want to use it.'
@@ -304,7 +315,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
},
],
content: SaveManifest,
- editJson: true,
+ editJson: false,
subText: () => formatMessage('Name and save your skill manifest.'),
title: () => formatMessage('Save your skill manifest'),
validate: ({ editingId, id, skillManifests }) => {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
new file mode 100644
index 0000000000..d02831cc9e
--- /dev/null
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -0,0 +1,89 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+/** @jsx jsx */
+import { jsx } from '@emotion/core';
+import { SharedColors } from '@uifabric/fluent-theme';
+import formatMessage from 'format-message';
+import { ActionButton, css, FontWeights, TextField } from 'office-ui-fabric-react';
+import React from 'react';
+import { tableColumnHeader, tableRow, tableRowItem } from '../../../botProject/styles';
+import { ContentProps } from '../constants';
+
+const header = css`
+ display: flex;
+ flex-direction: row;
+ height: 42px;
+`;
+
+const addNewAllowCallers = {
+ root: {
+ fontSize: 12,
+ fontWeight: FontWeights.regular,
+ color: SharedColors.cyanBlue10,
+ paddingLeft: 0,
+ marginLeft: 5,
+ },
+};
+
+const removeCaller = {
+ root: {
+ fontSize: 12,
+ fontWeight: FontWeights.regular,
+ color: SharedColors.cyanBlue10,
+ paddingLeft: 0,
+ paddingBottom: 5,
+ },
+};
+
+export const AddCallers: React.FC = ({ projectId, callers, setCallers }) => {
+ const handleRemove = (index) => {
+ var currentCallers = callers.slice();
+ currentCallers?.splice(index, 1);
+ setCallers(currentCallers);
+ };
+ const handleAdd = () => {
+ var currentCallers = callers.slice();
+ currentCallers?.push('0000-11111-00000-11111');
+ setCallers(currentCallers);
+ };
+
+ return (
+
+
+
{formatMessage('Allowed Callers')}
+
+ {callers?.map((caller, index) => {
+ return (
+
+
+ {
+ var currentCallers = callers.slice();
+ currentCallers[index] = newValue ?? '';
+ setCallers(currentCallers);
+ }}
+ borderless
+ >
+
+
+
handleRemove(index)}>
+ {formatMessage('Remove')}
+
+
+
+ );
+ })}
+
{
+ handleAdd();
+ }}
+ >
+ {formatMessage('Add allowd callers')}
+
+
+ );
+};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index 6d98e76899..0f47a079b7 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -1,18 +1,17 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+/** @jsx jsx */
+import { jsx } from '@emotion/core';
import { PublishTarget, SkillManifestFile } from '@bfc/shared';
import formatMessage from 'format-message';
-import { css, Dropdown, Icon, IDropdownOption, PrimaryButton, TextField, TooltipHost } from 'office-ui-fabric-react';
+import { css, Dropdown, Icon, IDropdownOption, TextField, TooltipHost } from 'office-ui-fabric-react';
import React, { useEffect, useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
-import {
- botDisplayNameState,
- currentTargetState,
- dispatcherState,
- settingsState,
- skillManifestsState,
-} from '../../../../recoilModel';
+
+import { botDisplayNameState, dispatcherState, settingsState, skillManifestsState } from '../../../../recoilModel';
import { PublishTargets } from '../../../botProject/PublishTargets';
import { iconStyle } from '../../../botProject/runtime-settings/style';
-import Publish from '../../../publish/Publish';
import { ContentProps, VERSION_REGEX } from '../constants';
const styles = {
@@ -89,7 +88,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
setCurrentTarget(target);
updateCurrentTarget(projectId, target);
const config = JSON.parse(target.configuration);
- setEndpointUrl(`https://${config.hostname}.azurewebsites.net`);
+ setEndpointUrl(`https://${config.hostname}.azurewebsites.net/api/messages`);
setAppId(config.settings.MicrosoftAppId);
setSkillManifest({
@@ -140,20 +139,6 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const settings = useRecoilValue(settingsState(projectId));
- const OnEndpointChange = useMemo(
- () => (e, newValue) => {
- setEndpointUrl(newValue);
- },
- [setEndpointUrl]
- );
-
- const OnAppIdChange = useMemo(
- () => (e, newValue) => {
- setAppId(newValue);
- },
- [setAppId]
- );
-
useEffect(() => {
setPublishingTargets(settings.publishTargets || []);
}, [settings]);
@@ -177,22 +162,22 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
onChange={updateCurrentProfile}
/>
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
index 6393bb15a4..406a08129d 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
@@ -13,10 +13,11 @@ import {
PublishTarget,
} from '@bfc/shared';
import { JSONSchema7 } from '@bfc/extension-client';
+import { luIndexer } from '@bfc/indexers';
-import { Activities, Activity, activityHandlerMap, ActivityTypes, DispatchModels } from './constants';
import { createManifestFile } from '../../../utils/manifestFileUtil';
-import { luIndexer } from '@bfc/indexers';
+
+import { Activities, Activity, activityHandlerMap, ActivityTypes, DispatchModels } from './constants';
const getActivityType = (kind: SDKKinds): ActivityTypes | undefined => activityHandlerMap[kind];
@@ -142,11 +143,11 @@ export const generateDispatchModels = (
const baseEndpointUrl = `https://${config.hostname}.azurewebsites.net/manifests`;
for (const rootLuFile of rootLuFiles) {
- const currentFileName = `skill-${rootLuFile.id}.lu`;
+ const currentFileName = `skill-${rootLuFile.id}`;
const parsedLuFile = luIndexer.parse(rootLuFile.content, rootLuFile.id, {});
const contents = parsedLuFile.intents.map((x) => {
if (intents.find((intent) => intent == x.Name) != -1) {
- return x.Body;
+ return [`# ${x.Name}`, x.Body].join('\n');
}
});
const mergedContents = contents.join('\n');
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 49eb6c9292..5909b3328d 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -11,6 +11,7 @@ import { JSONSchema7 } from '@bfc/extension-client';
import { Link } from 'office-ui-fabric-react/lib/components/Link';
import { useRecoilValue } from 'recoil';
import { SkillManifestFile } from '@bfc/shared';
+import { navigate } from '@reach/router';
import {
dispatcherState,
@@ -20,23 +21,15 @@ import {
dialogSchemasState,
currentTargetState,
luFilesSelectorFamily,
+ settingsState,
+ rootBotProjectIdSelector,
} from '../../../recoilModel';
-import { editorSteps, ManifestEditorSteps, order } from './constants';
-import { generateSkillManifest } from './generateSkillManifest';
import { styles } from './styles';
-import {
- getTenantIdFromCache,
- getTokenFromCache,
- isGetTokenFromUser,
- isShowAuthDialog,
- setTenantId,
-} from '../../../utils/auth';
-import { AuthClient } from '../../../utils/authClient';
-import { createNotification } from '../../../recoilModel/dispatchers/notification';
-import { getPendingNotificationCardProps, getPendingNotificationSkillCardProps } from '../../publish/Notifications';
-import { AuthDialog } from '../../../components/Auth/AuthDialog';
-import { navigate } from '@reach/router';
+import { generateSkillManifest } from './generateSkillManifest';
+import { editorSteps, ManifestEditorSteps, order } from './constants';
+import { mergePropertiesManagedByRootBot } from '../../../recoilModel/dispatchers/utils/project';
+import { cloneDeep } from 'lodash';
interface ExportSkillModalProps {
isOpen: boolean;
@@ -68,6 +61,24 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const editorStep = order[currentStep];
const { buttons = [], content: Content, editJson, helpLink, subText, title, validate } = editorSteps[editorStep];
+ const settings = useRecoilValue(settingsState(projectId));
+ const rootBotProjectId = useRecoilValue(rootBotProjectIdSelector) || '';
+ const mergedSettings = mergePropertiesManagedByRootBot(projectId, rootBotProjectId, settings);
+ const { skillConfiguration } = mergedSettings;
+ const { setSettings } = useRecoilValue(dispatcherState);
+ const [callers, setCallers] = useState(skillConfiguration?.allowedCallers ?? []);
+
+ const updateAllowedCallers = React.useCallback(
+ (allowedCallers: string[] = []) => {
+ const updatedSetting = {
+ ...cloneDeep(mergedSettings),
+ skillConfiguration: { ...skillConfiguration, allowedCallers },
+ };
+ setSettings(projectId, updatedSetting);
+ },
+ [mergedSettings, projectId, skillConfiguration]
+ );
+
const handleGenerateManifest = () => {
const manifest = generateSkillManifest(
schema,
@@ -94,24 +105,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const handleTriggerPublish = async () => {
navigate(`/bot/${projectId}/publish/all`);
- // get token
- // setShowAuthDialog(true);
- // let token = '';
- // // TODO: this logic needs to be moved into the Azure publish extensions
- // if (isGetTokenFromUser()) {
- // token = getTokenFromCache('accessToken');
- // } else {
- // let tenant = getTenantIdFromCache();
- // if (!tenant) {
- // const tenants = await AuthClient.getTenants();
- // tenant = tenants?.[0]?.tenantId;
- // setTenantId(tenant);
- // }
- // token = await AuthClient.getARMTokenForTenant(tenant);
- // }
- // // const notification = createNotification(getPendingNotificationSkillCardProps());
- // // addNotification(notification);
- // await publishToTarget(projectId, currentTarget, {}, null, token);
};
const handleSave = () => {
@@ -132,6 +125,10 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
}
};
+ const onSaveSkill = () => {
+ updateAllowedCallers(callers);
+ };
+
const handleNext = (options?: { dismiss?: boolean; id?: string; save?: boolean }) => {
const validated =
typeof validate === 'function' ? validate({ content, editingId, id, schema, skillManifests }) : errors;
@@ -188,6 +185,8 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
setSkillManifest={setSkillManifest}
skillManifests={skillManifests}
value={content}
+ callers={callers}
+ setCallers={setCallers}
onChange={(manifestContent) => setSkillManifest({ ...skillManifest, content: manifestContent })}
/>
@@ -213,6 +212,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
onSave: handleSave,
onPublish: handleTriggerPublish,
onSubmit,
+ onSaveSkill,
})}
/>
);
@@ -221,17 +221,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
{editJson && }
- {/* {clickPublish && isShowAuthDialog(false) && (
- {
- // setDialogHidden(false);
- }}
- onDismiss={() => {
- setShowAuthDialog(false);
- }}
- />
- )} */}
);
From 5426207fefdacbdde39e2d7b680fe13f2e18ee6e Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 31 Mar 2021 17:42:10 +0800
Subject: [PATCH 13/55] add manifest path to BotStructureFilesPatterns
---
Composer/packages/server/src/models/bot/botStructure.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/Composer/packages/server/src/models/bot/botStructure.ts b/Composer/packages/server/src/models/bot/botStructure.ts
index 608dcf516f..521b77bbdd 100644
--- a/Composer/packages/server/src/models/bot/botStructure.ts
+++ b/Composer/packages/server/src/models/bot/botStructure.ts
@@ -62,6 +62,7 @@ export const BotStructureFilesPatterns = [
templateInterpolate(BotStructureTemplate.dialogs.entry, { DIALOGNAME: '*' }),
templateInterpolate(BotStructureTemplate.dialogs.dialogSchema, { DIALOGNAME: '*' }),
templateInterpolate(BotStructureTemplate.dialogs.recognizer, { DIALOGNAME: '*', RECOGNIZERNAME: '*.dialog' }),
+ templateInterpolate(BotStructureTemplate.manifestLu, { FILENAME: '*' }),
templateInterpolate(BotStructureTemplate.formDialogs, { FORMDIALOGNAME: '*.form' }),
templateInterpolate(BotStructureTemplate.skillManifests, { MANIFESTFILENAME: '*.json' }),
From 63a04c67f9e92fd34266f0883373a5fd055a8d66 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Wed, 31 Mar 2021 17:43:38 +0800
Subject: [PATCH 14/55] fix e2e
---
.../client/src/pages/design/exportSkillModal/constants.tsx | 2 +-
.../client/src/pages/design/exportSkillModal/index.tsx | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index a3beae3148..cf6d056b98 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -222,7 +222,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
text: () => formatMessage('Generate and Publish'),
onClick: ({ generateManifest, onNext, onPublish }) => () => {
generateManifest();
- onNext();
+ onNext({ dismiss: true, save: true });
onPublish();
},
},
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 5909b3328d..0da903f76a 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -93,6 +93,9 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
projectId
);
setSkillManifest(manifest);
+ if (manifest.content && manifest.id) {
+ updateSkillManifest(manifest as SkillManifestFile, projectId);
+ }
};
const handleEditJson = () => {
From 11be116e138eca4bd79e84b37e589eac1249b29e Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 31 Mar 2021 18:36:33 +0800
Subject: [PATCH 15/55] notification
---
.../src/pages/publish/Notifications.tsx | 108 +++++++++++++-----
.../client/src/pages/publish/Publish.tsx | 6 +-
2 files changed, 83 insertions(+), 31 deletions(-)
diff --git a/Composer/packages/client/src/pages/publish/Notifications.tsx b/Composer/packages/client/src/pages/publish/Notifications.tsx
index 1e9500c7a5..c3dcbc8202 100644
--- a/Composer/packages/client/src/pages/publish/Notifications.tsx
+++ b/Composer/packages/client/src/pages/publish/Notifications.tsx
@@ -9,6 +9,8 @@ import { Icon } from 'office-ui-fabric-react/lib/Icon';
import { CardProps } from '../../components/Notifications/NotificationCard';
import { BotStatus } from './type';
+import { IconButton } from 'office-ui-fabric-react/lib/Button';
+import { FontSizes } from '@uifabric/fluent-theme';
const cardContent = css`
display: flex;
@@ -56,11 +58,11 @@ export const getPublishedNotificationCardProps = (item: BotStatus): CardProps =>
name: item.name,
publishTarget: item.publishTarget,
}),
- type: 'pending',
+ type: item.status === 200 ? 'success' : 'error',
onRenderCardContent: (props) => (
-
+
@@ -69,41 +71,91 @@ export const getPublishedNotificationCardProps = (item: BotStatus): CardProps =>
};
};
-export const getSkillPublishedNotificationCardProps = (
- item: BotStatus,
- endpoint?: string,
- manifestName?: string
-): CardProps => {
+export const getSkillPublishedNotificationCardProps = (item: BotStatus, url?: string): CardProps => {
+ const skillCardContent = css`
+ display: flex;
+ padding: 0 16px 16px 12px;
+ min-height: 64px;
+ `;
const statusIconStyle = css({
margin: '12px 0 0 -1px',
width: '12px',
height: '12px',
fontSize: '12px',
- color: item.status === 200 ? '#27AE60' : 'rgb(161, 159, 157)',
- transform: item.status !== 200 ? 'rotate(45deg)' : '',
+ color: '#D92525',
});
+ const errorType = css`
+ margin-top: 4px;
+ color: #d92525;
+ `;
+ const successType = css`
+ margin-top: 4px;
+ color: #27ae60;
+ `;
+ const cardTitle = css`
+ font-size: ${FontSizes.size16};
+ lint-height: 22px;
+ margin-right: 16px;
+ `;
+
+ const cardDescription = css`
+ text-size-adjust: none;
+ font-size: ${FontSizes.size10};
+ margin-top: 8px;
+ margin-right: 16px;
+ word-break: break-word;
+ `;
+
+ const linkButton = css`
+ color: #0078d4;
+ float: right;
+ font-size: 12px;
+ height: auto;
+ margin: 10px 8px 0 0;
+ `;
return {
- title: '',
+ title: item.status === 200 ? formatMessage('Your skill is ready to be shared!') : '',
description:
item.status === 200
- ? formatMessage(`You have successfully published {name} to {publishTarget}`, {
- name: item.name,
- publishTarget: item.publishTarget,
- })
- : formatMessage(`Publishing {name} to {publishTarget} failed.`, {
- name: item.name,
- publishTarget: item.publishTarget,
- }),
- type: 'pending',
- onRenderCardContent: (props) => (
-
- ),
+ ? formatMessage(
+ 'Keep this URL handy to share it with other developers to use in their bot projects. You can find this URL in the project settings tab.'
+ )
+ : formatMessage(`Your skill could not be published.`),
+ type: item.status === 200 ? 'success' : 'error',
+ onRenderCardContent: (props) => {
+ const { title, description } = props;
+ if (item.status === 200) {
+ return (
+
+
+
+
{title}
+ {description &&
{description}
}
+ {url && (
+
+ {url}
+ navigator.clipboard.writeText(url)}
+ />
+
+ )}
+
+
+ );
+ } else {
+ return (
+
+ );
+ }
+ },
};
};
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index 0ab8b7a3fe..4eef49cab0 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -45,7 +45,6 @@ import {
generateBotStatusList,
deleteNotificationInterval,
} from './publishPageUtils';
-import { manifestUrl } from '../design/styles';
const SKILL_PUBLISH_STATUS = {
INITIAL: 'inital',
@@ -222,11 +221,12 @@ const Publish: React.FC
{
deleteNotification(resultNotification.id);
showNotificationsRef.current = { ...displayedNotifications, [botProjectId]: false };
From 9a4ed9985b4dcf2b17e1764bfb5c2fefae2893b2 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Thu, 1 Apr 2021 10:00:07 +0800
Subject: [PATCH 16/55] add publish skill settings update
---
extensions/azurePublish/src/node/deploy.ts | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index bc57c5906f..eca8141c80 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -60,6 +60,9 @@ export class BotProjectDeploy {
await this.BindKeyVault(absSettings, hostname);
}
+ const skillManifestPath = path.join(this.projPath, 'ComposerDialogs', 'manifests');
+ const msAppId = settings.MicrosoftAppId;
+ await this.updateSkillSettings(profileName, hostname, msAppId, skillManifestPath);
// STEP 1: CLEAN UP PREVIOUS BUILDS
// cleanup any previous build
if (await fs.pathExists(this.zipPath)) {
@@ -146,6 +149,44 @@ export class BotProjectDeploy {
}
}
+ /**
+ * update the skill related settings to skills' manifest
+ * @param hostname hostname of web app
+ * @param msAppId microsoft app id
+ * @param skillSettingsPath the path of skills manifest settings
+ */
+ private async updateSkillSettings(profileName: string, hostname: string, msAppId: string, skillSettingsPath: string) {
+ const manifestFiles = (await fs.readdir(skillSettingsPath)).filter((x) => x.endsWith('.json'));
+ if (manifestFiles.length === 0) {
+ this.logger({
+ status: BotProjectDeployLoggerType.DEPLOY_INFO,
+ message: `The manifest does not exsit on path: ${skillSettingsPath}`,
+ });
+ return;
+ }
+
+ for (const manifestFile of manifestFiles) {
+ const hostEndpoint = `https://${hostname}.azurewebsites.net/api/messages`;
+
+ const manifest = await fs.readJson(path.join(skillSettingsPath, manifestFile));
+
+ const endpointIndex = manifest.endpoints.findIndex((x) => x.name === profileName);
+ if (endpointIndex > -1) {
+ // already exists
+ return;
+ }
+ manifest.endpoints.push({
+ protocol: 'BotFrameworkV3',
+ name: profileName,
+ endpointUrl: hostEndpoint,
+ description: '',
+ msAppId: msAppId,
+ });
+
+ await fs.writeJson(path.join(skillSettingsPath, manifestFile), manifest);
+ }
+ }
+
private async zipDirectory(source: string, out: string) {
try {
const archive = archiver('zip', { zlib: { level: 9 } });
From 46e6817322d9f443ef98b13a90d54babe4f1c825 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Thu, 1 Apr 2021 19:05:59 +0800
Subject: [PATCH 17/55] pop auth
---
.../client/src/pages/publish/Publish.tsx | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index 4eef49cab0..2e306846bb 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -142,7 +142,7 @@ const Publish: React.FC bot.id === projectId);
changePublishTarget(publishTargetName, currentBotStatus);
setCheckedSkillIds([projectId]);
- setPublishDialogVisiblity(true);
+ onPublish();
}
}, [publishTargetName, botStatusList]);
@@ -267,6 +267,15 @@ const Publish: React.FC {
+ if (isShowAuthDialog(false)) {
+ setShowAuthDialog(true);
+ } else {
+ setPublishDialogVisiblity(true);
+ }
+ TelemetryClient.track('ToolbarButtonClicked', { name: 'publishSelectedBots' });
+ };
+
const publish = async (items: BotStatus[]) => {
const tenantTokenMap = new Map();
// get token
@@ -431,14 +440,7 @@ const Publish: React.FC {
- if (isShowAuthDialog(false)) {
- setShowAuthDialog(true);
- } else {
- setPublishDialogVisiblity(true);
- }
- TelemetryClient.track('ToolbarButtonClicked', { name: 'publishSelectedBots' });
- }}
+ onPublish={onPublish}
onPull={() => {
setPullDialogVisiblity(true);
TelemetryClient.track('ToolbarButtonClicked', { name: 'pullFromProfile' });
From 87261fb4e2f944caf9bb600ecbe920d21fe2dd28 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Fri, 2 Apr 2021 11:27:28 +0800
Subject: [PATCH 18/55] add skill hostendpoint
---
extensions/azurePublish/src/node/deploy.ts | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index eca8141c80..d3f7b25187 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -62,7 +62,7 @@ export class BotProjectDeploy {
const skillManifestPath = path.join(this.projPath, 'ComposerDialogs', 'manifests');
const msAppId = settings.MicrosoftAppId;
- await this.updateSkillSettings(profileName, hostname, msAppId, skillManifestPath);
+ await this.updateSkillSettings(profileName, hostname, msAppId, skillManifestPath, settings);
// STEP 1: CLEAN UP PREVIOUS BUILDS
// cleanup any previous build
if (await fs.pathExists(this.zipPath)) {
@@ -155,7 +155,13 @@ export class BotProjectDeploy {
* @param msAppId microsoft app id
* @param skillSettingsPath the path of skills manifest settings
*/
- private async updateSkillSettings(profileName: string, hostname: string, msAppId: string, skillSettingsPath: string) {
+ private async updateSkillSettings(
+ profileName: string,
+ hostname: string,
+ msAppId: string,
+ skillSettingsPath: string,
+ settings: any
+ ) {
const manifestFiles = (await fs.readdir(skillSettingsPath)).filter((x) => x.endsWith('.json'));
if (manifestFiles.length === 0) {
this.logger({
@@ -184,6 +190,11 @@ export class BotProjectDeploy {
});
await fs.writeJson(path.join(skillSettingsPath, manifestFile), manifest);
+
+ // update skill host endpoint
+ if (settings.skillHostEndpoint) {
+ settings.skillHostEndpoint = `https://${hostname}.azurewebsites.net/api/skills`;
+ }
}
}
From 62b2be590f3552b6463d2714b7171fe1b3b2fa44 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Tue, 6 Apr 2021 10:41:36 +0800
Subject: [PATCH 19/55] fix comments
---
.../src/pages/design/exportSkillModal/constants.tsx | 3 ---
.../design/exportSkillModal/content/AddCallers.tsx | 4 ++--
.../design/exportSkillModal/content/SelectProfile.tsx | 10 ++++++++--
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index cf6d056b98..5bcb31744f 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -131,7 +131,6 @@ interface EditorStep {
}
export enum ManifestEditorSteps {
- // ENDPOINTS = 'ENDPOINTS',
FETCH_MANIFEST_SCHEMA = 'FETCH_MANIFEST_SCHEMA',
MANIFEST_DESCRIPTION = 'MANIFEST_DESCRIPTION',
MANIFEST_REVIEW = 'MANIFEST_REVIEW',
@@ -151,8 +150,6 @@ export const order: ManifestEditorSteps[] = [
ManifestEditorSteps.SELECT_TRIGGERS,
ManifestEditorSteps.ADD_CALLERS,
ManifestEditorSteps.SELECT_PROFILE,
- // ManifestEditorSteps.MANIFEST_REVIEW,
- // ManifestEditorSteps.SAVE_MANIFEST,
];
const cancelButton: Button = {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
index d02831cc9e..6c81d42d03 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -60,7 +60,7 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
{
- var currentCallers = callers.slice();
+ const currentCallers = callers.slice();
currentCallers[index] = newValue ?? '';
setCallers(currentCallers);
}}
@@ -82,7 +82,7 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
handleAdd();
}}
>
- {formatMessage('Add allowd callers')}
+ {formatMessage('Add allowed callers')}
);
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index 0f47a079b7..d3f09d25a6 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -37,8 +37,14 @@ const onRenderLabel = (props) => {
fontSize: '14px',
}}
>
- {' '}
- {props.label}{' '}
+
+ {props.label}
+
From f03067ad4ed93844ecaf1b13dde761a3da199bdc Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 7 Apr 2021 11:06:21 +0800
Subject: [PATCH 20/55] title change
---
.../client/src/components/ProjectTree/ProjectHeader.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/components/ProjectTree/ProjectHeader.tsx b/Composer/packages/client/src/components/ProjectTree/ProjectHeader.tsx
index 8318f52085..e9cf7ce6ee 100644
--- a/Composer/packages/client/src/components/ProjectTree/ProjectHeader.tsx
+++ b/Composer/packages/client/src/components/ProjectTree/ProjectHeader.tsx
@@ -118,7 +118,7 @@ export const ProjectHeader = (props: ProjectHeaderProps) => {
onClick: () => {},
},
{
- label: formatMessage('Create/edit skill manifest'),
+ label: formatMessage('Share as a skill'),
onClick: () => {
onBotEditManifest(projectId);
},
From ebbcd1c3915c5a3f282a6224e2fbbd0a2361ef1c Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 7 Apr 2021 15:20:01 +0800
Subject: [PATCH 21/55] fix copy url wrong
---
.../src/pages/publish/BotStatusList.tsx | 22 +++----------------
.../src/pages/publish/publishPageUtils.tsx | 10 ++++++---
2 files changed, 10 insertions(+), 22 deletions(-)
diff --git a/Composer/packages/client/src/pages/publish/BotStatusList.tsx b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
index 443ad91eab..6ace4c58af 100644
--- a/Composer/packages/client/src/pages/publish/BotStatusList.tsx
+++ b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
@@ -49,20 +49,10 @@ export const BotStatusList: React.FC = ({
}) => {
const [expandedBotIds, setExpandedBotIds] = useState>({});
const [currentSort, setSort] = useState({ key: 'Bot', descending: true });
- const [clipboardText, setClipboardText] = useState('');
- const clipboardTextFieldRef = useRef(null);
const copyStringToClipboard = (value?: string) => {
try {
- if (clipboardTextFieldRef.current) {
- setClipboardText(value || '');
- setTimeout(() => {
- if (clipboardTextFieldRef.current) {
- clipboardTextFieldRef.current.select();
- document.execCommand('copy');
- }
- }, 10);
- }
+ value && navigator.clipboard.writeText(value);
} catch (e) {
// eslint-disable-next-line no-console
console.error('Something went wrong when copying to the clipboard.', e, location);
@@ -270,8 +260,8 @@ export const BotStatusList: React.FC = ({
name: '',
className: 'skillManifest',
fieldName: 'skillManifestUrl',
- minWidth: 114,
- maxWidth: 134,
+ minWidth: 134,
+ maxWidth: 150,
data: 'string',
onRender: (item: BotStatus) => {
return (
@@ -366,12 +356,6 @@ export const BotStatusList: React.FC = ({
onRenderRow={renderTableRow}
/>
-
);
};
diff --git a/Composer/packages/client/src/pages/publish/publishPageUtils.tsx b/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
index fa53f1c251..abd565e6a0 100644
--- a/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
+++ b/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
@@ -31,11 +31,11 @@ export const generateBotPropertyData = (botProjectData: BotProjectType[]) => {
return { botPropertyData, botList };
};
-const findSkillManifestUrl = (skillManifests: SkillManifestFile[], appId: string) => {
+const findSkillManifestUrl = (skillManifests: SkillManifestFile[], hostname: string, appId: string) => {
for (const skillManifest of skillManifests || []) {
for (const endpoint of skillManifest?.content?.endpoints || []) {
if (endpoint?.msAppId === appId) {
- return endpoint?.endpointUrl;
+ return `https://${hostname}.azurewebsites.net/manifests/${skillManifest.id}.json`;
}
}
}
@@ -67,7 +67,11 @@ export const generateBotStatusList = (
const config = JSON.parse(currentPublishTarget.configuration);
const appId = config?.settings?.MicrosoftAppId;
if (appId) {
- botStatus.skillManifestUrl = findSkillManifestUrl(botPropertyData[bot.id].skillManifests, appId);
+ botStatus.skillManifestUrl = findSkillManifestUrl(
+ botPropertyData[bot.id].skillManifests,
+ config.hostname,
+ appId
+ );
}
}
}
From 98e3d5caa0f8a41c1da788c231a015467d812060 Mon Sep 17 00:00:00 2001
From: Qi Kang
Date: Wed, 7 Apr 2021 17:10:34 +0800
Subject: [PATCH 22/55] fix filtered lu files
---
.../src/pages/design/exportSkillModal/generateSkillManifest.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
index 406a08129d..6984908364 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/generateSkillManifest.ts
@@ -146,7 +146,7 @@ export const generateDispatchModels = (
const currentFileName = `skill-${rootLuFile.id}`;
const parsedLuFile = luIndexer.parse(rootLuFile.content, rootLuFile.id, {});
const contents = parsedLuFile.intents.map((x) => {
- if (intents.find((intent) => intent == x.Name) != -1) {
+ if (intents.findIndex((intent) => intent == x.Name) !== -1) {
return [`# ${x.Name}`, x.Body].join('\n');
}
});
From 4b1f1286f6193a4d998c261ffaa89d7e605a7507 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 7 Apr 2021 17:18:58 +0800
Subject: [PATCH 23/55] merge selectManifest & fetchManifest & description
popup
---
.../design/exportSkillModal/constants.tsx | 6 +-
.../exportSkillModal/content/Description.tsx | 158 +++++++++++++++---
.../pages/design/exportSkillModal/index.tsx | 5 +-
3 files changed, 134 insertions(+), 35 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 5bcb31744f..602956daad 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -3,7 +3,6 @@
import formatMessage from 'format-message';
import { JSONSchema7 } from '@bfc/extension-client';
-import { resolveRef } from '@bfc/adaptive-form';
import { SkillManifestFile } from '@bfc/shared';
import startCase from 'lodash/startCase';
import { SDKKinds } from '@bfc/shared';
@@ -12,7 +11,6 @@ import { nameRegex } from '../../../constants';
import {
Description,
- Endpoints,
FetchManifestSchema,
ReviewManifest,
SaveManifest,
@@ -143,8 +141,8 @@ export enum ManifestEditorSteps {
}
export const order: ManifestEditorSteps[] = [
- ManifestEditorSteps.SELECT_MANIFEST,
- ManifestEditorSteps.FETCH_MANIFEST_SCHEMA,
+ // ManifestEditorSteps.SELECT_MANIFEST,
+ // ManifestEditorSteps.FETCH_MANIFEST_SCHEMA,
ManifestEditorSteps.MANIFEST_DESCRIPTION,
ManifestEditorSteps.SELECT_DIALOGS,
ManifestEditorSteps.SELECT_TRIGGERS,
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
index 5ff2dc68d4..e56c2ca10b 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
@@ -3,7 +3,7 @@
/** @jsx jsx */
import { css, jsx } from '@emotion/core';
-import React, { useMemo, useEffect } from 'react';
+import React, { useMemo, useEffect, Fragment, useState } from 'react';
import AdaptiveForm, { FieldLabel } from '@bfc/adaptive-form';
import { FieldProps, JSONSchema7, UIOptions } from '@bfc/extension-client';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
@@ -12,6 +12,17 @@ import { v4 as uuid } from 'uuid';
import { ContentProps } from '../constants';
import { botDisplayNameState } from '../../../../recoilModel';
+import { Label } from 'office-ui-fabric-react/lib/Label';
+import formatMessage from 'format-message';
+import { Dropdown, IDropdownOption, ResponsiveMode } from 'office-ui-fabric-react/lib/Dropdown';
+import { LoadingSpinner } from '@bfc/ui-shared/lib/components/LoadingSpinner';
+
+export const VERSION_REGEX = /\d\.\d+\.(\d+|preview-\d+)|\d\.\d+/i;
+
+export const SCHEMA_URIS = [
+ 'https://schemas.botframework.com/schemas/skills/v2.1/skill-manifest.json',
+ 'https://schemas.botframework.com/schemas/skills/skill-manifest-2.0.0.json',
+];
const styles = {
row: css`
@@ -25,6 +36,12 @@ const styles = {
`,
};
+const chooseVersion = css`
+ display: flex;
+ width: 72%;
+ margin: 10px 18px;
+ justify-content: space-between;
+`;
const InlineLabelField: React.FC = (props) => {
const { id, placeholder, rawErrors, value = '', onChange } = props;
@@ -50,39 +67,86 @@ const InlineLabelField: React.FC = (props) => {
);
};
-export const Description: React.FC = ({ errors, value, schema, onChange, projectId }) => {
+export const Description: React.FC = ({
+ errors,
+ value,
+ schema,
+ skillManifests,
+ onChange,
+ projectId,
+ setSchema,
+ setSkillManifest,
+ editJson,
+}) => {
const botName = useRecoilValue(botDisplayNameState(projectId));
+ const [isFetchCompleted, setIsFetchCompleted] = useState(false);
const { $schema, ...rest } = value;
- const { hidden, properties } = useMemo(
+ const { hidden, properties } = useMemo(() => {
+ if (!schema.properties) return { hidden: [], properties: {} } as any;
+ return Object.entries(schema.properties as JSONSchema7).reduce(
+ ({ hidden, properties }, [key, property]) => {
+ if (property.type === 'object' || (property.type === 'array' && property?.items?.type !== 'string')) {
+ return { hidden: [...hidden, key], properties };
+ }
+
+ const itemSchema = property?.items as JSONSchema7;
+ const serializer =
+ itemSchema?.type === 'string'
+ ? {
+ get: (value) => (Array.isArray(value) ? value.join(',') : value),
+ set: (value) => (typeof value === 'string' ? value.split(/\s*,\s*/) : value),
+ }
+ : null;
+
+ return {
+ hidden,
+ properties: { ...properties, [key]: { field: InlineLabelField, hideError: true, serializer } },
+ };
+ },
+ { hidden: [], properties: {} } as any
+ );
+ }, [schema]);
+
+ const options: IDropdownOption[] = useMemo(
() =>
- Object.entries(schema?.properties as JSONSchema7).reduce(
- ({ hidden, properties }, [key, property]) => {
- if (property.type === 'object' || (property.type === 'array' && property?.items?.type !== 'string')) {
- return { hidden: [...hidden, key], properties };
- }
-
- const itemSchema = property?.items as JSONSchema7;
- const serializer =
- itemSchema?.type === 'string'
- ? {
- get: (value) => (Array.isArray(value) ? value.join(',') : value),
- set: (value) => (typeof value === 'string' ? value.split(/\s*,\s*/) : value),
- }
- : null;
-
- return {
- hidden,
- properties: { ...properties, [key]: { field: InlineLabelField, hideError: true, serializer } },
- };
- },
- { hidden: [], properties: {} } as any
- ),
+ SCHEMA_URIS.map((key, index) => {
+ const [version] = VERSION_REGEX.exec(key) || [];
+
+ return {
+ text: formatMessage('Version {version}', { version }),
+ key,
+ selected: !index,
+ };
+ }),
[]
);
useEffect(() => {
- if (!value.$id) {
+ if (!$schema) {
+ const skillManifest = skillManifests.find((manifest) => manifest.content.$schema === SCHEMA_URIS[0]) || {
+ content: { $schema: SCHEMA_URIS[0] },
+ };
+ setSkillManifest(skillManifest);
+ }
+ (async function () {
+ try {
+ if ($schema) {
+ const res = await fetch($schema);
+ const schema = await res.json();
+ setSchema(schema);
+ setIsFetchCompleted(true);
+ } else {
+ editJson();
+ }
+ } catch (error) {
+ editJson();
+ }
+ })();
+ }, [$schema]);
+
+ useEffect(() => {
+ if (!value.$id && value.$schema) {
onChange({ $schema, $id: `${botName}-${uuid()}`, endpoints: [{}], name: botName, ...rest });
}
}, []);
@@ -96,5 +160,45 @@ export const Description: React.FC = ({ errors, value, schema, onC
properties,
};
- return ;
+ const handleChange = (_e: React.FormEvent, option?: IDropdownOption) => {
+ if (option) {
+ const skillManifest = skillManifests.find((manifest) => manifest.content.$schema === option.key) || {
+ content: { $schema: option.key as string },
+ };
+ setIsFetchCompleted(false);
+ setSkillManifest(skillManifest);
+ }
+ };
+
+ return (
+
+
+
+ {formatMessage('Manifest Version')}
+
+
+
+ {isFetchCompleted ? (
+
+ ) : (
+
+ )}
+
+ );
};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index b449c6b28b..c599fc269c 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -47,7 +47,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const skillManifests = useRecoilValue(skillManifestsState(projectId));
const { updateSkillManifest } = useRecoilValue(dispatcherState);
- const [editingId, setEditingId] = useState();
const [currentStep, setCurrentStep] = useState(0);
const [errors, setErrors] = useState({});
const [schema, setSchema] = useState({});
@@ -136,13 +135,11 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
};
const handleNext = (options?: { dismiss?: boolean; id?: string; save?: boolean }) => {
- const validated =
- typeof validate === 'function' ? validate({ content, editingId, id, schema, skillManifests }) : errors;
+ const validated = typeof validate === 'function' ? validate({ content, id, schema, skillManifests }) : errors;
if (!Object.keys(validated).length) {
setCurrentStep((current) => (current + 1 < order.length ? current + 1 : current));
options?.save && handleSave();
- options?.id && setEditingId(options.id);
options?.dismiss && handleDismiss();
setErrors({});
} else {
From 7a23ae9fefac6103f4675037efa22db6d7cc7f87 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 7 Apr 2021 18:42:01 +0800
Subject: [PATCH 24/55] next bugfix
---
.../exportSkillModal/content/Description.tsx | 26 +++++++++----------
.../pages/design/exportSkillModal/index.tsx | 9 +++++--
.../pages/design/exportSkillModal/styles.ts | 8 +++---
3 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
index e56c2ca10b..a84976d64c 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
@@ -80,7 +80,7 @@ export const Description: React.FC = ({
}) => {
const botName = useRecoilValue(botDisplayNameState(projectId));
const [isFetchCompleted, setIsFetchCompleted] = useState(false);
- const { $schema, ...rest } = value;
+ const { $id, $schema, ...rest } = value;
const { hidden, properties } = useMemo(() => {
if (!schema.properties) return { hidden: [], properties: {} } as any;
@@ -123,12 +123,18 @@ export const Description: React.FC = ({
);
useEffect(() => {
- if (!$schema) {
- const skillManifest = skillManifests.find((manifest) => manifest.content.$schema === SCHEMA_URIS[0]) || {
- content: { $schema: SCHEMA_URIS[0] },
- };
- setSkillManifest(skillManifest);
- }
+ const skillManifest = skillManifests.find(
+ (manifest) => manifest.content.$schema === ($schema || SCHEMA_URIS[0])
+ ) || {
+ content: {
+ $schema: $schema || SCHEMA_URIS[0],
+ $id: `${botName}-${uuid()}`,
+ endpoints: [{}],
+ name: botName,
+ ...rest,
+ },
+ };
+ setSkillManifest(skillManifest);
(async function () {
try {
if ($schema) {
@@ -145,12 +151,6 @@ export const Description: React.FC = ({
})();
}, [$schema]);
- useEffect(() => {
- if (!value.$id && value.$schema) {
- onChange({ $schema, $id: `${botName}-${uuid()}`, endpoints: [{}], name: botName, ...rest });
- }
- }, []);
-
const required = schema?.required || [];
const uiOptions: UIOptions = {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index c599fc269c..bbeaca8d82 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -3,7 +3,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
-import React, { useEffect, useMemo, useRef, useState } from 'react';
+import React, { useState } from 'react';
import formatMessage from 'format-message';
import { Dialog, DialogFooter, DialogType } from 'office-ui-fabric-react/lib/Dialog';
import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react/lib/Button';
@@ -173,7 +173,12 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
)}
-
+
Date: Thu, 8 Apr 2021 15:49:32 +0800
Subject: [PATCH 25/55] bugfix
---
.../exportSkillModal/content/Description.tsx | 9 +--------
.../exportSkillModal/content/SelectItems.tsx | 2 +-
.../src/pages/design/exportSkillModal/index.tsx | 15 +++++++++++++--
.../packages/client/src/pages/publish/Publish.tsx | 1 +
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
index a84976d64c..63ef959138 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
@@ -10,20 +10,13 @@ import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { useRecoilValue } from 'recoil';
import { v4 as uuid } from 'uuid';
-import { ContentProps } from '../constants';
+import { ContentProps, SCHEMA_URIS, VERSION_REGEX } from '../constants';
import { botDisplayNameState } from '../../../../recoilModel';
import { Label } from 'office-ui-fabric-react/lib/Label';
import formatMessage from 'format-message';
import { Dropdown, IDropdownOption, ResponsiveMode } from 'office-ui-fabric-react/lib/Dropdown';
import { LoadingSpinner } from '@bfc/ui-shared/lib/components/LoadingSpinner';
-export const VERSION_REGEX = /\d\.\d+\.(\d+|preview-\d+)|\d\.\d+/i;
-
-export const SCHEMA_URIS = [
- 'https://schemas.botframework.com/schemas/skills/v2.1/skill-manifest.json',
- 'https://schemas.botframework.com/schemas/skills/skill-manifest-2.0.0.json',
-];
-
const styles = {
row: css`
display: flex;
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectItems.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectItems.tsx
index 1e69515a6c..6584e61922 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectItems.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectItems.tsx
@@ -77,7 +77,7 @@ export const SelectItems: React.FC = ({ items, selection, tabl
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index bbeaca8d82..2895c1400a 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -27,7 +27,7 @@ import {
import { styles } from './styles';
import { generateSkillManifest } from './generateSkillManifest';
-import { editorSteps, ManifestEditorSteps, order } from './constants';
+import { editorSteps, ManifestEditorSteps, order, VERSION_REGEX } from './constants';
import { mergePropertiesManagedByRootBot } from '../../../recoilModel/dispatchers/utils/project';
import { cloneDeep } from 'lodash';
@@ -138,7 +138,18 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const validated = typeof validate === 'function' ? validate({ content, id, schema, skillManifests }) : errors;
if (!Object.keys(validated).length) {
- setCurrentStep((current) => (current + 1 < order.length ? current + 1 : current));
+ setCurrentStep((current) => {
+ if (current === 1) {
+ const [version] = VERSION_REGEX.exec(content.$schema) || [];
+ if (current + 1 === order.length) {
+ return current;
+ } else {
+ return version === '2.0.0' ? current + 2 : current + 1;
+ }
+ } else {
+ return current + 1 < order.length ? current + 1 : current;
+ }
+ });
options?.save && handleSave();
options?.dismiss && handleDismiss();
setErrors({});
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index b60ebe5e08..4b0fed67d6 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -143,6 +143,7 @@ const Publish: React.FC
Date: Thu, 8 Apr 2021 17:08:35 +0800
Subject: [PATCH 26/55] merge main & popup err
---
.../client/src/pages/design/DebugPanel/TabExtensions/index.ts | 2 +-
Composer/packages/client/src/pages/publish/Publish.tsx | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
index f17f2ca037..8d33f1ae8c 100644
--- a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
+++ b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
@@ -3,7 +3,7 @@
import { TabExtensionConfig } from './types';
import { DiagnosticsTabConfig } from './DiagnosticsTab';
-import { WebChatLogTabConfig } from './WebChatLog/config';
+import { WebChatLogTabConfig } from './WebchatLog/config';
import { RuntimeOutputTabConfig } from './RuntimeOutputLog';
const implementedDebugExtensions: TabExtensionConfig[] = [
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index 7925fba78f..a7af062450 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -4,7 +4,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
import { useState, useEffect, useMemo, Fragment, useRef } from 'react';
-import { RouteComponentProps } from '@reach/router';
+import { navigate, RouteComponentProps } from '@reach/router';
import formatMessage from 'format-message';
import { useRecoilValue } from 'recoil';
import { PublishResult, PublishTarget } from '@bfc/shared';
@@ -149,7 +149,7 @@ const Publish: React.FC
Date: Fri, 9 Apr 2021 09:33:59 +0800
Subject: [PATCH 27/55] Fix endpoint not update issue
---
extensions/azurePublish/src/node/deploy.ts | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index 5721ef1832..f3f0c1f298 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -60,9 +60,11 @@ export class BotProjectDeploy {
await this.BindKeyVault(absSettings, hostname);
}
- const skillManifestPath = path.join(this.projPath, 'ComposerDialogs', 'manifests');
- const msAppId = settings.MicrosoftAppId;
- await this.updateSkillSettings(profileName, hostname, msAppId, skillManifestPath, settings);
+ const skillManifestPath = path.join(this.projPath, 'wwwroot', 'manifests');
+ if (await fs.pathExists(skillManifestPath)) {
+ await this.updateSkillSettings(profileName, hostname, settings.MicrosoftAppId, skillManifestPath, settings);
+ }
+
// STEP 1: CLEAN UP PREVIOUS BUILDS
// cleanup any previous build
if (await fs.pathExists(this.zipPath)) {
@@ -171,6 +173,11 @@ export class BotProjectDeploy {
return;
}
+ // update skill host endpoint
+ if (settings.skillHostEndpoint) {
+ settings.skillHostEndpoint = `https://${hostname}.azurewebsites.net/api/skills`;
+ }
+
for (const manifestFile of manifestFiles) {
const hostEndpoint = `https://${hostname}.azurewebsites.net/api/messages`;
@@ -190,11 +197,6 @@ export class BotProjectDeploy {
});
await fs.writeJson(path.join(skillSettingsPath, manifestFile), manifest);
-
- // update skill host endpoint
- if (settings.skillHostEndpoint) {
- settings.skillHostEndpoint = `https://${hostname}.azurewebsites.net/api/skills`;
- }
}
}
From d3a03969cf0aee720f065c2c204f7eb91742dba2 Mon Sep 17 00:00:00 2001
From: Lu Han <32191031+luhan2017@users.noreply.github.com>
Date: Fri, 9 Apr 2021 10:24:40 +0800
Subject: [PATCH 28/55] Fix new adaptive runtime copy skill manifests to
wwwroot folder
---
extensions/azurePublish/src/node/index.ts | 11 +++++++++++
extensions/runtimes/src/index.ts | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/extensions/azurePublish/src/node/index.ts b/extensions/azurePublish/src/node/index.ts
index 87543cee36..c4076eef2c 100644
--- a/extensions/azurePublish/src/node/index.ts
+++ b/extensions/azurePublish/src/node/index.ts
@@ -206,6 +206,17 @@ export default async (composer: IExtensionRegistration): Promise => {
// copy bot and runtime into projFolder
await copy(srcTemplate, buildFolder);
+
+ let manifestPath;
+ for (const file of botFiles) {
+ const pattern = /manifests\/[0-9A-z-]*.json/;
+ if (file.relativePath.match(pattern)) {
+ manifestPath = path.dirname(file.path);
+ }
+ }
+
+ // save manifest
+ runtime.setSkillManifest(buildFolder, project.fileStorage, manifestPath, project.fileStorage, mode);
} else {
const botFolder = this.getBotFolder(resourcekey, mode);
const runtimeFolder = this.getRuntimeFolder(resourcekey);
diff --git a/extensions/runtimes/src/index.ts b/extensions/runtimes/src/index.ts
index 2b91b0b996..a42cacd27a 100644
--- a/extensions/runtimes/src/index.ts
+++ b/extensions/runtimes/src/index.ts
@@ -450,7 +450,7 @@ export default async (composer: any): Promise => {
) => {
// update manifst into runtime wwwroot
if (mode === 'azurewebapp') {
- const manifestDstDir = path.resolve(dstRuntimePath, 'azurewebapp', 'wwwroot', 'manifests');
+ const manifestDstDir = path.resolve(dstRuntimePath, 'wwwroot', 'manifests');
if (await fs.pathExists(manifestDstDir)) {
await removeDirAndFiles(manifestDstDir);
From 4ba00b2cbdff1575b97c342c05cef4fac3ec93b7 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Fri, 9 Apr 2021 11:19:29 +0800
Subject: [PATCH 29/55] skip step revert
---
.../pages/design/DebugPanel/TabExtensions/index.ts | 2 +-
.../src/pages/design/exportSkillModal/index.tsx | 13 +------------
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
index 8d33f1ae8c..f17f2ca037 100644
--- a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
+++ b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
@@ -3,7 +3,7 @@
import { TabExtensionConfig } from './types';
import { DiagnosticsTabConfig } from './DiagnosticsTab';
-import { WebChatLogTabConfig } from './WebchatLog/config';
+import { WebChatLogTabConfig } from './WebChatLog/config';
import { RuntimeOutputTabConfig } from './RuntimeOutputLog';
const implementedDebugExtensions: TabExtensionConfig[] = [
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 2895c1400a..39b089e145 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -138,18 +138,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const validated = typeof validate === 'function' ? validate({ content, id, schema, skillManifests }) : errors;
if (!Object.keys(validated).length) {
- setCurrentStep((current) => {
- if (current === 1) {
- const [version] = VERSION_REGEX.exec(content.$schema) || [];
- if (current + 1 === order.length) {
- return current;
- } else {
- return version === '2.0.0' ? current + 2 : current + 1;
- }
- } else {
- return current + 1 < order.length ? current + 1 : current;
- }
- });
+ setCurrentStep((current) => (current + 1 < order.length ? current + 1 : current));
options?.save && handleSave();
options?.dismiss && handleDismiss();
setErrors({});
From b57aac146d4cf97eba7d37d9f517ff9837bbefaf Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Fri, 9 Apr 2021 15:09:52 +0800
Subject: [PATCH 30/55] tooltip
---
.../src/pages/publish/BotStatusList.tsx | 37 ++++++++++++-------
.../src/pages/publish/publishPageUtils.tsx | 11 +++---
.../packages/client/src/pages/publish/type.ts | 2 +-
3 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/Composer/packages/client/src/pages/publish/BotStatusList.tsx b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
index e672837745..ac3c0fc91a 100644
--- a/Composer/packages/client/src/pages/publish/BotStatusList.tsx
+++ b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
@@ -24,6 +24,8 @@ import { ApiStatus } from '../../utils/publishStatusPollingUpdater';
import { PublishStatusList } from './PublishStatusList';
import { detailList, listRoot, tableView } from './styles';
import { BotPublishHistory, BotStatus } from './type';
+import { TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
+import { flexContentSpaceBetween } from '../language-understanding/styles';
const copiedCalloutStyles = {
root: {
@@ -32,25 +34,34 @@ const copiedCalloutStyles = {
};
type SkillManifestUrlFieldProps = {
- url: string;
+ urls: string[];
};
-const SkillManifestUrlField = ({ url }: SkillManifestUrlFieldProps) => {
- const { isCopiedToClipboard, copyTextToClipboard, resetIsCopiedToClipboard } = useCopyToClipboard(url);
+const SkillManifestUrlField = ({ urls }: SkillManifestUrlFieldProps) => {
+ const { isCopiedToClipboard, copyTextToClipboard, resetIsCopiedToClipboard } = useCopyToClipboard(urls[0]);
const calloutTarget = useRef();
return (
- {
- calloutTarget.current = e.target as HTMLElement;
- copyTextToClipboard();
- }}
+ (
+
+ {url}
+ navigator.clipboard.writeText(url)} />
+
+ ))}
>
- {formatMessage('Copy Skill Manifest URL')}
-
+ {
+ calloutTarget.current = e.target as HTMLElement;
+ copyTextToClipboard();
+ }}
+ >
+ {formatMessage('Copy Skill Manifest URL')}
+
+
{isCopiedToClipboard && (
= ({
maxWidth: 150,
data: 'string',
onRender: (item: BotStatus) => {
- return item?.skillManifestUrl && ;
+ return item?.skillManifestUrls.length > 0 && ;
},
isPadded: true,
},
diff --git a/Composer/packages/client/src/pages/publish/publishPageUtils.tsx b/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
index abd565e6a0..75f00d442b 100644
--- a/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
+++ b/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
@@ -31,16 +31,17 @@ export const generateBotPropertyData = (botProjectData: BotProjectType[]) => {
return { botPropertyData, botList };
};
-const findSkillManifestUrl = (skillManifests: SkillManifestFile[], hostname: string, appId: string) => {
+const findSkillManifestUrl = (skillManifests: SkillManifestFile[], hostname: string, appId: string): string[] => {
+ const urls: string[] = [];
for (const skillManifest of skillManifests || []) {
for (const endpoint of skillManifest?.content?.endpoints || []) {
if (endpoint?.msAppId === appId) {
- return `https://${hostname}.azurewebsites.net/manifests/${skillManifest.id}.json`;
+ urls.push(`https://${hostname}.azurewebsites.net/manifests/${skillManifest.id}.json`);
}
}
}
- return undefined;
+ return urls;
};
export const generateBotStatusList = (
@@ -49,7 +50,7 @@ export const generateBotStatusList = (
botPublishHistoryList: BotPublishHistory
): BotStatus[] => {
const bots = botList.map((bot) => {
- const botStatus: BotStatus = Object.assign({}, bot);
+ const botStatus: BotStatus = Object.assign({ skillManifestUrls: [] }, bot);
const publishTargets: PublishTarget[] = botPropertyData[bot.id].publishTargets;
const publishHistory = botPublishHistoryList[bot.id];
if (publishTargets.length > 0 && botStatus.publishTarget && publishHistory) {
@@ -67,7 +68,7 @@ export const generateBotStatusList = (
const config = JSON.parse(currentPublishTarget.configuration);
const appId = config?.settings?.MicrosoftAppId;
if (appId) {
- botStatus.skillManifestUrl = findSkillManifestUrl(
+ botStatus.skillManifestUrls = findSkillManifestUrl(
botPropertyData[bot.id].skillManifests,
config.hostname,
appId
diff --git a/Composer/packages/client/src/pages/publish/type.ts b/Composer/packages/client/src/pages/publish/type.ts
index bb537f8e01..da3041d94d 100644
--- a/Composer/packages/client/src/pages/publish/type.ts
+++ b/Composer/packages/client/src/pages/publish/type.ts
@@ -19,7 +19,7 @@ export type BotStatus = {
/**
* The skill manifest URL associated with the current publishTarget.
*/
- skillManifestUrl?: string;
+ skillManifestUrls: string[];
};
export type Bot = {
From 52f06ac8b8871f8d2f6b674f40273489a3eabd7d Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Fri, 9 Apr 2021 16:59:04 +0800
Subject: [PATCH 31/55] add back button & fix url color
---
.../design/exportSkillModal/constants.tsx | 14 +++++++++++
.../exportSkillModal/content/Description.tsx | 9 +++++--
.../content/SelectDialogs.tsx | 24 +++++++++----------
.../content/SelectTriggers.tsx | 23 +++++++++---------
.../pages/design/exportSkillModal/index.tsx | 7 ++++++
.../src/pages/publish/BotStatusList.tsx | 5 ++--
.../src/pages/publish/Notifications.tsx | 4 ++--
7 files changed, 57 insertions(+), 29 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 602956daad..d952af7b83 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -95,6 +95,8 @@ export interface ContentProps {
setSelectedTriggers: (selectedTriggers: any[]) => void;
setSkillManifest: (_: Partial) => void;
schema: JSONSchema7;
+ selectedDialogs: any[];
+ selectedTriggers: any[];
skillManifests: SkillManifestFile[];
value: { [key: string]: any };
onChange: (_: any) => void;
@@ -161,6 +163,12 @@ const nextButton: Button = {
onClick: ({ onNext }) => onNext,
};
+const backButton: Button = {
+ primary: true,
+ text: () => formatMessage('Back'),
+ onClick: ({ onBack }) => onBack,
+};
+
const validate = ({ content, schema }) => {
const required = schema?.required || [];
@@ -212,6 +220,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.SELECT_PROFILE]: {
buttons: [
cancelButton,
+ backButton,
{
primary: true,
text: () => formatMessage('Generate and Publish'),
@@ -231,6 +240,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.ADD_CALLERS]: {
buttons: [
cancelButton,
+ backButton,
{
primary: true,
text: () => formatMessage('Next'),
@@ -251,6 +261,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.MANIFEST_REVIEW]: {
buttons: [
cancelButton,
+ backButton,
{
primary: true,
text: () => formatMessage('Next'),
@@ -264,6 +275,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.SELECT_DIALOGS]: {
buttons: [
cancelButton,
+ backButton,
{
primary: true,
text: () => formatMessage('Next'),
@@ -281,6 +293,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.SELECT_TRIGGERS]: {
buttons: [
cancelButton,
+ backButton,
{
primary: true,
text: () => formatMessage('Next'),
@@ -301,6 +314,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
[ManifestEditorSteps.SAVE_MANIFEST]: {
buttons: [
cancelButton,
+ backButton,
{
primary: true,
text: () => formatMessage('Save'),
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
index 63ef959138..2178682c70 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
@@ -105,11 +105,16 @@ export const Description: React.FC = ({
() =>
SCHEMA_URIS.map((key, index) => {
const [version] = VERSION_REGEX.exec(key) || [];
-
+ let selected = false;
+ if ($schema) {
+ selected = $schema && key === $schema;
+ } else {
+ selected = !index;
+ }
return {
text: formatMessage('Version {version}', { version }),
key,
- selected: !index,
+ selected,
};
}),
[]
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
index ee90f5fd68..7c59a879f7 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
@@ -93,7 +93,7 @@ const DescriptionColumn: React.FC = (props) => {
);
};
-export const SelectDialogs: React.FC = ({ setSelectedDialogs, projectId }) => {
+export const SelectDialogs: React.FC = ({ selectedDialogs, setSelectedDialogs, projectId }) => {
const dialogs = useRecoilValue(dialogsSelectorFamily(projectId));
const items = useMemo(() => dialogs.map(({ id, content, displayName }) => ({ id, content, displayName })), [
projectId,
@@ -138,16 +138,16 @@ export const SelectDialogs: React.FC = ({ setSelectedDialogs, proj
[projectId]
);
- const selection = useMemo(
- () =>
- new Selection({
- onSelectionChanged: () => {
- const selectedItems = selection.getSelection();
- setSelectedDialogs(selectedItems);
- },
- }),
- []
- );
-
+ const selection = useMemo(() => {
+ const listSelection = new Selection({
+ onSelectionChanged: () => {
+ const selectedItems = listSelection.getSelection();
+ setSelectedDialogs(selectedItems);
+ },
+ });
+ listSelection.setItems(selectedDialogs);
+ listSelection.setAllSelected(true);
+ return listSelection;
+ }, []);
return ;
};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
index f1a5127be7..9275a884a9 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
@@ -20,7 +20,7 @@ const getLabel = (kind: SDKKinds, uiSchema) => {
return label || kind.replace('Microsoft.', '');
};
-export const SelectTriggers: React.FC = ({ setSelectedTriggers, projectId }) => {
+export const SelectTriggers: React.FC = ({ selectedTriggers, setSelectedTriggers, projectId }) => {
const dialogs = useRecoilValue(dialogsSelectorFamily(projectId));
const schemas = useRecoilValue(schemasState(projectId));
@@ -80,16 +80,17 @@ export const SelectTriggers: React.FC = ({ setSelectedTriggers, pr
},
];
- const selection = useMemo(
- () =>
- new Selection({
- onSelectionChanged: () => {
- const selectedItems = selection.getSelection();
- setSelectedTriggers(selectedItems);
- },
- }),
- []
- );
+ const selection = useMemo(() => {
+ const listSelection = new Selection({
+ onSelectionChanged: () => {
+ const selectedItems = listSelection.getSelection();
+ setSelectedTriggers(selectedItems);
+ },
+ });
+ listSelection.setItems(selectedTriggers);
+ listSelection.setAllSelected(true);
+ return listSelection;
+ }, []);
return ;
};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 39b089e145..b6c307b782 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -147,6 +147,10 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
}
};
+ const handleBack = () => {
+ setCurrentStep((current) => (current > 0 ? current - 1 : current));
+ };
+
return (
= ({ onSubmit, onDismiss
manifest={skillManifest}
projectId={projectId}
schema={schema}
+ selectedDialogs={selectedDialogs}
+ selectedTriggers={selectedTriggers}
setErrors={setErrors}
setSchema={setSchema}
setSelectedDialogs={setSelectedDialogs}
@@ -217,6 +223,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
manifest: skillManifest,
onDismiss: handleDismiss,
onNext: handleNext,
+ onBack: handleBack,
onSave: handleSave,
onPublish: handleTriggerPublish,
onSubmit,
diff --git a/Composer/packages/client/src/pages/publish/BotStatusList.tsx b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
index ac3c0fc91a..71f5cb6fe1 100644
--- a/Composer/packages/client/src/pages/publish/BotStatusList.tsx
+++ b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
@@ -24,7 +24,7 @@ import { ApiStatus } from '../../utils/publishStatusPollingUpdater';
import { PublishStatusList } from './PublishStatusList';
import { detailList, listRoot, tableView } from './styles';
import { BotPublishHistory, BotStatus } from './type';
-import { TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
+import { ITooltipHostStyles, ITooltipStyles, TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
import { flexContentSpaceBetween } from '../language-understanding/styles';
const copiedCalloutStyles = {
@@ -41,12 +41,13 @@ const SkillManifestUrlField = ({ urls }: SkillManifestUrlFieldProps) => {
const { isCopiedToClipboard, copyTextToClipboard, resetIsCopiedToClipboard } = useCopyToClipboard(urls[0]);
const calloutTarget = useRef();
+ const clipUrl = (url) => url.replace('azurewebsites.net/manifests/', 'azureweb...');
return (
(
- {url}
+ {clipUrl(url)}
navigator.clipboard.writeText(url)} />
))}
diff --git a/Composer/packages/client/src/pages/publish/Notifications.tsx b/Composer/packages/client/src/pages/publish/Notifications.tsx
index 66df23a214..1a9a93bb79 100644
--- a/Composer/packages/client/src/pages/publish/Notifications.tsx
+++ b/Composer/packages/client/src/pages/publish/Notifications.tsx
@@ -107,7 +107,7 @@ export const getSkillPublishedNotificationCardProps = (item: BotStatus, url?: st
`;
const linkButton = css`
- color: #0078d4;
+ color: #323130;
float: right;
font-size: 12px;
height: auto;
@@ -136,7 +136,7 @@ export const getSkillPublishedNotificationCardProps = (item: BotStatus, url?: st
{url}
navigator.clipboard.writeText(url)}
/>
From 2c51c070b067b7463f4a8b99c1f535cfb5ef6258 Mon Sep 17 00:00:00 2001
From: Lu Han <32191031+luhan2017@users.noreply.github.com>
Date: Mon, 12 Apr 2021 10:57:41 +0800
Subject: [PATCH 32/55] Update the logic of updating skill host endpoint
---
extensions/azurePublish/src/node/deploy.ts | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index ae7bb2aeba..42b1d1ab4b 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -62,6 +62,12 @@ export class BotProjectDeploy {
await this.BindKeyVault(absSettings, hostname);
}
+ // Update skill host endpoint
+ if (settings.skillHostEndpoint) {
+ settings.skillHostEndpoint = `https://${hostname}.azurewebsites.net/api/skills`;
+ }
+
+ // Update endpoints in skill manifests
const skillManifestPath = path.join(this.projPath, 'wwwroot', 'manifests');
if (await fs.pathExists(skillManifestPath)) {
await this.updateSkillSettings(profileName, hostname, settings.MicrosoftAppId, skillManifestPath, settings);
@@ -186,11 +192,6 @@ export class BotProjectDeploy {
return;
}
- // update skill host endpoint
- if (settings.skillHostEndpoint) {
- settings.skillHostEndpoint = `https://${hostname}.azurewebsites.net/api/skills`;
- }
-
for (const manifestFile of manifestFiles) {
const hostEndpoint = `https://${hostname}.azurewebsites.net/api/messages`;
From 9314af5f819f26e1652476de9f0131147220848c Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Mon, 12 Apr 2021 13:27:21 +0800
Subject: [PATCH 33/55] callers set
---
.../design/DebugPanel/TabExtensions/index.ts | 2 +-
.../pages/design/exportSkillModal/index.tsx | 23 +++++++++++++------
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
index f17f2ca037..8d33f1ae8c 100644
--- a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
+++ b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
@@ -3,7 +3,7 @@
import { TabExtensionConfig } from './types';
import { DiagnosticsTabConfig } from './DiagnosticsTab';
-import { WebChatLogTabConfig } from './WebChatLog/config';
+import { WebChatLogTabConfig } from './WebchatLog/config';
import { RuntimeOutputTabConfig } from './RuntimeOutputLog';
const implementedDebugExtensions: TabExtensionConfig[] = [
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index b6c307b782..f8caada6b0 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -30,6 +30,7 @@ import { generateSkillManifest } from './generateSkillManifest';
import { editorSteps, ManifestEditorSteps, order, VERSION_REGEX } from './constants';
import { mergePropertiesManagedByRootBot } from '../../../recoilModel/dispatchers/utils/project';
import { cloneDeep } from 'lodash';
+import { isUsingAdaptiveRuntime } from '@bfc/shared';
interface ExportSkillModalProps {
isOpen: boolean;
@@ -63,19 +64,27 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const settings = useRecoilValue(settingsState(projectId));
const rootBotProjectId = useRecoilValue(rootBotProjectIdSelector) || '';
const mergedSettings = mergePropertiesManagedByRootBot(projectId, rootBotProjectId, settings);
- const { skillConfiguration } = mergedSettings;
+ const { skillConfiguration, runtime, runtimeSettings } = mergedSettings;
const { setSettings } = useRecoilValue(dispatcherState);
- const [callers, setCallers] = useState(skillConfiguration?.allowedCallers ?? []);
+ const isAdaptive = isUsingAdaptiveRuntime(runtime);
+ const [callers, setCallers] = useState(
+ !isAdaptive ? skillConfiguration?.allowedCallers : runtimeSettings?.skills?.allowedCallers ?? []
+ );
const updateAllowedCallers = React.useCallback(
(allowedCallers: string[] = []) => {
- const updatedSetting = {
- ...cloneDeep(mergedSettings),
- skillConfiguration: { ...skillConfiguration, allowedCallers },
- };
+ const updatedSetting = isAdaptive
+ ? {
+ ...cloneDeep(mergedSettings),
+ runtimeSettings: { skills: { allowedCallers } },
+ }
+ : {
+ ...cloneDeep(mergedSettings),
+ skillConfiguration: { ...skillConfiguration, allowedCallers },
+ };
setSettings(projectId, updatedSetting);
},
- [mergedSettings, projectId, skillConfiguration]
+ [mergedSettings, projectId, isAdaptive, skillConfiguration, runtimeSettings]
);
const handleGenerateManifest = () => {
From a634daa8760a66dea9c52a1cfd90885875af41c7 Mon Sep 17 00:00:00 2001
From: Lu Han <32191031+luhan2017@users.noreply.github.com>
Date: Mon, 12 Apr 2021 14:10:54 +0800
Subject: [PATCH 34/55] remove the physical file provider
---
runtime/dotnet/azurewebapp/Startup.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/runtime/dotnet/azurewebapp/Startup.cs b/runtime/dotnet/azurewebapp/Startup.cs
index a7b18b6ec0..2205860ec3 100644
--- a/runtime/dotnet/azurewebapp/Startup.cs
+++ b/runtime/dotnet/azurewebapp/Startup.cs
@@ -235,9 +235,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
// Expose static files in manifests folder for skill scenarios.
app.UseStaticFiles(new StaticFileOptions
{
- FileProvider = new PhysicalFileProvider(
- Path.Combine(env.WebRootPath, "manifests")),
- RequestPath = "/manifests",
ContentTypeProvider = provider
});
From b29bdfba1f6d55dab6cbdfc26ca1120c10539a9e Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Mon, 12 Apr 2021 14:13:33 +0800
Subject: [PATCH 35/55] back button
---
.../content/SelectDialogs.tsx | 22 +++++++++--------
.../content/SelectTriggers.tsx | 24 ++++++++++---------
2 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
index 7c59a879f7..bd3e68bf76 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
@@ -138,16 +138,18 @@ export const SelectDialogs: React.FC = ({ selectedDialogs, setSele
[projectId]
);
- const selection = useMemo(() => {
- const listSelection = new Selection({
- onSelectionChanged: () => {
- const selectedItems = listSelection.getSelection();
- setSelectedDialogs(selectedItems);
- },
- });
- listSelection.setItems(selectedDialogs);
- listSelection.setAllSelected(true);
- return listSelection;
+ const selection = new Selection({
+ getKey: (item) => item.id,
+ onSelectionChanged: () => {
+ const selectedItems = selection.getSelection();
+ setSelectedDialogs(selectedItems);
+ },
+ });
+
+ useEffect(() => {
+ for (const item of selectedDialogs) {
+ selection.setKeySelected(selection.getKey(item), true, false);
+ }
}, []);
return ;
};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
index 9275a884a9..888d2296aa 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
@@ -3,7 +3,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
-import React, { useMemo } from 'react';
+import React, { useEffect, useMemo } from 'react';
import { DialogInfo, ITrigger, SDKKinds, getFriendlyName } from '@bfc/shared';
import { Selection } from 'office-ui-fabric-react/lib/DetailsList';
import { useRecoilValue } from 'recoil';
@@ -80,16 +80,18 @@ export const SelectTriggers: React.FC = ({ selectedTriggers, setSe
},
];
- const selection = useMemo(() => {
- const listSelection = new Selection({
- onSelectionChanged: () => {
- const selectedItems = listSelection.getSelection();
- setSelectedTriggers(selectedItems);
- },
- });
- listSelection.setItems(selectedTriggers);
- listSelection.setAllSelected(true);
- return listSelection;
+ const selection = new Selection({
+ getKey: (item) => item.id,
+ onSelectionChanged: () => {
+ const selectedItems = selection.getSelection();
+ setSelectedTriggers(selectedItems);
+ },
+ });
+
+ useEffect(() => {
+ for (const item of selectedTriggers) {
+ selection.setKeySelected(selection.getKey(item), true, false);
+ }
}, []);
return ;
From 8bd1ff51999a56744314f454a53e5afd8eaa2967 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Mon, 12 Apr 2021 16:03:25 +0800
Subject: [PATCH 36/55] default select publish profie
---
.../design/DebugPanel/TabExtensions/index.ts | 2 +-
.../exportSkillModal/content/SelectDialogs.tsx | 18 +++++++++++-------
.../exportSkillModal/content/SelectProfile.tsx | 3 ++-
.../content/SelectTriggers.tsx | 18 +++++++++++-------
.../pages/design/exportSkillModal/index.tsx | 2 +-
5 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
index 8d33f1ae8c..f17f2ca037 100644
--- a/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
+++ b/Composer/packages/client/src/pages/design/DebugPanel/TabExtensions/index.ts
@@ -3,7 +3,7 @@
import { TabExtensionConfig } from './types';
import { DiagnosticsTabConfig } from './DiagnosticsTab';
-import { WebChatLogTabConfig } from './WebchatLog/config';
+import { WebChatLogTabConfig } from './WebChatLog/config';
import { RuntimeOutputTabConfig } from './RuntimeOutputLog';
const implementedDebugExtensions: TabExtensionConfig[] = [
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
index bd3e68bf76..3cdc0c97eb 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
@@ -138,13 +138,17 @@ export const SelectDialogs: React.FC = ({ selectedDialogs, setSele
[projectId]
);
- const selection = new Selection({
- getKey: (item) => item.id,
- onSelectionChanged: () => {
- const selectedItems = selection.getSelection();
- setSelectedDialogs(selectedItems);
- },
- });
+ const selection = useMemo(
+ () =>
+ new Selection({
+ getKey: (item) => item.id,
+ onSelectionChanged: () => {
+ const selectedItems = selection.getSelection();
+ setSelectedDialogs(selectedItems);
+ },
+ }),
+ []
+ );
useEffect(() => {
for (const item of selectedDialogs) {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index d3f09d25a6..d0f6f5ff6f 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -137,9 +137,10 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
);
const publishingOptions = useMemo(() => {
- return publishingTargets.map((t) => ({
+ return publishingTargets.map((t, index) => ({
key: t.name,
text: t.name,
+ selected: !index,
}));
}, [publishingTargets]);
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
index 888d2296aa..10de552175 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
@@ -80,13 +80,17 @@ export const SelectTriggers: React.FC = ({ selectedTriggers, setSe
},
];
- const selection = new Selection({
- getKey: (item) => item.id,
- onSelectionChanged: () => {
- const selectedItems = selection.getSelection();
- setSelectedTriggers(selectedItems);
- },
- });
+ const selection = useMemo(
+ () =>
+ new Selection({
+ getKey: (item) => item.id,
+ onSelectionChanged: () => {
+ const selectedItems = selection.getSelection();
+ setSelectedTriggers(selectedItems);
+ },
+ }),
+ []
+ );
useEffect(() => {
for (const item of selectedTriggers) {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index f8caada6b0..55bf31200e 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -27,7 +27,7 @@ import {
import { styles } from './styles';
import { generateSkillManifest } from './generateSkillManifest';
-import { editorSteps, ManifestEditorSteps, order, VERSION_REGEX } from './constants';
+import { editorSteps, ManifestEditorSteps, order } from './constants';
import { mergePropertiesManagedByRootBot } from '../../../recoilModel/dispatchers/utils/project';
import { cloneDeep } from 'lodash';
import { isUsingAdaptiveRuntime } from '@bfc/shared';
From 897e6d71c31de172d3038f391c1046b13d8be268 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Mon, 12 Apr 2021 16:14:55 +0800
Subject: [PATCH 37/55] disabled generated & publish button when no profie
---
.../src/pages/design/exportSkillModal/constants.tsx | 1 +
.../src/pages/design/exportSkillModal/index.tsx | 13 +++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index d952af7b83..747864f6f0 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -222,6 +222,7 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
cancelButton,
backButton,
{
+ disabled: ({ publishTargets }) => publishTargets.length === 0,
primary: true,
text: () => formatMessage('Generate and Publish'),
onClick: ({ generateManifest, onNext, onPublish }) => () => {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 55bf31200e..901a89c510 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -64,7 +64,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const settings = useRecoilValue(settingsState(projectId));
const rootBotProjectId = useRecoilValue(rootBotProjectIdSelector) || '';
const mergedSettings = mergePropertiesManagedByRootBot(projectId, rootBotProjectId, settings);
- const { skillConfiguration, runtime, runtimeSettings } = mergedSettings;
+ const { skillConfiguration, runtime, runtimeSettings, publishTargets } = mergedSettings;
const { setSettings } = useRecoilValue(dispatcherState);
const isAdaptive = isUsingAdaptiveRuntime(runtime);
const [callers, setCallers] = useState(
@@ -218,7 +218,16 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
{buttons.map(({ disabled, primary, text, onClick }, index) => {
const Button = primary ? PrimaryButton : DefaultButton;
- const isDisabled = typeof disabled === 'function' ? disabled({ manifest: skillManifest }) : !!disabled;
+
+ let isDisabled = false;
+ if (typeof disabled === 'function') {
+ isDisabled =
+ editorStep === ManifestEditorSteps.SELECT_MANIFEST
+ ? disabled({ manifest: skillManifest })
+ : disabled({ publishTargets });
+ } else {
+ isDisabled = !!disabled;
+ }
return (
Date: Mon, 12 Apr 2021 17:51:54 +0800
Subject: [PATCH 38/55] url wrong
---
.../pages/design/exportSkillModal/content/SelectProfile.tsx | 4 ++--
Composer/packages/client/src/pages/publish/Publish.tsx | 4 +++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index d0f6f5ff6f..7b5b850a1c 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -137,10 +137,9 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
);
const publishingOptions = useMemo(() => {
- return publishingTargets.map((t, index) => ({
+ return publishingTargets.map((t) => ({
key: t.name,
text: t.name,
- selected: !index,
}));
}, [publishingTargets]);
@@ -165,6 +164,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
label={formatMessage('Publishing Profile')}
options={publishingOptions}
placeholder={'Select one'}
+ selectedKey={publishingOptions[0].key}
styles={{ root: { paddingBottom: '8px' } }}
onChange={updateCurrentProfile}
/>
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index a7af062450..c9e5eb889a 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -141,6 +141,7 @@ const Publish: React.FC {
if (publishTargetName && botStatusList.length > 0 && skillPublishStatus === SKILL_PUBLISH_STATUS.INITIAL) {
@@ -149,6 +150,7 @@ const Publish: React.FC
Date: Mon, 12 Apr 2021 17:57:08 +0800
Subject: [PATCH 39/55] default publish target
---
.../content/SelectProfile.tsx | 50 ++++++++++---------
1 file changed, 27 insertions(+), 23 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index 7b5b850a1c..07c220402e 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -90,33 +90,36 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const target = publishingTargets.find((t) => {
return t.name === option?.key;
});
- if (target) {
- setCurrentTarget(target);
- updateCurrentTarget(projectId, target);
- const config = JSON.parse(target.configuration);
- setEndpointUrl(`https://${config.hostname}.azurewebsites.net/api/messages`);
- setAppId(config.settings.MicrosoftAppId);
-
- setSkillManifest({
- content: {
- ...rest,
- endpoints: [
- {
- protocol: 'BotFrameworkV3',
- name: option?.key,
- endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
- description: '',
- msAppId: config.settings.MicrosoftAppId,
- },
- ],
- },
- id: id,
- });
- }
+ setCurrentTarget(target);
},
[publishingTargets]
);
+ useEffect(() => {
+ if (currentTarget) {
+ setCurrentTarget(currentTarget);
+ updateCurrentTarget(projectId, currentTarget);
+ const config = JSON.parse(currentTarget.configuration);
+ setEndpointUrl(`https://${config.hostname}.azurewebsites.net/api/messages`);
+ setAppId(config.settings.MicrosoftAppId);
+
+ setSkillManifest({
+ content: {
+ ...rest,
+ endpoints: [
+ {
+ protocol: 'BotFrameworkV3',
+ name: currentTarget.name,
+ endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
+ description: '',
+ msAppId: config.settings.MicrosoftAppId,
+ },
+ ],
+ },
+ id: id,
+ });
+ }
+ }, [currentTarget]);
const isProfileValid = useMemo(
() => () => {
if (!publishingTargets) {
@@ -147,6 +150,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
useEffect(() => {
setPublishingTargets(settings.publishTargets || []);
+ setCurrentTarget(settings.publishTargets[0]);
}, [settings]);
useEffect(() => {
From 738a163b3de47c87d0c8bc3a25e8e2b1f05d38a7 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Mon, 12 Apr 2021 19:59:27 +0800
Subject: [PATCH 40/55] callers error
---
.../client/src/pages/design/exportSkillModal/index.tsx | 2 +-
Composer/packages/client/src/pages/publish/Publish.tsx | 7 +++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index 901a89c510..8807d6028b 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -76,7 +76,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const updatedSetting = isAdaptive
? {
...cloneDeep(mergedSettings),
- runtimeSettings: { skills: { allowedCallers } },
+ runtimeSettings: { ...runtimeSettings, skills: { ...runtimeSettings.skills, allowedCallers } },
}
: {
...cloneDeep(mergedSettings),
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index c9e5eb889a..edea342838 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -231,8 +231,11 @@ const Publish: React.FC
Date: Mon, 12 Apr 2021 20:48:04 +0800
Subject: [PATCH 41/55] add create publish profile dialog
---
.../botProject/CreatePublishProfileDialog.tsx | 113 ++++++++++++++++++
.../content/SelectProfile.tsx | 6 +-
2 files changed, 116 insertions(+), 3 deletions(-)
create mode 100644 Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
diff --git a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
new file mode 100644
index 0000000000..539444ce6d
--- /dev/null
+++ b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
@@ -0,0 +1,113 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+/** @jsx jsx */
+import React, { Fragment, useState, useEffect } from 'react';
+import { jsx } from '@emotion/core';
+import { useRecoilValue } from 'recoil';
+import { PublishTarget } from '@bfc/shared';
+import formatMessage from 'format-message';
+import { ActionButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
+
+import { dispatcherState, settingsState, publishTypesState } from '../../recoilModel';
+import { AuthDialog } from '../../components/Auth/AuthDialog';
+import { isShowAuthDialog } from '../../utils/auth';
+
+import { PublishProfileDialog } from './create-publish-profile/PublishProfileDialog';
+import { actionButton } from './styles';
+import { useBoolean } from '@uifabric/react-hooks';
+import Dialog, { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
+import { styles } from '../design/styles';
+
+// -------------------- CreatePublishProfileDialog -------------------- //
+
+type CreatePublishProfileDialogProps = {
+ projectId: string;
+ scrollToSectionId?: string;
+};
+
+export const CreatePublishProfileDialog: React.FC = (props) => {
+ const { projectId } = props;
+ const { publishTargets } = useRecoilValue(settingsState(projectId));
+ const { getPublishTargetTypes, setPublishTargets } = useRecoilValue(dispatcherState);
+ const publishTypes = useRecoilValue(publishTypesState(projectId));
+
+ const [dialogHidden, setDialogHidden] = useState(true);
+ const [showAuthDialog, setShowAuthDialog] = useState(false);
+ const [hideDialog, { toggle: toggleHideDialog }] = useBoolean(false);
+
+ const dialogTitle = {
+ title: formatMessage('Create a publish profile to continue'),
+ subText: formatMessage(
+ 'To make your bot available as a remote skill you will need to provision Azure resources . This process may take a few minutes depending on the resources you select.'
+ ),
+ };
+ const [current, setCurrent] = useState<{ index: number; item: PublishTarget } | null>(null);
+
+ useEffect(() => {
+ if (projectId) {
+ getPublishTargetTypes(projectId);
+ }
+ }, [projectId]);
+
+ return (
+
+
+
+
{
+ if (isShowAuthDialog(true)) {
+ setShowAuthDialog(true);
+ } else {
+ setDialogHidden(false);
+ }
+ }}
+ >
+ {formatMessage('Create new publish profile')}
+
+
+
+
+
+
+ {showAuthDialog && (
+ {
+ setDialogHidden(false);
+ }}
+ onDismiss={() => {
+ setShowAuthDialog(false);
+ }}
+ />
+ )}
+ {!dialogHidden ? (
+ {
+ setDialogHidden(true);
+ // reset current
+ setCurrent(null);
+ }}
+ current={current}
+ projectId={projectId}
+ setPublishTargets={setPublishTargets}
+ targets={publishTargets || []}
+ types={publishTypes}
+ />
+ ) : null}
+
+ );
+};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index 07c220402e..1a03a97161 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -10,7 +10,7 @@ import React, { useEffect, useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { botDisplayNameState, dispatcherState, settingsState, skillManifestsState } from '../../../../recoilModel';
-import { PublishTargets } from '../../../botProject/PublishTargets';
+import { CreatePublishProfileDialog } from '../../../botProject/CreatePublishProfileDialog';
import { iconStyle } from '../../../botProject/runtime-settings/style';
import { ContentProps, VERSION_REGEX } from '../constants';
@@ -150,7 +150,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
useEffect(() => {
setPublishingTargets(settings.publishTargets || []);
- setCurrentTarget(settings.publishTargets[0]);
+ setCurrentTarget((settings.publishTargets || [])[0]);
}, [settings]);
useEffect(() => {
@@ -195,7 +195,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
) : (
);
};
From 39c6543b2404e59e2269580a01262968ea115c42 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Tue, 13 Apr 2021 17:28:13 +0800
Subject: [PATCH 42/55] comments
---
.../botProject/CreatePublishProfileDialog.tsx | 13 +-
.../design/exportSkillModal/constants.tsx | 36 +---
.../exportSkillModal/content/AddCallers.tsx | 10 +-
.../content/FetchManifestSchema.tsx | 28 ---
.../content/SelectManifest.tsx | 171 ------------------
.../content/SelectProfile.tsx | 82 +++++----
.../design/exportSkillModal/content/index.ts | 2 -
extensions/azurePublish/src/node/deploy.ts | 7 +-
8 files changed, 60 insertions(+), 289 deletions(-)
delete mode 100644 Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx
delete mode 100644 Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx
diff --git a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
index 539444ce6d..7a6719f68d 100644
--- a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
+++ b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
@@ -17,7 +17,6 @@ import { PublishProfileDialog } from './create-publish-profile/PublishProfileDia
import { actionButton } from './styles';
import { useBoolean } from '@uifabric/react-hooks';
import Dialog, { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
-import { styles } from '../design/styles';
// -------------------- CreatePublishProfileDialog -------------------- //
@@ -42,7 +41,9 @@ export const CreatePublishProfileDialog: React.FC(null);
+ const [currentPublishProfile, setCurrentPublishProfile] = useState<{ index: number; item: PublishTarget } | null>(
+ null
+ );
useEffect(() => {
if (projectId) {
@@ -74,13 +75,14 @@ export const CreatePublishProfileDialog: React.FC
{formatMessage('Create new publish profile')}
-
+
{showAuthDialog && (
@@ -99,9 +101,10 @@ export const CreatePublishProfileDialog: React.FC {
setDialogHidden(true);
// reset current
- setCurrent(null);
+ toggleHideDialog();
+ setCurrentPublishProfile(null);
}}
- current={current}
+ current={currentPublishProfile}
projectId={projectId}
setPublishTargets={setPublishTargets}
targets={publishTargets || []}
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 747864f6f0..a71bcc6815 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -9,15 +9,7 @@ import { SDKKinds } from '@bfc/shared';
import { nameRegex } from '../../../constants';
-import {
- Description,
- FetchManifestSchema,
- ReviewManifest,
- SaveManifest,
- SelectDialogs,
- SelectManifest,
- SelectTriggers,
-} from './content';
+import { Description, ReviewManifest, SaveManifest, SelectDialogs, SelectTriggers } from './content';
import { SelectProfile } from './content/SelectProfile';
import { AddCallers } from './content/AddCallers';
@@ -131,11 +123,9 @@ interface EditorStep {
}
export enum ManifestEditorSteps {
- FETCH_MANIFEST_SCHEMA = 'FETCH_MANIFEST_SCHEMA',
MANIFEST_DESCRIPTION = 'MANIFEST_DESCRIPTION',
MANIFEST_REVIEW = 'MANIFEST_REVIEW',
SAVE_MANIFEST = 'SAVE_MANIFEST',
- SELECT_MANIFEST = 'SELECT_MANIFEST',
SELECT_DIALOGS = 'SELECT_DIALOGS',
SELECT_TRIGGERS = 'SELECT_TRIGGERS',
SELECT_PROFILE = 'SELECT_PROFILE',
@@ -143,8 +133,6 @@ export enum ManifestEditorSteps {
}
export const order: ManifestEditorSteps[] = [
- // ManifestEditorSteps.SELECT_MANIFEST,
- // ManifestEditorSteps.FETCH_MANIFEST_SCHEMA,
ManifestEditorSteps.MANIFEST_DESCRIPTION,
ManifestEditorSteps.SELECT_DIALOGS,
ManifestEditorSteps.SELECT_TRIGGERS,
@@ -187,28 +175,6 @@ const validate = ({ content, schema }) => {
};
export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
- [ManifestEditorSteps.SELECT_MANIFEST]: {
- buttons: [
- cancelButton,
- {
- disabled: ({ manifest }) => !manifest?.id,
- primary: true,
- text: () => formatMessage('Edit'),
- onClick: ({ onNext, manifest }) => () => {
- onNext({ id: manifest?.id });
- },
- },
- ],
- content: SelectManifest,
- editJson: false,
- subText: () => formatMessage('Create a new skill manifest or select which one you want to edit'),
- title: () => formatMessage('Create or edit skill manifest'),
- },
- [ManifestEditorSteps.FETCH_MANIFEST_SCHEMA]: {
- content: FetchManifestSchema,
- editJson: false,
- title: () => formatMessage('Select manifest version'),
- },
[ManifestEditorSteps.MANIFEST_DESCRIPTION]: {
buttons: [cancelButton, nextButton],
content: Description,
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
index 6c81d42d03..9fc59705d3 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -38,11 +38,10 @@ const removeCaller = {
export const AddCallers: React.FC = ({ projectId, callers, setCallers }) => {
const handleRemove = (index) => {
- var currentCallers = callers.slice();
- currentCallers?.splice(index, 1);
+ const currentCallers = callers.splice(index, 1);
setCallers(currentCallers);
};
- const handleAdd = () => {
+ const handleAddNewAllowedCallerClick = () => {
var currentCallers = callers.slice();
currentCallers?.push('0000-11111-00000-11111');
setCallers(currentCallers);
@@ -65,7 +64,7 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
setCallers(currentCallers);
}}
borderless
- >
+ />
handleRemove(index)}>
@@ -76,10 +75,9 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
);
})}
{
- handleAdd();
+ handleAddNewAllowedCallerClick();
}}
>
{formatMessage('Add allowed callers')}
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx
deleted file mode 100644
index ff2d1fc9d6..0000000000
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import React, { useEffect } from 'react';
-
-import { LoadingSpinner } from '../../../../components/LoadingSpinner';
-import { ContentProps } from '../constants';
-
-export const FetchManifestSchema: React.FC = ({ completeStep, editJson, value, setSchema }) => {
- useEffect(() => {
- (async function () {
- try {
- if (value?.$schema) {
- const res = await fetch(value.$schema);
- const schema = await res.json();
- setSchema(schema);
- completeStep();
- } else {
- editJson();
- }
- } catch (error) {
- editJson();
- }
- })();
- }, [value]);
-
- return ;
-};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx
deleted file mode 100644
index 0fb117aeaf..0000000000
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-/** @jsx jsx */
-import { css, jsx } from '@emotion/core';
-import React, { useMemo, useState } from 'react';
-import { Dropdown, IDropdownOption, ResponsiveMode } from 'office-ui-fabric-react/lib/Dropdown';
-import { Label } from 'office-ui-fabric-react/lib/Label';
-import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
-import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
-import { ScrollablePane, ScrollbarVisibility } from 'office-ui-fabric-react/lib/ScrollablePane';
-import {
- CheckboxVisibility,
- DetailsList,
- DetailsListLayoutMode,
- SelectionMode,
-} from 'office-ui-fabric-react/lib/DetailsList';
-import { TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
-import formatMessage from 'format-message';
-
-import { calculateTimeDiff } from '../../../../utils/fileUtil';
-import { ContentProps, SCHEMA_URIS, VERSION_REGEX } from '../constants';
-
-const styles = {
- detailListContainer: css`
- position: relative;
- max-height: 40vh;
- padding-top: 10px;
- overflow: hidden;
- flex-grow: 1;
- min-height: 250px;
- `,
- create: css`
- display: flex;
- `,
-};
-
-export const SelectManifest: React.FC = ({ completeStep, skillManifests, setSkillManifest }) => {
- const [manifestVersion, setManifestVersion] = useState(SCHEMA_URIS[0]);
- const [errors, setErrors] = useState<{ version?: string }>({});
- const [version] = useMemo(() => VERSION_REGEX.exec(manifestVersion) || [''], []);
-
- const options: IDropdownOption[] = useMemo(
- () =>
- SCHEMA_URIS.map((key, index) => {
- const [version] = VERSION_REGEX.exec(key) || [];
-
- return {
- text: formatMessage('Version {version}', { version }),
- key,
- selected: !index,
- };
- }),
- []
- );
-
- const handleChange = (_e: React.FormEvent, option?: IDropdownOption) => {
- if (option) {
- setManifestVersion(option.key as string);
- }
- };
-
- const handleCreate = () => {
- if (!version) {
- setErrors({ version: formatMessage('Please select a version of the manifest schema') });
- return;
- }
- setSkillManifest({ content: { $schema: manifestVersion } });
- completeStep();
- };
-
- // for detail file list in open panel
- const tableColumns = [
- {
- key: 'column1',
- name: formatMessage('Name'),
- fieldName: 'id',
- minWidth: 300,
- maxWidth: 350,
- isRowHeader: true,
- isResizable: true,
- isSorted: true,
- isSortedDescending: false,
- sortAscendingAriaLabel: formatMessage('Sorted A to Z'),
- sortDescendingAriaLabel: formatMessage('Sorted Z to A'),
- data: 'string',
- onRender: (item) => {
- return {item.id} ;
- },
- isPadded: true,
- },
- {
- key: 'column2',
- name: formatMessage('Date Modified'),
- fieldName: 'lastModified',
- minWidth: 60,
- maxWidth: 70,
- isResizable: true,
- data: 'number',
- onRender: (item) => {
- return {calculateTimeDiff(item.lastModified)} ;
- },
- isPadded: true,
- },
- ];
-
- function onRenderDetailsHeader(props, defaultRender) {
- return (
-
- {defaultRender({
- ...props,
- onRenderColumnHeaderTooltip: (tooltipHostProps) => ,
- })}
-
- );
- }
-
- return (
-
-
-
- {formatMessage('Manifest Version')}
-
-
-
-
- {formatMessage('Create')}
-
-
-
-
-
- item.name}
- items={skillManifests}
- layoutMode={DetailsListLayoutMode.justified}
- selectionMode={SelectionMode.single}
- onActiveItemChanged={setSkillManifest}
- onRenderDetailsHeader={onRenderDetailsHeader}
- />
-
-
-
- );
-};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index 1a03a97161..cf92828e5b 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -6,7 +6,7 @@ import { jsx } from '@emotion/core';
import { PublishTarget, SkillManifestFile } from '@bfc/shared';
import formatMessage from 'format-message';
import { css, Dropdown, Icon, IDropdownOption, TextField, TooltipHost } from 'office-ui-fabric-react';
-import React, { useEffect, useMemo, useState } from 'react';
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { botDisplayNameState, dispatcherState, settingsState, skillManifestsState } from '../../../../recoilModel';
@@ -39,8 +39,7 @@ const onRenderLabel = (props) => {
>
{props.label}
@@ -63,7 +62,7 @@ export const getManifestId = (
let fileId = version ? `${botName}-${version.replace(/\./g, '-')}-manifest` : `${botName}-manifest`;
let i = -1;
- while (skillManifests.some(({ id }) => id === fileId)) {
+ while (skillManifests.some(({ id }) => id === fileId) && i < skillManifests.length) {
if (i < 0) {
fileId = fileId.concat(`-${++i}`);
} else {
@@ -78,6 +77,7 @@ export const SelectProfile: React.FC
= ({ manifest, setSkillManife
const [publishingTargets, setPublishingTargets] = useState([]);
const [currentTarget, setCurrentTarget] = useState();
const { updateCurrentTarget } = useRecoilValue(dispatcherState);
+ const settings = useRecoilValue(settingsState(projectId));
const [endpointUrl, setEndpointUrl] = useState();
const [appId, setAppId] = useState();
const { id, content } = manifest;
@@ -85,7 +85,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const skillManifests = useRecoilValue(skillManifestsState(projectId));
const { ...rest } = content;
- const updateCurrentProfile = useMemo(
+ const handleCurrentProfileChange = useMemo(
() => (_e, option?: IDropdownOption) => {
const target = publishingTargets.find((t) => {
return t.name === option?.key;
@@ -96,32 +96,36 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
);
useEffect(() => {
- if (currentTarget) {
- setCurrentTarget(currentTarget);
- updateCurrentTarget(projectId, currentTarget);
- const config = JSON.parse(currentTarget.configuration);
- setEndpointUrl(`https://${config.hostname}.azurewebsites.net/api/messages`);
- setAppId(config.settings.MicrosoftAppId);
-
- setSkillManifest({
- content: {
- ...rest,
- endpoints: [
- {
- protocol: 'BotFrameworkV3',
- name: currentTarget.name,
- endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
- description: '',
- msAppId: config.settings.MicrosoftAppId,
- },
- ],
- },
- id: id,
- });
+ try {
+ if (currentTarget) {
+ setCurrentTarget(currentTarget);
+ updateCurrentTarget(projectId, currentTarget);
+ const config = JSON.parse(currentTarget.configuration);
+ setEndpointUrl(`https://${config.hostname}.azurewebsites.net/api/messages`);
+ setAppId(config.settings.MicrosoftAppId);
+
+ setSkillManifest({
+ content: {
+ ...rest,
+ endpoints: [
+ {
+ protocol: 'BotFrameworkV3',
+ name: currentTarget.name,
+ endpointUrl: `https://${config.hostname}.azurewebsites.net/api/messages`,
+ description: '',
+ msAppId: config.settings.MicrosoftAppId,
+ },
+ ],
+ },
+ id: id,
+ });
+ }
+ } catch (err) {
+ console.log(err.message);
}
}, [currentTarget]);
- const isProfileValid = useMemo(
- () => () => {
+ const isProfileValid = useMemo(() => {
+ try {
if (!publishingTargets) {
return false;
}
@@ -135,9 +139,11 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
);
});
return filteredProfile.length > 0;
- },
- [publishingTargets]
- );
+ } catch (err) {
+ console.log(err.message);
+ return false;
+ }
+ }, [publishingTargets]);
const publishingOptions = useMemo(() => {
return publishingTargets.map((t) => ({
@@ -146,8 +152,6 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
}));
}, [publishingTargets]);
- const settings = useRecoilValue(settingsState(projectId));
-
useEffect(() => {
setPublishingTargets(settings.publishTargets || []);
setCurrentTarget((settings.publishTargets || [])[0]);
@@ -160,24 +164,24 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
}
}, []);
- return isProfileValid() ? (
+ return isProfileValid ? (
= ({ manifest, setSkillManife
required
ariaLabel={formatMessage('The app id of your application registration')}
label={formatMessage('Microsoft App Id')}
- placeholder={'The app id'}
+ placeholder={formatMessage('The app id')}
styles={{ root: { paddingBottom: '8px' } }}
value={appId}
onRenderLabel={onRenderLabel}
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/index.ts b/Composer/packages/client/src/pages/design/exportSkillModal/content/index.ts
index 94ea08db69..d0ea0a1c97 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/index.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/index.ts
@@ -3,9 +3,7 @@
export * from './Description';
export * from './Endpoints';
-export * from './FetchManifestSchema';
export * from './ReviewManifest';
export * from './SaveManifest';
-export * from './SelectManifest';
export * from './SelectDialogs';
export * from './SelectTriggers';
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index 42b1d1ab4b..943b081b21 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -17,6 +17,7 @@ import { AzurePublishErrors, createCustomizeError, stringifyError } from './util
import { copyDir } from './utils/copyDir';
import { KeyVaultApi } from './keyvaultHelper/keyvaultApi';
import { KeyVaultApiConfig } from './keyvaultHelper/keyvaultApiConfig';
+import { DialogSetting } from '@botframework-composer/types';
export class BotProjectDeploy {
private accessToken: string;
@@ -45,7 +46,7 @@ export class BotProjectDeploy {
*/
public async deploy(
project: any,
- settings: any,
+ settings: DialogSetting,
profileName: string,
name: string,
environment: string,
@@ -181,13 +182,13 @@ export class BotProjectDeploy {
hostname: string,
msAppId: string,
skillSettingsPath: string,
- settings: any
+ settings: DialogSetting
) {
const manifestFiles = (await fs.readdir(skillSettingsPath)).filter((x) => x.endsWith('.json'));
if (manifestFiles.length === 0) {
this.logger({
status: BotProjectDeployLoggerType.DEPLOY_INFO,
- message: `The manifest does not exsit on path: ${skillSettingsPath}`,
+ message: `The manifest does not exist on path: ${skillSettingsPath}`,
});
return;
}
From c45e63b7e8519e96e521712d1b23a67b52b1eed4 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Tue, 13 Apr 2021 17:40:30 +0800
Subject: [PATCH 43/55] callers
---
.../src/pages/design/exportSkillModal/content/AddCallers.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
index 9fc59705d3..a9fdfc201d 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -38,8 +38,7 @@ const removeCaller = {
export const AddCallers: React.FC = ({ projectId, callers, setCallers }) => {
const handleRemove = (index) => {
- const currentCallers = callers.splice(index, 1);
- setCallers(currentCallers);
+ setCallers(callers.filter((_, i) => i !== index));
};
const handleAddNewAllowedCallerClick = () => {
var currentCallers = callers.slice();
From 517286f995547370d52bebb32fb9035c55b766a0 Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Tue, 13 Apr 2021 18:23:09 +0800
Subject: [PATCH 44/55] lint
---
.../botProject/CreatePublishProfileDialog.tsx | 6 +++---
.../exportSkillModal/content/AddCallers.tsx | 9 ++++++---
.../exportSkillModal/content/Description.tsx | 8 ++++----
.../content/SelectProfile.tsx | 9 ++++++---
.../pages/design/exportSkillModal/index.tsx | 20 ++++++-------------
.../src/pages/publish/BotStatusList.tsx | 6 +++---
.../src/pages/publish/Notifications.tsx | 4 ++--
7 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
index 7a6719f68d..6e8649fc06 100644
--- a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
+++ b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
@@ -8,6 +8,8 @@ import { useRecoilValue } from 'recoil';
import { PublishTarget } from '@bfc/shared';
import formatMessage from 'format-message';
import { ActionButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
+import { useBoolean } from '@uifabric/react-hooks';
+import Dialog, { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
import { dispatcherState, settingsState, publishTypesState } from '../../recoilModel';
import { AuthDialog } from '../../components/Auth/AuthDialog';
@@ -15,8 +17,6 @@ import { isShowAuthDialog } from '../../utils/auth';
import { PublishProfileDialog } from './create-publish-profile/PublishProfileDialog';
import { actionButton } from './styles';
-import { useBoolean } from '@uifabric/react-hooks';
-import Dialog, { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
// -------------------- CreatePublishProfileDialog -------------------- //
@@ -82,7 +82,7 @@ export const CreatePublishProfileDialog: React.FC
-
+
{showAuthDialog && (
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
index a9fdfc201d..451038eb8b 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -5,8 +5,11 @@
import { jsx } from '@emotion/core';
import { SharedColors } from '@uifabric/fluent-theme';
import formatMessage from 'format-message';
-import { ActionButton, css, FontWeights, TextField } from 'office-ui-fabric-react';
+import { ActionButton } from 'office-ui-fabric-react/lib/Button';
+import { FontWeights } from 'office-ui-fabric-react/lib/Styling';
+import { TextField } from 'office-ui-fabric-react/lib/TextField';
import React from 'react';
+
import { tableColumnHeader, tableRow, tableRowItem } from '../../../botProject/styles';
import { ContentProps } from '../constants';
@@ -41,7 +44,7 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
setCallers(callers.filter((_, i) => i !== index));
};
const handleAddNewAllowedCallerClick = () => {
- var currentCallers = callers.slice();
+ const currentCallers = callers.slice();
currentCallers?.push('0000-11111-00000-11111');
setCallers(currentCallers);
};
@@ -56,13 +59,13 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
{
const currentCallers = callers.slice();
currentCallers[index] = newValue ?? '';
setCallers(currentCallers);
}}
- borderless
/>
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
index 2178682c70..1f83649d05 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
@@ -9,14 +9,14 @@ import { FieldProps, JSONSchema7, UIOptions } from '@bfc/extension-client';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { useRecoilValue } from 'recoil';
import { v4 as uuid } from 'uuid';
-
-import { ContentProps, SCHEMA_URIS, VERSION_REGEX } from '../constants';
-import { botDisplayNameState } from '../../../../recoilModel';
import { Label } from 'office-ui-fabric-react/lib/Label';
import formatMessage from 'format-message';
import { Dropdown, IDropdownOption, ResponsiveMode } from 'office-ui-fabric-react/lib/Dropdown';
import { LoadingSpinner } from '@bfc/ui-shared/lib/components/LoadingSpinner';
+import { botDisplayNameState } from '../../../../recoilModel';
+import { ContentProps, SCHEMA_URIS, VERSION_REGEX } from '../constants';
+
const styles = {
row: css`
display: flex;
@@ -180,9 +180,9 @@ export const Description: React.FC = ({
{formatMessage('Manifest Version')}
= ({ onSubmit, onDismiss
}}
>
= ({ onSubmit, onDismiss
schema={schema}
selectedDialogs={selectedDialogs}
selectedTriggers={selectedTriggers}
+ setCallers={setCallers}
setErrors={setErrors}
setSchema={setSchema}
setSelectedDialogs={setSelectedDialogs}
@@ -208,8 +210,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
setSkillManifest={setSkillManifest}
skillManifests={skillManifests}
value={content}
- callers={callers}
- setCallers={setCallers}
onChange={(manifestContent) => setSkillManifest({ ...skillManifest, content: manifestContent })}
/>
@@ -219,15 +219,7 @@ const ExportSkillModal: React.FC
= ({ onSubmit, onDismiss
{buttons.map(({ disabled, primary, text, onClick }, index) => {
const Button = primary ? PrimaryButton : DefaultButton;
- let isDisabled = false;
- if (typeof disabled === 'function') {
- isDisabled =
- editorStep === ManifestEditorSteps.SELECT_MANIFEST
- ? disabled({ manifest: skillManifest })
- : disabled({ publishTargets });
- } else {
- isDisabled = !!disabled;
- }
+ const isDisabled = typeof disabled === 'function' ? disabled({ publishTargets }) : !!disabled;
return (
= ({
onRender: (item: BotStatus) => {
return (
Date: Tue, 13 Apr 2021 23:12:55 +0800
Subject: [PATCH 45/55] lint fix
---
.../src/pages/design/exportSkillModal/content/AddCallers.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
index 451038eb8b..f8df2823c5 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -2,7 +2,7 @@
// Licensed under the MIT License.
/** @jsx jsx */
-import { jsx } from '@emotion/core';
+import { css, jsx } from '@emotion/core';
import { SharedColors } from '@uifabric/fluent-theme';
import formatMessage from 'format-message';
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
From c1539faace8c8ce63b966ef47fb350df05473e9b Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Wed, 14 Apr 2021 10:30:16 +0800
Subject: [PATCH 46/55] lint ignore
---
extensions/azurePublish/src/node/deploy.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index 943b081b21..f25d13542b 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -10,6 +10,7 @@ import archiver from 'archiver';
import { AzureBotService } from '@azure/arm-botservice';
import { TokenCredentials } from '@azure/ms-rest-js';
import { composeRenderFunction } from '@uifabric/utilities';
+import { DialogSetting } from '@botframework-composer/types';
import { BotProjectDeployConfig, BotProjectDeployLoggerType } from './types';
import { build, publishLuisToPrediction } from './luisAndQnA';
@@ -17,7 +18,6 @@ import { AzurePublishErrors, createCustomizeError, stringifyError } from './util
import { copyDir } from './utils/copyDir';
import { KeyVaultApi } from './keyvaultHelper/keyvaultApi';
import { KeyVaultApiConfig } from './keyvaultHelper/keyvaultApiConfig';
-import { DialogSetting } from '@botframework-composer/types';
export class BotProjectDeploy {
private accessToken: string;
@@ -184,6 +184,7 @@ export class BotProjectDeploy {
skillSettingsPath: string,
settings: DialogSetting
) {
+ /* eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe as no value holds user input */
const manifestFiles = (await fs.readdir(skillSettingsPath)).filter((x) => x.endsWith('.json'));
if (manifestFiles.length === 0) {
this.logger({
From a56ec8c8ef68f98eb24b4bfc737c433f20423707 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Wed, 14 Apr 2021 11:48:14 +0800
Subject: [PATCH 47/55] test case
---
.../__tests__/generateSkillManifest.test.ts | 70 +++++++++++++++----
.../src/pages/publish/BotStatusList.tsx | 3 +-
2 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/__tests__/generateSkillManifest.test.ts b/Composer/packages/client/src/pages/design/exportSkillModal/__tests__/generateSkillManifest.test.ts
index 47a857c5e7..0106f803e0 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/__tests__/generateSkillManifest.test.ts
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/__tests__/generateSkillManifest.test.ts
@@ -11,6 +11,14 @@ import {
generateDispatchModels,
} from '../generateSkillManifest';
+const projectId = '42345.23432';
+const currentTarget = {
+ configuration:
+ '{\n "name": "test",\n "environment": "composer",\n "tenantId": "aaa",\n "subscriptionId": "aaa",\n "resourceGroup": "testGroup",\n "botName": "test",\n "hostname": "test",\n "luisResource": "test",\n "runtimeIdentifier": "win-x64",\n "region": "westus",\n "settings": {\n "applicationInsights": {},\n "luis": {"authoringKey":"aaa", "endpointKey": "aaa",\n "endpoint": "https://westus.api.cognitive.microsoft.com/"\n },\n "qna": {},\n "MicrosoftAppId": "aaa",\n "MicrosoftAppPassword": "aaa"\n }\n}',
+ name: 'test',
+ type: 'azurePublish',
+ lastPublished: new Date('2021-04-08T08:38:17.566Z'),
+};
const dialogSchema = {
id: 'test',
content: {
@@ -188,7 +196,15 @@ describe('generateDispatchModels', () => {
const selectedTriggers = [];
const luFiles = [];
const qnaFiles = [];
- const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
+ const result = generateDispatchModels(
+ schema,
+ dialogs,
+ selectedTriggers,
+ luFiles,
+ qnaFiles,
+ currentTarget,
+ projectId
+ );
expect(result).toEqual({});
});
@@ -201,7 +217,15 @@ describe('generateDispatchModels', () => {
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles = [];
- const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
+ const result = generateDispatchModels(
+ schema,
+ dialogs,
+ selectedTriggers,
+ luFiles,
+ qnaFiles,
+ currentTarget,
+ projectId
+ );
expect(result).toEqual({});
});
@@ -214,7 +238,15 @@ describe('generateDispatchModels', () => {
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles = [];
- const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
+ const result = generateDispatchModels(
+ schema,
+ dialogs,
+ selectedTriggers,
+ luFiles,
+ qnaFiles,
+ currentTarget,
+ projectId
+ );
expect(result).toEqual({});
});
@@ -227,37 +259,45 @@ describe('generateDispatchModels', () => {
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles: any = [{ id: 'test.es-es', empty: false }];
- const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
+ const result = generateDispatchModels(
+ schema,
+ dialogs,
+ selectedTriggers,
+ luFiles,
+ qnaFiles,
+ currentTarget,
+ projectId
+ );
expect(result).toEqual(
expect.objectContaining({
dispatchModels: {
+ intents: ['testIntent'],
languages: {
'en-us': [
{
- name: 'test',
contentType: 'application/lu',
- url: ``,
description: '',
+ name: 'test',
+ url: 'https://test.azurewebsites.net/manifests/skill-test.en-us.lu',
},
],
- 'fr-FR': [
+ 'es-es': [
{
- name: 'test',
- contentType: 'application/lu',
- url: ``,
+ contentType: 'application/qna',
description: '',
+ name: 'test',
+ url: 'https://test.azurewebsites.net/manifests/skill-test.es-es.qna',
},
],
- 'es-es': [
+ 'fr-FR': [
{
- name: 'test',
- contentType: 'application/qna',
- url: ``,
+ contentType: 'application/lu',
description: '',
+ name: 'test',
+ url: 'https://test.azurewebsites.net/manifests/skill-test.fr-FR.lu',
},
],
},
- intents: ['testIntent'],
},
})
);
diff --git a/Composer/packages/client/src/pages/publish/BotStatusList.tsx b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
index 28c957f16e..84bc6196af 100644
--- a/Composer/packages/client/src/pages/publish/BotStatusList.tsx
+++ b/Composer/packages/client/src/pages/publish/BotStatusList.tsx
@@ -18,10 +18,9 @@ import { FontSizes } from '@uifabric/styling';
import get from 'lodash/get';
import { useCopyToClipboard } from '@bfc/ui-shared';
import { Callout } from 'office-ui-fabric-react/lib/Callout';
-import { ITooltipHostStyles, ITooltipStyles, TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
+import { TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
import { ApiStatus } from '../../utils/publishStatusPollingUpdater';
-import { flexContentSpaceBetween } from '../language-understanding/styles';
import { PublishStatusList } from './PublishStatusList';
import { detailList, listRoot, tableView } from './styles';
From 4a8b25c5279375fed5732416efb4d2dacb7c1f9e Mon Sep 17 00:00:00 2001
From: Long Jun
Date: Wed, 14 Apr 2021 18:01:34 +0800
Subject: [PATCH 48/55] remove manifest folder from read patterns
---
Composer/packages/server/src/models/bot/botStructure.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/Composer/packages/server/src/models/bot/botStructure.ts b/Composer/packages/server/src/models/bot/botStructure.ts
index 0b67466ae5..f3139c0e51 100644
--- a/Composer/packages/server/src/models/bot/botStructure.ts
+++ b/Composer/packages/server/src/models/bot/botStructure.ts
@@ -65,7 +65,6 @@ export const BotStructureFilesPatterns = [
templateInterpolate(BotStructureTemplate.dialogs.entry, { DIALOGNAME: '*' }),
templateInterpolate(BotStructureTemplate.dialogs.dialogSchema, { DIALOGNAME: '*' }),
templateInterpolate(BotStructureTemplate.dialogs.recognizer, { DIALOGNAME: '*', RECOGNIZERNAME: '*.dialog' }),
- templateInterpolate(BotStructureTemplate.manifestLu, { FILENAME: '*' }),
templateInterpolate(BotStructureTemplate.formDialogs, { FORMDIALOGNAME: '*.form' }),
templateInterpolate(BotStructureTemplate.skillManifests, { MANIFESTFILENAME: '*.json' }),
From 6ff0cdf4fc362b7cf7b46b9c889eae070767aed2 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Thu, 15 Apr 2021 15:20:06 +0800
Subject: [PATCH 49/55] comments
---
.../botProject/CreatePublishProfileDialog.tsx | 7 +------
.../pages/design/exportSkillModal/constants.tsx | 2 +-
.../exportSkillModal/content/AddCallers.tsx | 15 +++++----------
.../exportSkillModal/content/Description.tsx | 4 ++--
.../exportSkillModal/content/SelectProfile.tsx | 4 +---
.../src/pages/design/exportSkillModal/index.tsx | 6 +++---
.../client/src/pages/publish/Notifications.tsx | 8 ++++----
.../packages/client/src/pages/publish/Publish.tsx | 2 +-
.../client/src/recoilModel/atoms/botState.ts | 2 +-
.../client/src/recoilModel/dispatchers/project.ts | 2 +-
.../packages/server/src/controllers/project.ts | 8 ++++----
11 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
index 6e8649fc06..bfc5a41a3c 100644
--- a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
+++ b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
@@ -22,7 +22,6 @@ import { actionButton } from './styles';
type CreatePublishProfileDialogProps = {
projectId: string;
- scrollToSectionId?: string;
};
export const CreatePublishProfileDialog: React.FC = (props) => {
@@ -70,11 +69,7 @@ export const CreatePublishProfileDialog: React.FC {
- if (isShowAuthDialog(true)) {
- setShowAuthDialog(true);
- } else {
- setDialogHidden(false);
- }
+ isShowAuthDialog(true) ? setShowAuthDialog(true) : setDialogHidden(false);
toggleHideDialog();
}}
>
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index a71bcc6815..4008bc46f9 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -94,7 +94,7 @@ export interface ContentProps {
onChange: (_: any) => void;
projectId: string;
callers: string[];
- setCallers: (callers: string[]) => void;
+ onUpdateCallers: (callers: string[]) => void;
}
interface Button {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
index f8df2823c5..4951b2ebae 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/AddCallers.tsx
@@ -39,14 +39,14 @@ const removeCaller = {
},
};
-export const AddCallers: React.FC = ({ projectId, callers, setCallers }) => {
+export const AddCallers: React.FC = ({ projectId, callers, onUpdateCallers }) => {
const handleRemove = (index) => {
- setCallers(callers.filter((_, i) => i !== index));
+ onUpdateCallers(callers.filter((_, i) => i !== index));
};
const handleAddNewAllowedCallerClick = () => {
const currentCallers = callers.slice();
currentCallers?.push('0000-11111-00000-11111');
- setCallers(currentCallers);
+ onUpdateCallers(currentCallers);
};
return (
@@ -64,7 +64,7 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
onChange={(e, newValue) => {
const currentCallers = callers.slice();
currentCallers[index] = newValue ?? '';
- setCallers(currentCallers);
+ onUpdateCallers(currentCallers);
}}
/>
@@ -76,12 +76,7 @@ export const AddCallers: React.FC = ({ projectId, callers, setCall
);
})}
- {
- handleAddNewAllowedCallerClick();
- }}
- >
+
{formatMessage('Add allowed callers')}
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
index 1f83649d05..ac6092a281 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/Description.tsx
@@ -117,7 +117,7 @@ export const Description: React.FC = ({
selected,
};
}),
- []
+ [$schema]
);
useEffect(() => {
@@ -174,7 +174,7 @@ export const Description: React.FC = ({
{formatMessage('Manifest Version')}
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index ade10a596b..ff5db7b8e6 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -87,7 +87,6 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const botName = useRecoilValue(botDisplayNameState(projectId));
const skillManifests = useRecoilValue(skillManifestsState(projectId));
- const { ...rest } = content;
const handleCurrentProfileChange = useMemo(
() => (_e, option?: IDropdownOption) => {
const target = publishingTargets.find((t) => {
@@ -101,7 +100,6 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
useEffect(() => {
try {
if (currentTarget) {
- setCurrentTarget(currentTarget);
updateCurrentTarget(projectId, currentTarget);
const config = JSON.parse(currentTarget.configuration);
setEndpointUrl(`https://${config.hostname}.azurewebsites.net/api/messages`);
@@ -109,7 +107,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
setSkillManifest({
content: {
- ...rest,
+ content,
endpoints: [
{
protocol: 'BotFrameworkV3',
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index bd5b298908..c834d127f7 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -76,7 +76,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
const updatedSetting = isAdaptive
? {
...cloneDeep(mergedSettings),
- runtimeSettings: { ...runtimeSettings, skills: { ...runtimeSettings.skills, allowedCallers } },
+ runtimeSettings: { ...runtimeSettings, skills: { ...runtimeSettings?.skills, allowedCallers } },
}
: {
...cloneDeep(mergedSettings),
@@ -114,7 +114,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
}
};
- const handleTriggerPublish = async () => {
+ const handleTriggerPublish = () => {
const filePath = `https://${JSON.parse(currentTarget.configuration).hostname}.azurewebsites.net/manifests/${
skillManifest.id
}.json`;
@@ -202,7 +202,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
schema={schema}
selectedDialogs={selectedDialogs}
selectedTriggers={selectedTriggers}
- setCallers={setCallers}
+ onUpdateCallers={setCallers}
setErrors={setErrors}
setSchema={setSchema}
setSelectedDialogs={setSelectedDialogs}
diff --git a/Composer/packages/client/src/pages/publish/Notifications.tsx b/Composer/packages/client/src/pages/publish/Notifications.tsx
index 96f315d711..c80ec363a8 100644
--- a/Composer/packages/client/src/pages/publish/Notifications.tsx
+++ b/Composer/packages/client/src/pages/publish/Notifications.tsx
@@ -6,7 +6,7 @@ import formatMessage from 'format-message';
import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator';
import { Icon } from 'office-ui-fabric-react/lib/Icon';
import { IconButton } from 'office-ui-fabric-react/lib/Button';
-import { FontSizes } from '@uifabric/fluent-theme';
+import { CommunicationColors, FontSizes, SharedColors } from '@uifabric/fluent-theme';
import { CardProps } from '../../components/Notifications/NotificationCard';
@@ -82,11 +82,11 @@ export const getSkillPublishedNotificationCardProps = (item: BotStatus, url?: st
width: '12px',
height: '12px',
fontSize: '12px',
- color: '#D92525',
+ color: SharedColors.red10,
});
const errorType = css`
margin-top: 4px;
- color: #d92525;
+ color: ${SharedColors.red10};
`;
const successType = css`
margin-top: 4px;
@@ -136,7 +136,7 @@ export const getSkillPublishedNotificationCardProps = (item: BotStatus, url?: st
{url}
navigator.clipboard.writeText(url)}
/>
diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx
index edea342838..ff97f64edc 100644
--- a/Composer/packages/client/src/pages/publish/Publish.tsx
+++ b/Composer/packages/client/src/pages/publish/Publish.tsx
@@ -153,7 +153,7 @@ const Publish: React.FC {
if (currentBotList.length < botList.length) {
diff --git a/Composer/packages/client/src/recoilModel/atoms/botState.ts b/Composer/packages/client/src/recoilModel/atoms/botState.ts
index 9f6591ba47..4cbead2191 100644
--- a/Composer/packages/client/src/recoilModel/atoms/botState.ts
+++ b/Composer/packages/client/src/recoilModel/atoms/botState.ts
@@ -371,7 +371,7 @@ export const isEjectRuntimeExistState = atomFamily({
default: false,
});
-export const currentTargetState = atomFamily({
+export const currentTargetState = atomFamily({
key: getFullyQualifiedKey('currentTarget'),
default: {} as PublishTarget,
});
diff --git a/Composer/packages/client/src/recoilModel/dispatchers/project.ts b/Composer/packages/client/src/recoilModel/dispatchers/project.ts
index c475c2ea68..3bdd900599 100644
--- a/Composer/packages/client/src/recoilModel/dispatchers/project.ts
+++ b/Composer/packages/client/src/recoilModel/dispatchers/project.ts
@@ -503,7 +503,7 @@ export const projectDispatcher = () => {
);
const updateCurrentTarget = useRecoilCallback<[string, PublishTarget], void>(
- ({ set }: CallbackInterface) => async (projectId: string, currentTarget) => {
+ ({ set }: CallbackInterface) => (projectId: string, currentTarget) => {
set(currentTargetState(projectId), currentTarget);
}
);
diff --git a/Composer/packages/server/src/controllers/project.ts b/Composer/packages/server/src/controllers/project.ts
index 07e24b3c04..0d13b281cb 100644
--- a/Composer/packages/server/src/controllers/project.ts
+++ b/Composer/packages/server/src/controllers/project.ts
@@ -356,7 +356,7 @@ async function updateManifestFile(req: Request, res: Response) {
res.status(200).json({ lastModified: lastModified });
} else {
res.status(404).json({
- message: 'No such bot project opened',
+ message: 'No such bot project found',
});
}
}
@@ -374,7 +374,7 @@ async function createManifestFile(req: Request, res: Response) {
res.status(200).json(file);
} else {
res.status(404).json({
- message: 'No such bot project opened',
+ message: 'No such bot project found',
});
}
}
@@ -388,7 +388,7 @@ async function removeManifestFile(req: Request, res: Response) {
const dialogResources = await currentProject.deleteManifestLuFile(req.params.name);
res.status(200).json(dialogResources);
} else {
- res.status(404).json({ error: 'No bot project opened' });
+ res.status(404).json({ error: 'No bot project found' });
}
}
@@ -400,7 +400,7 @@ async function getSkill(req: Request, res: Response) {
const currentProject = await BotProjectService.getProjectById(projectId, user);
if (currentProject === undefined) {
res.status(404).json({
- message: 'No such bot project opened',
+ message: 'No such bot project found',
});
}
}
From 79ac9cf0bc193a3ee42f8abbdf8ccac0b1d99ebc Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Thu, 15 Apr 2021 17:46:17 +0800
Subject: [PATCH 50/55] comments & conflict
---
.../content/SelectDialogs.tsx | 22 +--
.../content/SelectManifest.tsx | 171 ------------------
.../content/SelectProfile.tsx | 2 +-
.../content/SelectTriggers.tsx | 24 ++-
.../pages/design/exportSkillModal/index.tsx | 14 +-
.../src/pages/publish/Notifications.tsx | 2 +-
.../client/src/recoilModel/atoms/botState.ts | 2 +-
.../src/recoilModel/dispatchers/project.ts | 4 +-
8 files changed, 33 insertions(+), 208 deletions(-)
delete mode 100644 Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
index 3cdc0c97eb..882ed6b526 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectDialogs.tsx
@@ -138,22 +138,20 @@ export const SelectDialogs: React.FC = ({ selectedDialogs, setSele
[projectId]
);
- const selection = useMemo(
- () =>
- new Selection({
- getKey: (item) => item.id,
- onSelectionChanged: () => {
- const selectedItems = selection.getSelection();
- setSelectedDialogs(selectedItems);
- },
- }),
- []
+ const selectionRef = useRef(
+ new Selection({
+ getKey: (item) => item.id,
+ onSelectionChanged: () => {
+ const selectedItems = selectionRef.current.getSelection();
+ setSelectedDialogs(selectedItems);
+ },
+ })
);
useEffect(() => {
for (const item of selectedDialogs) {
- selection.setKeySelected(selection.getKey(item), true, false);
+ selectionRef.current.setKeySelected(selectionRef.current.getKey(item), true, false);
}
}, []);
- return ;
+ return ;
};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx
deleted file mode 100644
index 3e4faca419..0000000000
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectManifest.tsx
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-/** @jsx jsx */
-import { css, jsx } from '@emotion/core';
-import React, { useMemo, useState } from 'react';
-import { Dropdown, IDropdownOption, ResponsiveMode } from 'office-ui-fabric-react/lib/Dropdown';
-import { Label } from 'office-ui-fabric-react/lib/Label';
-import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
-import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
-import { ScrollablePane, ScrollbarVisibility } from 'office-ui-fabric-react/lib/ScrollablePane';
-import {
- CheckboxVisibility,
- DetailsList,
- DetailsListLayoutMode,
- SelectionMode,
-} from 'office-ui-fabric-react/lib/DetailsList';
-import { TooltipHost } from 'office-ui-fabric-react/lib/Tooltip';
-import formatMessage from 'format-message';
-
-import { calculateTimeDiff } from '../../../../utils/fileUtil';
-import { ContentProps, SCHEMA_URIS, VERSION_REGEX } from '../constants';
-
-const styles = {
- detailListContainer: css`
- position: relative;
- max-height: 40vh;
- padding-top: 10px;
- overflow: hidden;
- flex-grow: 1;
- min-height: 250px;
- `,
- create: css`
- display: flex;
- `,
-};
-
-export const SelectManifest: React.FC = ({ completeStep, skillManifests, setSkillManifest }) => {
- const [manifestVersion, setManifestVersion] = useState(SCHEMA_URIS[0]);
- const [errors, setErrors] = useState<{ version?: string }>({});
- const [version] = useMemo(() => VERSION_REGEX.exec(manifestVersion) || [''], []);
-
- const options: IDropdownOption[] = useMemo(
- () =>
- SCHEMA_URIS.map((key, index) => {
- const [version] = VERSION_REGEX.exec(key) || [];
-
- return {
- text: formatMessage('Version {version}', { version }),
- key,
- selected: !index,
- };
- }),
- []
- );
-
- const handleChange = (_e: React.FormEvent, option?: IDropdownOption) => {
- if (option) {
- setManifestVersion(option.key as string);
- }
- };
-
- const handleCreate = () => {
- if (!version) {
- setErrors({ version: formatMessage('Please select a version of the manifest schema') });
- return;
- }
- setSkillManifest({ content: { $schema: manifestVersion } });
- completeStep();
- };
-
- // for detail file list in open panel
- const tableColumns = [
- {
- key: 'column1',
- name: formatMessage('Name'),
- fieldName: 'id',
- minWidth: 300,
- maxWidth: 350,
- isRowHeader: true,
- isResizable: true,
- isSorted: true,
- isSortedDescending: false,
- sortAscendingAriaLabel: formatMessage('Sorted A to Z'),
- sortDescendingAriaLabel: formatMessage('Sorted Z to A'),
- data: 'string',
- onRender: (item) => {
- return {item.id} ;
- },
- isPadded: true,
- },
- {
- key: 'column2',
- name: formatMessage('Date modified'),
- fieldName: 'lastModified',
- minWidth: 60,
- maxWidth: 70,
- isResizable: true,
- data: 'number',
- onRender: (item) => {
- return {calculateTimeDiff(item.lastModified)} ;
- },
- isPadded: true,
- },
- ];
-
- function onRenderDetailsHeader(props, defaultRender) {
- return (
-
- {defaultRender({
- ...props,
- onRenderColumnHeaderTooltip: (tooltipHostProps) => ,
- })}
-
- );
- }
-
- return (
-
-
-
- {formatMessage('Manifest Version')}
-
-
-
-
- {formatMessage('Create')}
-
-
-
-
-
- item.name}
- items={skillManifests}
- layoutMode={DetailsListLayoutMode.justified}
- selectionMode={SelectionMode.single}
- onActiveItemChanged={setSkillManifest}
- onRenderDetailsHeader={onRenderDetailsHeader}
- />
-
-
-
- );
-};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index ff5db7b8e6..f8063a2a52 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -163,7 +163,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const fileId = getManifestId(botName, skillManifests, manifest);
setSkillManifest({ ...manifest, id: fileId });
}
- }, []);
+ }, [id]);
return isProfileValid ? (
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
index 10de552175..ccf13b1ccc 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectTriggers.tsx
@@ -3,7 +3,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
-import React, { useEffect, useMemo } from 'react';
+import React, { useEffect, useMemo, useRef } from 'react';
import { DialogInfo, ITrigger, SDKKinds, getFriendlyName } from '@bfc/shared';
import { Selection } from 'office-ui-fabric-react/lib/DetailsList';
import { useRecoilValue } from 'recoil';
@@ -80,23 +80,21 @@ export const SelectTriggers: React.FC = ({ selectedTriggers, setSe
},
];
- const selection = useMemo(
- () =>
- new Selection({
- getKey: (item) => item.id,
- onSelectionChanged: () => {
- const selectedItems = selection.getSelection();
- setSelectedTriggers(selectedItems);
- },
- }),
- []
+ const selectionRef = useRef(
+ new Selection({
+ getKey: (item) => item.id,
+ onSelectionChanged: () => {
+ const selectedItems = selectionRef.current.getSelection();
+ setSelectedTriggers(selectedItems);
+ },
+ })
);
useEffect(() => {
for (const item of selectedTriggers) {
- selection.setKeySelected(selection.getKey(item), true, false);
+ selectionRef.current.setKeySelected(selectionRef.current.getKey(item), true, false);
}
}, []);
- return ;
+ return ;
};
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
index c834d127f7..5efb3939d9 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/index.tsx
@@ -21,7 +21,7 @@ import {
qnaFilesSelectorFamily,
dialogsSelectorFamily,
dialogSchemasState,
- currentTargetState,
+ currentPublishTargetState,
luFilesSelectorFamily,
settingsState,
rootBotProjectIdSelector,
@@ -42,7 +42,7 @@ interface ExportSkillModalProps {
const ExportSkillModal: React.FC = ({ onSubmit, onDismiss: handleDismiss, projectId }) => {
const dialogs = useRecoilValue(dialogsSelectorFamily(projectId));
const dialogSchemas = useRecoilValue(dialogSchemasState(projectId));
- const currentTarget = useRecoilValue(currentTargetState(projectId));
+ const currentPublishTarget = useRecoilValue(currentPublishTargetState(projectId));
const luFiles = useRecoilValue(luFilesSelectorFamily(projectId));
const qnaFiles = useRecoilValue(qnaFilesSelectorFamily(projectId));
const skillManifests = useRecoilValue(skillManifestsState(projectId));
@@ -97,7 +97,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
qnaFiles,
selectedTriggers,
selectedDialogs,
- currentTarget,
+ currentPublishTarget,
projectId
);
setSkillManifest(manifest);
@@ -115,10 +115,10 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
};
const handleTriggerPublish = () => {
- const filePath = `https://${JSON.parse(currentTarget.configuration).hostname}.azurewebsites.net/manifests/${
+ const filePath = `https://${JSON.parse(currentPublishTarget.configuration).hostname}.azurewebsites.net/manifests/${
skillManifest.id
}.json`;
- navigate(`/bot/${projectId}/publish/all?publishTargetName=${currentTarget.name}&url=${filePath}`);
+ navigate(`/bot/${projectId}/publish/all?publishTargetName=${currentPublishTarget.name}&url=${filePath}`);
};
const handleSave = () => {
@@ -131,7 +131,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
qnaFiles,
selectedTriggers,
selectedDialogs,
- currentTarget,
+ currentPublishTarget,
projectId
);
if (manifest.content && manifest.id) {
@@ -202,7 +202,6 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
schema={schema}
selectedDialogs={selectedDialogs}
selectedTriggers={selectedTriggers}
- onUpdateCallers={setCallers}
setErrors={setErrors}
setSchema={setSchema}
setSelectedDialogs={setSelectedDialogs}
@@ -211,6 +210,7 @@ const ExportSkillModal: React.FC = ({ onSubmit, onDismiss
skillManifests={skillManifests}
value={content}
onChange={(manifestContent) => setSkillManifest({ ...skillManifest, content: manifestContent })}
+ onUpdateCallers={setCallers}
/>
diff --git a/Composer/packages/client/src/pages/publish/Notifications.tsx b/Composer/packages/client/src/pages/publish/Notifications.tsx
index c80ec363a8..fcabdbe05b 100644
--- a/Composer/packages/client/src/pages/publish/Notifications.tsx
+++ b/Composer/packages/client/src/pages/publish/Notifications.tsx
@@ -161,7 +161,7 @@ export const getSkillPublishedNotificationCardProps = (item: BotStatus, url?: st
export const getPendingNotificationCardProps = (items: BotStatus[], isSkill = false): CardProps => {
const description = isSkill
- ? 'Publishing your skill...'
+ ? formatMessage('Publishing your skill...')
: formatMessage(
`Publishing {
count, plural,
diff --git a/Composer/packages/client/src/recoilModel/atoms/botState.ts b/Composer/packages/client/src/recoilModel/atoms/botState.ts
index 7b8da41f2a..d27379da68 100644
--- a/Composer/packages/client/src/recoilModel/atoms/botState.ts
+++ b/Composer/packages/client/src/recoilModel/atoms/botState.ts
@@ -372,7 +372,7 @@ export const isEjectRuntimeExistState = atomFamily({
default: false,
});
-export const currentTargetState = atomFamily({
+export const currentPublishTargetState = atomFamily({
key: getFullyQualifiedKey('currentTarget'),
default: {} as PublishTarget,
});
diff --git a/Composer/packages/client/src/recoilModel/dispatchers/project.ts b/Composer/packages/client/src/recoilModel/dispatchers/project.ts
index 1169deff8b..823ed33a53 100644
--- a/Composer/packages/client/src/recoilModel/dispatchers/project.ts
+++ b/Composer/packages/client/src/recoilModel/dispatchers/project.ts
@@ -28,7 +28,7 @@ import {
createQnAOnState,
creationFlowTypeState,
currentProjectIdState,
- currentTargetState,
+ currentPublishTargetState,
dispatcherState,
feedState,
fetchReadMePendingState,
@@ -504,7 +504,7 @@ export const projectDispatcher = () => {
const updateCurrentTarget = useRecoilCallback<[string, PublishTarget], void>(
({ set }: CallbackInterface) => (projectId: string, currentTarget) => {
- set(currentTargetState(projectId), currentTarget);
+ set(currentPublishTargetState(projectId), currentTarget);
}
);
From ecd2711887d6cf17087e3647fadbc3bd7812d91e Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Thu, 15 Apr 2021 22:11:01 +0800
Subject: [PATCH 51/55] type
---
Composer/packages/client/src/recoilModel/atoms/botState.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/recoilModel/atoms/botState.ts b/Composer/packages/client/src/recoilModel/atoms/botState.ts
index d27379da68..4e337064a5 100644
--- a/Composer/packages/client/src/recoilModel/atoms/botState.ts
+++ b/Composer/packages/client/src/recoilModel/atoms/botState.ts
@@ -372,7 +372,7 @@ export const isEjectRuntimeExistState = atomFamily({
default: false,
});
-export const currentPublishTargetState = atomFamily({
+export const currentPublishTargetState = atomFamily({
key: getFullyQualifiedKey('currentTarget'),
default: {} as PublishTarget,
});
From 56e1a13669acc42191abad5556a3cd4d4c5645aa Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Fri, 16 Apr 2021 10:46:35 +0800
Subject: [PATCH 52/55] bugfix
---
.../src/pages/design/exportSkillModal/content/SelectProfile.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index f8063a2a52..fb8284b11b 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -107,7 +107,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
setSkillManifest({
content: {
- content,
+ ...content,
endpoints: [
{
protocol: 'BotFrameworkV3',
From 72855ea1eaf62aac30c46a02c99a8cc662d18f35 Mon Sep 17 00:00:00 2001
From: Lu Han <32191031+luhan2017@users.noreply.github.com>
Date: Fri, 16 Apr 2021 13:55:39 +0800
Subject: [PATCH 53/55] Fix the logic of updating skill settings
---
extensions/azurePublish/src/node/deploy.ts | 23 +++++++++-------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/extensions/azurePublish/src/node/deploy.ts b/extensions/azurePublish/src/node/deploy.ts
index f25d13542b..d34cdac12e 100644
--- a/extensions/azurePublish/src/node/deploy.ts
+++ b/extensions/azurePublish/src/node/deploy.ts
@@ -68,12 +68,6 @@ export class BotProjectDeploy {
settings.skillHostEndpoint = `https://${hostname}.azurewebsites.net/api/skills`;
}
- // Update endpoints in skill manifests
- const skillManifestPath = path.join(this.projPath, 'wwwroot', 'manifests');
- if (await fs.pathExists(skillManifestPath)) {
- await this.updateSkillSettings(profileName, hostname, settings.MicrosoftAppId, skillManifestPath, settings);
- }
-
// STEP 1: CLEAN UP PREVIOUS BUILDS
// cleanup any previous build
if (await fs.pathExists(this.zipPath)) {
@@ -137,6 +131,13 @@ export class BotProjectDeploy {
path.join(pathToArtifacts, 'wwwroot', 'manifests'),
project.fileStorage
);
+ // Update skill endpoint url in skill manifest.
+ await this.updateSkillSettings(
+ profileName,
+ hostname,
+ settings.MicrosoftAppId,
+ path.join(pathToArtifacts, 'wwwroot', 'manifests')
+ );
}
// STEP 4: ZIP THE ASSETS
@@ -177,13 +178,7 @@ export class BotProjectDeploy {
* @param msAppId microsoft app id
* @param skillSettingsPath the path of skills manifest settings
*/
- private async updateSkillSettings(
- profileName: string,
- hostname: string,
- msAppId: string,
- skillSettingsPath: string,
- settings: DialogSetting
- ) {
+ private async updateSkillSettings(profileName: string, hostname: string, msAppId: string, skillSettingsPath: string) {
/* eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe as no value holds user input */
const manifestFiles = (await fs.readdir(skillSettingsPath)).filter((x) => x.endsWith('.json'));
if (manifestFiles.length === 0) {
@@ -212,7 +207,7 @@ export class BotProjectDeploy {
msAppId: msAppId,
});
- await fs.writeJson(path.join(skillSettingsPath, manifestFile), manifest);
+ await fs.writeJson(path.join(skillSettingsPath, manifestFile), manifest, { spaces: 2 });
}
}
From bec3056db32484ae9331edf454b0a2bd4f563bcc Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Fri, 16 Apr 2021 14:41:24 +0800
Subject: [PATCH 54/55] delete duplicate manifest url
---
.../packages/client/src/pages/publish/publishPageUtils.tsx | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Composer/packages/client/src/pages/publish/publishPageUtils.tsx b/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
index 75f00d442b..c5b52ccaa5 100644
--- a/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
+++ b/Composer/packages/client/src/pages/publish/publishPageUtils.tsx
@@ -35,7 +35,10 @@ const findSkillManifestUrl = (skillManifests: SkillManifestFile[], hostname: str
const urls: string[] = [];
for (const skillManifest of skillManifests || []) {
for (const endpoint of skillManifest?.content?.endpoints || []) {
- if (endpoint?.msAppId === appId) {
+ if (
+ endpoint?.msAppId === appId &&
+ !urls.includes(`https://${hostname}.azurewebsites.net/manifests/${skillManifest.id}.json`)
+ ) {
urls.push(`https://${hostname}.azurewebsites.net/manifests/${skillManifest.id}.json`);
}
}
From ea9372e6043c2b476f1080064345f5520074d471 Mon Sep 17 00:00:00 2001
From: Long Alan
Date: Fri, 16 Apr 2021 16:05:08 +0800
Subject: [PATCH 55/55] add profile popup logic
---
.../botProject/CreatePublishProfileDialog.tsx | 2 --
.../design/exportSkillModal/constants.tsx | 21 ++++++++++++++++++-
.../content/SelectProfile.tsx | 1 +
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
index bfc5a41a3c..402d8e3918 100644
--- a/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
+++ b/Composer/packages/client/src/pages/botProject/CreatePublishProfileDialog.tsx
@@ -95,8 +95,6 @@ export const CreatePublishProfileDialog: React.FC {
setDialogHidden(true);
- // reset current
- toggleHideDialog();
setCurrentPublishProfile(null);
}}
current={currentPublishProfile}
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
index 4008bc46f9..18f7c5c883 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/constants.tsx
@@ -188,7 +188,26 @@ export const editorSteps: { [key in ManifestEditorSteps]: EditorStep } = {
cancelButton,
backButton,
{
- disabled: ({ publishTargets }) => publishTargets.length === 0,
+ disabled: ({ publishTargets }) => {
+ try {
+ return (
+ publishTargets.findIndex((item) => {
+ const config = JSON.parse(item.configuration);
+ return (
+ config.settings &&
+ config.settings.MicrosoftAppId &&
+ config.hostname &&
+ config.settings.MicrosoftAppId.length > 0 &&
+ config.hostname.length > 0
+ );
+ }) < 0
+ );
+ } catch (err) {
+ console.log(err.message);
+ return true;
+ }
+ },
+
primary: true,
text: () => formatMessage('Generate and Publish'),
onClick: ({ generateManifest, onNext, onPublish }) => () => {
diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
index fb8284b11b..51bf07dc99 100644
--- a/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
+++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/SelectProfile.tsx
@@ -133,6 +133,7 @@ export const SelectProfile: React.FC = ({ manifest, setSkillManife
const filteredProfile = publishingTargets.filter((item) => {
const config = JSON.parse(item.configuration);
return (
+ config.settings &&
config.settings.MicrosoftAppId &&
config.hostname &&
config.settings.MicrosoftAppId.length > 0 &&