Skip to content

Commit

Permalink
Merge branch 'main' into julong/zoom-in-out
Browse files Browse the repository at this point in the history
* main:
  fix: update l10n file (#4247)
  fix: fix loading of extensions by removing sample-ui-plugin (#4251)
  fix: split qna resource to another template (#4212)
  feat: UI Schema - Recognizer (#4135)
  fix: Change http to https for petstore.swagger.io calls (#4238)
  feat: install remote extensions from npm (#4224)
  fix: refactored select skill ui-plugin (#4207)
  feat: Added fieldSets to UIOptions (#4231)
  fix: New LG template not sync to other locale files (#4230)
  • Loading branch information
alanlong9278 committed Sep 24, 2020
2 parents 8c5c5cc + e2510d3 commit 38a15f2
Show file tree
Hide file tree
Showing 149 changed files with 2,350 additions and 1,495 deletions.
3 changes: 3 additions & 0 deletions Composer/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ packages/server/schemas/*.schema
packages/server/schemas/*.uischema
!packages/server/schemas/sdk.schema
!packages/server/schemas/sdk.uischema

# remote extensions
.composer
2 changes: 1 addition & 1 deletion Composer/packages/adaptive-form/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
const { createConfig } = require('@bfc/test-utils');

module.exports = createConfig('adaptive-form', 'react', {
coveragePathIgnorePatterns: ['defaultRecognizers.ts', 'defaultRoleSchema.ts', 'defaultUiSchema.ts'],
coveragePathIgnorePatterns: ['defaultRoleSchema.ts', 'defaultUiSchema.ts'],
});
12 changes: 6 additions & 6 deletions Composer/packages/adaptive-form/src/components/CollapseField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ const styles = {
};

interface CollapseField {
defaultCollapsed?: boolean;
label?: string | boolean;
defaultExpanded?: boolean;
title?: string | boolean;
}

export const CollapseField: React.FC<CollapseField> = ({ children, defaultCollapsed, label }) => {
const [isOpen, setIsOpen] = useState(!!defaultCollapsed);
export const CollapseField: React.FC<CollapseField> = ({ children, defaultExpanded, title }) => {
const [isOpen, setIsOpen] = useState(!!defaultExpanded);

return (
<Fragment>
<div
data-is-focusable
aria-expanded={isOpen}
aria-label={typeof label === 'string' ? label : formatMessage('Field Set')}
aria-label={typeof title === 'string' ? title : formatMessage('Field Set')}
css={styles.header}
role="presentation"
onClick={() => {
Expand All @@ -47,7 +47,7 @@ export const CollapseField: React.FC<CollapseField> = ({ children, defaultCollap
iconProps={{ iconName: isOpen ? 'ChevronDown' : 'ChevronRight' }}
styles={{ root: { color: NeutralColors.gray150 } }}
/>
{label && <Label styles={{ root: { fontWeight: FontWeights.semibold } }}>{label}</Label>}
{title && <Label styles={{ root: { fontWeight: FontWeights.semibold } }}>{title}</Label>}
</div>
<Separator styles={{ root: { height: 0 } }} />
<div>
Expand Down
17 changes: 8 additions & 9 deletions Composer/packages/adaptive-form/src/components/FormTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ interface FormTitleProps {
const FormTitle: React.FC<FormTitleProps> = (props) => {
const { description, schema, formData, uiOptions = {} } = props;
const { shellApi, ...shellData } = useShellApi();
const { currentDialog } = shellData;
const recognizers = useRecognizerConfig();
const selectedRecognizer = recognizers.find((r) => r.isSelected(currentDialog?.content?.recognizer));
const { currentRecognizer: selectedRecognizer } = useRecognizerConfig();
// use a ref because the syncIntentName is debounced and we need the most current version to invoke the api
const shell = useRef({
data: shellData,
Expand All @@ -69,12 +67,13 @@ const FormTitle: React.FC<FormTitleProps> = (props) => {
debounce(async (newIntentName?: string, data?: any) => {
if (newIntentName && selectedRecognizer) {
const normalizedIntentName = newIntentName?.replace(/[^a-zA-Z0-9-_]+/g, '');
await selectedRecognizer.renameIntent(
data?.intent,
normalizedIntentName,
shell.current.data,
shell.current.api
);
typeof selectedRecognizer.renameIntent === 'function' &&
(await selectedRecognizer.renameIntent(
data?.intent,
normalizedIntentName,
shell.current.data,
shell.current.api
));
}
}, 400),
[]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { FieldProps } from '@bfc/extension-client';
import { JsonEditor } from '@bfc/code-editor';

export const CustomRecognizerField: React.FC<FieldProps> = (props) => {
const { value, onChange } = props;
return (
<JsonEditor
key="customRecognizerField"
height={200}
id="customRecognizerField"
value={value as object}
onChange={onChange}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { FieldProps } from '@bfc/extension-client';

import { CollapseField } from '../CollapseField';
import { getFieldSets } from '../../utils';

import { ObjectField } from './ObjectField';

export const FieldSets: React.FC<FieldProps<object>> = (props) => {
const { schema, uiOptions: baseUiOptions, value } = props;
const { fieldSets: _, ...uiOptions } = baseUiOptions;

const fieldSets = getFieldSets(schema, baseUiOptions, value);

return (
<React.Fragment>
{fieldSets.map(({ fields, schema, ...rest }, key) => (
<CollapseField key={key} {...rest}>
<ObjectField {...props} schema={schema} uiOptions={uiOptions} />
</CollapseField>
))}
</React.Fragment>
);
};

export default FieldSets;
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,29 @@
// Licensed under the MIT License.

import React from 'react';
import { FieldProps, useShellApi, useRecognizerConfig, FieldWidget } from '@bfc/extension-client';
import { FieldProps, useRecognizerConfig } from '@bfc/extension-client';
import formatMessage from 'format-message';
import { SDKKinds } from '@bfc/shared';

import { FieldLabel } from '../FieldLabel';

const IntentField: React.FC<FieldProps> = (props) => {
const { id, description, uiOptions, value, required, onChange } = props;
const { currentDialog } = useShellApi();
const recognizers = useRecognizerConfig();
const { currentRecognizer } = useRecognizerConfig();

const Editor = currentRecognizer?.intentEditor;
const label = formatMessage('Trigger phrases (intent: #{intentName})', { intentName: value });

const handleChange = () => {
onChange(value);
};

const recognizer = recognizers.find((r) => r.isSelected(currentDialog?.content?.recognizer));
let Editor: FieldWidget | undefined;
if (recognizer && recognizer.id === SDKKinds.CrossTrainedRecognizerSet) {
Editor = recognizers.find((r) => r.id === SDKKinds.LuisRecognizer)?.editor;
} else {
Editor = recognizer?.editor;
}
const label = formatMessage('Trigger phrases (intent: #{intentName})', { intentName: value });

return (
<React.Fragment>
<FieldLabel description={description} helpLink={uiOptions?.helpLink} id={id} label={label} required={required} />
{Editor ? (
<Editor {...props} onChange={handleChange} />
) : (
formatMessage('No Editor for {type}', { type: recognizer?.id })
formatMessage('No Editor for {type}', { type: currentRecognizer?.id })
)}
</React.Fragment>
);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/** @jsx jsx */
import { jsx } from '@emotion/core';
import React, { useMemo } from 'react';
import { FieldProps, useShellApi, useRecognizerConfig } from '@bfc/extension-client';
import { MicrosoftIRecognizer } from '@bfc/shared';
import { Dropdown, ResponsiveMode, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import formatMessage from 'format-message';

import { FieldLabel } from '../../FieldLabel';

import { useMigrationEffect } from './useMigrationEffect';
import { mapDropdownOptionToRecognizerSchema } from './mappers';
import { getDropdownOptions } from './getDropdownOptions';

export const RecognizerField: React.FC<FieldProps<MicrosoftIRecognizer>> = (props) => {
const { value, id, label, description, uiOptions, required, onChange } = props;
const { shellApi, ...shellData } = useShellApi();

useMigrationEffect(value, onChange);
const { recognizers: recognizerConfigs, currentRecognizer } = useRecognizerConfig();
const dropdownOptions = useMemo(() => getDropdownOptions(recognizerConfigs), [recognizerConfigs]);

const RecognizerEditor = currentRecognizer?.recognizerEditor;
const widget = RecognizerEditor ? <RecognizerEditor {...props} /> : null;

const submit = (_, option?: IDropdownOption): void => {
if (!option) return;

const recognizerDefinition = mapDropdownOptionToRecognizerSchema(option, recognizerConfigs);

const seedNewRecognizer = recognizerDefinition?.seedNewRecognizer;
const recognizerInstance =
typeof seedNewRecognizer === 'function'
? seedNewRecognizer(shellData, shellApi)
: { $kind: option.key as string, intents: [] }; // fallback to default Recognizer instance;
onChange(recognizerInstance);
};

return (
<React.Fragment>
<FieldLabel description={description} helpLink={uiOptions?.helpLink} id={id} label={label} required={required} />
<Dropdown
data-testid="recognizerTypeDropdown"
label={formatMessage('Recognizer Type')}
options={dropdownOptions}
responsiveMode={ResponsiveMode.large}
selectedKey={currentRecognizer?.id}
onChange={submit}
/>
{widget}
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { SDKKinds } from '@bfc/shared';

export const defaultRecognizerOrder = [SDKKinds.CrossTrainedRecognizerSet, SDKKinds.RegexRecognizer];

export const recognizerOrderMap: { [$kind: string]: number } = defaultRecognizerOrder.reduce((result, $kind, index) => {
result[$kind] = index;
return result;
}, {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { RecognizerSchema, FallbackRecognizerKey } from '@bfc/extension-client';

import { recognizerOrderMap } from './defaultRecognizerOrder';
import { mapRecognizerSchemaToDropdownOption } from './mappers';

const getRankScore = (r: RecognizerSchema) => {
// Always put disabled recognizer behind. Handle 'disabled' before 'default'.
if (r.disabled) return Number.MAX_VALUE;
// Always put default recognzier ahead.
if (r.default) return -1;
// Put fallback recognizer behind.
if (r.id === FallbackRecognizerKey) return Number.MAX_VALUE - 1;
return recognizerOrderMap[r.id] ?? Number.MAX_VALUE - 1;
};

export const getDropdownOptions = (recognizerConfigs: RecognizerSchema[]) => {
return recognizerConfigs
.filter((r) => !r.disabled)
.sort((r1, r2) => {
return getRankScore(r1) - getRankScore(r2);
})
.map(mapRecognizerSchemaToDropdownOption);
};
Loading

0 comments on commit 38a15f2

Please sign in to comment.