Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Trigger UI Schema #4079

Merged
merged 67 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
c1df63a
chore: move TriggerCreationModal to folder
yeze322 Sep 10, 2020
e777525
chore: move styles into styles.ts
yeze322 Sep 10, 2020
11aea2d
chore: move validators out
yeze322 Sep 10, 2020
45a29ef
Extract dropdown options as constants
yeze322 Sep 10, 2020
360fd69
remove outdated dropdown option generators
yeze322 Sep 10, 2020
bde230d
don't re-declare SDKKinds as type key
yeze322 Sep 10, 2020
eb76dd0
remove initialError, fix tslint
yeze322 Sep 10, 2020
8d80721
fix warning icon size
yeze322 Sep 10, 2020
7dd1340
refactor show warning logic
yeze322 Sep 10, 2020
5d4a0d9
move static func outside TriggerModal
yeze322 Sep 11, 2020
134568e
refactor: move trigger widget out of Modal
yeze322 Sep 11, 2020
d5d9df8
Merge branch 'main' into uischema/trigger
yeze322 Sep 24, 2020
d04c877
replay changes in #4117 'mutiple projects'
yeze322 Sep 24, 2020
732ae47
fix a wrong import path
yeze322 Sep 24, 2020
a86389b
Merge branch 'main' into uischema/trigger
yeze322 Sep 27, 2020
2c75030
Merge branch 'main' into uischema/trigger
yeze322 Oct 14, 2020
f6482a1
refactor: extract TriggerDropdownGroup
yeze322 Oct 14, 2020
78413bc
define builtinSchema
yeze322 Oct 14, 2020
2635ccc
TriggerOptionTree
yeze322 Oct 14, 2020
7a6891c
remove duplicated $kinds
yeze322 Oct 14, 2020
ea57599
link leaf ndoe to parent node
yeze322 Oct 17, 2020
235b99d
migrate to option tree
yeze322 Oct 17, 2020
e72611a
Merge branch 'main' into uischema/trigger
yeze322 Oct 19, 2020
1f3824e
fix a React grammar
yeze322 Oct 19, 2020
f186639
rename builtinSchema
yeze322 Oct 19, 2020
ba8013a
refactor the warning icon logic of trigger modal
yeze322 Oct 19, 2020
80cd840
remove unreferenced utils
yeze322 Oct 19, 2020
a049f21
add a todo
yeze322 Oct 19, 2020
b6d5978
fix UT by adding data-testid
yeze322 Oct 19, 2020
23dd5b8
declare TriggerUISchema in extension
yeze322 Oct 19, 2020
4d70307
use trigger uischema from extension context
yeze322 Oct 19, 2020
f3a76a4
check trigger option existence
yeze322 Oct 19, 2020
2e8cf9b
sort trigger dropdown labels
yeze322 Oct 19, 2020
ce3b69d
Merge branch 'main' into uischema/trigger
cwhitten Oct 19, 2020
7d912c7
Merge branch 'main' into uischema/trigger
yeze322 Oct 20, 2020
7f918b7
move root text out of tree utils
yeze322 Oct 21, 2020
2aceb82
pass in option compare fn
yeze322 Oct 21, 2020
4718f6f
add UT for triggerOptionTree
yeze322 Oct 21, 2020
60615fa
Merge branch 'uischema/trigger' of https://github.com/yeze322/BotFram…
yeze322 Oct 21, 2020
9027017
Merge branch 'main' into uischema/trigger
yeze322 Oct 30, 2020
66c6c37
align icon size with main
yeze322 Nov 18, 2020
4693034
Merge branch 'main' into uischema/trigger
yeze322 Nov 18, 2020
d85f49f
migrate 1.2 PVA logic
yeze322 Nov 18, 2020
9b92c0a
use 'Boolean' to filter trigger menus
yeze322 Nov 18, 2020
e844fa3
wrap trigger UI Schema with formatMessage
yeze322 Nov 18, 2020
a569fbf
add 'px' unit to styles
yeze322 Nov 18, 2020
7dafd08
Merge branch 'uischema/trigger' of https://github.com/yeze322/BotFram…
yeze322 Nov 30, 2020
42ab589
Merge branch 'main' into uischema/trigger
yeze322 Nov 30, 2020
3b865a0
add trigger menu order
yeze322 Nov 30, 2020
fe233c9
'order' property to manage trigger order
yeze322 Nov 30, 2020
6261692
early returning & add comments
yeze322 Nov 30, 2020
3bf9618
avoid duplicated iteration and add comments
yeze322 Nov 30, 2020
d6c5c29
fix trigger modal UT
yeze322 Nov 30, 2020
19554e7
lint
yeze322 Nov 30, 2020
7d2532b
Merge branch 'main' into uischema/trigger
yeze322 Dec 11, 2020
e7dc9ae
Merge branch 'main' into uischema/trigger
yeze322 Jan 8, 2021
2eb8d89
replay Ben's commit
yeze322 Jan 8, 2021
328207b
Merge branch 'main' into uischema/trigger
yeze322 Jan 11, 2021
7e26895
Merge branch 'main' into uischema/trigger
yeze322 Jan 13, 2021
9e3755f
Merge branch 'main' into uischema/trigger
yeze322 Jan 15, 2021
f4cc1d5
Merge branch 'main' into uischema/trigger
yeze322 Jan 19, 2021
d559d08
Merge branch 'main' into uischema/trigger
yeze322 Jan 20, 2021
385c848
Merge branch 'main' into uischema/trigger
a-b-r-o-w-n Jan 21, 2021
2fa8db1
CI fix
yeze322 Jan 22, 2021
7ff43f2
Merge branch 'main' into uischema/trigger
yeze322 Jan 25, 2021
c3c6091
Merge branch 'main' into uischema/trigger
yeze322 Jan 26, 2021
8c44790
Merge branch 'main' into uischema/trigger
yeze322 Jan 26, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,45 @@

