Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Composer/packages/client/src/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const content = css`
padding: 20px;
position: relative;
overflow: auto;
height: 100%;
height: calc(100% - 40px);
label: PageContent;
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const initialFormDataErrors = {

const getLuDiagnostics = (intent: string, triggerPhrases: string) => {
const content = `#${intent}\n${triggerPhrases}`;
const { diagnostics } = luIndexer.parse(content);
const { diagnostics } = luIndexer.parse(content, '', {});
return combineMessage(diagnostics);
};

Expand Down Expand Up @@ -431,6 +431,7 @@ export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = (props)
projectId,
fileId: dialogId,
sectionId: PlaceHolderSectionName,
luFeatures: {},
}}
placeholder={inlineModePlaceholder}
value={formData.triggerPhrases}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,12 @@ const CodeEditor: React.FC<CodeEditorProps> = (props) => {
[file, intent, projectId]
);

const luFeatures = settings?.luFeatures || {};
const luOption = {
projectId,
fileId: file?.id || dialogId,
sectionId: intent?.Name,
luFeatures,
};

const handleSettingsChange = (settings: Partial<CodeEditorSettings>) => {
Expand Down Expand Up @@ -158,6 +160,7 @@ const CodeEditor: React.FC<CodeEditorProps> = (props) => {
editorSettings={userSettings.codeEditor}
luOption={{
fileId: dialogId,
luFeatures,
}}
options={{
readOnly: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import { dispatcherState } from '../../../recoilModel/DispatcherWrapper';
import { Dispatcher } from '..';
import { luDispatcher } from '../lu';

const luFeatures = {};

jest.mock('../../parsers/luWorker', () => {
return {
parse: (id, content) => ({ id, content }),
parse: (id, content, luFeatures) => ({ id, content, luFeatures }),
addIntent: require('@bfc/indexers/lib/utils/luUtil').addIntent,
addIntents: require('@bfc/indexers/lib/utils/luUtil').addIntents,
updateIntent: require('@bfc/indexers/lib/utils/luUtil').updateIntent,
Expand All @@ -29,7 +31,7 @@ const file1 = {
content: `\r\n# Hello\r\n-hi`,
};

const luFiles = [luUtil.parse(file1.id, file1.content)] as LuFile[];
const luFiles = [luUtil.parse(file1.id, file1.content, luFeatures)] as LuFile[];

const getLuIntent = (Name, Body): LuIntentSection =>
({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ describe('setting dispatcher', () => {
MicrosoftAppPassword: 'test',
luis: { ...settings.luis, authoringKey: 'test', endpointKey: 'test' },
qna: { ...settings.qna, subscriptionKey: 'test', endpointKey: 'test' },
luFeatures: {},
});
});

Expand Down
52 changes: 38 additions & 14 deletions Composer/packages/client/src/recoilModel/dispatchers/lu.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/* eslint-disable react-hooks/rules-of-hooks */
import { LuFile, LuIntentSection } from '@bfc/shared';
import { LuFile, LuIntentSection, ILUFeaturesConfig } from '@bfc/shared';
import { useRecoilCallback, CallbackInterface } from 'recoil';
import differenceBy from 'lodash/differenceBy';
import formatMessage from 'format-message';
Expand All @@ -19,7 +19,12 @@ const intentIsNotEmpty = ({ Name, Body }) => {
// fill other locale luFile new added intent with '- '
const initialBody = '- ';

export const updateLuFileState = async (luFiles: LuFile[], updatedLuFile: LuFile, projectId: string) => {
const updateLuFileState = async (
luFiles: LuFile[],
updatedLuFile: LuFile,
projectId: string,
luFeatures: ILUFeaturesConfig
) => {
const { id } = updatedLuFile;
const dialogId = getBaseName(id);
const locale = getExtension(id);
Expand Down Expand Up @@ -50,10 +55,11 @@ export const updateLuFileState = async (luFiles: LuFile[], updatedLuFile: LuFile
// sync add/remove intents
if (onlyAdds || onlyDeletes) {
for (const item of sameIdOtherLocaleFiles) {
let newLuFile = (await luWorker.addIntents(item, addedIntents)) as LuFile;
let newLuFile = (await luWorker.addIntents(item, addedIntents, luFeatures)) as LuFile;
newLuFile = (await luWorker.removeIntents(
newLuFile,
deletedIntents.map(({ Name }) => Name)
deletedIntents.map(({ Name }) => Name),
luFeatures
)) as LuFile;
changes.push(newLuFile);
}
Expand All @@ -76,9 +82,9 @@ export const createLuFileState = async (
const { set, snapshot } = callbackHelpers;
const luFiles = await snapshot.getPromise(luFilesState(projectId));
const locale = await snapshot.getPromise(localeState(projectId));
const { languages } = await snapshot.getPromise(settingsState(projectId));
const { languages, luFeatures } = await snapshot.getPromise(settingsState(projectId));
const createdLuId = `${id}.${locale}`;
const createdLuFile = (await luWorker.parse(id, content)) as LuFile;
const createdLuFile = (await luWorker.parse(id, content, luFeatures)) as LuFile;
if (luFiles.find((lu) => lu.id === createdLuId)) {
throw new Error('lu file already exist');
}
Expand Down Expand Up @@ -127,9 +133,11 @@ export const luDispatcher = () => {
}) => {
const { set, snapshot } = callbackHelpers;
const luFiles = await snapshot.getPromise(luFilesState(projectId));
const { luFeatures } = await snapshot.getPromise(settingsState(projectId));

try {
const updatedFile = (await luWorker.parse(id, content)) as LuFile;
const result = await updateLuFileState(luFiles, updatedFile, projectId);
const updatedFile = (await luWorker.parse(id, content, luFeatures)) as LuFile;
const result = await updateLuFileState(luFiles, updatedFile, projectId, luFeatures);
set(luFilesState(projectId), result);
} catch (error) {
setError(callbackHelpers, error);
Expand All @@ -151,6 +159,8 @@ export const luDispatcher = () => {
}) => {
const { set, snapshot } = callbackHelpers;
const luFiles = await snapshot.getPromise(luFilesState(projectId));
const { luFeatures } = await snapshot.getPromise(settingsState(projectId));

const luFile = luFiles.find((temp) => temp.id === id);
if (!luFile) return luFiles;

Expand All @@ -168,7 +178,12 @@ export const luDispatcher = () => {
if (intent.Name !== intentName) {
const changes: LuFile[] = [];
for (const item of sameIdOtherLocaleFiles) {
const updatedFile = (await luWorker.updateIntent(item, intentName, { Name: intent.Name })) as LuFile;
const updatedFile = (await luWorker.updateIntent(
item,
intentName,
{ Name: intent.Name },
luFeatures
)) as LuFile;
changes.push(updatedFile);
}

Expand All @@ -180,7 +195,12 @@ export const luDispatcher = () => {
});
// body change, only update current locale file
} else {
const updatedFile = (await luWorker.updateIntent(luFile, intentName, { Body: intent.Body })) as LuFile;
const updatedFile = (await luWorker.updateIntent(
luFile,
intentName,
{ Body: intent.Body },
luFeatures
)) as LuFile;
set(luFilesState(projectId), (luFiles) => {
return luFiles.map((file) => {
return file.id === id ? updatedFile : file;
Expand All @@ -205,11 +225,13 @@ export const luDispatcher = () => {
}) => {
const { set, snapshot } = callbackHelpers;
const luFiles = await snapshot.getPromise(luFilesState(projectId));
const { luFeatures } = await snapshot.getPromise(settingsState(projectId));

const file = luFiles.find((temp) => temp.id === id);
if (!file) return luFiles;
try {
const updatedFile = (await luWorker.addIntent(file, intent)) as LuFile;
const result = await updateLuFileState(luFiles, updatedFile, projectId);
const updatedFile = (await luWorker.addIntent(file, intent, luFeatures)) as LuFile;
const result = await updateLuFileState(luFiles, updatedFile, projectId, luFeatures);
set(luFilesState(projectId), result);
} catch (error) {
setError(callbackHelpers, error);
Expand All @@ -229,11 +251,13 @@ export const luDispatcher = () => {
}) => {
const { set, snapshot } = callbackHelpers;
const luFiles = await snapshot.getPromise(luFilesState(projectId));
const { luFeatures } = await snapshot.getPromise(settingsState(projectId));

const file = luFiles.find((temp) => temp.id === id);
if (!file) return luFiles;
try {
const updatedFile = (await luWorker.removeIntent(file, intentName)) as LuFile;
const result = await updateLuFileState(luFiles, updatedFile, projectId);
const updatedFile = (await luWorker.removeIntent(file, intentName, luFeatures)) as LuFile;
const result = await updateLuFileState(luFiles, updatedFile, projectId, luFeatures);
set(luFilesState(projectId), result);
} catch (error) {
setError(callbackHelpers, error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { Range, Position, LuIntentSection } from '@bfc/shared';

import luWorker from '../luWorker';

const luFeatures = {};

jest.mock('./../workers/luParser.worker.ts', () => {
class Test {
onmessage = (data) => data;
Expand All @@ -29,7 +31,7 @@ describe('test lu worker', () => {
it('get expected parse result', async () => {
const content = `# Hello
- hi`;
const result: any = await luWorker.parse('', content);
const result: any = await luWorker.parse('', content, luFeatures);
const expected = [
{ Body: '- hi', Entities: [], Name: 'Hello', range: new Range(new Position(1, 0), new Position(2, 4)) },
];
Expand All @@ -45,7 +47,7 @@ hi
@ simple friendsName

`;
const { intents, diagnostics }: any = await luWorker.parse('', content);
const { intents, diagnostics }: any = await luWorker.parse('', content, luFeatures);
expect(intents.length).toEqual(1);
expect(diagnostics.length).toEqual(1);
expect(diagnostics[0].range.start.line).toEqual(2);
Expand All @@ -55,7 +57,7 @@ hi
});

it('get expected add intent result', async () => {
const result: any = await luWorker.addIntent(luFile, getLuIntent('New', '-IntentValue'));
const result: any = await luWorker.addIntent(luFile, getLuIntent('New', '-IntentValue'), luFeatures);
const expected = {
Body: '-IntentValue',
Entities: [],
Expand All @@ -68,10 +70,11 @@ hi
});

it('get expected add intents result', async () => {
const result: any = await luWorker.addIntents(luFile, [
getLuIntent('New1', '-IntentValue1'),
getLuIntent('New2', '-IntentValue2'),
]);
const result: any = await luWorker.addIntents(
luFile,
[getLuIntent('New1', '-IntentValue1'), getLuIntent('New2', '-IntentValue2')],
luFeatures
);
const expected = {
Body: '-IntentValue2',
Entities: [],
Expand All @@ -84,7 +87,7 @@ hi
});

it('get expected update intent result', async () => {
const result: any = await luWorker.updateIntent(luFile, 'New', getLuIntent('New', '-update'));
const result: any = await luWorker.updateIntent(luFile, 'New', getLuIntent('New', '-update'), luFeatures);
const expected = {
Body: '-update',
Entities: [],
Expand All @@ -97,14 +100,14 @@ hi
});

it('get expected remove intent result', async () => {
const result: any = await luWorker.removeIntent(luFile, 'New2');
const result: any = await luWorker.removeIntent(luFile, 'New2', luFeatures);
expect(result.intents.length).toBe(3);
expect(result.intents[3]).toBeUndefined();
luFile = result;
});

it('get expected remove intent result', async () => {
const result: any = await luWorker.removeIntents(luFile, ['New1', 'New']);
const result: any = await luWorker.removeIntents(luFile, ['New1', 'New'], luFeatures);
expect(result.intents.length).toBe(1);
});
});
24 changes: 12 additions & 12 deletions Composer/packages/client/src/recoilModel/parsers/luWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,33 @@ import {
} from './types';
// Wrapper class
class LuWorker extends BaseWorker<LuActionType> {
parse(id: string, content: string) {
const payload = { id, content };
parse(id: string, content: string, luFeatures) {
const payload = { id, content, luFeatures };
return this.sendMsg<LuParsePayload>(LuActionType.Parse, payload);
}

addIntent(luFile: LuFile, intent: LuIntentSection) {
const payload = { luFile, intent };
addIntent(luFile: LuFile, intent: LuIntentSection, luFeatures) {
const payload = { luFile, intent, luFeatures };
return this.sendMsg<LuAddIntentPayload>(LuActionType.AddIntent, payload);
}

updateIntent(luFile: LuFile, intentName: string, intent?: { Name?: string; Body?: string }) {
const payload = { luFile, intentName, intent };
updateIntent(luFile: LuFile, intentName: string, intent: { Name?: string; Body?: string }, luFeatures) {
const payload = { luFile, intentName, intent, luFeatures };
return this.sendMsg<LuUpdateIntentPayload>(LuActionType.UpdateIntent, payload);
}

removeIntent(luFile: LuFile, intentName: string) {
const payload = { luFile, intentName };
removeIntent(luFile: LuFile, intentName: string, luFeatures) {
const payload = { luFile, intentName, luFeatures };
return this.sendMsg<LuRemoveIntentPayload>(LuActionType.RemoveIntent, payload);
}

addIntents(luFile: LuFile, intents: LuIntentSection[]) {
const payload = { luFile, intents };
addIntents(luFile: LuFile, intents: LuIntentSection[], luFeatures) {
const payload = { luFile, intents, luFeatures };
return this.sendMsg<LuAddIntentsPayload>(LuActionType.AddIntents, payload);
}

removeIntents(luFile: LuFile, intentNames: string[]) {
const payload = { luFile, intentNames };
removeIntents(luFile: LuFile, intentNames: string[], luFeatures) {
const payload = { luFile, intentNames, luFeatures };
return this.sendMsg<LuRemoveIntentsPayload>(LuActionType.RemoveIntents, payload);
}
}
Expand Down
9 changes: 8 additions & 1 deletion Composer/packages/client/src/recoilModel/parsers/types.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { LuIntentSection, LgFile, LuFile, QnASection, FileInfo, LgTemplate } from '@bfc/shared';
import { LuIntentSection, LgFile, LuFile, QnASection, FileInfo, LgTemplate, ILUFeaturesConfig } from '@bfc/shared';

export type LuParsePayload = {
id: string;
content: string;
luFeatures: ILUFeaturesConfig;
};

export type LuAddIntentPayload = {
luFile: LuFile;
intent: LuIntentSection;
luFeatures: ILUFeaturesConfig;
};

export type LuAddIntentsPayload = {
luFile: LuFile;
intents: LuIntentSection[];
luFeatures: ILUFeaturesConfig;
};

export type LuUpdateIntentPayload = {
luFile: LuFile;
intentName: string;
intent?: { Name?: string; Body?: string };
luFeatures: ILUFeaturesConfig;
};

export type LuRemoveIntentPayload = {
luFile: LuFile;
intentName: string;
luFeatures: ILUFeaturesConfig;
};

export type LuRemoveIntentsPayload = {
luFile: LuFile;
intentNames: string[];
luFeatures: ILUFeaturesConfig;
};

export type LgParsePayload = {
Expand Down Expand Up @@ -98,6 +104,7 @@ export type IndexPayload = {
botName: string;
schemas: any;
locale: string;
luFeatures: { key: string; value: boolean };
};

export type QnAPayload = {
Expand Down
Loading