+
{manifest.name || ''}
+
+
{formatMessage('Description')}
+
{manifest.description || ''}
+
+
+
{formatMessage('Version')}
+
{manifest.version || ''}
+
+
+
{formatMessage('Activities')}
+
{manifest.activities ? Object.keys(manifest.activities).join(', ') : ''}
+
+
+
{formatMessage('Publisher')}
+
{manifest.publisherName || ''}
+
+
+ );
+};
diff --git a/Composer/packages/client/src/components/AddRemoteSkillModal/helper.ts b/Composer/packages/client/src/components/AddRemoteSkillModal/helper.ts
new file mode 100644
index 0000000000..fd9f6d141d
--- /dev/null
+++ b/Composer/packages/client/src/components/AddRemoteSkillModal/helper.ts
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import formatMessage from 'format-message';
+import { luIndexer, combineMessage } from '@bfc/indexers';
+import { OpenConfirmModal } from '@bfc/ui-shared';
+
+import httpClient from '../../utils/httpUtil';
+import TelemetryClient from '../../telemetry/TelemetryClient';
+
+const conflictConfirmationTitle = formatMessage('Conflicting changes detected');
+const conflictConfirmationPrompt = formatMessage(
+ 'This operation will overwrite changes made to previously imported files. Do you want to proceed?'
+);
+
+export const importOrchestractor = async (projectId: string, reloadProject, setApplicationLevelError) => {
+ const reqBody = {
+ package: 'Microsoft.Bot.Builder.AI.Orchestrator',
+ version: '',
+ source: 'https://botbuilder.myget.org/F/botbuilder-v4-dotnet-daily/api/v3/index.json',
+ isUpdating: false,
+ isPreview: true,
+ };
+ try {
+ const results = await httpClient.post(`projects/${projectId}/import`, reqBody);
+ // check to see if there was a conflict that requires confirmation
+ if (results.data.success === false) {
+ TelemetryClient.track('PackageInstallConflictFound', { ...reqBody, isUpdate: reqBody.isUpdating });
+ const confirmResult = await OpenConfirmModal(conflictConfirmationTitle, conflictConfirmationPrompt);
+
+ if (confirmResult) {
+ TelemetryClient.track('PackageInstallConflictResolved', { ...reqBody, isUpdate: reqBody.isUpdating });
+ // update package, set isUpdating to true
+ await httpClient.post(`projects/${projectId}/import`, { ...reqBody, isUpdate: true });
+ }
+ } else {
+ TelemetryClient.track('PackageInstalled', { ...reqBody, isUpdate: reqBody.isUpdating });
+ // reload modified content
+ await reloadProject(projectId);
+ }
+ } catch (err) {
+ TelemetryClient.track('PackageInstallFailed', { ...reqBody, isUpdate: reqBody.isUpdating });
+ setApplicationLevelError({
+ status: err.response.status,
+ message: err.response && err.response.data.message ? err.response.data.message : err,
+ summary: formatMessage('Install Error'),
+ });
+ }
+};
+
+export const getLuDiagnostics = (intent: string, triggerPhrases: string) => {
+ const content = `#${intent}\n${triggerPhrases}`;
+ const { diagnostics } = luIndexer.parse(content, '', {
+ enableListEntities: false,
+ enableCompositeEntities: false,
+ enableMLEntities: false,
+ enablePrebuiltEntities: false,
+ enableRegexEntities: false,
+ });
+ return combineMessage(diagnostics);
+};
diff --git a/Composer/packages/client/src/components/CreateSkillModal.tsx b/Composer/packages/client/src/components/CreateSkillModal.tsx
deleted file mode 100644
index 22f9ee7423..0000000000
--- a/Composer/packages/client/src/components/CreateSkillModal.tsx
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import React, { useRef, useState, useMemo } from 'react';
-import formatMessage from 'format-message';
-import { Dropdown, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
-import { Label } from 'office-ui-fabric-react/lib/Label';
-import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
-import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
-import { Stack, StackItem } from 'office-ui-fabric-react/lib/Stack';
-import { TextField } from 'office-ui-fabric-react/lib/TextField';
-import { useRecoilValue } from 'recoil';
-import debounce from 'lodash/debounce';
-import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
-
-import { addSkillDialog } from '../constants';
-import httpClient from '../utils/httpUtil';
-import { skillsStateSelector } from '../recoilModel';
-import TelemetryClient from '../telemetry/TelemetryClient';
-
-export interface SkillFormDataErrors {
- endpoint?: string;
- manifestUrl?: string;
- name?: string;
-}
-
-export const urlRegex = /^http[s]?:\/\/\w+/;
-export const skillNameRegex = /^\w[-\w]*$/;
-export const msAppIdRegex = /^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/;
-
-export interface CreateSkillModalProps {
- projectId: string;
- onSubmit: (manifestUrl: string, endpointName: string) => void;
- onDismiss: () => void;
-}
-
-enum ValidationState {
- NotValidated = 'NotValidated',
- Validating = 'Validating',
- Validated = 'Validated',
-}
-
-export const validateEndpoint = ({
- formData,
- formDataErrors,
- setFormDataErrors,
- setValidationState,
- validationState,
-}) => {
- const { msAppId, endpointUrl } = formData;
- const { endpoint: _, ...errors } = formDataErrors;
-
- if (!msAppId || !endpointUrl) {
- setFormDataErrors({ ...errors, endpoint: formatMessage('Please select a valid endpoint') });
- } else if (!urlRegex.test(endpointUrl) || !msAppIdRegex.test(msAppId)) {
- setFormDataErrors({ ...errors, endpoint: formatMessage('Skill manifest endpoint is configured improperly') });
- } else {
- setFormDataErrors(errors);
- setValidationState({ ...validationState, endpoint: ValidationState.Validated });
- }
-};
-
-export const validateManifestUrl = async ({
- formData,
- formDataErrors,
- projectId,
- setFormDataErrors,
- setValidationState,
- setSkillManifest,
- validationState,
-}) => {
- const { manifestUrl } = formData;
- const { manifestUrl: _, ...errors } = formDataErrors;
-
- if (!manifestUrl) {
- setFormDataErrors({ ...errors, manifestUrl: formatMessage('Please input a manifest URL') });
- } else if (!urlRegex.test(manifestUrl)) {
- setFormDataErrors({ ...errors, manifestUrl: formatMessage('URL should start with http:// or https://') });
- } else {
- try {
- setValidationState({ ...validationState, manifestUrl: ValidationState.Validating });
- const { data } = await httpClient.get(`/projects/${projectId}/skill/retrieveSkillManifest`, {
- params: {
- url: manifestUrl,
- },
- });
- setFormDataErrors(errors);
- setSkillManifest(data);
- setValidationState({ ...validationState, manifestUrl: ValidationState.Validated });
- } catch (error) {
- setFormDataErrors({ ...errors, manifestUrl: formatMessage('Manifest URL can not be accessed') });
- setValidationState({ ...validationState, manifestUrl: ValidationState.NotValidated });
- }
- }
-};
-
-export const CreateSkillModal: React.FC