Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
1 change: 1 addition & 0 deletions Composer/packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@reach/router": "^1.2.1",
"axios": "^0.18.0",
"botbuilder-lg": "4.7.0-preview.93464",
"botframework-expressions": "4.7.0-preview.93464",
"format-message": "^6.2.3",
"immer": "^2.1.4",
"jwt-decode": "^2.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const LGPage: React.FC<RouteComponentProps> = props => {

useEffect(() => {
// dialog lg templates is part of commong.lg. By restricting edit in root view, user would aware that the changes they made may affect other dialogs.
if (!isRoot) {
if (!isRoot && fileValid) {
setEditMode(false);
}

Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/client/src/utils/dialogUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ConceptLabels, DialogGroup, SDKTypes, dialogGroups, seedNewDialog } fro
import get from 'lodash/get';
import set from 'lodash/set';
import cloneDeep from 'lodash/cloneDeep';
import { ExpressionEngine } from 'botbuilder-expression-parser';
import { ExpressionEngine } from 'botframework-expressions';
import { IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import { DialogInfo } from '@bfc/indexers';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PrimaryButton, DefaultButton, DirectionalHint } from 'office-ui-fabric-
import debounce from 'lodash/debounce';
import nanoid from 'nanoid';
import { initializeIcons } from '@uifabric/icons';
import { ExpressionEngine } from 'botbuilder-expression-parser';
import { ExpressionEngine } from 'botframework-expressions';
import { seedNewDialog, ShellApi } from '@bfc/shared';
import { LuFile, DialogInfo } from '@bfc/indexers';

Expand Down
5 changes: 2 additions & 3 deletions Composer/packages/extensions/obiformeditor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"name": "@bfc/obiformeditor",
"license": "MIT",
"version": "1.0.0",
"description": "obieditortest React component",
"engines": {
Expand Down Expand Up @@ -62,7 +61,7 @@
"@types/react": "16.9.0",
"@types/react-dom": "16.9.0",
"autoprefixer": "^9.5.1",
"botbuilder-expression-parser": "^4.5.11",
"botframework-expressions": "4.7.0-preview.93464",
"codemirror": "^5.44.0",
"copyfiles": "^2.1.0",
"css-loader": "^2.1.1",
Expand Down Expand Up @@ -92,4 +91,4 @@
"keywords": [
"react-component"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface FormContext
dialogOptions: { value: string; label: string }[];
dialogId?: string;
isRoot: boolean;
formErrors: any;
}

interface EnumOption {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TextField, ITextFieldProps, ITextFieldStyles } from 'office-ui-fabric-r
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
import { JSONSchema6 } from 'json-schema';
import formatMessage from 'format-message';
import get from 'lodash/get';

import { FormContext } from '../types';
import { EditableField } from '../fields/EditableField';
Expand All @@ -25,8 +26,9 @@ interface ExpresionWidgetProps extends ITextFieldProps {
options?: any;
}

const getDefaultErrorMessage = () => {
return formatMessage.rich('Invalid expression syntax. Refer to the syntax documentation<a>here</a>', {
const getDefaultErrorMessage = errMessage => {
return formatMessage.rich('{errMessage}. Refer to the syntax documentation<a>here</a>', {
errMessage,
a: ({ children }) => (
<a
key="a"
Expand All @@ -41,39 +43,13 @@ const getDefaultErrorMessage = () => {
};

export const ExpressionWidget: React.FC<ExpresionWidgetProps> = props => {
const {
rawErrors,
formContext,
schema,
id,
label,
editable,
hiddenErrMessage,
onValidate,
options = {},
...rest
} = props;
const { shellApi } = formContext;
const { formContext, schema, id, label, editable, hiddenErrMessage, onValidate, options = {}, ...rest } = props;
const { description } = schema;
const { hideLabel } = options;
const name = props.id?.split('_')[props.id?.split('_').length - 1];

const onGetErrorMessage = async (value: string): Promise<JSX.Element | string> => {
if (!value) {
if (hiddenErrMessage) {
onValidate && onValidate();
}
return '';
}

const isValid = await shellApi.validateExpression(value);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let errMessage: string | any[] = '';
if (!isValid) {
errMessage = getDefaultErrorMessage();
} else if (rawErrors && rawErrors.length > 0) {
errMessage = rawErrors[0];
}
const onGetErrorMessage = (): JSX.Element | string => {
const errMessage = name && get(formContext, ['formErrors', name], '');

const messageBar = errMessage ? (
<MessageBar
Expand All @@ -83,7 +59,7 @@ export const ExpressionWidget: React.FC<ExpresionWidgetProps> = props => {
truncated
overflowButtonAriaLabel={formatMessage('See more')}
>
{errMessage}
{getDefaultErrorMessage(`${label} ${errMessage}`)}
</MessageBar>
) : (
''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,14 @@ interface LgEditorWidgetProps {

export const LgEditorWidget: React.FC<LgEditorWidgetProps> = props => {
const { formContext, name, value, height = 250 } = props;
const [errorMsg, setErrorMsg] = useState('');
const lgName = new LgMetaData(name, formContext.dialogId || '').toString();
const lgFileId = formContext.currentDialog.lgFile || 'common';
const lgFile = formContext.lgFiles && formContext.lgFiles.find(file => file.id === lgFileId);

const updateLgTemplate = useMemo(
() =>
debounce((body: string) => {
formContext.shellApi
.updateLgTemplate(lgFileId, lgName, body)
.then(() => setErrorMsg(''))
.catch(error => setErrorMsg(error));
formContext.shellApi.updateLgTemplate(lgFileId, lgName, body).catch(() => {});
}, 500),
[lgName, lgFileId]
);
Expand All @@ -70,6 +66,18 @@ export const LgEditorWidget: React.FC<LgEditorWidgetProps> = props => {
body: getInitialTemplate(name, value),
};

const lgStartLine = (lgFile && lgFile.content.split('\n').findIndex(item => item.trim() === `# ${lgName}()`)) || -1;
Comment thread
zhixzhan marked this conversation as resolved.
Outdated
const templateBodyLines = template.body.split('\n').length;

const diagnostic =
lgFile &&
lgFile.diagnostics &&
lgFile.diagnostics.find(d => {
return d.range && lgStartLine + 1 < d.range.start.line && lgStartLine + 1 + templateBodyLines >= d.range.end.line;
});
const errorMsg = diagnostic
? diagnostic.message.split('error message: ')[diagnostic.message.split('error message: ').length - 1]
Comment thread
alanlong9278 marked this conversation as resolved.
: '';
const [localValue, setLocalValue] = useState(template.body);
const lgOption = {
inline: true,
Expand Down
23 changes: 22 additions & 1 deletion Composer/packages/extensions/obiformeditor/src/FormEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

/** @jsx jsx */
import { Global, jsx } from '@emotion/core';
import React, { useState } from 'react';
import React, { useState, useMemo } from 'react';
import { Dropdown } from 'office-ui-fabric-react/lib/Dropdown';
import { JSONSchema6Definition, JSONSchema6 } from 'json-schema';
import merge from 'lodash/merge';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import { appschema, ShellData, ShellApi } from '@bfc/shared';
import { Diagnostic } from '@bfc/indexers';

import Form from './Form';
import { uiSchema } from './schema/uischema';
Expand All @@ -33,6 +34,25 @@ export const FormEditor: React.FunctionComponent<FormEditorProps> = props => {
const [localData, setLocalData] = useState(data);
const type = getType(localData);

const formErrors = useMemo(() => {
if (props.currentDialog && props.currentDialog.diagnostics) {
const currentPath = props.focusPath.replace('#', '');
const diagnostics = get(props.currentDialog, 'diagnostics', [] as Diagnostic[]);

return diagnostics.reduce((errors, d) => {
const [dPath, dType, dProp] = d.path?.split('#') || [];

if (dPath === currentPath && dType === type && dProp) {
errors[dProp] = d.message;
}

return errors;
}, {});
}

return {};
}, [props.currentDialog]);

if (!type) {
return (
<div>
Expand Down Expand Up @@ -112,6 +132,7 @@ export const FormEditor: React.FunctionComponent<FormEditorProps> = props => {
focusedEvent: props.focusedEvent,
focusedSteps: props.focusedSteps,
focusedTab: props.focusedTab,
formErrors,
}}
idPrefix={props.focusPath}
>
Expand Down
18 changes: 8 additions & 10 deletions Composer/packages/lib/code-editor/src/RichEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,14 @@ export function RichEditor(props: RichEditorProps) {
}
}, [editor]);

const errorHelp = formatMessage.rich(
'This text has errors in the syntax. Refer to the syntax documentation<a>here</a>.',
{
a: ({ children }) => (
<a key="a" href={helpURL} target="_blank" rel="noopener noreferrer">
{children}
</a>
),
}
);
const errorHelp = formatMessage.rich('{errorMsg}. Refer to the syntax documentation<a>here</a>.', {
errorMsg,
a: ({ children }) => (
<a key="a" href={helpURL} target="_blank" rel="noopener noreferrer">
{children}
</a>
),
});

const getHeight = () => {
if (height === null || height === undefined) {
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/lib/indexers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"ts-jest": "^24.1.0"
},
"dependencies": {
"botbuilder-expression-parser": "^4.5.11",
"botbuilder-lg": "4.7.0-preview.93464",
"botframework-expressions": "4.7.0-preview.93464",
"lodash": "^4.17.15",
"ludown": "^1.3.4"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import get from 'lodash/get';
import { ExpressionEngine } from 'botbuilder-expression-parser';
import { ExpressionEngine } from 'botframework-expressions';
import formatMessage from 'format-message';

import { Diagnostic } from '../diagnostic';
Expand All @@ -26,7 +26,7 @@ export const IsExpression: CheckerFunc = (
try {
ExpressionParser.parse(exp);
} catch (error) {
message = formatMessage(`must be an expression`);
message = `${formatMessage('must be an expression:')} ${error})`;
}
}
if (message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Licensed under the MIT License.
*/

import { ReturnType } from 'botbuilder-expression';
import { ReturnType } from 'botframework-expressions';
export class FunctionEntity {
public constructor(params: string[], returntype: ReturnType, introduction: string) {
this.Params = params;
Expand Down
32 changes: 0 additions & 32 deletions Composer/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4388,28 +4388,6 @@ botbuilder-core@4.7.0-preview.93464:
assert "^1.4.1"
botframework-schema "4.7.0-preview.93464"

botbuilder-expression-parser@^4.5.11:
version "4.5.11"
resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/botbuilder-expression-parser/-/botbuilder-expression-parser-4.5.11.tgz#fcce377a2b2c1a2c2345b2c77d9cf4289e171f9f"
integrity sha1-/M43eissGiwjRbLHfZz0KJ4XH58=
dependencies:
antlr4ts "0.5.0-alpha.1"
botbuilder-expression "https://botbuilder.myget.org/F/botbuilder-declarative/npm/botbuilder-expression/-/4.5.11.tgz"

"botbuilder-expression@https://botbuilder.myget.org/F/botbuilder-declarative/npm/botbuilder-expression/-/4.5.11.tgz":
version "4.5.11"
resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/botbuilder-expression/-/4.5.11.tgz#d15384417be9c0e17d46bf729fe707b81b66ef68"
dependencies:
"@microsoft/recognizers-text-data-types-timex-expression" "^1.1.4"
antlr4ts "0.5.0-alpha.1"
jspath "^0.4.0"
lru-cache "^5.1.1"
moment "2.24.0"
moment-timezone "^0.5.25"
xml2js "^0.4.19"
xmldom "^0.1.27"
xpath "0.0.27"

botbuilder-lg@4.7.0-preview.93464:
version "4.7.0-preview.93464"
resolved "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/botbuilder-lg/-/botbuilder-lg-4.7.0-preview.93464.tgz#504c647aca501998a0bcf89da33612c808334825"
Expand Down Expand Up @@ -17138,21 +17116,11 @@ xmlbuilder@^9.0.7, xmlbuilder@~9.0.1:
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=

xmldom@^0.1.27:
version "0.1.27"
resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk=

xmlhttprequest@1:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=

xpath@0.0.27:
version "0.0.27"
resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92"
integrity sha1-3TQh+9zFZGrDLEhTG01+nQws+pI=

xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
Expand Down