import * as React from 'react';
import { fireEvent, waitFor } from '@botframework-composer/test-utils';
import { EditorExtension, PluginConfig } from '@bfc/extension-client';

import { TriggerCreationModal } from '../../src/components/ProjectTree/TriggerCreationModal';
import { renderWithRecoil } from '../testUtils';
import { TriggerCreationModal } from '../../../src/components/TriggerCreationModal';
import { renderWithRecoil } from '../../testUtils';

const projectId = '123a-bv3c4';

describe('<TriggerCreationModal/>', () => {
const onSubmitMock = jest.fn();
const onDismissMock = jest.fn();

const pluginsStub: PluginConfig = {
uiSchema: {
'Microsoft.OnIntent': {
trigger: {
label: 'Intent recognized',
order: 1,
},
},
'Microsoft.OnQnAMatch': {
trigger: {
label: 'QnA Intent recognized',
order: 2,
},
},
},
};

function renderComponent() {
return renderWithRecoil(
<TriggerCreationModal
isOpen
dialogId={'todobot'}
projectId={projectId}
onDismiss={onDismissMock}
onSubmit={onSubmitMock}
/>
<EditorExtension plugins={pluginsStub} projectId={''} shell={{ api: {} as any, data: {} as any }}>
<TriggerCreationModal
isOpen
dialogId={'todobot'}
projectId={projectId}
onDismiss={onDismissMock}
onSubmit={onSubmitMock}
/>
</EditorExtension>
);
}

Expand All @@ -30,7 +50,7 @@ describe('<TriggerCreationModal/>', () => {
expect(component.container).toBeDefined();
});

it('hould create a Luis Intent recognized', async () => {
it('should create a Luis Intent recognized', async () => {
const component = renderComponent();
const triggerType = component.getByTestId('triggerTypeDropDown');
fireEvent.click(triggerType);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { TriggerUISchema } from '@bfc/extension-client';
import { SDKKinds } from '@botframework-composer/types';

import {
generateTriggerOptionTree,
TriggerOptionGroupNode,
} from '../../../src/components/TriggerCreationModal/TriggerOptionTree';

describe('generateTriggerOptionTree()', () => {
it('can generate one layer tree.', () => {
const simpleTriggerUIOptions: TriggerUISchema = {
[SDKKinds.OnIntent]: {
label: '1.OnIntent',
order: 1,
},
[SDKKinds.OnInvokeActivity]: {
label: '2.OnInvokeActivity',
order: 2,
},
};
const tree = generateTriggerOptionTree(simpleTriggerUIOptions, 'Select a trigger', 'Which trigger?');

expect(tree.prompt).toEqual('Select a trigger');
expect(tree.placeholder).toEqual('Which trigger?');

expect(tree.parent).toBeNull();
expect(tree.children.length).toEqual(2);

expect(tree.children[0].label).toEqual('1.OnIntent');
expect(tree.children[0].parent).toEqual(tree);

expect(tree.children[1].label).toEqual('2.OnInvokeActivity');
expect(tree.children[1].parent).toEqual(tree);
});

it('can generate tree with submenu.', () => {
const advancedTriggerUIOptions: TriggerUISchema = {
[SDKKinds.OnIntent]: {
label: '1.OnIntent',
order: 1,
},
[SDKKinds.OnTypingActivity]: {
label: '2.1.OnTypingActivity',
order: 2.1,
submenu: {
label: '2.Activities',
prompt: 'Select an activity trigger',
placeholder: 'Which activity?',
},
},
[SDKKinds.OnEventActivity]: {
label: '2.2OnEventActivity',
order: 2.2,
submenu: '2.Activities',
},
[SDKKinds.OnInvokeActivity]: {
label: '2.3OnInvokeActivity',
order: 2.3,
submenu: '2.Activities',
},
};
const tree = generateTriggerOptionTree(advancedTriggerUIOptions, 'Select a trigger', 'Which trigger?');

expect(tree.children.length).toEqual(2);

expect(tree.children[0].label).toEqual('1.OnIntent');
expect(tree.children[0].parent).toEqual(tree);

const secondChild = tree.children[1] as TriggerOptionGroupNode;
expect(secondChild.label).toEqual('2.Activities');
expect(secondChild.prompt).toEqual('Select an activity trigger');
expect(secondChild.children.length).toEqual(3);

expect(secondChild.children[0].label).toEqual('2.1.OnTypingActivity');
expect(secondChild.children[0].parent).toEqual(secondChild);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { fireEvent } from '@botframework-composer/test-utils';
import { renderWithRecoil } from '../testUtils';
import { SAMPLE_DIALOG } from '../mocks/sampleDialog';
import { ProjectTree } from '../../src/components/ProjectTree/ProjectTree';
import { TriggerCreationModal } from '../../src/components/ProjectTree/TriggerCreationModal';
import { TriggerCreationModal } from '../../src/components/TriggerCreationModal';
import { CreateDialogModal } from '../../src/pages/design/createDialogModal';
import {
dialogsSelectorFamily,
Expand Down
49 changes: 0 additions & 49 deletions Composer/packages/client/__tests__/utils/dialogUtil.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {
updateRegExIntent,
yeze322 marked this conversation as resolved.
Show resolved Hide resolved
createSelectedPath,
deleteTrigger,
getTriggerTypes,
getEventTypes,
getActivityTypes,
getFriendlyName,
getBreadcrumbLabel,
getSelected,
Expand Down Expand Up @@ -181,52 +178,6 @@ describe('deleteTrigger', () => {
});
});

describe('getTriggerTypes', () => {
it('return trigger types', () => {
const triggerTypes = getTriggerTypes();
expect(triggerTypes).toEqual([
{ key: 'Microsoft.OnIntent', text: 'Intent recognized' },
{ key: 'Microsoft.OnQnAMatch', text: 'QnA Intent recognized' },
{ key: 'Microsoft.OnUnknownIntent', text: 'Unknown intent' },
{ key: 'Microsoft.OnDialogEvent', text: 'Dialog events' },
{ key: 'Microsoft.OnActivity', text: 'Activities' },
{ key: 'Microsoft.OnChooseIntent', text: 'Duplicated intents recognized' },
{ key: 'OnCustomEvent', text: 'Custom events' },
]);
});
});

describe('getEventTypes', () => {
it('return event types', () => {
const eventTypes = getEventTypes();
expect(eventTypes).toEqual([
{ key: 'Microsoft.OnBeginDialog', text: 'Dialog started (Begin dialog event)' },
{ key: 'Microsoft.OnCancelDialog', text: 'Dialog cancelled (Cancel dialog event)' },
{ key: 'Microsoft.OnError', text: 'Error occurred (Error event)' },
{ key: 'Microsoft.OnRepromptDialog', text: 'Re-prompt for input (Reprompt dialog event)' },
]);
});
});

describe('getActivityTypes', () => {
it('return activity types', () => {
const activityTypes = getActivityTypes();
expect(activityTypes).toEqual([
{ key: 'Microsoft.OnActivity', text: 'Activities (Activity received)' },
{ key: 'Microsoft.OnConversationUpdateActivity', text: 'Greeting (ConversationUpdate activity)' },
{ key: 'Microsoft.OnEndOfConversationActivity', text: 'Conversation ended (EndOfConversation activity)' },
{ key: 'Microsoft.OnEventActivity', text: 'Event received (Event activity)' },
{ key: 'Microsoft.OnHandoffActivity', text: 'Handover to human (Handoff activity)' },
{ key: 'Microsoft.OnInvokeActivity', text: 'Conversation invoked (Invoke activity)' },
{ key: 'Microsoft.OnTypingActivity', text: 'User is typing (Typing activity)' },
{ key: 'Microsoft.OnMessageActivity', text: 'Message received (Message received activity)' },
{ key: 'Microsoft.OnMessageDeleteActivity', text: 'Message deleted (Message deleted activity)' },
{ key: 'Microsoft.OnMessageReactionActivity', text: 'Message reaction (Message reaction activity)' },
{ key: 'Microsoft.OnMessageUpdateActivity', text: 'Message updated (Message updated activity)' },
]);
});
});

describe('getFriendlyName', () => {
it('return friendly name', () => {
const name = getFriendlyName(dialogs[0].content);
Expand Down
20 changes: 9 additions & 11 deletions Composer/packages/client/config/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ const dotenvFiles = [
// since normally you expect tests to produce the same
// results for everyone
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
paths.dotenv
paths.dotenv,
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set. Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
dotenvFiles.forEach(dotenvFile => {
dotenvFiles.forEach((dotenvFile) => {
if (fs.existsSync(dotenvFile)) {
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile
path: dotenvFile,
})
);
}
Expand All @@ -61,8 +61,8 @@ function getGitSha() {
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(folder => folder && !path.isAbsolute(folder))
.map(folder => path.resolve(appDirectory, folder))
.filter((folder) => folder && !path.isAbsolute(folder))
.map((folder) => path.resolve(appDirectory, folder))
.join(path.delimiter);

// Grab NODE_ENV and COMPOSER_* environment variables and prepare them to be
Expand All @@ -71,7 +71,7 @@ const COMPOSER = /^COMPOSER_/i;

function getClientEnvironment(publicUrl) {
const raw = Object.keys(process.env)
.filter(key => COMPOSER.test(key))
.filter((key) => COMPOSER.test(key))
.reduce(
(env, key) => {
env[key] = process.env[key];
Expand All @@ -86,24 +86,22 @@ function getClientEnvironment(publicUrl) {
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
PUBLIC_URL: publicUrl,
GIT_SHA: getGitSha()
.toString()
.replace('\n', ''),
GIT_SHA: getGitSha().toString().replace('\n', ''),
SDK_PACKAGE_VERSION: '4.11.0', // TODO: change this when Composer supports custom schema/custom runtime
COMPOSER_VERSION: '1.3.1',
LOCAL_PUBLISH_PATH:
process.env.LOCAL_PUBLISH_PATH || path.resolve(process.cwd(), '../../../extensions/localPublish/hostedBots'),
WEBLOGIN_CLIENTID: process.env.WEBLOGIN_CLIENTID,
WEBLOGIN_TENANTID: process.env.WEBLOGIN_TENANTID,
WEBLOGIN_REDIRECTURL: process.env.WEBLOGIN_REDIRECTURL
WEBLOGIN_REDIRECTURL: process.env.WEBLOGIN_REDIRECTURL,
}
);
// Stringify all values so we can feed into Webpack DefinePlugin
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {})
}, {}),
};

return { raw, stringified };
Expand Down
Loading