Skip to content

Commit

Permalink
#1237 - added new copy and updated functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
justinwilaby committed Jan 16, 2019
1 parent 0f2e107 commit ffd52c1
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
.browse-button {
overflow: hidden;
position: absolute;
right: 0;
bottom: 12px;
right: 4px;
bottom: 11.5px;
}

.input-container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

import { newNotification, SharedConstants } from '@bfemulator/app-shared';
import { SharedConstants } from '@bfemulator/app-shared';
import { mount } from 'enzyme';
import * as React from 'react';
import { Provider } from 'react-redux';
import { combineReducers, createStore } from 'redux';
import * as BotActions from '../../../data/action/botActions';
import { beginAdd } from '../../../data/action/notificationActions';
import { bot } from '../../../data/reducer/bot';
import { CommandServiceImpl } from '../../../platform/commands/commandServiceImpl';
import { ActiveBotHelper } from '../../helpers/activeBotHelper';
Expand Down Expand Up @@ -72,13 +71,11 @@ const bots = [
];

describe('The OpenBotDialog', () => {
let mockDispatch;
let node;
let parent;
let instance;
beforeEach(() => {
mockStore.dispatch(BotActions.load(bots));
mockDispatch = jest.spyOn(mockStore, 'dispatch');
parent = mount(<Provider store={ mockStore }>
<OpenBotDialogContainer/>
</Provider>);
Expand All @@ -92,47 +89,6 @@ describe('The OpenBotDialog', () => {
expect(spy).toHaveBeenCalled();
});

it('should orchestrate the appropriate sequences when a recent bot is clicked', async () => {
const commandServiceSpy = jest.spyOn(CommandServiceImpl, 'call').mockResolvedValue(true);
const dialogSpy = jest.spyOn(DialogService, 'hideDialog');
await instance.onBotSelected(bots[0]);
const { Switch } = SharedConstants.Commands.Bot;
expect(commandServiceSpy).toHaveBeenCalledWith(Switch, '/some/path');
expect(dialogSpy).toHaveBeenCalled();
});

it('should send a notification when the bot fails to open', async () => {
await instance.onBotSelected(null);
const message = `An Error occurred on the Open Bot Dialog: TypeError: Cannot read property 'path' of null`;
const notification = newNotification(message);
const action = beginAdd(notification);
notification.timestamp = jasmine.any(Number) as any;
notification.id = jasmine.any(String) as any;
expect(mockDispatch).toHaveBeenLastCalledWith(action);
});

it('should make the appropriate calls when onCreateNewBotClick in called', async () => {
const commandServiceSpy = jest.spyOn(CommandServiceImpl, 'call').mockResolvedValue(true);
const dialogSpy = jest.spyOn(DialogService, 'hideDialog');

await instance.onCreateNewBotClick();
expect(commandServiceSpy).toHaveBeenLastCalledWith(SharedConstants.Commands.UI.ShowBotCreationDialog);
expect(dialogSpy).toHaveBeenCalled();
});

it('should send a notification when onCreateNewBotClick fails', async () => {
const commandServiceSpy = jest.spyOn(CommandServiceImpl, 'call').mockRejectedValue('oh noes!');
await instance.onCreateNewBotClick();
const message = `An Error occurred on the Open Bot Dialog: oh noes!`;
const notification = newNotification(message);
const action = beginAdd(notification);
notification.timestamp = jasmine.any(Number) as any;
notification.id = jasmine.any(String) as any;
expect(mockDispatch).toHaveBeenLastCalledWith(action);

expect(commandServiceSpy).toHaveBeenLastCalledWith(SharedConstants.Commands.UI.ShowBotCreationDialog);
});

it('should properly set the state when the input changes', () => {
instance.onInputChange({
target: {
Expand Down Expand Up @@ -174,7 +130,7 @@ describe('The OpenBotDialog', () => {
} as any);

const botHelperSpy = jest.spyOn(ActiveBotHelper, 'confirmAndOpenBotFromFile').mockResolvedValue(true);
await instance.onOpenClick();
await instance.onSubmit();

expect(botHelperSpy).toHaveBeenCalledWith('some/path/to/myBot.bot');
});
Expand All @@ -188,7 +144,7 @@ describe('The OpenBotDialog', () => {
} as any);

const commandServiceSpy = jest.spyOn(CommandServiceImpl, 'call');
await instance.onOpenClick();
await instance.onSubmit();

expect(commandServiceSpy).toHaveBeenCalledWith(SharedConstants.Commands.Emulator.NewLiveChat,
{ endpoint: 'http://localhost:6500/api/messages' });
Expand Down
90 changes: 34 additions & 56 deletions packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,15 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

import { BotInfo } from '@bfemulator/app-shared';
// import { BotInfo } from '@bfemulator/app-shared';
import { DefaultButton, Dialog, DialogFooter, PrimaryButton, TextField } from '@bfemulator/ui-react';
import * as React from 'react';
import { ChangeEvent, FocusEvent, ReactNode } from 'react';
import { RecentBotsListContainer } from '../../editor/recentBotsList/recentBotsListContainer';
// import { RecentBotsListContainer } from '../../editor/recentBotsList/recentBotsListContainer';
import * as styles from '../dialogStyles.scss';
import * as openBotStyles from './openBotDialog.scss';

export interface OpenBotDialogProps {
showCreateNewBotDialog?: () => Promise<void>;
onDialogCancel?: () => void;
openBot?: (urlOrPath: string) => Promise<void>;
sendNotification?: (error: Error) => void;
Expand Down Expand Up @@ -71,64 +70,43 @@ export class OpenBotDialog extends React.Component<OpenBotDialogProps, OpenBotDi
<Dialog
cancel={ this.props.onDialogCancel }
className={ `${ styles.dialogMedium } ${ openBotStyles.themeOverrides }` }
title="Open a Bot">
<p>
{ `You can open a bot using just a URL, choose from a list of recently opened bots or ` }
<a href="javascript:void(0);" onClick={ this.onCreateNewBotClick }>create a new bot configuration</a>
</p>
<TextField
errorMessage={ errorMessage }
inputContainerClassName={ openBotStyles.inputContainer }
label="Bot URL or File Location"
onChange={ this.onInputChange }
onFocus={ this.onFocus }
value={ botUrl }>
title="Open a bot">
<form onSubmit={ this.onSubmit }>
<TextField
errorMessage={ errorMessage }
inputContainerClassName={ openBotStyles.inputContainer }
label="Bot URL or file location"
onChange={ this.onInputChange }
onFocus={ this.onFocus }
value={ botUrl }>

<PrimaryButton
className={ openBotStyles.browseButton }>
Browse
<input
className={ openBotStyles.fileInput }
onChange={ this.onInputChange }
accept=".bot"
type="file"/>
</PrimaryButton>
<PrimaryButton
className={ openBotStyles.browseButton }>
Browse
<input
className={ openBotStyles.fileInput }
onChange={ this.onInputChange }
accept=".bot"
type="file"/>
</PrimaryButton>

</TextField>
<RecentBotsListContainer onBotSelected={ this.onBotSelected }/>
<DialogFooter>
<PrimaryButton
text="Close"
onClick={ this.props.onDialogCancel }
/>
<DefaultButton
disabled={ !!errorMessage }
onClick={ this.onOpenClick }
text="Open/Connect"
/>
</DialogFooter>
</TextField>
<DialogFooter>
<DefaultButton
text="Cancel"
onClick={ this.props.onDialogCancel }
/>
<PrimaryButton
type="submit"
disabled={ !!errorMessage || !botUrl }
text="Connect"
/>
</DialogFooter>
</form>
</Dialog>
);
}

private onBotSelected = async (bot: BotInfo) => {
try {
await this.props.switchToBot(bot.path);
this.props.onDialogCancel();
} catch (e) {
this.props.sendNotification(e);
}
}

private onCreateNewBotClick = async () => {
try {
await this.props.showCreateNewBotDialog();
this.props.onDialogCancel();
} catch (e) {
this.props.sendNotification(e);
}
}

private onFocus = (event: FocusEvent<HTMLInputElement>) => {
const input = event.target as HTMLInputElement;
input.setSelectionRange(0, (input.value || '').length);
Expand All @@ -140,7 +118,7 @@ export class OpenBotDialog extends React.Component<OpenBotDialogProps, OpenBotDi
this.setState({ botUrl });
}

private onOpenClick = async () => {
private onSubmit = async () => {
try {
await this.props.openBot(this.state.botUrl);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,17 @@
//

import { newNotification, SharedConstants } from '@bfemulator/app-shared';
import { Action } from 'redux';
import { IEndpointService } from 'botframework-config/lib/schema';
import { connect } from 'react-redux';
import { Action } from 'redux';
import { beginAdd } from '../../../data/action/notificationActions';
import { RootState } from '../../../data/store';
import { CommandServiceImpl } from '../../../platform/commands/commandServiceImpl';
import { ActiveBotHelper } from '../../helpers/activeBotHelper';
import { DialogService } from '../service';
import { OpenBotDialog, OpenBotDialogProps } from './openBotDialog';

const mapStateToProps = (state: RootState, ownProps: { [propName: string]: any }): OpenBotDialogProps => {
return {
showCreateNewBotDialog: () => CommandServiceImpl.call(SharedConstants.Commands.UI.ShowBotCreationDialog),
...ownProps
};
};

const mapDispatchToProps = (dispatch: (action: Action) => void): OpenBotDialogProps => {
const { Commands: { Emulator: { NewLiveChat }, Bot: { Switch } } } = SharedConstants;
const { Commands: { Emulator: { NewLiveChat } } } = SharedConstants;
return {
onDialogCancel: () => DialogService.hideDialog(),
openBot: (urlOrPath: string) => {
Expand All @@ -62,11 +54,10 @@ const mapDispatchToProps = (dispatch: (action: Action) => void): OpenBotDialogPr
},
sendNotification: (error: Error) =>
dispatch(beginAdd(newNotification(`An Error occurred on the Open Bot Dialog: ${ error }`))),
switchToBot: (path: string) => CommandServiceImpl.call(Switch, path)
};
};

export const OpenBotDialogContainer = connect(
mapStateToProps,
null,
mapDispatchToProps
)(OpenBotDialog);
47 changes: 17 additions & 30 deletions packages/app/client/src/ui/helpers/activeBotHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const ActiveBotHelper = new class {
CommandServiceImpl.remoteCall(SharedConstants.Commands.Electron.SetTitleBar, getBotDisplayName(bot))
]);
} catch (e) {
const errMsg = `Error while setting active bot: ${e}`;
const errMsg = `Error while setting active bot: ${ e }`;
const notification = newNotification(errMsg);
store.dispatch(beginAdd(notification));
throw new Error(errMsg);
Expand All @@ -112,7 +112,7 @@ export const ActiveBotHelper = new class {
CommandServiceImpl.remoteCall(SharedConstants.Commands.Electron.SetTitleBar, '');
})
.catch(err => {
const errMsg = `Error while closing active bot: ${err}`;
const errMsg = `Error while closing active bot: ${ err }`;
const notification = newNotification(errMsg);
store.dispatch(beginAdd(notification));
throw new Error(errMsg);
Expand Down Expand Up @@ -159,7 +159,7 @@ export const ActiveBotHelper = new class {
store.dispatch(NavBarActions.select(Constants.NAVBAR_BOT_EXPLORER));
store.dispatch(ExplorerActions.showExplorer(true));
} catch (err) {
const errMsg = `Error during bot create: ${err}`;
const errMsg = `Error during bot create: ${ err }`;
const notification = newNotification(errMsg);
store.dispatch(beginAdd(notification));
throw new Error(errMsg);
Expand Down Expand Up @@ -194,34 +194,21 @@ export const ActiveBotHelper = new class {
await CommandServiceImpl.call(SharedConstants.Commands.Bot.Switch, activeBot);
return;
}
const result = this.confirmSwitchBot();

try {
const result = this.confirmSwitchBot();

if (result) {
try {
store.dispatch(EditorActions.closeNonGlobalTabs());
const bot = await CommandServiceImpl.remoteCall(SharedConstants.Commands.Bot.Open, filename)
// Secret prompt dialog was closed
.catch(_err => null);
if (!bot) {
return;
}
await CommandServiceImpl.remoteCall(SharedConstants.Commands.Bot.SetActive, bot);
await CommandServiceImpl.call(SharedConstants.Commands.Bot.Load, bot);
} catch (err) {
console.error('Error while trying to open bot from file: ', err);
throw new Error(`[confirmAndOpenBotFromFile] Error while trying to open bot from file: ${err}`);
}
if (result) {
store.dispatch(EditorActions.closeNonGlobalTabs());
const bot = await CommandServiceImpl.remoteCall(SharedConstants.Commands.Bot.Open, filename);
if (!bot) {
return;
}
} catch (err) {
console.error('Error while calling confirmSwitchBot: ', err);
throw new Error(`[confirmAndOpenBotFromFile] Error while calling confirmSwitchBot: ${err}`);
await CommandServiceImpl.remoteCall(SharedConstants.Commands.Bot.SetActive, bot);
await CommandServiceImpl.call(SharedConstants.Commands.Bot.Load, bot);
}
}
} catch (err) {
console.error('Error while calling browseForBotFile: ', err);
throw new Error(`[confirmAndOpenBotFromFile] Error while calling browseForBotFile: ${err}`);
throw new Error(`[confirmAndOpenBotFromFile] Error while calling browseForBotFile: ${ err }`);
}
}

Expand All @@ -241,13 +228,13 @@ export const ActiveBotHelper = new class {
await CommandServiceImpl.call(
SharedConstants.Commands.Emulator.NewLiveChat, currentActiveBot.services[0]);
} catch (e) {
throw new Error(`[confirmAndSwitchBots] Error while trying to open bot at ${botPath}: ${e}`);
throw new Error(`[confirmAndSwitchBots] Error while trying to open bot at ${ botPath }: ${ e }`);
}
return;
}

// TODO: We need to think about merging this with confirmAndCreateBot
console.log(`Switching to bot ${botPath}`);
console.log(`Switching to bot ${ botPath }`);

try {
// prompt the user to confirm the switch
Expand All @@ -261,7 +248,7 @@ export const ActiveBotHelper = new class {
try {
newActiveBot = await CommandServiceImpl.remoteCall(SharedConstants.Commands.Bot.Open, bot);
} catch (e) {
throw new Error(`[confirmAndSwitchBots] Error while trying to open bot at ${botPath}: ${e}`);
throw new Error(`[confirmAndSwitchBots] Error while trying to open bot at ${ botPath }: ${ e }`);
}
} else {
newActiveBot = bot;
Expand Down Expand Up @@ -300,7 +287,7 @@ export const ActiveBotHelper = new class {
store.dispatch(ExplorerActions.showExplorer(true));
}
} catch (e) {
const errMsg = `Error while trying to switch to bot: ${botPath}`;
const errMsg = `Error while trying to switch to bot: ${ botPath }`;
const notification = newNotification(errMsg);
store.dispatch(beginAdd(notification));
throw new Error(errMsg);
Expand All @@ -324,7 +311,7 @@ export const ActiveBotHelper = new class {
}
})
.catch(err => {
const errMsg = `Error while closing active bot: ${err}`;
const errMsg = `Error while closing active bot: ${ err }`;
const notification = newNotification(errMsg);
store.dispatch(beginAdd(notification));
throw new Error(errMsg);
Expand Down
Loading

0 comments on commit ffd52c1

Please sign in to comment.