Skip to content

Commit

Permalink
chore: Rebase main on feature branch (#4932)
Browse files Browse the repository at this point in the history
  • Loading branch information
srinaath authored Nov 22, 2020
1 parent f55001a commit 74a95ad
Show file tree
Hide file tree
Showing 64 changed files with 1,747 additions and 262 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export const RecognizerField: React.FC<FieldProps<MicrosoftIRecognizer>> = (prop

useMigrationEffect(value, onChange);
const { recognizers: recognizerConfigs, currentRecognizer } = useRecognizerConfig();
const dropdownOptions = useMemo(() => getDropdownOptions(recognizerConfigs), [recognizerConfigs]);
const dropdownOptions = useMemo(() => getDropdownOptions(recognizerConfigs, shellData, shellApi), [
recognizerConfigs,
]);

const RecognizerEditor = currentRecognizer?.recognizerEditor;
const widget = RecognizerEditor ? <RecognizerEditor {...props} /> : null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { RecognizerSchema, FallbackRecognizerKey } from '@bfc/extension-client';
import { RecognizerSchema, FallbackRecognizerKey, ShellApi, ShellData } from '@bfc/extension-client';

import { recognizerOrderMap } from './defaultRecognizerOrder';
import { mapRecognizerSchemaToDropdownOption } from './mappers';

const getRankScore = (r: RecognizerSchema) => {
const getRankScore = (r: RecognizerSchema, shellData: ShellData, shellApi: ShellApi) => {
// Always put disabled recognizer behind. Handle 'disabled' before 'default'.
if (r.disabled) return Number.MAX_VALUE;
if ((typeof r.disabled === 'function' && r.disabled(shellData, shellApi)) || r.disabled) return Number.MAX_VALUE;
// Always put default recognzier ahead.
if (r.default) return -1;
// Put fallback recognizer behind.
if (r.id === FallbackRecognizerKey) return Number.MAX_VALUE - 1;
return recognizerOrderMap[r.id] ?? Number.MAX_VALUE - 1;
};

export const getDropdownOptions = (recognizerConfigs: RecognizerSchema[]) => {
export const getDropdownOptions = (recognizerConfigs: RecognizerSchema[], shellData: ShellData, shellApi: ShellApi) => {
return recognizerConfigs
.filter((r) => !r.disabled)
.filter((r) => (typeof r.disabled === 'function' && !r.disabled(shellData, shellApi)) || !r.disabled)
.sort((r1, r2) => {
return getRankScore(r1) - getRankScore(r2);
return getRankScore(r1, shellData, shellApi) - getRankScore(r2, shellData, shellApi);
})
.map(mapRecognizerSchemaToDropdownOption);
};
1 change: 1 addition & 0 deletions Composer/packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@bfc/ui-plugin-dialog-schema-editor": "*",
"@bfc/ui-plugin-lg": "*",
"@bfc/ui-plugin-luis": "*",
"@bfc/ui-plugin-orchestrator": "*",
"@bfc/ui-plugin-prompts": "*",
"@bfc/ui-plugin-select-dialog": "*",
"@bfc/ui-plugin-select-skill-dialog": "*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { Dropdown, ResponsiveMode, IDropdownOption } from 'office-ui-fabric-reac
import { Text, Tips, Links, nameRegex } from '../../constants';
import { FieldConfig, useForm } from '../../hooks/useForm';
import { getReferredQnaFiles } from '../../utils/qnaUtil';
import { getReferredLuFiles } from '../../utils/luUtil';
import { dialogsSelectorFamily, luFilesState, qnaFilesState } from '../../recoilModel';
import { getLuisBuildLuFiles } from '../../utils/luUtil';
import { luFilesState, qnaFilesState, validateDialogsSelectorFamily } from '../../recoilModel';

// -------------------- Styles -------------------- //
const textFieldLabel = css`
Expand Down Expand Up @@ -105,11 +105,11 @@ interface IPublishDialogProps {

export const PublishDialog: React.FC<IPublishDialogProps> = (props) => {
const { isOpen, onDismiss, onPublish, botName, config, projectId } = props;
const dialogs = useRecoilValue(dialogsSelectorFamily(projectId));
const dialogs = useRecoilValue(validateDialogsSelectorFamily(projectId));
const luFiles = useRecoilValue(luFilesState(projectId));
const qnaFiles = useRecoilValue(qnaFilesState(projectId));
const qnaConfigShow = getReferredQnaFiles(qnaFiles, dialogs).length > 0;
const luConfigShow = getReferredLuFiles(luFiles, dialogs).length > 0;
const luConfigShow = getLuisBuildLuFiles(luFiles, dialogs).length > 0;

const formConfig: FieldConfig<FormData> = {
name: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { FeatureFlagKey } from '@bfc/shared';
import { FeatureFlagKey } from '@botframework-composer/types';
import React, { Fragment } from 'react';

import { useFeatureFlag } from '../utils/hooks';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { jsx } from '@emotion/core';
import React from 'react';
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
import { FeatureFlagKey } from '@bfc/shared';
import { FeatureFlagKey } from '@botframework-composer/types';

import * as styles from './styles';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { jsx } from '@emotion/core';
import { Fragment, useState } from 'react';
import formatMessage from 'format-message';
import { FeatureFlag, FeatureFlagKey } from '@bfc/shared';
import { FeatureFlag, FeatureFlagKey } from '@botframework-composer/types';
import { useRecoilValue } from 'recoil';

import { dispatcherState, featureFlagsState } from '../../../recoilModel';
Expand Down
2 changes: 2 additions & 0 deletions Composer/packages/client/src/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import prompts from '@bfc/ui-plugin-prompts';
import schemaEditor from '@bfc/ui-plugin-dialog-schema-editor';
import selectDialog from '@bfc/ui-plugin-select-dialog';
import selectSkillDialog from '@bfc/ui-plugin-select-skill-dialog';
import orchestrator from '@bfc/ui-plugin-orchestrator';
import lg from '@bfc/ui-plugin-lg';
import lu from '@bfc/ui-plugin-luis';
import crossTrained from '@bfc/ui-plugin-cross-trained';
Expand Down Expand Up @@ -43,6 +44,7 @@ export default mergePluginConfigs(
selectSkillDialog,
lg,
lu,
orchestrator,
crossTrained,
schemaEditor
);
26 changes: 17 additions & 9 deletions Composer/packages/client/src/recoilModel/Recognizers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { crossTrainConfigState, luFilesState, qnaFilesState, settingsState } fro
import { dialogsSelectorFamily } from './selectors';
import { recognizersSelectorFamily } from './selectors/recognizers';

const LuisRecognizerTemplate = (target: string, fileName: string) => ({
export const LuisRecognizerTemplate = (target: string, fileName: string) => ({
$kind: SDKKinds.LuisRecognizer,
id: `LUIS_${target}`,
applicationId: `=settings.luis.${fileName.replace(/[.-]/g, '_')}_lu.appId`,
Expand All @@ -24,28 +24,34 @@ const LuisRecognizerTemplate = (target: string, fileName: string) => ({
endpointKey: '=settings.luis.endpointKey',
});

const QnAMakerRecognizerTemplate = (target: string, fileName: string) => ({
export const QnAMakerRecognizerTemplate = (target: string, fileName: string) => ({
$kind: SDKKinds.QnAMakerRecognizer,
id: `QnA_${target}`,
knowledgeBaseId: `=settings.qna.${fileName.replace(/[.-]/g, '_')}_qna`,
hostname: '=settings.qna.hostname',
endpointKey: '=settings.qna.endpointKey',
});

const MultiLanguageRecognizerTemplate = (target: string, fileType: 'lu' | 'qna') => ({
export const MultiLanguageRecognizerTemplate = (target: string, fileType: 'lu' | 'qna') => ({
$kind: SDKKinds.MultiLanguageRecognizer,
id: `${fileType === 'lu' ? 'LUIS' : 'QnA'}_${target}`,
recognizers: {},
});

const CrossTrainedRecognizerTemplate = (): {
$kind: string;
export const CrossTrainedRecognizerTemplate = (): {
$kind: SDKKinds.CrossTrainedRecognizerSet;
recognizers: string[];
} => ({
$kind: SDKKinds.CrossTrainedRecognizerSet,
recognizers: [],
});

export const OrchestratorRecognizerTemplate = (target: string, fileName: string) => ({
$kind: SDKKinds.OrchestratorRecognizer,
modelPath: '=settings.orchestrator.modelPath',
snapshotPath: `=settings.orchestrator.snapshots.${fileName.replace(/[.-]/g, '_')}`,
});

export const getMultiLanguagueRecognizerDialog = (
target: string,
files: { empty: boolean; id: string }[],
Expand Down Expand Up @@ -140,11 +146,11 @@ export const Recognizer = React.memo((props: { projectId: string }) => {
const luFiles = useRecoilValue(luFilesState(projectId));
const qnaFiles = useRecoilValue(qnaFilesState(projectId));
const settings = useRecoilValue(settingsState(projectId));
const curRecognizers = useRecoilValue(recognizersSelectorFamily(projectId));

useEffect(() => {
let recognizers: RecognizerFile[] = [];
dialogs
.filter((dialog) => !dialog.isFormDialog)
.filter((dialog) => isCrossTrainedRecognizerSet(dialog) || isLuisRecognizer(dialog))
.forEach((dialog) => {
const filtedLus = luFiles.filter((item) => getBaseName(item.id) === dialog.id);
Expand All @@ -160,17 +166,19 @@ export const Recognizer = React.memo((props: { projectId: string }) => {

if (luisRecognizers.length) {
recognizers.push(luMultiLanguagueRecognizer);
recognizers = [...recognizers, ...preserveRecognizer(luisRecognizers, [])];
recognizers = [...recognizers, ...preserveRecognizer(luisRecognizers, curRecognizers)];
}
if (isCrossTrain) {
recognizers.push(crossTrainedRecognizer);
}
if (isCrossTrain && qnaMakeRecognizers.length) {
recognizers.push(qnaMultiLanguagueRecognizer);
recognizers = [...recognizers, ...preserveRecognizer(qnaMakeRecognizers, [])];
recognizers = [...recognizers, ...preserveRecognizer(qnaMakeRecognizers, curRecognizers)];
}
});
setRecognizers(recognizers);
if (!isEqual([...recognizers].sort(), [...curRecognizers].sort())) {
setRecognizers(recognizers);
}
}, [dialogs, luFiles, qnaFiles]);

useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/client/src/recoilModel/atoms/botState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const recognizerIdsState = atomFamily<string[], string>({
export const recognizerState = atomFamily<RecognizerFile, { projectId: string; id: string }>({
key: getFullyQualifiedKey('recognizer'),
default: () => {
return { id: '', content: {}, lastModified: '' };
return {} as RecognizerFile;
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/* eslint-disable react-hooks/rules-of-hooks */
import { SDKKinds } from '@bfc/shared';
import { LuProviderType } from '@botframework-composer/types';
import { CallbackInterface, useRecoilCallback } from 'recoil';

import { recognizerState } from '../atoms';
import { LuisRecognizerTemplate, OrchestratorRecognizerTemplate } from '../Recognizers';

import { recognizersSelectorFamily } from './../selectors/recognizers';

const LuProviderRecognizer = [SDKKinds.OrchestratorRecognizer, SDKKinds.LuisRecognizer];

const templates = {
[SDKKinds.OrchestratorRecognizer]: OrchestratorRecognizerTemplate,
[SDKKinds.LuisRecognizer]: LuisRecognizerTemplate,
};

export const recognizerDispatcher = () => {
const updateRecognizer = useRecoilCallback(
({ set }: CallbackInterface) => async (projectId: string, recognizerId: string, content: any) => {
set(recognizerState({ projectId, id: recognizerId }), content);
({ set, snapshot }: CallbackInterface) => async (projectId: string, dialogId: string, kind: LuProviderType) => {
const recognizers = await snapshot.getPromise(recognizersSelectorFamily(projectId));

const updates = recognizers.filter(
({ id, content }) =>
id.split('.')[0] === dialogId && LuProviderRecognizer.includes(content.$kind) && content.$kind !== kind
);

updates.forEach(({ id }) => {
set(recognizerState({ projectId, id }), {
id,
content: templates[kind](dialogId, id.replace('.lu.dialog', '')),
});
});
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { useRecoilCallback, CallbackInterface } from 'recoil';
import isArray from 'lodash/isArray';
import formatMessage from 'format-message';
import { FeatureFlagKey, FeatureFlagMap } from '@bfc/shared';
import { FeatureFlagMap, FeatureFlagKey } from '@botframework-composer/types';

import httpClient from '../../utils/httpUtil';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { validateDialog } from '@bfc/indexers';
import { DialogInfo } from '@bfc/shared';

import { botProjectIdsState, dialogIdsState, schemasState, lgFilesState, luFilesState, dialogState } from '../atoms';
import { getLuProvider } from '../../utils/dialogUtil';

import { recognizersSelectorFamily } from './recognizers';

type validateDialogSelectorFamilyParams = { projectId: string; dialogId: string };
const validateDialogSelectorFamily = selectorFamily({
Expand All @@ -15,8 +18,9 @@ const validateDialogSelectorFamily = selectorFamily({
const schemas = get(schemasState(projectId));
const lgFiles = get(lgFilesState(projectId));
const luFiles = get(luFilesState(projectId));

return { ...dialog, diagnostics: validateDialog(dialog, schemas.sdk.content, lgFiles, luFiles) };
const recognizers = get(recognizersSelectorFamily(projectId));
const luProvider = getLuProvider(dialogId, recognizers);
return { ...dialog, diagnostics: validateDialog(dialog, schemas.sdk.content, lgFiles, luFiles), luProvider };
},
});

Expand Down
15 changes: 14 additions & 1 deletion Composer/packages/client/src/shell/useShell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
// Licensed under the MIT License.

import { useMemo, useRef } from 'react';
import { ShellApi, ShellData, Shell, DialogSchemaFile, DialogInfo, SDKKinds } from '@botframework-composer/types';
import {
ShellApi,
ShellData,
Shell,
DialogSchemaFile,
DialogInfo,
FeatureFlagKey,
SDKKinds,
} from '@botframework-composer/types';
import { useRecoilValue } from 'recoil';
import formatMessage from 'format-message';

Expand All @@ -27,6 +35,7 @@ import {
luFilesState,
rateInfoState,
rootBotProjectIdSelector,
featureFlagsState,
} from '../recoilModel';
import { undoFunctionState } from '../recoilModel/undo/history';
import { skillsStateSelector } from '../recoilModel/selectors';
Expand Down Expand Up @@ -86,6 +95,7 @@ export function useShell(source: EventSource, projectId: string): Shell {

const userSettings = useRecoilValue(userSettingsState);
const clipboardActions = useRecoilValue(clipboardActionsState);
const featureFlags = useRecoilValue(featureFlagsState);
const {
updateDialog,
updateDialogSchema,
Expand All @@ -103,6 +113,7 @@ export function useShell(source: EventSource, projectId: string): Shell {
updateZoomRate,
reloadProject,
setApplicationLevelError,
updateRecognizer,
} = useRecoilValue(dispatcherState);

const lgApi = useLgApi(projectId);
Expand Down Expand Up @@ -202,6 +213,7 @@ export function useShell(source: EventSource, projectId: string): Shell {
commitChanges();
});
},
updateRecognizer,
updateRegExIntent: updateRegExIntentHandler,
renameRegExIntent: renameRegExIntentHandler,
updateIntentTrigger: updateIntentTriggerHandler,
Expand All @@ -225,6 +237,7 @@ export function useShell(source: EventSource, projectId: string): Shell {
redo,
commitChanges,
displayManifestModal: (skillId) => displayManifestModal(skillId, projectId),
isFeatureEnabled: (featureFlagKey: FeatureFlagKey): boolean => featureFlags?.[featureFlagKey]?.enabled ?? false,
updateDialogSchema: async (dialogSchema: DialogSchemaFile) => {
updateDialogSchema(dialogSchema, projectId);
},
Expand Down
10 changes: 7 additions & 3 deletions Composer/packages/client/src/utils/buildUtil.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { DialogInfo, LuFile, SDKKinds } from '@bfc/shared';
import { DialogInfo, LuFile, QnAFile, SDKKinds } from '@bfc/shared';

import { LuisConfig, QnaConfig } from '../constants';

import { getReferredLuFiles } from './luUtil';
import { getLuisBuildLuFiles } from './luUtil';
import { getReferredQnaFiles } from './qnaUtil';
import { getBaseName } from './fileUtil';

Expand Down Expand Up @@ -45,7 +45,7 @@ export function createCrossTrainConfig(dialogs: DialogInfo[], luFiles: LuFile[],

export function isBuildConfigComplete(config, dialogs, luFiles, qnaFiles) {
let complete = true;
if (getReferredLuFiles(luFiles, dialogs).length > 0) {
if (getLuisBuildLuFiles(luFiles, dialogs).length > 0) {
if (Object.values(LuisConfig).some((luisConfigKey) => config.luis[luisConfigKey] === '')) {
complete = false;
}
Expand All @@ -58,6 +58,10 @@ export function isBuildConfigComplete(config, dialogs, luFiles, qnaFiles) {
return complete;
}

export function isKeyRequired(dialogs: DialogInfo[], luFiles: LuFile[], qnaFiles: QnAFile[]) {
return getLuisBuildLuFiles(luFiles, dialogs).length || getReferredQnaFiles(qnaFiles, dialogs).length;
}

// return true if dialogs have one with default recognizer.
export function needsBuild(dialogs) {
return dialogs.some((dialog) => typeof dialog.content.recognizer === 'string');
Expand Down
Loading

0 comments on commit 74a95ad

Please sign in to comment.