Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bumped react & react-dom to 16.8.6 #1939

Merged
merged 3 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [client] Bumped Web Chat to v4.5.3 in PR [1925](https://github.com/microsoft/BotFramework-Emulator/pull/1925)
- [client] Fixed issue that was causing Web Chat interactions to clear Adaptive Card content in PR [1930](https://github.com/microsoft/BotFramework-Emulator/pull/1930)
- [client/main] Added a new property, `source`, to the `bot_open` telemetry event to distinguish between bots opened via .bot file and via url, in PR [1937](https://github.com/microsoft/BotFramework-Emulator/pull/1937)
- [client] Bumped `react` & `react-dom` to `^16.8.6` to sync with Web Chat in PR [1939](https://github.com/microsoft/BotFramework-Emulator/pull/1939)
- [client] Fixed an issue with the `<AutoComplete />` component so that it can now accept an empty string as an input in "controlled mode" in PR [1939](https://github.com/microsoft/BotFramework-Emulator/pull/1939)


## v4.5.2 - 2019 - 07 - 17
Expand Down
349 changes: 179 additions & 170 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/app/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@
"botframework-webchat-core": "4.5.3",
"eslint-plugin-react": "^7.12.3",
"markdown-it": "^8.4.2",
"react": "~16.3.2",
"react-dom": "~16.3.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
Expand Down
7 changes: 5 additions & 2 deletions packages/app/client/src/commands/uiCommands.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,13 @@ describe('the uiCommands', () => {
});

it('should call DialogService.showDialog when the ShowOpenBotDialog command is dispatched', async () => {
const spy = jest.spyOn(DialogService, 'showDialog').mockResolvedValueOnce(true);
const spy = jest.spyOn(DialogService, 'showDialog').mockResolvedValue(true);
const result = await registry.getCommand(Commands.ShowOpenBotDialog)();
expect(spy).toHaveBeenCalledWith(OpenBotDialogContainer, { isDebug: false });
expect(spy).toHaveBeenCalledWith(OpenBotDialogContainer, { isDebug: false, mode: undefined });
expect(result).toBe(true);

await registry.getCommand(Commands.ShowOpenBotDialog)(true);
expect(spy).toHaveBeenCalledWith(OpenBotDialogContainer, { isDebug: true, mode: 'debug' });
});

describe('should dispatch the appropriate action to the store', () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/app/client/src/commands/uiCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,10 @@ export class UiCommands {
// Shows a bot creation dialog
@Command(UI.ShowOpenBotDialog)
protected async showOpenBotDialog(isDebug: boolean = false): Promise<void> {
const mode = isDebug ? 'debug' : undefined;
return await DialogService.showDialog<ComponentClass, void>(OpenBotDialogContainer, {
isDebug,
mode,
} as OpenBotDialogProps);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import { clientAwareSettingsChanged } from '../../../state/actions/clientAwareSe
import { bot } from '../../../state/reducers/bot';
import { clientAwareSettings } from '../../../state/reducers/clientAwareSettings';
import { DialogService } from '../service';
import { ariaAlertService } from '../../a11y';
import { executeCommand } from '../../../state/actions/commandActions';

import { OpenBotDialog } from './openBotDialog';
Expand Down
31 changes: 11 additions & 20 deletions packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ import { EmulatorMode } from '@bfemulator/sdk-shared';
import * as openBotStyles from './openBotDialog.scss';

export interface OpenBotDialogProps {
mode?: EmulatorMode;
appId?: string;
appPassword?: string;
botUrl?: string;
isAzureGov?: boolean;
isDebug?: boolean;
mode?: EmulatorMode;
onAnchorClick?: (url: string) => void;
onDialogCancel?: () => void;
openBot?: (state: OpenBotDialogState) => void;
Expand Down Expand Up @@ -98,29 +102,16 @@ export class OpenBotDialog extends Component<OpenBotDialogProps, OpenBotDialogSt
return endpoint.endsWith('.bot') ? ValidationResult.Valid : ValidationResult.Invalid;
}

public static getDerivedStateFromProps(
newProps: OpenBotDialogProps = {},
newState: OpenBotDialogState = {}
): OpenBotDialogState {
let { mode = 'livechat' } = newProps;
const { isDebug } = newProps;
if (isDebug) {
mode = 'debug';
if (!(newState.botUrl || '').startsWith('http')) newState.botUrl = '';
}
return { ...newState, mode, isDebug };
}

constructor(props: OpenBotDialogProps) {
super(props);
const { mode = 'livechat' } = props;
const { appId = '', appPassword = '', botUrl = '', isAzureGov = false, isDebug = false, mode = 'livechat' } = props;
this.state = {
botUrl: '',
appId: '',
appPassword: '',
isDebug: false,
appId,
appPassword,
botUrl,
isAzureGov,
isDebug,
mode,
isAzureGov: false,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ describe('The Inspector component', () => {
const instance = node.instance();
instance.setInspectorTitle('Yo!');

expect(instance.state.title).toBe('Yo!');
expect(instance.state.titleOverride).toBe('Yo!');
});

it('should send the initialization stack to the inspector when the dom is ready', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ declare type ElectronHTMLWebViewElement = HTMLWebViewElement & {
send: (...args: any[]) => void;
};

// TODO: Component could be greatly simplified by storing inspector state
// in the redux store referenced by owning document id.
export class Inspector extends React.Component<InspectorProps, InspectorState> {
private static renderAccessoryIcon(icon: string) {
if (icon === 'Spinner') {
Expand Down Expand Up @@ -144,9 +146,11 @@ export class Inspector extends React.Component<InspectorProps, InspectorState> {
const inspectorResult = Inspector.getInspector(document.inspectorObjects);
const { inspector = { name: '' } } = inspectorResult.response;
const buttons = Inspector.getButtons(inspector.accessories);
const { inspector: prevInspector = {} } = prevState;
const { inspector: prevInspector = {}, titleOverride } = prevState;

if (prevState.buttons && inspector.name === prevInspector.name) {
const inspectorChanged = inspector.name !== prevInspector.name;

if (prevState.buttons && !inspectorChanged) {
Object.assign(buttons, prevState.buttons);
}
return {
Expand All @@ -160,6 +164,7 @@ export class Inspector extends React.Component<InspectorProps, InspectorState> {
inspectObj: inspectorResult.inspectObj,
themeInfo: themeInfo,
title: inspector.name,
titleOverride: inspectorChanged ? '' : titleOverride,
buttons,
};
}
Expand Down Expand Up @@ -206,9 +211,10 @@ export class Inspector extends React.Component<InspectorProps, InspectorState> {

public render() {
if (this.state.inspector && this.state.inspectObj) {
const { title, titleOverride } = this.state;
return (
<div aria-label="inspector panel" className={styles.detailPanel} role="region">
<Panel title={['inspector', this.state.title].filter(s => s && s.length).join(' - ')}>
<Panel title={['inspector', titleOverride || title].filter(s => s && s.length).join(' - ')}>
{this.renderAccessoryButtons()}
<PanelContent>
<div className={styles.inspectorContainer}>
Expand Down Expand Up @@ -305,7 +311,7 @@ export class Inspector extends React.Component<InspectorProps, InspectorState> {
this.inspect(newState.inspectObj);
}

if ((oldState.themeInfo || { themeName: '' }).themeName !== newState.themeInfo.themeName) {
if ((oldState.themeInfo || { themeName: '' }).themeName !== (newState.themeInfo || { themeName: '' }).themeName) {
this.sendToExtension(ExtensionChannel.Theme, newState.themeInfo);
}
}
Expand Down Expand Up @@ -379,8 +385,8 @@ export class Inspector extends React.Component<InspectorProps, InspectorState> {
};

private setInspectorTitle = (title: string) => {
if (this.state.title !== title) {
this.setState({ title });
if (this.state.titleOverride !== title) {
this.setState({ titleOverride: title });
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,31 +82,6 @@ export class EndpointEditor extends Component<EndpointEditorProps, EndpointEdito
private endpointWarningDelay: any;
private absContent: HTMLDivElement;

public static getDerivedStateFromProps(nextProps: EndpointEditorProps) {
const { endpointService, botService } = nextProps;
const derivedState: EndpointEditorState = {} as EndpointEditorState;

if (endpointService) {
Object.assign(derivedState, {
endpointService: new EndpointService(endpointService),
nameError: '',
endpointError: '',
appPasswordError: '',
appIdError: '',
endpointWarning: '',
isDirty: false,
});
}

if (botService) {
Object.assign(derivedState, {
botService: new BotService(botService),
});
}

return derivedState;
}

private static validateEndpoint(endpoint: string): string {
const controllerRegEx = /api\/messages\/?$/;
return controllerRegEx.test(endpoint) ? '' : `Please include route if necessary: "/api/messages"`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
//
import * as React from 'react';
import { Provider } from 'react-redux';
import { mount } from 'enzyme';
import { mount, ReactWrapper } from 'enzyme';
import { combineReducers, createStore } from 'redux';
import { ServiceTypes } from 'botframework-config/lib/schema';
import { BotConfigWithPathImpl } from '@bfemulator/sdk-shared';
Expand Down Expand Up @@ -62,7 +62,7 @@ jest.mock('../servicePane/servicePane.scss', () => ({}));
jest.mock('./resourceExplorer.scss', () => ({}));

describe('The ServicesExplorer component should', () => {
let parent;
let parent: ReactWrapper<any, any, any>;
let node;
let mockChat;
let mockTranscript;
Expand All @@ -82,7 +82,7 @@ describe('The ServicesExplorer component should', () => {

parent = mount(
<Provider store={mockStore}>
<ResourceExplorerContainer files={[mockChat, mockTranscript]} />
<ResourceExplorerContainer files={[mockChat, mockTranscript]} fileToRename={mockTranscript} />
</Provider>
);
node = parent.find(ResourceExplorer);
Expand Down Expand Up @@ -114,11 +114,18 @@ describe('The ServicesExplorer component should', () => {
expect(mockDispatch).toHaveBeenCalledWith(openContextMenuForResource(mockChat));
});

it('should dispatch to rename the resource when input is blurred', () => {
const instance = node.instance();
instance.setState({ modifiedFileName: 'newTestTranscript' });
instance.onInputBlur();
expect(mockDispatch).toHaveBeenCalledWith(renameResource({ ...mockTranscript, name: 'newTestTranscript' }));
});

it('should dispatch to rename the resource when the enter key is pressed while focused in an input field', () => {
const instance = node.instance();
instance.setState({ fileToRename: mockTranscript });
instance.onInputKeyUp({ which: 13 });
expect(mockDispatch).toHaveBeenCalledWith(renameResource(mockTranscript));
instance.setState({ modifiedFileName: 'newTestTranscript' });
instance.onInputKeyUp({ key: 'Enter' });
expect(mockDispatch).toHaveBeenCalledWith(renameResource({ ...mockTranscript, name: 'newTestTranscript' }));
});

it('should open the resource when the enter key is pressed while focused on a link', () => {
Expand All @@ -135,4 +142,12 @@ describe('The ServicesExplorer component should', () => {
instance.onChooseLocationClick();
expect(spy).toHaveBeenCalledWith(openResourcesSettings({ dialog: ResourcesSettingsContainer }));
});

it('should return the file to rename', () => {
const instance = node.instance();
expect(instance.fileToRename).toEqual(mockTranscript);

instance.setState({ modifiedFileName: 'newTestTranscript' });
expect(instance.fileToRename).toEqual({ ...mockTranscript, name: 'newTestTranscript' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,24 @@ function simpleNameSort(a: IFileService, b: IFileService): 0 | 1 | -1 {
}

export interface ResourceExplorerState extends ServicePaneState {
fileToRename?: IFileService;
modifiedFileName: string;
}

export interface ResourceExplorerProps extends ServicePaneProps, ResourceExplorerState {
files?: IFileService[];
fileToRename?: IFileService;
renameResource: (resource: IFileService) => void;
openResource: (resource: IFileService) => void;
resourcesPath?: string;
openResourcesSettings?: (dialog: ComponentClass<any>) => void;
}

export class ResourceExplorer extends ServicePane<ResourceExplorerProps, ResourceExplorerState> {
public static getDerivedStateFromProps(newProps: ResourceExplorerProps) {
const { fileToRename = {} } = newProps;
return { fileToRename: { ...fileToRename } }; // Copies only
constructor(props: ResourceExplorerProps, context: ResourceExplorerState) {
super(props, context);
this.state = {
modifiedFileName: '',
};
}

protected get controls(): JSX.Element {
Expand All @@ -74,7 +77,8 @@ export class ResourceExplorer extends ServicePane<ResourceExplorerProps, Resourc

protected get links() {
const { files = [] } = this.props;
const fileToRename = this.state.fileToRename || { id: '', name: '' };
const fileToRename = this.fileToRename || { id: '', name: '' };

return files.sort(simpleNameSort).map((file, index) => {
const mutable = fileToRename.id === file.id;
if (!mutable) {
Expand Down Expand Up @@ -162,20 +166,18 @@ export class ResourceExplorer extends ServicePane<ResourceExplorerProps, Resourc
};

private onInputChange = (event: ChangeEvent<HTMLInputElement>): void => {
const { fileToRename } = this.state;
fileToRename.name = event.target.value;
this.setState({ modifiedFileName: event.target.value });
};

private onInputBlur = (): void => {
this.props.renameResource(this.state.fileToRename);
this.props.renameResource(this.fileToRename);
};

private onInputKeyUp = (event: KeyboardEvent<HTMLInputElement>): void => {
if (event.which !== 13) {
if (event.key !== 'Enter') {
return;
}
const { fileToRename } = this.state;
this.props.renameResource(fileToRename);
this.props.renameResource(this.fileToRename);
};

private editableInputRef = (ref: HTMLInputElement): void => {
Expand All @@ -188,4 +190,12 @@ export class ResourceExplorer extends ServicePane<ResourceExplorerProps, Resourc
});
}
};

private get fileToRename(): IFileService {
const { fileToRename } = this.props;
if (this.state.modifiedFileName) {
return { ...fileToRename, name: this.state.modifiedFileName };
}
return fileToRename;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,16 @@ const portalMap = {
};

export class ConnectedServiceEditor extends Component<ConnectedServiceEditorProps, ConnectedServiceEditorState> {
public state: ConnectedServiceEditorState = {} as ConnectedServiceEditorState;

public static getDerivedStateFromProps(props: ConnectedServiceEditorProps, state: ConnectedServiceEditorState) {
const connectedServiceCopy = BotConfigurationBase.serviceFromJSON(
props.connectedService || {
type: props.serviceType,
name: '',
}
);

if (JSON.stringify(connectedServiceCopy) !== JSON.stringify(state.connectedServiceCopy)) {
return { connectedServiceCopy };
}

return state;
}

constructor(props: ConnectedServiceEditorProps, state: ConnectedServiceEditorState) {
super(props, state);
this.state = ConnectedServiceEditor.getDerivedStateFromProps(props, state || ({} as ConnectedServiceEditorState));
this.state = {
connectedServiceCopy: BotConfigurationBase.serviceFromJSON(
props.connectedService || {
type: props.serviceType,
name: '',
}
),
};
}

public render(): JSX.Element {
Expand Down
2 changes: 1 addition & 1 deletion packages/app/client/src/vendors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

import 'base64url';
import 'botframework-config/lib/models';
import 'botframework-config/lib/schema';
import 'botframework-webchat';
import 'react';
import 'react-dom';
import 'redux';
import 'redux-promise-middleware';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was removed as a dependency in #1721 (line where it was removed)

import 'redux-saga';
Loading