From b06016583899f79b22755ebce10fd52e0eb76c65 Mon Sep 17 00:00:00 2001 From: Soroush Date: Thu, 25 Mar 2021 13:51:20 -0700 Subject: [PATCH 1/5] enable insert/tag in trigger modal --- .../TriggerCreationModal/TriggerCreationModal.tsx | 10 ++++++++-- .../TriggerCreationModal/resolveTriggerWidget.tsx | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Composer/packages/client/src/components/TriggerCreationModal/TriggerCreationModal.tsx b/Composer/packages/client/src/components/TriggerCreationModal/TriggerCreationModal.tsx index 3cc727d1ed..c1a8b0634f 100644 --- a/Composer/packages/client/src/components/TriggerCreationModal/TriggerCreationModal.tsx +++ b/Composer/packages/client/src/components/TriggerCreationModal/TriggerCreationModal.tsx @@ -12,7 +12,7 @@ import { useRecoilValue } from 'recoil'; import { TriggerFormData, TriggerFormDataErrors } from '../../utils/dialogUtil'; import { userSettingsState } from '../../recoilModel/atoms'; -import { dialogsSelectorFamily } from '../../recoilModel'; +import { currentDialogState, dialogsSelectorFamily, localeState, luFilesState } from '../../recoilModel'; import { isRegExRecognizerType, resolveRecognizer$kind } from '../../utils/dialogValidator'; import TelemetryClient from '../../telemetry/TelemetryClient'; @@ -50,6 +50,11 @@ export const TriggerCreationModal: React.FC = (props) const isRegEx = isRegExRecognizerType(dialogFile); const regexIntents = (dialogFile?.content?.recognizer as RegexRecognizer)?.intents ?? []; + const luFiles = useRecoilValue(luFilesState(projectId)); + const locale = useRecoilValue(localeState(projectId)); + const currentDialog = useRecoilValue(currentDialogState({ projectId, dialogId })); + const luFile = luFiles.find((f) => f.id === `${currentDialog?.id}.${locale}`); + const [formData, setFormData] = useState(initialFormData); const [selectedType, setSelectedType] = useState(SDKKinds.OnIntent); @@ -76,7 +81,8 @@ export const TriggerCreationModal: React.FC = (props) setFormData, userSettings, projectId, - dialogId + dialogId, + luFile ); return ( diff --git a/Composer/packages/client/src/components/TriggerCreationModal/resolveTriggerWidget.tsx b/Composer/packages/client/src/components/TriggerCreationModal/resolveTriggerWidget.tsx index 025908beca..0c272c1207 100644 --- a/Composer/packages/client/src/components/TriggerCreationModal/resolveTriggerWidget.tsx +++ b/Composer/packages/client/src/components/TriggerCreationModal/resolveTriggerWidget.tsx @@ -6,7 +6,7 @@ import formatMessage from 'format-message'; import { Label } from 'office-ui-fabric-react/lib/Label'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { PlaceHolderSectionName } from '@bfc/indexers/lib/utils/luUtil'; -import { UserSettings, DialogInfo, SDKKinds } from '@bfc/shared'; +import { UserSettings, DialogInfo, SDKKinds, LuFile } from '@bfc/shared'; import { LuEditor, inlineModePlaceholder } from '@bfc/code-editor'; import { TriggerFormData, TriggerFormDataErrors } from '../../utils/dialogUtil'; @@ -22,7 +22,8 @@ export function resolveTriggerWidget( setFormData: (data: TriggerFormData) => void, userSettings: UserSettings, projectId: string, - dialogId: string + dialogId: string, + luFile?: LuFile ) { const isRegEx = isRegExRecognizerType(dialogFile); const isLUISnQnA = isLUISnQnARecognizerType(dialogFile) || isPVARecognizerType(dialogFile); @@ -99,6 +100,7 @@ export function resolveTriggerWidget( editorSettings={userSettings.codeEditor} errorMessage={formData.errors.triggerPhrases} height={225} + luFile={luFile} luOption={{ projectId, fileId: dialogId, From 11ebc1fd9f979ed70db5f8ed6f187a9fa14aeb4f Mon Sep 17 00:00:00 2001 From: Soroush Date: Thu, 25 Mar 2021 14:04:36 -0700 Subject: [PATCH 2/5] dont show labeling menu if no ML entities --- Composer/packages/lib/code-editor/src/lu/LuLabelingMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Composer/packages/lib/code-editor/src/lu/LuLabelingMenu.tsx b/Composer/packages/lib/code-editor/src/lu/LuLabelingMenu.tsx index 830fa5fb78..ac3849eadd 100644 --- a/Composer/packages/lib/code-editor/src/lu/LuLabelingMenu.tsx +++ b/Composer/packages/lib/code-editor/src/lu/LuLabelingMenu.tsx @@ -86,11 +86,11 @@ export const LuLabelingMenu = ({ editor, luFile, onMenuToggled, onInsertEntity } [onInsertEntity] ); - const { menuProps } = useLabelingMenuProps('filter', luFile, itemClick, { + const { menuProps, noEntities } = useLabelingMenuProps('filter', luFile, itemClick, { menuHeaderText: formatMessage('Tag entity'), }); - return menuTargetElm ? ( + return menuTargetElm && !noEntities ? ( Date: Thu, 25 Mar 2021 14:26:40 -0700 Subject: [PATCH 3/5] update "trigger phrases" tooltip for luis --- .../src/components/fields/IntentField.tsx | 27 ++++++++++++++++--- .../src/hooks/useRecognizerConfig.ts | 2 +- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Composer/packages/adaptive-form/src/components/fields/IntentField.tsx b/Composer/packages/adaptive-form/src/components/fields/IntentField.tsx index 96e2dcd8d6..9b7922acdc 100644 --- a/Composer/packages/adaptive-form/src/components/fields/IntentField.tsx +++ b/Composer/packages/adaptive-form/src/components/fields/IntentField.tsx @@ -1,26 +1,45 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import React from 'react'; -import { FieldProps, useRecognizerConfig } from '@bfc/extension-client'; +import { DialogInfo, FieldProps, useRecognizerConfig, useShellApi } from '@bfc/extension-client'; import formatMessage from 'format-message'; +import get from 'lodash/get'; +import React from 'react'; import { FieldLabel } from '../FieldLabel'; +const isLuisRecognizer = (dialog: DialogInfo) => { + if (!dialog) return false; + const recognizer = get(dialog, 'content.recognizer', ''); + return typeof recognizer === 'string' && recognizer.endsWith('.lu.qna'); +}; + +const luisEntityHelpUrl = 'https://docs.microsoft.com/en-us/composer/concept-language-understanding#utterances'; + const IntentField: React.FC = (props) => { - const { id, description, uiOptions, value, required, onChange } = props; + const { id, uiOptions, value, required, onChange } = props; const { currentRecognizer } = useRecognizerConfig(); + const { currentDialog } = useShellApi(); const Editor = currentRecognizer?.intentEditor; const label = formatMessage('Trigger phrases'); + let description = props.description; + let helpLink = uiOptions.helpLink; + if (isLuisRecognizer(currentDialog)) { + description = formatMessage( + 'Trigger phrases are inputs from users that will be used to train your LUIS model. This follows .lu file format.' + ); + helpLink = luisEntityHelpUrl; + } + const handleChange = () => { onChange(value); }; return ( - + {Editor ? ( ) : ( diff --git a/Composer/packages/extension-client/src/hooks/useRecognizerConfig.ts b/Composer/packages/extension-client/src/hooks/useRecognizerConfig.ts index 0c0b548e2f..209c3d9218 100644 --- a/Composer/packages/extension-client/src/hooks/useRecognizerConfig.ts +++ b/Composer/packages/extension-client/src/hooks/useRecognizerConfig.ts @@ -64,7 +64,7 @@ export function useRecognizerConfig(): RecognizerSchemaConfig { const recognizerWidgets = plugins.widgets?.recognizer ?? {}; const schemas = Object.entries(plugins.uiSchema) - .filter(([_, uiOptions]) => uiOptions && uiOptions.recognizer) + .filter(([_, uiOptions]) => uiOptions?.recognizer) .map(([$kind, uiOptions]) => { const recognizerOptions = uiOptions?.recognizer as RecognizerOptions; const intentEditor = resolveRecognizerWidget(recognizerOptions.intentEditor, recognizerWidgets); From 983fa3ca8bfef155adc66dd7cd7c759f26fc4283 Mon Sep 17 00:00:00 2001 From: Soroush Date: Thu, 25 Mar 2021 15:23:57 -0700 Subject: [PATCH 4/5] strings --- Composer/packages/server/src/locales/en-US.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Composer/packages/server/src/locales/en-US.json b/Composer/packages/server/src/locales/en-US.json index 6efa3509b1..6ce3ecf016 100644 --- a/Composer/packages/server/src/locales/en-US.json +++ b/Composer/packages/server/src/locales/en-US.json @@ -3440,6 +3440,9 @@ "trigger_connects_user_intent_with_bot_responses_th_57279180": { "message": "Trigger connects user intent with bot responses. Think of a trigger as one capability of your bot. So a dialog contains a collection of triggers. To add a new trigger from the dialog menu." }, + "trigger_phrases_are_inputs_from_users_that_will_be_f8c61866": { + "message": "Trigger phrases are inputs from users that will be used to train your LUIS model. This follows .lu file format." + }, "trigger_phrases_f6754fa": { "message": "Trigger phrases" }, From c88cb26d72c65eb376787ea2a32ce3fc7e6984eb Mon Sep 17 00:00:00 2001 From: Soroush Date: Thu, 25 Mar 2021 15:25:40 -0700 Subject: [PATCH 5/5] strings --- Composer/packages/server/src/locales/en-US.json | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Composer/packages/server/src/locales/en-US.json b/Composer/packages/server/src/locales/en-US.json index b8d2ee18f5..07a82bbfa2 100644 --- a/Composer/packages/server/src/locales/en-US.json +++ b/Composer/packages/server/src/locales/en-US.json @@ -299,6 +299,9 @@ "apr_9_2020_3c8b47d7": { "message": "Apr 9, 2020" }, + "are_you_sure_you_want_to_delete_your_bot_this_acti_214a9e11": { + "message": "Are you sure you want to delete your bot? This action cannot be undone and your bot and all related files in the bot project folder will be permanently deleted. Your Azure resources will remain unchanged." + }, "are_you_sure_you_want_to_exit_the_onboarding_produ_c2de1b23": { "message": "Are you sure you want to exit the Onboarding Product Tour? You can restart the tour in the onboarding settings." }, @@ -1427,9 +1430,6 @@ "extension_settings_899ccb55": { "message": "Extension Settings" }, - "external_resources_will_not_be_changed_c08b0009": { - "message": "External resources will not be changed." - }, "external_service_adapters_5218e6a3": { "message": "External service adapters" }, @@ -1640,9 +1640,6 @@ "http_request_79847109": { "message": "HTTP Request" }, - "i_want_to_delete_this_bot_f81a4735": { - "message": "I want to delete this bot" - }, "i_want_to_keep_the_template_content_in_the_file_ju_769331d9": { "message": "I want to keep the template content in the file, just want to dereference from this response (hint: keep the content if you currently, or plan to re-use in another location)" }, @@ -3641,9 +3638,6 @@ "warning_aacb8c24": { "message": "Warning" }, - "warning_the_action_you_are_about_to_take_cannot_be_1071a3c3": { - "message": "Warning: the action you are about to take cannot be undone. Going further will delete this bot and any related files in the bot project folder." - }, "warningsmsg_e2c04bfe": { "message": "{ warningsMsg }" }, @@ -3734,6 +3728,9 @@ "yes_dde87d5": { "message": "Yes" }, + "yes_delete_d43476ee": { + "message": "Yes, delete" + }, "you_already_have_a_kb_with_that_name_choose_anothe_b7f7c517": { "message": "You already have a KB with that name. Choose another name and try again." },