Skip to content

Commit

Permalink
propagate code editor settings to all editor surfaces (#3520)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Whitten <christopher.whitten@microsoft.com>
  • Loading branch information
a-b-r-o-w-n and cwhitten authored Jun 29, 2020
1 parent d70a316 commit 99240e9
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const DisplayManifestModal: React.FC<DisplayManifestModalProps> = ({
onDismiss,
}) => {
const { state } = useContext(StoreContext);
const { skills } = state;
const { skills, userSettings } = state;

useEffect(() => onDismiss, []);

Expand Down Expand Up @@ -63,6 +63,7 @@ export const DisplayManifestModal: React.FC<DisplayManifestModalProps> = ({
>
<div css={styles.content}>
<JsonEditor
editorSettings={userSettings.codeEditor}
height={'100%'}
id={'modaljsonview'}
options={{ readOnly: true }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/** @jsx jsx */
import { jsx } from '@emotion/core';
import React, { useState, useContext } from 'react';
import React, { useState } from 'react';
import formatMessage from 'format-message';
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
Expand Down Expand Up @@ -33,7 +33,7 @@ import {
regexRecognizerKey,
} from '../../utils/dialogUtil';
import { addIntent } from '../../utils/luUtil';
import { StoreContext } from '../../store';
import { useStoreContext } from '../../hooks';

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

Expand Down Expand Up @@ -152,8 +152,8 @@ interface TriggerCreationModalProps {

export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = (props) => {
const { isOpen, onDismiss, onSubmit, dialogId } = props;
const { state } = useContext(StoreContext);
const { dialogs, luFiles, locale, projectId, schemas } = state;
const { state } = useStoreContext();
const { dialogs, luFiles, locale, projectId, schemas, userSettings } = state;
const luFile = luFiles.find(({ id }) => id === `${dialogId}.${locale}`);
const dialogFile = dialogs.find((dialog) => dialog.id === dialogId);
const isRegEx = (dialogFile?.content?.recognizer?.$kind ?? '') === regexRecognizerKey;
Expand Down Expand Up @@ -358,6 +358,7 @@ export const TriggerCreationModal: React.FC<TriggerCreationModalProps> = (props)
<React.Fragment>
<Label>{formatMessage('Trigger phrases')}</Label>
<LuEditor
editorSettings={userSettings.codeEditor}
errorMessage={formData.errors.triggerPhrases}
height={225}
luOption={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,24 @@ import React from 'react';
import { JsonEditor } from '@bfc/code-editor';

import { ContentProps } from '../constants';
import { useStoreContext } from '../../../../hooks';

export const ReviewManifest: React.FC<ContentProps> = ({ setErrors, value, onChange }) => {
const {
state: { userSettings },
} = useStoreContext();

const handleError = (error) => {
setErrors(error ? { error } : {});
};

return <JsonEditor height={'100%'} value={value} onChange={onChange} onError={handleError} />;
return (
<JsonEditor
editorSettings={userSettings.codeEditor}
height={'100%'}
value={value}
onChange={onChange}
onError={handleError}
/>
);
};
10 changes: 6 additions & 4 deletions Composer/packages/client/src/pages/design/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/** @jsx jsx */
import { jsx } from '@emotion/core';
import React, { Suspense, useContext, useEffect, useMemo, useState } from 'react';
import React, { Suspense, useEffect, useMemo, useState } from 'react';
import { Breadcrumb, IBreadcrumbItem } from 'office-ui-fabric-react/lib/Breadcrumb';
import formatMessage from 'format-message';
import { globalHistory, RouteComponentProps } from '@reach/router';
Expand All @@ -23,12 +23,12 @@ import { Conversation } from '../../components/Conversation';
import { dialogStyle } from '../../components/Modal/styles';
import { OpenConfirmModal } from '../../components/Modal/Confirm';
import { ProjectTree } from '../../components/ProjectTree';
import { StoreContext } from '../../store';
import { ToolBar, IToolBarItem } from '../../components/ToolBar/index';
import { clearBreadcrumb } from '../../utils/navigation';
import undoHistory from '../../store/middlewares/undo/history';
import { navigateTo } from '../../utils';
import { useShell } from '../../shell';
import { useStoreContext } from '../../hooks';

import { VisualEditorAPI } from './FrameAPI';
import {
Expand Down Expand Up @@ -84,7 +84,7 @@ const getTabFromFragment = () => {
};

const DesignPage: React.FC<RouteComponentProps<{ dialogId: string; projectId: string }>> = (props) => {
const { state, actions } = useContext(StoreContext);
const { state, actions } = useStoreContext();
const {
dialogs,
displaySkillManifest,
Expand All @@ -94,6 +94,7 @@ const DesignPage: React.FC<RouteComponentProps<{ dialogId: string; projectId: st
schemas,
focusPath,
designPageLocation,
userSettings,
} = state;
const {
dismissManifestModal,
Expand Down Expand Up @@ -426,7 +427,8 @@ const DesignPage: React.FC<RouteComponentProps<{ dialogId: string; projectId: st
{breadcrumbItems}
{dialogJsonVisible ? (
<JsonEditor
key={'dialogjson'}
key="dialogjson"
editorSettings={userSettings.codeEditor}
id={currentDialog.id}
schema={schemas.sdk.content}
value={currentDialog.content || undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'
import { JsonEditor } from '@bfc/code-editor';

import { PublishTarget, PublishType } from '../../store/types';
import { useStoreContext } from '../../hooks';

import { label } from './styles';

Expand All @@ -28,6 +29,9 @@ const CreatePublishTarget: React.FC<CreatePublishTargetProps> = (props) => {
const [name, setName] = useState(props.current ? props.current.name : '');
const [config, setConfig] = useState(props.current ? JSON.parse(props.current.configuration) : undefined);
const [errorMessage, setErrorMsg] = useState('');
const {
state: { userSettings },
} = useStoreContext();

const targetTypes = useMemo(() => {
return props.types.map((t) => ({ key: t.name, text: t.description }));
Expand Down Expand Up @@ -105,7 +109,14 @@ const CreatePublishTarget: React.FC<CreatePublishTargetProps> = (props) => {
/>
{instructions && <p>{instructions}</p>}
<div css={label}>{formatMessage('Publish Configuration')}</div>
<JsonEditor key={targetType} height={200} schema={schema} value={config} onChange={updateConfig} />
<JsonEditor
key={targetType}
editorSettings={userSettings.codeEditor}
height={200}
schema={schema}
value={config}
onChange={updateConfig}
/>
<button hidden disabled={isDisable()} type="submit" />
</form>
<DialogFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

/** @jsx jsx */
import { jsx } from '@emotion/core';
import { useContext } from 'react';
import React from 'react';
import { JsonEditor } from '@bfc/code-editor';
import formatMessage from 'format-message';
import { Link } from 'office-ui-fabric-react/lib/Link';
import { RouteComponentProps } from '@reach/router';

import { StoreContext } from '../../../store';
import { useStoreContext } from '../../../hooks';

import { hostedSettings, hostedControls, settingsEditor } from './style';

Expand All @@ -25,8 +25,8 @@ const hostControlLabels = {
};

export const DialogSettings: React.FC<RouteComponentProps> = () => {
const { state, actions } = useContext(StoreContext);
const { botName, settings, projectId } = state;
const { state, actions } = useStoreContext();
const { botName, settings, projectId, userSettings } = state;

const saveChangeResult = (result) => {
try {
Expand Down Expand Up @@ -61,7 +61,7 @@ export const DialogSettings: React.FC<RouteComponentProps> = () => {
<div css={hostedSettings}>
{hostedControl()}
<div css={settingsEditor}>
<JsonEditor value={settings} onChange={handleChange} />
<JsonEditor editorSettings={userSettings.codeEditor} value={settings} onChange={handleChange} />
</div>
</div>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/** @jsx jsx */
import { jsx, css } from '@emotion/core';
import React from 'react';
import { FieldProps } from '@bfc/extension';
import { FieldProps, useShellApi } from '@bfc/extension';
import { JsonEditor } from '@bfc/code-editor';

import { FieldLabel } from '../FieldLabel';
Expand All @@ -17,12 +17,19 @@ const fieldStyle = css`

const JsonField: React.FC<FieldProps> = (props) => {
const { onChange, value, id, label, description, uiOptions, required, schema } = props;
const { userSettings } = useShellApi();

return (
<React.Fragment>
<FieldLabel description={description} helpLink={uiOptions?.helpLink} id={id} label={label} required={required} />
<div css={fieldStyle} data-testid="JsonFieldEditor">
<JsonEditor height={200} schema={schema} value={value} onChange={onChange} />
<JsonEditor
editorSettings={userSettings.codeEditor}
height={200}
schema={schema}
value={value}
onChange={onChange}
/>
</div>
</React.Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import { JsonField } from '../JsonField';

import { fieldProps } from './testUtils';

jest.mock('@bfc/extension', () => ({
useShellApi: () => ({
userSettings: {},
}),
}));

function renderSubject(overrides = {}) {
const props = assign({}, fieldProps(), overrides);
return render(<JsonField {...props} />);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/** @jsx jsx */
import { jsx, css } from '@emotion/core';
import React, { useMemo, useState } from 'react';
import { FieldProps } from '@bfc/extension';
import { FieldProps, useShellApi } from '@bfc/extension';
import { FieldLabel, resolveFieldWidget, usePluginConfig, getUiPlaceholder } from '@bfc/adaptive-form';
import { Dropdown, ResponsiveMode, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import { JsonEditor } from '@bfc/code-editor';
Expand Down Expand Up @@ -35,6 +35,7 @@ const ExpressionField: React.FC<FieldProps> = (props) => {
const { id, value, label, description, schema, uiOptions, definitions, required, className } = props;
const { $role, ...expressionSchema } = schema;
const pluginConfig = usePluginConfig();
const { userSettings } = useShellApi();

const options = useMemo(() => getOptions(expressionSchema, definitions), []);
const initialSelectedOption = useMemo(
Expand Down Expand Up @@ -84,6 +85,7 @@ const ExpressionField: React.FC<FieldProps> = (props) => {
return (
<JsonEditor
key={selectedSchema.type}
editorSettings={userSettings.codeEditor}
height={100}
id={props.id}
schema={selectedSchema}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { render } from '@bfc/test-utils';
import assign from 'lodash/assign';

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

const defaultProps = {
depth: 0,
schema: {},
definitions: {},
uiOptions: {},
name: 'testName',
id: 'testId',
onChange: jest.fn(),
onBlur: jest.fn(),
onFocus: jest.fn(),
};

function renderSubject(overrides = {}) {
const props = assign({}, defaultProps, overrides);
return render(<ExpressionField {...props} />);
}

describe('<ExpressionField />', () => {
const schema = {
$role: 'expression',
oneOf: [
{
type: 'string',
title: 'String Value',
},
{
type: 'number',
title: 'Number Value',
},
{
type: 'string',
title: 'Expression Value',
},
],
};

it('renders a dropdown with the types', () => {
const { getByTestId } = renderSubject({ schema, label: 'test' });
expect(getByTestId('expression-type-dropdown-test')).toBeInTheDocument();
});
});

0 comments on commit 99240e9

Please sign in to comment.