diff --git a/BotProject/CSharp/Schemas/sdk.schema b/BotProject/CSharp/Schemas/sdk.schema
index c071385d77..2f1e13ade5 100644
--- a/BotProject/CSharp/Schemas/sdk.schema
+++ b/BotProject/CSharp/Schemas/sdk.schema
@@ -645,7 +645,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -1033,7 +1033,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -1410,7 +1410,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -1814,7 +1814,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -4333,7 +4333,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -4572,7 +4572,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -6885,7 +6885,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
diff --git a/Composer/packages/extensions/obiformeditor/package.json b/Composer/packages/extensions/obiformeditor/package.json
index 04d5914975..ec8d649d0c 100644
--- a/Composer/packages/extensions/obiformeditor/package.json
+++ b/Composer/packages/extensions/obiformeditor/package.json
@@ -24,7 +24,8 @@
"watch": "yarn build:ts --watch"
},
"dependencies": {
- "@bfcomposer/react-jsonschema-form": "1.6.2",
+ "@bfcomposer/react-jsonschema-form": "1.6.5",
+ "@emotion/core": "^10.0.17",
"@uifabric/fluent-theme": "7.1.4",
"@uifabric/styling": "7.7.1",
"classnames": "^2.2.6",
@@ -35,6 +36,7 @@
"lodash.isequal": "^4.5.0",
"lodash.merge": "^4.6.1",
"lodash.omit": "^4.5.0",
+ "lodash.pick": "^4.4.0",
"nanoid": "^2.0.1",
"office-ui-fabric-react": "7.37.1",
"react-error-boundary": "^1.2.5",
@@ -60,6 +62,7 @@
"@types/lodash.isequal": "^4.5.5",
"@types/lodash.merge": "^4.6.6",
"@types/lodash.omit": "^4.5.6",
+ "@types/lodash.pick": "^4.4.6",
"@types/lodash.startcase": "^4.4.6",
"@types/nanoid": "^1.2.1",
"@types/react": "16.9.0",
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/FieldTemplate.tsx b/Composer/packages/extensions/obiformeditor/src/Form/FieldTemplate.tsx
index 240d051be7..a3fd574153 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/FieldTemplate.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/FieldTemplate.tsx
@@ -13,5 +13,5 @@ export default function FieldTemplate(props: FieldTemplateProps) {
return null;
}
- return <>{children}>;
+ return
{children}
;
}
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/EditableField.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/EditableField.tsx
new file mode 100644
index 0000000000..3cea6036ec
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/EditableField.tsx
@@ -0,0 +1,83 @@
+import React, { useState, useEffect } from 'react';
+import { TextField, ITextFieldStyles, ITextFieldProps } from 'office-ui-fabric-react';
+import { NeutralColors } from '@uifabric/fluent-theme';
+import { mergeStyles } from '@uifabric/styling';
+
+interface EditableFieldProps extends ITextFieldProps {
+ onChange: (e: any, newTitle?: string) => void;
+ styleOverrides?: Partial;
+ placeholder?: string;
+ fontSize?: string;
+}
+
+export const EditableField: React.FC = props => {
+ const { styleOverrides = {}, placeholder, fontSize, onChange, onBlur, value, ...rest } = props;
+ const [editing, setEditing] = useState(false);
+ const [hasFocus, setHasFocus] = useState(false);
+ const [localValue, setLocalValue] = useState(value);
+ const [hasBeenEdited, setHasBeenEdited] = useState(false);
+
+ useEffect(() => {
+ if (!hasBeenEdited) {
+ setLocalValue(value);
+ }
+ }, [value]);
+
+ const handleChange = (_e: any, newValue?: string) => {
+ setLocalValue(newValue);
+ setHasBeenEdited(true);
+ onChange(_e, newValue);
+ };
+
+ const handleCommit = (e: React.FocusEvent) => {
+ setHasFocus(false);
+ setEditing(false);
+ onBlur && onBlur(e);
+ };
+
+ let borderColor: string | undefined = undefined;
+
+ if (!editing) {
+ borderColor = localValue ? 'transparent' : NeutralColors.gray30;
+ }
+
+ return (
+ setEditing(true)} onMouseLeave={() => !hasFocus && setEditing(false)}>
+ setHasFocus(true)}
+ onChange={handleChange}
+ autoComplete="off"
+ {...rest}
+ />
+
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/BotAsks.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/BotAsks.tsx
new file mode 100644
index 0000000000..8708435738
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/BotAsks.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import { FieldProps } from '@bfcomposer/react-jsonschema-form';
+import formatMessage from 'format-message';
+
+import { TextareaWidget } from '../../widgets';
+
+import { GetSchema, PromptFieldChangeHandler } from './types';
+
+interface BotAsksProps extends FieldProps {
+ onChange: PromptFieldChangeHandler;
+ getSchema: GetSchema;
+}
+
+export const BotAsks: React.FC = props => {
+ const { onChange, getSchema, idSchema, formData, formContext } = props;
+
+ return (
+ <>
+
+ >
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/ChoiceOptions.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/ChoiceOptions.tsx
new file mode 100644
index 0000000000..c760eaec5b
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/ChoiceOptions.tsx
@@ -0,0 +1,70 @@
+import React from 'react';
+import formatMessage from 'format-message';
+import { IdSchema } from '@bfcomposer/react-jsonschema-form';
+import { JSONSchema6 } from 'json-schema';
+import get from 'lodash.get';
+
+import { field } from '../styles';
+import { TextWidget, CheckboxWidget } from '../../../widgets';
+import { FormContext } from '../../../types';
+
+interface ChoiceOptionsProps {
+ idSchema: IdSchema;
+ schema: JSONSchema6;
+ formData: IChoiceOption;
+ onChange: (field: keyof IChoiceOption) => (data: any) => void;
+ formContext: FormContext;
+}
+
+export const ChoiceOptions: React.FC = props => {
+ const { schema, formData, onChange, idSchema, formContext } = props;
+
+ const optionSchema = (field: keyof IChoiceOption): JSONSchema6 => {
+ return get(schema, ['properties', field]);
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/Choices.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/Choices.tsx
new file mode 100644
index 0000000000..a08f768910
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/Choices.tsx
@@ -0,0 +1,194 @@
+/** @jsx jsx */
+import { jsx } from '@emotion/core';
+import React, { useState } from 'react';
+import { JSONSchema6 } from 'json-schema';
+import formatMessage from 'format-message';
+import { TextField, IconButton, IContextualMenuItem } from 'office-ui-fabric-react';
+import { NeutralColors, FontSizes } from '@uifabric/fluent-theme';
+
+import { field, choiceItemContainer, choiceItemValue, choiceItemSynonyms } from '../styles';
+import { swap, remove } from '../../../utils';
+// import { FormContext } from '../../../types';
+import { WidgetLabel } from '../../../widgets/WidgetLabel';
+import { EditableField } from '../../EditableField';
+
+interface ChoiceItemProps {
+ index: number;
+ choice: IChoice;
+ hasMoveUp: boolean;
+ hasMoveDown: boolean;
+ onReorder: (a: number, b: number) => void;
+ onDelete: (idx: number) => void;
+ onEdit: (idx: number, value?: IChoice) => void;
+}
+
+interface ChoicesProps {
+ id: string;
+ schema: JSONSchema6;
+ formData?: IChoice[];
+ label: string;
+ onChange: (data: IChoice[]) => void;
+}
+
+const ChoiceItem: React.FC = props => {
+ const { choice, index, onEdit, hasMoveUp, hasMoveDown, onReorder, onDelete } = props;
+
+ const contextItems: IContextualMenuItem[] = [
+ {
+ key: 'moveUp',
+ text: 'Move Up',
+ iconProps: { iconName: 'CaretSolidUp' },
+ disabled: !hasMoveUp,
+ onClick: () => onReorder(index, index - 1),
+ },
+ {
+ key: 'moveDown',
+ text: 'Move Down',
+ iconProps: { iconName: 'CaretSolidDown' },
+ disabled: !hasMoveDown,
+ onClick: () => onReorder(index, index + 1),
+ },
+ {
+ key: 'remove',
+ text: 'Remove',
+ iconProps: { iconName: 'Cancel' },
+ onClick: () => onDelete(index),
+ },
+ ];
+
+ const handleEdit = (field: 'value' | 'synonyms') => (_e: any, val?: string) => {
+ if (field === 'synonyms') {
+ onEdit(index, { ...choice, synonyms: val ? val.split(', ') : [] });
+ } else {
+ onEdit(index, { ...choice, value: val });
+ }
+ };
+
+ return (
+
+ );
+};
+
+export const Choices: React.FC = props => {
+ const { onChange, formData = [], id, label } = props;
+ const [newChoice, setNewChoice] = useState(null);
+ const [errorMsg, setErrorMsg] = useState('');
+
+ const handleReorder = (aIdx: number, bIdx: number) => {
+ onChange(swap(formData, aIdx, bIdx));
+ };
+
+ const handleDelete = (idx: number) => {
+ onChange(remove(formData, idx));
+ };
+
+ const handleEdit = (idx, val) => {
+ const choices = [...(formData || [])];
+ choices[idx] = val;
+ onChange(choices);
+ };
+
+ const handleNewChoiceEdit = (field: 'value' | 'synonyms') => (_e: any, data?: string) => {
+ if (field === 'synonyms') {
+ setNewChoice({ ...newChoice, synonyms: data ? data.split(', ') : [] });
+ } else {
+ setNewChoice({ ...newChoice, value: data });
+ }
+ };
+
+ const handleKeyDown = (e: React.KeyboardEvent) => {
+ if (e.key.toLowerCase() === 'enter') {
+ e.preventDefault();
+
+ if (newChoice) {
+ if (newChoice.value) {
+ onChange([...formData, newChoice]);
+ setNewChoice(null);
+ setErrorMsg('');
+ } else {
+ setErrorMsg(formatMessage('value required'));
+ }
+ }
+ }
+ };
+
+ return (
+
+
+
+ {formData &&
+ formData.map((c, i) => (
+ 0}
+ hasMoveUp={i !== formData.length - 1}
+ />
+ ))}
+
+
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/index.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/index.tsx
new file mode 100644
index 0000000000..ecea6fd134
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ChoiceInput/index.tsx
@@ -0,0 +1,66 @@
+import React from 'react';
+import { FieldProps, IdSchema } from '@bfcomposer/react-jsonschema-form';
+import formatMessage from 'format-message';
+import { JSONSchema6 } from 'json-schema';
+
+import { PromptFieldChangeHandler, GetSchema } from '../types';
+import { CheckboxWidget } from '../../../widgets';
+import { field } from '../styles';
+
+import { Choices } from './Choices';
+import { ChoiceOptions } from './ChoiceOptions';
+
+interface ChoiceInputSettingsProps extends FieldProps {
+ onChange: PromptFieldChangeHandler;
+ getSchema: GetSchema;
+}
+
+export const ChoiceInputSettings: React.FC = props => {
+ const { getSchema, formData, idSchema, onChange, formContext } = props;
+
+ const updateChoiceOptions = (field: keyof IChoiceOption) => (data: any) => {
+ const updater = onChange('choiceOptions');
+ updater({ ...formData.choiceOptions, [field]: data });
+ };
+
+ const recognizerOptionsSchema = getSchema('recognizerOptions');
+
+ return (
+ <>
+
+
+
+
+
+
+ onChange('recognizerOptions')({ noValue: data })}
+ schema={recognizerOptionsSchema.properties ? (recognizerOptionsSchema.properties.noValue as JSONSchema6) : {}}
+ id={idSchema.recognizerOptions && idSchema.recognizerOptions.__id}
+ value={formData.recognizerOptions}
+ label={formatMessage('Recognizer options: no value')}
+ formContext={formContext}
+ />
+
+ >
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ConfirmInput.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ConfirmInput.tsx
new file mode 100644
index 0000000000..c2d8819dde
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/ConfirmInput.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { FieldProps, IdSchema } from '@bfcomposer/react-jsonschema-form';
+import formatMessage from 'format-message';
+
+import { PromptFieldChangeHandler, GetSchema } from './types';
+import { Choices } from './ChoiceInput/Choices';
+import { ChoiceOptions } from './ChoiceInput/ChoiceOptions';
+
+interface ConfirmInputSettingsProps extends FieldProps {
+ onChange: PromptFieldChangeHandler;
+ getSchema: GetSchema;
+}
+
+export const ConfirmInputSettings: React.FC = props => {
+ const { getSchema, formData, idSchema, onChange, formContext } = props;
+
+ const updateChoiceOptions = (field: keyof IChoiceOption) => (data: any) => {
+ const updater = onChange('choiceOptions');
+ updater({ ...formData.choiceOptions, [field]: data });
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/Exceptions.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/Exceptions.tsx
new file mode 100644
index 0000000000..4e8ab19b4c
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/Exceptions.tsx
@@ -0,0 +1,63 @@
+import React from 'react';
+import { FieldProps } from '@bfcomposer/react-jsonschema-form';
+import formatMessage from 'format-message';
+
+import { TextareaWidget } from '../../widgets';
+
+import { Validations } from './Validations';
+import { field } from './styles';
+import { PromptFieldChangeHandler, GetSchema } from './types';
+
+interface ExceptionsProps extends FieldProps {
+ onChange: PromptFieldChangeHandler;
+ getSchema: GetSchema;
+}
+
+export const Exceptions: React.FC = props => {
+ const { onChange, getSchema, idSchema, formData, errorSchema } = props;
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/PromptSettings.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/PromptSettings.tsx
new file mode 100644
index 0000000000..4b629c3da8
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/PromptSettings.tsx
@@ -0,0 +1,73 @@
+/** @jsx jsx */
+import { jsx } from '@emotion/core';
+import formatMessage from 'format-message';
+import { FieldProps } from '@bfcomposer/react-jsonschema-form';
+
+import { TextWidget, SelectWidget, CheckboxWidget } from '../../widgets';
+
+import { field, settingsFields, settingsFieldHalf, settingsFieldFull, settingsFieldInline } from './styles';
+import { PromptFieldChangeHandler, GetSchema } from './types';
+
+interface PromptSettingsrops extends FieldProps {
+ onChange: PromptFieldChangeHandler;
+ getSchema: GetSchema;
+}
+
+export const PromptSettings: React.FC = props => {
+ const { formData, idSchema, getSchema, onChange, errorSchema } = props;
+
+ const interruptionOptions = (getSchema('allowInterruptions').enum || []).map(o => ({
+ label: o as string,
+ value: o as string,
+ }));
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/UserAnswers.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/UserAnswers.tsx
new file mode 100644
index 0000000000..428e75e9ab
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/UserAnswers.tsx
@@ -0,0 +1,101 @@
+import React from 'react';
+import { FieldProps } from '@bfcomposer/react-jsonschema-form';
+import formatMessage from 'format-message';
+import { JSONSchema6 } from 'json-schema';
+import { SDKTypes } from 'shared-menus';
+
+import { TextWidget, SelectWidget } from '../../widgets';
+
+import { field } from './styles';
+import { GetSchema, PromptFieldChangeHandler } from './types';
+import { ChoiceInputSettings } from './ChoiceInput';
+import { ConfirmInputSettings } from './ConfirmInput';
+
+const getOptions = (enumSchema: JSONSchema6) => {
+ if (!enumSchema || !enumSchema.enum || !Array.isArray(enumSchema.enum)) {
+ return [];
+ }
+
+ return enumSchema.enum.map(o => ({ label: o as string, value: o as string }));
+};
+
+interface UserAnswersProps extends FieldProps {
+ onChange: PromptFieldChangeHandler;
+ getSchema: GetSchema;
+}
+
+export const UserAnswers: React.FC = props => {
+ const { onChange, getSchema, idSchema, formData, errorSchema } = props;
+
+ return (
+ <>
+
+
+
+ {getSchema('outputFormat') && (
+
+
+
+ )}
+
+
+
+ {getSchema('defaultLocale') && (
+
+
+
+ )}
+ {getSchema('style') && (
+
+
+
+ )}
+ {formData.$type === SDKTypes.ChoiceInput && }
+ {formData.$type === SDKTypes.ConfirmInput && (
+
+ )}
+ >
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/Validations.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/Validations.tsx
new file mode 100644
index 0000000000..939bc6fc41
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/Validations.tsx
@@ -0,0 +1,166 @@
+/** @jsx jsx */
+import { jsx } from '@emotion/core';
+import React, { useState } from 'react';
+import formatMessage from 'format-message';
+import { JSONSchema6 } from 'json-schema';
+import { IconButton, IContextualMenuItem } from 'office-ui-fabric-react';
+import { NeutralColors, FontSizes } from '@uifabric/fluent-theme';
+
+import { swap, remove } from '../../utils';
+import { ExpressionWidget } from '../../widgets/ExpressionWidget';
+import { FormContext } from '../../types';
+
+import { validationItem, validationItemValue, field } from './styles';
+
+interface ValidationItemProps {
+ index: number;
+ value: string;
+ hasMoveUp: boolean;
+ hasMoveDown: boolean;
+ onReorder: (a: number, b: number) => void;
+ onDelete: (idx: number) => void;
+ formContext: FormContext;
+ schema: JSONSchema6;
+ onEdit: (idx: number, value?: string) => void;
+}
+
+const ValidationItem: React.FC = props => {
+ const { value, hasMoveDown, hasMoveUp, onReorder, onDelete, index, formContext, onEdit, schema } = props;
+
+ // This needs to return true to dismiss the menu after a click.
+ const fabricMenuItemClickHandler = fn => e => {
+ fn(e);
+ return true;
+ };
+
+ const contextItems: IContextualMenuItem[] = [
+ {
+ key: 'moveUp',
+ text: 'Move Up',
+ iconProps: { iconName: 'CaretSolidUp' },
+ disabled: !hasMoveUp,
+ onClick: fabricMenuItemClickHandler(() => onReorder(index, index - 1)),
+ },
+ {
+ key: 'moveDown',
+ text: 'Move Down',
+ iconProps: { iconName: 'CaretSolidDown' },
+ disabled: !hasMoveDown,
+ onClick: fabricMenuItemClickHandler(() => onReorder(index, index + 1)),
+ },
+ {
+ key: 'remove',
+ text: 'Remove',
+ iconProps: { iconName: 'Cancel' },
+ onClick: fabricMenuItemClickHandler(() => onDelete(index)),
+ },
+ ];
+
+ const handleEdit = (_e: any, newVal?: string) => {
+ onEdit(index, newVal);
+ };
+
+ const handleBlur = () => {
+ if (!value) {
+ onDelete(index);
+ }
+ };
+
+ return (
+
+ );
+};
+
+interface ValidationsProps {
+ onChange: (newData: string[]) => void;
+ formData: string[];
+ schema: JSONSchema6;
+ id: string;
+ formContext: FormContext;
+}
+
+export const Validations: React.FC = props => {
+ const { schema, id, formData, formContext } = props;
+ const [newValidation, setNewValidation] = useState('');
+
+ const handleChange = (_e: any, newValue?: string) => {
+ setNewValidation(newValue || '');
+ };
+
+ const submitNewValidation = (e: React.KeyboardEvent) => {
+ if (e.key.toLowerCase() === 'enter') {
+ e.preventDefault();
+
+ if (newValidation) {
+ props.onChange([...props.formData, newValidation]);
+ setNewValidation('');
+ }
+ }
+ };
+
+ const handleReorder = (aIdx: number, bIdx: number) => {
+ props.onChange(swap(props.formData, aIdx, bIdx));
+ };
+
+ const handleDelete = (idx: number) => {
+ props.onChange(remove(props.formData, idx));
+ };
+
+ const handleEdit = (idx, val) => {
+ const validationsCopy = [...props.formData];
+ validationsCopy[idx] = val;
+ props.onChange(validationsCopy);
+ };
+
+ return (
+
+
+
+
+
+ {formData.map((v, i) => (
+
+ ))}
+
+
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/index.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/index.tsx
new file mode 100644
index 0000000000..7c479b2b90
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/index.tsx
@@ -0,0 +1,62 @@
+/** @jsx jsx */
+import { jsx } from '@emotion/core';
+import React from 'react';
+import { FieldProps, IdSchema } from '@bfcomposer/react-jsonschema-form';
+import formatMessage from 'format-message';
+import { Pivot, PivotLinkSize, PivotItem } from 'office-ui-fabric-react';
+import get from 'lodash.get';
+
+import { BaseField } from '../BaseField';
+
+import { tabs, tabsContainer, settingsContainer } from './styles';
+import { BotAsks } from './BotAsks';
+import { UserAnswers } from './UserAnswers';
+import { Exceptions } from './Exceptions';
+import { PromptSettings } from './PromptSettings';
+import { GetSchema, PromptFieldChangeHandler } from './types';
+
+export const PromptField: React.FC = props => {
+ const promptSettingsIdSchema = ({ __id: props.idSchema.__id + 'promptSettings' } as unknown) as IdSchema;
+
+ const getSchema: GetSchema = field => {
+ const fieldSchema = get(props.schema, ['properties', field]);
+
+ return fieldSchema;
+ };
+
+ const updateField: PromptFieldChangeHandler = field => data => {
+ props.onChange({ ...props.formData, [field]: data });
+ };
+
+ return (
+
+
+
+
+
+ );
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/styles.ts b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/styles.ts
new file mode 100644
index 0000000000..ed7ca6d68d
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/styles.ts
@@ -0,0 +1,79 @@
+import { IPivotStyles } from 'office-ui-fabric-react';
+import { css } from '@emotion/core';
+
+export const tabs: Partial = {
+ root: {
+ display: 'flex',
+ padding: '0 18px',
+ },
+ link: {
+ flex: 1,
+ },
+ linkIsSelected: {
+ flex: 1,
+ },
+ itemContainer: {
+ padding: '24px 18px',
+ },
+};
+
+export const tabsContainer = css`
+ border-bottom: 1px solid #c8c6c4;
+`;
+
+export const validationItem = css`
+ display: flex;
+ align-items: center;
+ padding-left: 10px;
+
+ & + & {
+ margin-top: 10px;
+ }
+`;
+
+export const validationItemValue = css`
+ flex: 1;
+`;
+
+export const field = css`
+ margin: 10px 0;
+`;
+
+export const settingsContainer = css`
+ /* padding: 24px 0; */
+`;
+
+export const settingsFields = css`
+ display: flex;
+ flex-wrap: wrap;
+`;
+
+export const settingsFieldFull = css`
+ flex-basis: 100%;
+`;
+
+export const settingsFieldHalf = css`
+ flex: 1;
+
+ & + & {
+ margin-left: 36px;
+ }
+`;
+
+export const settingsFieldInline = css`
+ margin: 0;
+`;
+
+export const choiceItemContainer = (align: string = 'center') => css`
+ display: flex;
+ align-items: ${align};
+`;
+
+export const choiceItemValue = css`
+ width: 180px;
+`;
+
+export const choiceItemSynonyms = css`
+ flex: 1;
+ margin-left: 20px;
+`;
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/types.ts b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/types.ts
new file mode 100644
index 0000000000..dd1e9c1191
--- /dev/null
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/PromptField/types.ts
@@ -0,0 +1,5 @@
+import { JSONSchema6 } from 'json-schema';
+
+export type InputDialogKeys = keyof MicrosoftInputDialog | keyof ChoiceInput | keyof ConfirmInput;
+export type PromptFieldChangeHandler = (field: InputDialogKeys) => (data: any) => void;
+export type GetSchema = (field: InputDialogKeys) => JSONSchema6;
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/RootField.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/RootField.tsx
index d21014a72f..a43b5b7d51 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/fields/RootField.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/RootField.tsx
@@ -1,14 +1,15 @@
import { startCase, get } from 'lodash';
-import React, { useState } from 'react';
+import React from 'react';
import { FontClassNames, FontWeights } from '@uifabric/styling';
import classnames from 'classnames';
import { JSONSchema6 } from 'json-schema';
-import { NeutralColors, FontSizes } from '@uifabric/fluent-theme';
-import { TextField } from 'office-ui-fabric-react';
-import formatMessage from 'format-message';
+import { FontSizes } from '@uifabric/fluent-theme';
+import formatMessage, { date } from 'format-message';
import { FormContext } from '../types';
+import { EditableField } from './EditableField';
+
const overrideDefaults = {
collapsable: true,
defaultCollapsed: false,
@@ -27,60 +28,13 @@ interface RootFieldProps {
title?: string;
}
-interface EditableTitleProps {
- title: string;
- onChange: (newTitle?: string) => void;
-}
-
-const EditableTitle: React.FC = props => {
- const [editing, setEditing] = useState(false);
- const [hasFocus, setHasFocus] = useState(false);
- const [title, setTitle] = useState(props.title);
-
- const handleChange = (_e: any, newValue?: string) => {
- setTitle(newValue);
- props.onChange(newValue);
- };
-
- const handleCommit = () => {
- setHasFocus(false);
- setEditing(false);
- };
-
- return (
- setEditing(true)} onMouseLeave={() => !hasFocus && setEditing(false)}>
- setHasFocus(true)}
- onChange={handleChange}
- autoComplete="off"
- />
-
- );
-};
-
export const RootField: React.FC = props => {
const { title, name, description, schema, formData, formContext } = props;
const { currentDialog, editorSchema, isRoot } = formContext;
const sdkOverrides = get(editorSchema, ['content', 'SDKOverrides', formData.$type], overrideDefaults);
- const handleTitleChange = (newTitle?: string): void => {
+ const handleTitleChange = (e: any, newTitle?: string): void => {
if (props.onChange) {
props.onChange({ ...formData, $designer: { ...formData.$designer, name: newTitle } });
}
@@ -89,7 +43,7 @@ export const RootField: React.FC = props => {
const getTitle = (): string => {
const dialogName = isRoot && currentDialog.displayName;
- return dialogName || sdkOverrides.title || title || schema.title || startCase(name);
+ return formData.$designer.name || dialogName || sdkOverrides.title || title || schema.title || startCase(name);
};
const getDescription = (): string => {
@@ -99,7 +53,12 @@ export const RootField: React.FC = props => {
return (
-
+
{sdkOverrides.description !== false && (description || schema.description) && (
= props => {
{get(formData, '$designer.updatedAt')
- ? formatMessage('{ updatedAt, date, short } { updatedAt, time }', {
- updatedAt: Date.parse(get(formData, '$designer.updatedAt')),
- })
+ ? date(Date.parse(get(formData, '$designer.updatedAt')), 'short')
: 'N/A'}
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/fields/index.tsx b/Composer/packages/extensions/obiformeditor/src/Form/fields/index.tsx
index c632d84ce2..c7cc59d759 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/fields/index.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/fields/index.tsx
@@ -3,6 +3,7 @@ import './styles.css';
export * from './CasesField';
export * from './CodeField';
export * from './JsonField';
+export * from './PromptField';
export * from './RecognizerField';
export * from './RulesField';
export * from './SelectorField';
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/styles.css b/Composer/packages/extensions/obiformeditor/src/Form/styles.css
index 44933f3c25..0b4f5fdfc4 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/styles.css
+++ b/Composer/packages/extensions/obiformeditor/src/Form/styles.css
@@ -6,34 +6,6 @@
*/
}
-.FieldTemplate {
- display: flex;
- flex-direction: column;
- padding: 0 18px;
-}
-
-.FieldTemplate--inline {
- flex-direction: row;
- align-items: center;
- margin-top: 14px;
-}
-
-.FieldTemplate--inline>label {
- margin-right: 8px;
- margin-top: 0;
-}
-
-.FieldTemplate--reverse {
- flex-direction: row-reverse;
- justify-content: flex-end;
- align-items: center;
-}
-
-.FieldTemplate--reverse>label {
- margin-right: 0;
- margin-left: 8px;
-}
-
.FieldTemplateInfo:focus {
outline: 1px solid #323130;
}
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/types.ts b/Composer/packages/extensions/obiformeditor/src/Form/types.ts
index 5035604fb0..621a73aa3a 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/types.ts
+++ b/Composer/packages/extensions/obiformeditor/src/Form/types.ts
@@ -1,4 +1,5 @@
import { WidgetProps, FieldProps, ObjectFieldTemplateProps } from '@bfcomposer/react-jsonschema-form';
+import { JSONSchema6 } from 'json-schema';
import { ShellApi, LuFile, LgFile, DialogInfo } from '../types';
@@ -28,9 +29,12 @@ export interface BFDFieldProps extends FieldProps {
formContext: FormContext;
}
-export interface BFDWidgetProps extends WidgetProps {
+export interface BFDWidgetProps extends Partial
{
+ id: string;
+ schema: JSONSchema6;
+ onChange: (data: any) => void;
formContext: FormContext;
- options: {
+ options?: {
label?: string | false;
enumOptions?: EnumOption[];
};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/CheckboxWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/CheckboxWidget.tsx
index ca4486c42a..c6aad1347d 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/CheckboxWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/CheckboxWidget.tsx
@@ -1,10 +1,11 @@
import React from 'react';
import { Checkbox } from 'office-ui-fabric-react';
-import { WidgetProps } from '@bfcomposer/react-jsonschema-form';
+
+import { BFDWidgetProps } from '../types';
import { WidgetLabel } from './WidgetLabel';
-export function CheckboxWidget(props: WidgetProps) {
+export function CheckboxWidget(props: BFDWidgetProps) {
const { onChange, onBlur, onFocus, value, label, id, schema } = props;
const { description } = schema;
@@ -14,10 +15,15 @@ export function CheckboxWidget(props: WidgetProps) {
id={id}
checked={Boolean(value)}
onChange={(_, checked?: boolean) => onChange(checked)}
- onBlur={() => onBlur(id, Boolean(value))}
- onFocus={() => onFocus(id, Boolean(value))}
+ onBlur={() => onBlur && onBlur(id, Boolean(value))}
+ onFocus={() => onFocus && onFocus(id, Boolean(value))}
/>
);
}
+
+CheckboxWidget.defaultProps = {
+ schema: {},
+ options: {},
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/DateTimeWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/DateTimeWidget.tsx
index f4c8f14c85..f4f0e66fcf 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/DateTimeWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/DateTimeWidget.tsx
@@ -19,8 +19,8 @@ export function DateTimeWidget(props: BFDWidgetProps) {
onBlur(id, value)}
- onFocus={() => onFocus(id, value)}
+ onBlur={() => onBlur && onBlur(id, value)}
+ onFocus={() => onFocus && onFocus(id, value)}
onSelectDate={onSelectDate}
value={value ? new Date(value) : undefined}
/>
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/DialogSelectWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/DialogSelectWidget.tsx
index 83467eee31..0a0e5446f1 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/DialogSelectWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/DialogSelectWidget.tsx
@@ -90,8 +90,8 @@ export const DialogSelectWidget: React.FC = props => {
onBlur(id, value)}
- onFocus={() => onFocus(id, value)}
+ onBlur={() => onBlur && onBlur(id, value)}
+ onFocus={() => onFocus && onFocus(id, value)}
options={options}
selectedKey={comboboxTitle ? 'customTitle' : value || ''}
onItemClick={handleChange}
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/ExpressionWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/ExpressionWidget.tsx
index 0bc8588d69..506c3f3976 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/ExpressionWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/ExpressionWidget.tsx
@@ -4,6 +4,7 @@ import { TextField, ITextFieldProps } from 'office-ui-fabric-react';
import { JSONSchema6 } from 'json-schema';
import { FormContext } from '../types';
+import { EditableField } from '../fields/EditableField';
import { WidgetLabel } from './WidgetLabel';
@@ -24,13 +25,15 @@ const getErrorMessage = () =>
interface ExpresionWidgetProps extends ITextFieldProps {
formContext: FormContext;
- rawErrors: string[];
+ rawErrors?: string[];
schema: JSONSchema6;
onChange: (event: React.FormEvent, newValue?: string) => void;
+ /** Set to true to display as inline text that is editable on hover */
+ editable?: boolean;
}
export const ExpressionWidget: React.FC = props => {
- const { rawErrors, formContext, schema, id, label, ...rest } = props;
+ const { rawErrors, formContext, schema, id, label, editable, ...rest } = props;
const { shellApi } = formContext;
const { description } = schema;
@@ -52,10 +55,12 @@ export const ExpressionWidget: React.FC = props => {
return '';
};
+ const Field = editable ? EditableField : TextField;
+
return (
<>
-
+
>
);
};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/IntentWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/IntentWidget.tsx
index 8571b3affa..36c2d41352 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/IntentWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/IntentWidget.tsx
@@ -91,9 +91,9 @@ export const IntentWidget: React.FC = props => {
onBlur(id, value)}
+ onBlur={() => onBlur && onBlur(id, value)}
onChange={handleChange}
- onFocus={() => onFocus(id, value)}
+ onFocus={() => onFocus && onFocus(id, value)}
options={options}
selectedKey={value || null}
responsiveMode={ResponsiveMode.large}
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/RadioWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/RadioWidget.tsx
index c06acb98ca..1ac321275d 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/RadioWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/RadioWidget.tsx
@@ -20,9 +20,9 @@ export function RadioWidget(props: RadioWidgetProps) {
onBlur(id, value)}
+ onBlur={() => onBlur && onBlur(id, value)}
onChange={(e, option?: IChoiceGroupOption) => onChange(option ? option.key : null)}
- onFocus={() => onFocus(id, value)}
+ onFocus={() => onFocus && onFocus(id, value)}
options={choices}
selectedKey={value}
/>
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/SelectWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/SelectWidget.tsx
index 122c5d0f59..8b07a6aa8d 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/SelectWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/SelectWidget.tsx
@@ -23,9 +23,9 @@ export const SelectWidget: React.FunctionComponent = props =>
onBlur(id, value)}
+ onBlur={() => onBlur && onBlur(id, value)}
onChange={handleChange}
- onFocus={() => onFocus(id, value)}
+ onFocus={() => onFocus && onFocus(id, value)}
options={options.enumOptions.map(o => ({
key: o.value,
text: o.label,
@@ -39,3 +39,9 @@ export const SelectWidget: React.FunctionComponent = props =>
>
);
};
+
+SelectWidget.defaultProps = {
+ schema: {},
+ onBlur: () => {},
+ onFocus: () => {},
+};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextWidget.tsx
index fba7a4d9df..7c06a0e70c 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextWidget.tsx
@@ -46,7 +46,7 @@ export function TextWidget(props: BFDWidgetProps) {
onChange(newValue);
// need to allow form data to propagate before flushing to state
- setTimeout(() => onBlur(id, value));
+ setTimeout(() => onBlur && onBlur(id, value));
};
const step = type === 'integer' ? 1 : 0.1;
@@ -74,9 +74,9 @@ export function TextWidget(props: BFDWidgetProps) {
id,
value,
autoComplete: 'off',
- onBlur: () => onBlur(id, value),
+ onBlur: () => onBlur && onBlur(id, value),
onChange: (_, newValue?: string) => onChange(newValue),
- onFocus: () => onFocus(id, value),
+ onFocus: () => onFocus && onFocus(id, value),
placeholder: placeholderText,
readOnly: Boolean(schema.const) || readonly,
};
@@ -103,4 +103,7 @@ export function TextWidget(props: BFDWidgetProps) {
TextWidget.defaultProps = {
schema: {},
+ options: {},
+ onBlur: () => {},
+ onFocus: () => {},
};
diff --git a/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextareaWidget.tsx b/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextareaWidget.tsx
index 8d388d5e78..d21e1deccf 100644
--- a/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextareaWidget.tsx
+++ b/Composer/packages/extensions/obiformeditor/src/Form/widgets/TextareaWidget.tsx
@@ -1,10 +1,11 @@
import React from 'react';
import { TextField } from 'office-ui-fabric-react';
-import { WidgetProps } from '@bfcomposer/react-jsonschema-form';
+
+import { BFDWidgetProps } from '../types';
import { WidgetLabel } from './WidgetLabel';
-export const TextareaWidget: React.FunctionComponent = props => {
+export const TextareaWidget: React.FunctionComponent = props => {
const { onBlur, onChange, onFocus, readonly, value, placeholder, schema, id, disabled, label } = props;
const { description, examples = [] } = schema;
@@ -21,9 +22,9 @@ export const TextareaWidget: React.FunctionComponent = props => {
disabled={disabled}
id={id}
multiline
- onBlur={() => onBlur(id, value)}
+ onBlur={() => onBlur && onBlur(id, value)}
onChange={(_, newValue?: string) => onChange(newValue)}
- onFocus={() => onFocus(id, value)}
+ onFocus={() => onFocus && onFocus(id, value)}
placeholder={placeholderText}
readOnly={readonly}
value={value}
@@ -39,4 +40,7 @@ export const TextareaWidget: React.FunctionComponent = props => {
TextareaWidget.defaultProps = {
schema: {},
+ options: {},
+ onBlur: () => {},
+ onFocus: () => {},
};
diff --git a/Composer/packages/extensions/obiformeditor/src/schema/appschema.ts b/Composer/packages/extensions/obiformeditor/src/schema/appschema.ts
index 8b0fb8c6b9..f46e798432 100644
--- a/Composer/packages/extensions/obiformeditor/src/schema/appschema.ts
+++ b/Composer/packages/extensions/obiformeditor/src/schema/appschema.ts
@@ -1,4 +1,14 @@
import { JSONSchema6 } from 'json-schema';
+import { SDKTypes } from 'shared-menus';
+
+export const PROMPT_TYPES = [
+ SDKTypes.AttachmentInput,
+ SDKTypes.ChoiceInput,
+ SDKTypes.ConfirmInput,
+ SDKTypes.DateTimeInput,
+ SDKTypes.NumberInput,
+ SDKTypes.TextInput,
+];
export const FIELDS_TO_HIDE = [
'$id',
@@ -259,7 +269,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
@@ -575,7 +585,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
@@ -641,11 +651,11 @@ export const appschema: JSONSchema6 = {
title: 'Value',
description: 'the value to return when selected.',
},
- action: {
- title: 'Action',
- description: 'Card action for the choice',
- type: 'object',
- },
+ // action: {
+ // title: 'Action',
+ // description: 'Card action for the choice',
+ // type: 'object',
+ // },
synonyms: {
type: 'array',
title: 'Synonyms',
@@ -840,7 +850,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
@@ -933,31 +943,29 @@ export const appschema: JSONSchema6 = {
},
confirmChoices: {
type: 'array',
- items: [
- {
- type: 'object',
- properties: {
- value: {
+ items: {
+ type: 'object',
+ properties: {
+ value: {
+ type: 'string',
+ title: 'Value',
+ description: 'the value to return when selected.',
+ },
+ // action: {
+ // title: 'Action',
+ // description: 'Card action for the choice',
+ // type: 'object',
+ // },
+ synonyms: {
+ type: 'array',
+ title: 'Synonyms',
+ description: 'The list of synonyms to recognize in addition to the value. This is optional.',
+ items: {
type: 'string',
- title: 'Value',
- description: 'the value to return when selected.',
- },
- action: {
- title: 'Action',
- description: 'Card action for the choice',
- type: 'object',
- },
- synonyms: {
- type: 'array',
- title: 'Synonyms',
- description: 'The list of synonyms to recognize in addition to the value. This is optional.',
- items: {
- type: 'string',
- },
},
},
},
- ],
+ },
},
},
additionalProperties: false,
@@ -1165,7 +1173,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
@@ -3127,7 +3135,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
@@ -3318,7 +3326,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
@@ -5081,7 +5089,7 @@ export const appschema: JSONSchema6 = {
type: 'integer',
title: 'Max Turn Count',
description: 'The max retry count for this prompt.',
- default: 2147483647,
+ default: 3,
examples: [3],
},
validations: {
diff --git a/Composer/packages/extensions/obiformeditor/src/schema/types.d.ts b/Composer/packages/extensions/obiformeditor/src/schema/types.d.ts
index 5046376262..752c893caf 100644
--- a/Composer/packages/extensions/obiformeditor/src/schema/types.d.ts
+++ b/Composer/packages/extensions/obiformeditor/src/schema/types.d.ts
@@ -14,6 +14,8 @@ interface BaseSchema {
/* Union of components which implement the IActivityTemplate interface */
type MicrosoftIActivityTemplate = string;
+type MicrosoftIExpression = string;
+
interface IBaseDialog extends BaseSchema {
/** This is that will be passed in as InputProperty and also set as the OutputProperty */
property?: string;
@@ -23,15 +25,6 @@ interface IBaseDialog extends BaseSchema {
outputProperty?: string;
}
-declare enum ListStyle {
- None = 'None',
- Auto = 'Auto',
- Inline = 'Inline',
- List = 'List',
- SuggestedAction = 'SuggestedAction',
- HeroCard = 'HeroCard',
-}
-
interface OpenObject {
[x: string]: T;
}
@@ -46,53 +39,116 @@ interface IChoice {
synonyms?: string[];
}
+type IListStyle = 'None' | 'Auto' | 'Inline' | 'List' | 'SuggestedAction' | 'HeroCard';
+
+interface IChoiceOption {
+ /** Character used to separate individual choices when there are more than 2 choices */
+ inlineSeparator?: string;
+ /** Separator inserted between the choices when their are only 2 choices */
+ inlineOr?: string;
+ /** Separator inserted between the last 2 choices when their are more than 2 choices. */
+ inlineOrMore?: string;
+ /** If true, inline and list style choices will be prefixed with the index of the choice. */
+ includeNumbers?: boolean;
+}
+
+interface IConfirmChoice {
+ /** the value to return when selected. */
+ value?: string;
+ /** Card action for the choice */
+ action?: OpenObject;
+ /** The list of synonyms to recognize in addition to the value. This is optional. */
+ synonyms?: string[];
+}
+
+interface IRecognizerOption {
+ /** If true, the choices value field will NOT be search over */
+ noValue?: boolean;
+}
+
/**
- * Steps
+ * Inputs
*/
-/** This represents a dialog which gathers a choice responses */
-interface ChoiceInput extends IBaseDialog {
+interface InputDialog extends BaseSchema {
+ /** (Optional) id for the dialog */
+ id: string;
/** The message to send to as prompt for this input. */
- prompt?: MicrosoftIActivityTemplate;
- /** The message to send to prompt again. */
- retryPrompt?: MicrosoftIActivityTemplate;
- /** The message to send to when then input was not recognized or not valid for the input type. */
- invalidPrompt?: MicrosoftIActivityTemplate;
- /** The kind of choice list style to generate */
- style?: ListStyle;
+ prompt: MicrosoftIActivityTemplate;
+ /** The message to send if the last input is not recognized. */
+ unrecognizedPrompt: MicrosoftIActivityTemplate;
+ /** The message to send to when then input was not valid for the input type. */
+ invalidPrompt: MicrosoftIActivityTemplate;
+ /** The message to send to when max turn count has been exceeded and the default value is selected as the value. */
+ defaultValueResponse: MicrosoftIActivityTemplate;
+ /** The max retry count for this prompt. */
+ maxTurnCount: number;
+ /** Expressions to validate an input. */
+ validations: MicrosoftIExpression[];
+ /** The expression that you evaluated for input. */
+ value: MicrosoftIExpression;
+ /** Property that this input dialog is bound to */
+ property: MicrosoftIExpression;
+ /** Value to return if the value expression can't be evaluated. */
+ defaultValue: MicrosoftIExpression;
+ /** If set to true this will always prompt the user regardless if you already have the value or not. */
+ alwaysPrompt: boolean;
+ /** Always will always consult parent dialogs first, never will not consult parent dialogs, notRecognized will consult parent only when it's not recognized */
+ allowInterruptions: 'always' | 'never' | 'notRecognized';
+}
- choicesProperty?: string;
+/** This represents a dialog which gathers an attachment such as image or music */
+interface AttachmentInput extends Partial {
+ /** The attachment output format. */
+ outputFormat?: 'all' | 'first';
+}
+/** This represents a dialog which gathers a choice responses */
+interface ChoiceInput extends Partial {
+ /** The output format. */
+ outputFormat?: 'value' | 'index';
choices?: IChoice[];
+ /** Compose an output activity containing a set of choices */
+ appendChoices?: boolean;
+ /** The prompts default locale that should be recognized. */
+ defaultLocale?: string;
+ /** The kind of choice list style to generate */
+ style?: IListStyle;
+ choiceOptions?: IChoiceOption;
+ recognizerOptions?: IRecognizerOption;
}
-/** A dialog step that executes custom code */
-interface CodeStep extends IBaseDialog {
- codeHandler: string;
+/** This represents a dialog which gathers a yes/no style responses */
+interface ConfirmInput extends Partial {
+ outputFormat: undefined;
+ /** The prompts default locale that should be recognized. */
+ defaultLocale?: string;
+ /** The kind of choice list style to generate */
+ style?: IListStyle;
+ choiceOptions?: IChoiceOption;
+ confirmChoices?: IConfirmChoice[];
}
-/** This represents a dialog which gathers a yes/no style responses */
-interface ConfirmInput extends IBaseDialog {
- /** The message to send to as prompt for this input. */
- prompt?: MicrosoftIActivityTemplate;
- /** The message to send to prompt again. */
- retryPrompt?: MicrosoftIActivityTemplate;
- /** The message to send to when then input was not recognized or not valid for the input type. */
- invalidPrompt?: MicrosoftIActivityTemplate;
+interface DateTimeInput extends Partial {
+ outputFormat: undefined;
+ /** The prompts default locale that should be recognized. */
+ defaultLocale?: string;
+}
+interface NumberInput extends Partial {
+ /** The output format. */
+ outputFormat?: 'float' | 'integer';
+ /** The prompts default locale that should be recognized. */
+ defaultLocale?: string;
}
/** This represents a dialog which gathers a text from the user */
-interface TextInput extends IBaseDialog {
- /** The message to send to as prompt for this input. */
- prompt?: MicrosoftIActivityTemplate;
- /** The message to send to prompt again. */
- retryPrompt?: MicrosoftIActivityTemplate;
- /** The message to send to when then input was not recognized or not valid for the input type. */
- invalidPrompt?: MicrosoftIActivityTemplate;
- /** A regular expression pattern which must match */
- pattern?: string;
+interface TextInput extends Partial {
+ /** The output format. */
+ outputFormat?: 'none' | 'trim' | 'lowercase' | 'uppercase';
}
+type MicrosoftInputDialog = AttachmentInput | ChoiceInput | ConfirmInput | DateTimeInput | NumberInput | TextInput;
+
/**
* Recognizers
*/
diff --git a/Composer/packages/extensions/obiformeditor/src/schema/uischema.ts b/Composer/packages/extensions/obiformeditor/src/schema/uischema.ts
index 571bd3c6d8..8eca0bdb81 100644
--- a/Composer/packages/extensions/obiformeditor/src/schema/uischema.ts
+++ b/Composer/packages/extensions/obiformeditor/src/schema/uischema.ts
@@ -1,20 +1,19 @@
+import { SDKTypes } from 'shared-menus';
+import { UiSchema } from '@bfcomposer/react-jsonschema-form';
+
+import { PROMPT_TYPES } from './appschema';
+
const globalHidden = ['property', 'inputBindings', 'outputBinding', 'id', 'tags'];
-const activityFields = {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- 'ui:hidden': ['id', 'tags', 'value', 'inputBindings', 'outputBinding'],
-};
+const promptFieldsSchemas = PROMPT_TYPES.reduce((schemas, type) => {
+ schemas[type] = {
+ 'ui:field': 'PromptField',
+ };
+ return schemas;
+}, {});
-export const uiSchema = {
- 'Microsoft.AdaptiveDialog': {
+export const uiSchema: { [key in SDKTypes]?: UiSchema } = {
+ [SDKTypes.AdaptiveDialog]: {
recognizer: {
'ui:field': 'RecognizerField',
},
@@ -27,19 +26,13 @@ export const uiSchema = {
'ui:order': ['property', 'outputBinding', 'recognizer', 'events', '*'],
'ui:hidden': ['autoEndDialog', 'generator', ...globalHidden],
},
- 'Microsoft.BeginDialog': {
+ [SDKTypes.BeginDialog]: {
dialog: {
'ui:widget': 'DialogSelectWidget',
},
'ui:hidden': ['inputBindings', 'outputBinding'],
},
- 'Microsoft.CodeStep': {
- codeHandler: {
- 'ui:field': 'CodeField',
- },
- 'ui:hidden': [...globalHidden],
- },
- 'Microsoft.ConditionalSelector': {
+ [SDKTypes.ConditionalSelector]: {
ifFalse: {
'ui:field': 'SelectorField',
},
@@ -48,30 +41,30 @@ export const uiSchema = {
},
'ui:hidden': [...globalHidden],
},
- 'Microsoft.EditActions': {
+ [SDKTypes.EditActions]: {
actions: {
'ui:field': 'StepsField',
},
},
- 'Microsoft.Foreach': {
+ [SDKTypes.Foreach]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['listProperty', 'valueProperty', 'indexProperty', 'actions', '*'],
},
- 'Microsoft.ForeachPage': {
+ [SDKTypes.ForeachPage]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['listProperty', 'pageSize', 'valueProperty', 'actions', '*'],
},
- 'Microsoft.HttpRequest': {
+ [SDKTypes.HttpRequest]: {
body: {
'ui:field': 'JsonField',
},
'ui:order': ['method', 'url', 'body', 'property', 'responseTypes', 'headers', '*'],
},
- 'Microsoft.IfCondition': {
+ [SDKTypes.IfCondition]: {
actions: {
'ui:field': 'StepsField',
},
@@ -80,73 +73,63 @@ export const uiSchema = {
},
'ui:hidden': [...globalHidden],
},
- 'Microsoft.IfPropertyRule': {
- conditionals: {
- items: {
- events: {
- 'ui:field': 'RulesField',
- },
- },
- },
- 'ui:hidden': [...globalHidden],
- },
- 'Microsoft.OnActivity': {
+ [SDKTypes.OnActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnBeginDialog': {
+ [SDKTypes.OnBeginDialog]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnConversationUpdateActivity': {
+ [SDKTypes.OnConversationUpdateActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnDialogEvent': {
+ [SDKTypes.OnDialogEvent]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['events', 'constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnEndOfConversationActivity': {
+ [SDKTypes.OnEndOfConversationActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnEvent': {
+ [SDKTypes.OnEvent]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnEventActivity': {
+ [SDKTypes.OnEventActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnHandoffActivity': {
+ [SDKTypes.OnHandoffActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnIntent': {
+ [SDKTypes.OnIntent]: {
intent: {
'ui:widget': 'IntentWidget',
},
@@ -156,172 +139,62 @@ export const uiSchema = {
'ui:order': ['intent', 'constraint', 'entities', '*'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnInvokeActivity': {
+ [SDKTypes.OnInvokeActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnMessageActivity': {
+ [SDKTypes.OnMessageActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnMessageDeleteActivity': {
+ [SDKTypes.OnMessageDeleteActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnMessageReactionActivity': {
+ [SDKTypes.OnMessageReactionActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnMessageUpdateActivity': {
+ [SDKTypes.OnMessageUpdateActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnTypingActivity': {
+ [SDKTypes.OnTypingActivity]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.OnUnknownIntent': {
+ [SDKTypes.OnUnknownIntent]: {
actions: {
'ui:field': 'StepsField',
},
'ui:order': ['constraint', '*', 'actions'],
'ui:hidden': [...globalHidden],
},
- 'Microsoft.MostSpecificSelector': {
+ [SDKTypes.MostSpecificSelector]: {
selector: {
'ui:field': 'SelectorField',
},
'ui:hidden': [...globalHidden],
},
- 'Microsoft.TextInput': {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- 'ui:order': [
- 'prompt',
- 'property',
- 'outputFormat',
- 'validations',
- 'unrecognizedPrompt',
- 'invalidPrompt',
- 'maxTurnCount',
- 'value',
- 'defaultValue',
- '*',
- ],
- },
- 'Microsoft.NumberInput': {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- 'ui:order': [
- 'prompt',
- 'property',
- 'outputFormat',
- 'validations',
- 'unrecognizedPrompt',
- 'invalidPrompt',
- 'maxTurnCount',
- 'value',
- 'defaultValue',
- '*',
- ],
- },
- 'Microsoft.ConfirmInput': {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- 'ui:order': [
- 'prompt',
- 'property',
- 'style',
- 'defaultLocale',
- 'validations',
- 'unrecognizedPrompt',
- 'invalidPrompt',
- 'maxTurnCount',
- 'value',
- 'defaultValue',
- '*',
- ],
- // ConfirmInput defaults to YES/NO. using confirmchoices is complex
- // - must provide yes/no in special format along with alternatives that have to be handled
- // TODO: Implement confirmChoices-specific widget with appropriate business events.
- 'ui:hidden': ['confirmChoices'],
- },
- 'Microsoft.ChoiceInput': {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- choices: {
- items: {
- value: {
- 'ui:options': {
- label: false,
- },
- },
- },
- },
- ...activityFields,
- 'ui:order': [
- 'prompt',
- 'property',
- 'outputFormat',
- 'style',
- 'defaultLocale',
- 'choices',
- 'validations',
- 'unrecognizedPrompt',
- 'invalidPrompt',
- 'maxTurnCount',
- 'value',
- 'defaultValue',
- '*',
- ],
- },
- 'Microsoft.OAuthInput': {
+ [SDKTypes.OAuthInput]: {
prompt: {
'ui:widget': 'TextareaWidget',
},
@@ -333,42 +206,13 @@ export const uiSchema = {
},
'ui:order': ['connectionName', '*'],
},
- 'Microsoft.AttachmentInput': {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- 'ui:order': [
- 'prompt',
- 'property',
- 'outputFormat',
- 'validations',
- 'unrecognizedPrompt',
- 'invalidPrompt',
- 'maxTurnCount',
- 'value',
- 'defaultValue',
- '*',
- ],
- },
- 'Microsoft.ReplaceDialog': {
+ [SDKTypes.ReplaceDialog]: {
dialog: {
'ui:widget': 'DialogSelectWidget',
},
'ui:hidden': [...globalHidden],
},
- 'Microsoft.Rule': {
- actions: {
- 'ui:field': 'StepsField',
- },
- 'ui:hidden': [...globalHidden],
- },
- 'Microsoft.SwitchCondition': {
+ [SDKTypes.SwitchCondition]: {
cases: {
'ui:field': 'CasesField',
},
@@ -377,24 +221,11 @@ export const uiSchema = {
},
'ui:hidden': [...globalHidden],
},
- 'Microsoft.SendActivity': {
+ [SDKTypes.SendActivity]: {
activity: {
'ui:field': 'LgEditorField',
},
'ui:hidden': [...globalHidden],
},
- 'Microsoft.DateTimeInput': {
- prompt: {
- 'ui:widget': 'TextareaWidget',
- },
- unrecognizedPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- invalidPrompt: {
- 'ui:widget': 'TextareaWidget',
- },
- defaultValue: {
- 'ui:widget': 'DateTimeWidget',
- },
- },
+ ...promptFieldsSchemas,
};
diff --git a/Composer/packages/server/schemas/sdk.schema b/Composer/packages/server/schemas/sdk.schema
index 175312c93c..7749e87e8a 100644
--- a/Composer/packages/server/schemas/sdk.schema
+++ b/Composer/packages/server/schemas/sdk.schema
@@ -645,7 +645,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -1033,7 +1033,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -1410,7 +1410,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -1814,7 +1814,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -4333,7 +4333,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -4572,7 +4572,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
@@ -6885,7 +6885,7 @@
"type": "integer",
"title": "Max Turn Count",
"description": "The max retry count for this prompt.",
- "default": 2147483647,
+ "default": 3,
"examples": [
3
]
diff --git a/Composer/yarn.lock b/Composer/yarn.lock
index 81a6d472b7..fef239d2d5 100644
--- a/Composer/yarn.lock
+++ b/Composer/yarn.lock
@@ -1352,6 +1352,13 @@
dependencies:
regenerator-runtime "^0.13.2"
+"@babel/runtime@^7.5.5":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd"
+ integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==
+ dependencies:
+ regenerator-runtime "^0.13.2"
+
"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.0":
version "7.4.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b"
@@ -1430,10 +1437,10 @@
resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/@bfcomposer/monaco-editor/-/@bfcomposer/monaco-editor-0.17.4.tgz#bc2d75c48fcbee1121ee4c168c508de81bcd2ee9"
integrity sha1-vC11xI/L7hEh7kwWjFCN6BvNLuk=
-"@bfcomposer/react-jsonschema-form@1.6.2":
- version "1.6.2"
- resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/@bfcomposer/react-jsonschema-form/-/@bfcomposer/react-jsonschema-form-1.6.2.tgz#0615d0b8d84c180d58386489dee3de6370fd47f0"
- integrity sha1-BhXQuNhMGA1YOGSJ3uPeY3D9R/A=
+"@bfcomposer/react-jsonschema-form@1.6.5":
+ version "1.6.5"
+ resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/@bfcomposer/react-jsonschema-form/-/@bfcomposer/react-jsonschema-form-1.6.5.tgz#afd08049270eb00afe305cc756fd200011e12b4c"
+ integrity sha1-r9CASScOsAr+MFzHVv0gABHhK0w=
dependencies:
ajv "^6.7.0"
babel-runtime "^6.26.0"
@@ -1498,6 +1505,16 @@
"@emotion/babel-plugin-jsx-pragmatic" "^0.1.3"
babel-plugin-emotion "^10.0.14"
+"@emotion/cache@^10.0.17":
+ version "10.0.19"
+ resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.19.tgz#d258d94d9c707dcadaf1558def968b86bb87ad71"
+ integrity sha512-BoiLlk4vEsGBg2dAqGSJu0vJl/PgVtCYLBFJaEO8RmQzPugXewQCXZJNXTDFaRlfCs0W+quesayav4fvaif5WQ==
+ dependencies:
+ "@emotion/sheet" "0.9.3"
+ "@emotion/stylis" "0.8.4"
+ "@emotion/utils" "0.11.2"
+ "@emotion/weak-memoize" "0.2.4"
+
"@emotion/cache@^10.0.9":
version "10.0.9"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.9.tgz#e0c7b7a289f7530edcfad4dcf3858bd2e5700a6f"
@@ -1508,6 +1525,18 @@
"@emotion/utils" "0.11.1"
"@emotion/weak-memoize" "0.2.2"
+"@emotion/core@^10.0.17":
+ version "10.0.17"
+ resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.17.tgz#3367376709721f4ee2068cff54ba581d362789d8"
+ integrity sha512-gykyjjr0sxzVuZBVTVK4dUmYsorc2qLhdYgSiOVK+m7WXgcYTKZevGWZ7TLAgTZvMelCTvhNq8xnf8FR1IdTbg==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ "@emotion/cache" "^10.0.17"
+ "@emotion/css" "^10.0.14"
+ "@emotion/serialize" "^0.11.10"
+ "@emotion/sheet" "0.9.3"
+ "@emotion/utils" "0.11.2"
+
"@emotion/core@^10.0.7":
version "10.0.9"
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.9.tgz#f8afbccb0011100680f5dc94657b410c6aa1350e"
@@ -1519,6 +1548,15 @@
"@emotion/sheet" "0.9.2"
"@emotion/utils" "0.11.1"
+"@emotion/css@^10.0.14":
+ version "10.0.14"
+ resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.14.tgz#95dacabdd0e22845d1a1b0b5968d9afa34011139"
+ integrity sha512-MozgPkBEWvorcdpqHZE5x1D/PLEHUitALQCQYt2wayf4UNhpgQs2tN0UwHYS4FMy5ROBH+0ALyCFVYJ/ywmwlg==
+ dependencies:
+ "@emotion/serialize" "^0.11.8"
+ "@emotion/utils" "0.11.2"
+ babel-plugin-emotion "^10.0.14"
+
"@emotion/css@^10.0.9":
version "10.0.9"
resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.9.tgz#ea0df431965a308f6cb1d61386df8ad61e5befb5"
@@ -1538,6 +1576,11 @@
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.2.tgz#53211e564604beb9befa7a4400ebf8147473eeef"
integrity sha512-RMtr1i6E8MXaBWwhXL3yeOU8JXRnz8GNxHvaUfVvwxokvayUY0zoBeWbKw1S9XkufmGEEdQd228pSZXFkAln8Q==
+"@emotion/hash@0.7.3":
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.3.tgz#a166882c81c0c6040975dd30df24fae8549bd96f"
+ integrity sha512-14ZVlsB9akwvydAdaEnVnvqu6J2P6ySv39hYyl/aoB6w/V+bXX0tay8cF6paqbgZsN2n5Xh15uF4pE+GvE+itw==
+
"@emotion/is-prop-valid@^0.7.3":
version "0.7.3"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz#a6bf4fa5387cbba59d44e698a4680f481a8da6cc"
@@ -1555,6 +1598,22 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.2.tgz#7f4c71b7654068dfcccad29553520f984cc66b30"
integrity sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w==
+"@emotion/memoize@0.7.3":
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78"
+ integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==
+
+"@emotion/serialize@^0.11.10", "@emotion/serialize@^0.11.8":
+ version "0.11.11"
+ resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.11.tgz#c92a5e5b358070a7242d10508143306524e842a4"
+ integrity sha512-YG8wdCqoWtuoMxhHZCTA+egL0RSGdHEc+YCsmiSBPBEDNuVeMWtjEWtGrhUterSChxzwnWBXvzSxIFQI/3sHLw==
+ dependencies:
+ "@emotion/hash" "0.7.3"
+ "@emotion/memoize" "0.7.3"
+ "@emotion/unitless" "0.7.4"
+ "@emotion/utils" "0.11.2"
+ csstype "^2.5.7"
+
"@emotion/serialize@^0.11.6":
version "0.11.6"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.6.tgz#78be8b9ee9ff49e0196233ba6ec1c1768ba1e1fc"
@@ -1582,11 +1641,21 @@
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.2.tgz#74e5c6b5e489a1ba30ab246ab5eedd96916487c4"
integrity sha512-pVBLzIbC/QCHDKJF2E82V2H/W/B004mDFQZiyo/MSR+VC4pV5JLG0TF/zgQDFvP3fZL/5RTPGEmXlYJBMUuJ+A==
+"@emotion/sheet@0.9.3":
+ version "0.9.3"
+ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.3.tgz#689f135ecf87d3c650ed0c4f5ddcbe579883564a"
+ integrity sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A==
+
"@emotion/stylis@0.8.3":
version "0.8.3"
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.3.tgz#3ca7e9bcb31b3cb4afbaeb66156d86ee85e23246"
integrity sha512-M3nMfJ6ndJMYloSIbYEBq6G3eqoYD41BpDOxreE8j0cb4fzz/5qvmqU9Mb2hzsXcCnIlGlWhS03PCzVGvTAe0Q==
+"@emotion/stylis@0.8.4":
+ version "0.8.4"
+ resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.4.tgz#6c51afdf1dd0d73666ba09d2eb6c25c220d6fe4c"
+ integrity sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ==
+
"@emotion/unitless@0.7.3", "@emotion/unitless@^0.7.0":
version "0.7.3"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.3.tgz#6310a047f12d21a1036fb031317219892440416f"
@@ -1612,6 +1681,11 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.2.tgz#63985d3d8b02530e0869962f4da09142ee8e200e"
integrity sha512-n/VQ4mbfr81aqkx/XmVicOLjviMuy02eenSdJY33SVA7S2J42EU0P1H0mOogfYedb3wXA0d/LVtBrgTSm04WEA==
+"@emotion/weak-memoize@0.2.4":
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.4.tgz#622a72bebd1e3f48d921563b4b60a762295a81fc"
+ integrity sha512-6PYY5DVdAY1ifaQW6XYTnOMihmBVT27elqSjEoodchsGjzYlEsTQMcEhSud99kVawatyTZRTiVkJ/c6lwbQ7nA==
+
"@insin/npm-install-webpack-plugin@5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@insin/npm-install-webpack-plugin/-/npm-install-webpack-plugin-5.0.0.tgz#514a027a259cb51392d845086033d534eac9083f"
@@ -2221,6 +2295,13 @@
dependencies:
"@types/lodash" "*"
+"@types/lodash.pick@^4.4.6":
+ version "4.4.6"
+ resolved "https://registry.yarnpkg.com/@types/lodash.pick/-/lodash.pick-4.4.6.tgz#ae4e8f109e982786313bb6aac4b1a73aefa6e9be"
+ integrity sha512-u8bzA16qQ+8dY280z3aK7PoWb3fzX5ATJ0rJB6F+uqchOX2VYF02Aqa+8aYiHiHgPzQiITqCgeimlyKFy4OA6g==
+ dependencies:
+ "@types/lodash" "*"
+
"@types/lodash.startcase@^4.4.6":
version "4.4.6"
resolved "https://registry.yarnpkg.com/@types/lodash.startcase/-/lodash.startcase-4.4.6.tgz#0e91c90004c87f738ae495a24e7b858cdecf0e2f"
@@ -12661,6 +12742,11 @@ lodash.once@^4.0.0, lodash.once@^4.1.1:
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
+lodash.pick@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
+ integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
+
lodash.set@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"