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
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { useState, useContext } from 'react';
import { Dialog, DialogType } from 'office-ui-fabric-react';
import formatMessage from 'format-message';
import { DialogFooter, PrimaryButton, DefaultButton, Stack, TextField, IDropdownOption } from 'office-ui-fabric-react';
import { DialogFooter, PrimaryButton, DefaultButton, Stack, IDropdownOption } from 'office-ui-fabric-react';
import { Dropdown } from 'office-ui-fabric-react/lib/Dropdown';
import { get } from 'lodash';
import { appschema } from 'shared';

import {
addNewTrigger,
Expand All @@ -13,22 +12,29 @@ import {
TriggerFormDataErrors,
eventTypeKey,
intentTypeKey,
activityTypeKey,
getEventTypes,
getActivityTypes,
} from '../../utils/dialogUtil';
import { StoreContext } from '../../store';
import { DialogInfo } from '../../store/types';

import { styles, dropdownStyles, intent, dialogWindow } from './styles';
import { styles, dropdownStyles, dialogWindow } from './styles';

const isValidName = name => {
const nameRegex = /^[a-zA-Z0-9-_.]+$/;
return nameRegex.test(name);
};
const validateForm = (data: TriggerFormData): TriggerFormDataErrors => {
const errors: TriggerFormDataErrors = {};
const { $type, eventType } = data;
const { $type, specifiedType } = data;

if ($type === eventTypeKey && !eventType) {
errors.eventType = formatMessage('please select a event type');
if ($type === eventTypeKey && !specifiedType) {
errors.specifiedType = formatMessage('please select a event type');
}

if ($type === activityTypeKey && !specifiedType) {
errors.specifiedType = formatMessage('please select an activity type');
}

if (!$type) {
Expand All @@ -48,7 +54,7 @@ const initialFormData: TriggerFormData = {
errors: {},
$type: intentTypeKey,
intent: '',
eventType: '',
specifiedType: '',
};

const triggerTypeOptions: IDropdownOption[] = getTriggerTypes();
Expand All @@ -60,7 +66,6 @@ export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = props =
const { dialogs, luFiles } = state;
const luFile = luFiles.find(lu => lu.id === dialogId);
const dialogFile = dialogs.find(dialog => dialog.id === dialogId);

const onClickSubmitButton = e => {
e.preventDefault();
const errors = validateForm(formData);
Expand All @@ -78,28 +83,19 @@ export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = props =
};

const onSelectTriggerType = (e, option) => {
delete formData.eventType;
setFormData({ ...formData, $type: option.key });
};

const onSelectEventType = (e, option) => {
setFormData({ ...formData, eventType: option.key });
setFormData({ ...initialFormData, $type: option.key });
};

const onSelectIntent = (e, option) => {
setFormData({ ...formData, intent: option.key });
};

const updateForm = field => (e, newValue) => {
setFormData({
...formData,
[field]: newValue,
});
const onSelectSpecifiedTypeType = (e, option) => {
setFormData({ ...formData, specifiedType: option.key });
};

const eventTypes = get(appschema, `definitions.['${eventTypeKey}'].properties.event.enum`, []).map(t => {
return { key: t, text: t };
});
const eventTypes: IDropdownOption[] = getEventTypes();
const activityTypes: IDropdownOption[] = getActivityTypes();

const regexIntents = get(dialogFile, 'content.recognizer.intents', []);
const luisIntents = get(luFile, 'parsedContent.LUISJsonStructure.intents', []);
Expand All @@ -109,8 +105,10 @@ export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = props =
return { key: t.name || t.intent, text: t.name || t.intent };
});

const showEventDropDown = formData.$type === eventTypeKey;
const showIntentDropDown = formData.$type === intentTypeKey;
const showEventDropDown = formData.$type === eventTypeKey;
const showActivityDropDown = formData.$type === activityTypeKey;

return (
<Dialog
hidden={!isOpen}
Expand Down Expand Up @@ -143,11 +141,22 @@ export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = props =
label="What is the event?"
options={eventTypes}
styles={dropdownStyles}
onChange={onSelectEventType}
errorMessage={formData.errors.eventType}
onChange={onSelectSpecifiedTypeType}
errorMessage={formData.errors.specifiedType}
data-testid={'eventTypeDropDown'}
/>
)}
{showActivityDropDown && (
<Dropdown
placeholder="select an activity type"
label="What is the activity?"
options={activityTypes}
styles={dropdownStyles}
onChange={onSelectSpecifiedTypeType}
errorMessage={formData.errors.specifiedType}
data-testid={'activityTypeDropDown'}
/>
)}
{showIntentDropDown && (
<Dropdown
label={formatMessage('Which intent do you want to handle?')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ export const dropdownStyles = {

export const dialogWindow = css`
display: flex;
width: 400px;
flex-direction: column;
width: 400px;
height: 250px;
`;

export const textFieldlabel = {
Expand Down
43 changes: 37 additions & 6 deletions Composer/packages/client/src/utils/dialogUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ interface DialogsMap {
export interface TriggerFormData {
errors: TriggerFormDataErrors;
$type: string;
eventType: string;
intent: string;
specifiedType: string;
}

export interface TriggerFormDataErrors {
$type?: string;
eventType?: string;
intent?: string;
specifiedType?: string;
}

export function getDialog(dialogs: DialogInfo[], dialogId: string) {
Expand All @@ -34,6 +34,7 @@ export function getDialog(dialogs: DialogInfo[], dialogId: string) {

export const eventTypeKey: string = SDKTypes.OnDialogEvent;
export const intentTypeKey: string = SDKTypes.OnIntent;
export const activityTypeKey: string = SDKTypes.OnActivity;

export function getFriendlyName(data) {
if (get(data, '$designer.name')) {
Expand All @@ -54,11 +55,9 @@ export function getFriendlyName(data) {
export function insert(content, path: string, position: number | undefined, data: TriggerFormData) {
const current = get(content, path, []);
const optionalAttributes: { intent?: string; event?: string } = {};

if (data.eventType) {
optionalAttributes.event = data.eventType;
if (data.specifiedType) {
data.$type = data.specifiedType;
}

if (data.intent) {
optionalAttributes.intent = data.intent;
}
Expand Down Expand Up @@ -116,6 +115,38 @@ export function getTriggerTypes(): IDropdownOption[] {
return triggerTypes;
}

export function getEventTypes(): IDropdownOption[] {
const eventTypes: IDropdownOption[] = [
...dialogGroups[DialogGroup.DIALOG_EVENT_TYPES].types.map(t => {
let name = t as string;
const labelOverrides = ConceptLabels[t];

if (labelOverrides && labelOverrides.title) {
name = labelOverrides.title;
}

return { key: t, text: name || t };
}),
];
return eventTypes;
}

export function getActivityTypes(): IDropdownOption[] {
const activityTypes: IDropdownOption[] = [
...dialogGroups[DialogGroup.ADVANCED_EVENTS].types.map(t => {
let name = t as string;
const labelOverrides = ConceptLabels[t];

if (labelOverrides && labelOverrides.title) {
name = labelOverrides.title;
}

return { key: t, text: name || t };
}),
];
return activityTypes;
}

export function getDialogsMap(dialogs: DialogInfo[]): DialogsMap {
return dialogs.reduce((result, dialog) => {
result[dialog.id] = dialog.content;
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/lib/shared/src/dialogFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const initialDialogShape = {
},
'Microsoft.OnConversationUpdateActivity': {
$type: 'Microsoft.OnConversationUpdateActivity',
constraint: "toLower(turn.Activity.membersAdded[0].name) != 'bot'",
condition: "toLower(turn.Activity.membersAdded[0].name) != 'bot'",
},
};

Expand Down
12 changes: 9 additions & 3 deletions Composer/packages/lib/shared/src/viewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export enum DialogGroup {
LOG = 'LOG',
EVENTS = 'EVENTS',
ADVANCED_EVENTS = 'ADVANCED_EVENTS',
DIALOG_EVENT_TYPES = 'DIALOG_EVENT_TYPES',
RECOGNIZER = 'RECOGNIZER',
SELECTOR = 'SELECTOR',
OTHER = 'OTHER',
Expand Down Expand Up @@ -89,15 +90,20 @@ export const dialogGroups: DialogGroupsMap = {
types: [
SDKTypes.OnIntent,
SDKTypes.OnUnknownIntent,
SDKTypes.OnConversationUpdateActivity,
SDKTypes.OnBeginDialog,
SDKTypes.OnDialogEvent,
SDKTypes.OnActivity,
SDKTypes.OnCustomEvent,
],
},
[DialogGroup.DIALOG_EVENT_TYPES]: {
label: 'OnDialogEvents Types',
types: [SDKTypes.OnBeginDialog, SDKTypes.OnCancelDialog, SDKTypes.OnError, SDKTypes.OnRepromptDialog],
},
[DialogGroup.ADVANCED_EVENTS]: {
label: 'Advanced Events',
types: [
SDKTypes.OnActivity,
SDKTypes.OnConversationUpdateActivity,
SDKTypes.OnEndOfConversationActivity,
SDKTypes.OnEventActivity,
SDKTypes.OnHandoffActivity,
SDKTypes.OnInvokeActivity,
Expand Down