Skip to content

Commit

Permalink
Disables back button when there is no history (#377)
Browse files Browse the repository at this point in the history
This can happen whenever a user opens up a page from a URL.

A common way to hit this is to create a run from a notebook and click the link to see it in the UI.
  • Loading branch information
rileyjbauer authored and k8s-ci-robot committed Nov 26, 2018
1 parent c9d8ded commit f59c226
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 58 deletions.
6 changes: 3 additions & 3 deletions frontend/server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion frontend/src/components/Toolbar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import * as React from 'react';
import { shallow } from 'enzyme';
import { createBrowserHistory } from 'history';
import { createBrowserHistory, createMemoryHistory } from 'history';
import Toolbar from './Toolbar';
import HelpIcon from '@material-ui/icons/Help';
import InfoIcon from '@material-ui/icons/Info';
Expand Down Expand Up @@ -57,6 +57,10 @@ const breadcrumbs = [
const history = createBrowserHistory({});

describe('Toolbar', () => {
beforeAll(() => {
history.push('/pipelines');
});

it('renders nothing when there are no breadcrumbs or actions', () => {
const tree = shallow(<Toolbar breadcrumbs={[]} actions={[]} history={history} pageTitle='' />);
expect(tree).toMatchSnapshot();
Expand Down Expand Up @@ -154,4 +158,12 @@ describe('Toolbar', () => {
history={history} />);
expect(tree).toMatchSnapshot();
});

it('disables the back button when there is no browser history', () => {
// This test uses createMemoryHistory because createBroweserHistory returns a singleton, and
// there is no way to clear its entries which this test requires.
const emptyHistory = createMemoryHistory();
const tree = shallow(<Toolbar breadcrumbs={breadcrumbs} actions={actions} history={emptyHistory} pageTitle='' />);
expect(tree).toMatchSnapshot();
});
});
20 changes: 14 additions & 6 deletions frontend/src/components/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const css = stylesheet({
marginRight: spacing.units(-2),
},
backIcon: {
color: color.foreground,
fontSize: backIconHeight,
verticalAlign: 'bottom',
},
Expand All @@ -70,6 +69,12 @@ const css = stylesheet({
chevron: {
height: 12,
},
disabled: {
color: '#aaa',
},
enabled: {
color: color.foreground,
},
link: {
$nest: {
'&:hover': {
Expand Down Expand Up @@ -136,11 +141,14 @@ class Toolbar extends React.Component<ToolbarProps> {
{/* Back Arrow */}
{breadcrumbs.length > 0 &&
<Tooltip title={'Back'} enterDelay={300}>
<IconButton className={css.backLink}
// Need to handle this for when browsing back doesn't make sense
onClick={this.props.history!.goBack}>
<ArrowBackIcon className={css.backIcon} />
</IconButton>
<div> {/* Div needed because we sometimes disable a button within a tooltip */}
<IconButton className={css.backLink}
disabled={this.props.history!.length < 2}
onClick={this.props.history!.goBack}>
<ArrowBackIcon className={
classes(css.backIcon, this.props.history!.length < 2 ? css.disabled : css.enabled)} />
</IconButton>
</div>
</Tooltip>}
{/* Resource Name */}
<span className={classes(css.pageName, commonCss.ellipsis)} title={pageTitleTooltip}>
Expand Down
239 changes: 191 additions & 48 deletions frontend/src/components/__snapshots__/Toolbar.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,124 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Toolbar disables the back button when there is no browser history 1`] = `
<div
className="root topLevelToolbar"
>
<div
style={
Object {
"minWidth": 100,
}
}
>
<div
className="breadcrumbs flex"
>
<span
className="flex"
key="0"
title="test display name"
>
<Link
className="unstyled ellipsis link"
replace={false}
to="/some/test/path"
>
test display name
</Link>
</span>
<span
className="flex"
key="1"
title="test display name2"
>
<pure(ChevronRightIcon)
className="chevron"
/>
<Link
className="unstyled ellipsis link"
replace={false}
to="/some/test/path2"
>
test display name2
</Link>
</span>
</div>
<div
className="flex"
>
<WithStyles(Tooltip)
enterDelay={300}
title="Back"
>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={true}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon disabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
/>
</div>
</div>
<div
className="actions"
>
<WithStyles(Tooltip)
enterDelay={300}
key="0"
title="test tooltip"
>
<div>
<BusyButton
busy={false}
className=""
color="secondary"
icon={[Function]}
id="test id"
onClick={
[MockFunction] {
"calls": Array [
Array [],
],
}
}
outlined={false}
title="test title"
/>
</div>
</WithStyles(Tooltip)>
<WithStyles(Tooltip)
enterDelay={300}
key="1"
title="test disabled title2"
>
<div>
<BusyButton
busy={false}
className=""
color="secondary"
disabled={true}
icon={[Function]}
id="test id2"
onClick={[MockFunction]}
outlined={false}
title="test title2"
/>
</div>
</WithStyles(Tooltip)>
</div>
</div>
`;

exports[`Toolbar renders nothing when there are no breadcrumbs or actions 1`] = `""`;

exports[`Toolbar renders outlined action buttons 1`] = `
Expand Down Expand Up @@ -53,14 +172,18 @@ exports[`Toolbar renders outlined action buttons 1`] = `
enterDelay={300}
title="Back"
>
<WithStyles(IconButton)
className="backLink"
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon"
/>
</WithStyles(IconButton)>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={false}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon enabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
Expand Down Expand Up @@ -142,14 +265,18 @@ exports[`Toolbar renders primary action buttons 1`] = `
enterDelay={300}
title="Back"
>
<WithStyles(IconButton)
className="backLink"
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon"
/>
</WithStyles(IconButton)>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={false}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon enabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
Expand Down Expand Up @@ -231,14 +358,18 @@ exports[`Toolbar renders primary action buttons without outline, even if outline
enterDelay={300}
title="Back"
>
<WithStyles(IconButton)
className="backLink"
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon"
/>
</WithStyles(IconButton)>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={false}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon enabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
Expand Down Expand Up @@ -320,14 +451,18 @@ exports[`Toolbar renders with two breadcrumbs and two actions 1`] = `
enterDelay={300}
title="Back"
>
<WithStyles(IconButton)
className="backLink"
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon"
/>
</WithStyles(IconButton)>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={false}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon enabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
Expand Down Expand Up @@ -419,14 +554,18 @@ exports[`Toolbar renders without actions and one breadcrumb 1`] = `
enterDelay={300}
title="Back"
>
<WithStyles(IconButton)
className="backLink"
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon"
/>
</WithStyles(IconButton)>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={false}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon enabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
Expand Down Expand Up @@ -474,14 +613,18 @@ exports[`Toolbar renders without actions, one breadcrumb, and a page name 1`] =
enterDelay={300}
title="Back"
>
<WithStyles(IconButton)
className="backLink"
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon"
/>
</WithStyles(IconButton)>
<div>
<WithStyles(IconButton)
className="backLink"
disabled={false}
onClick={[Function]}
>
<pure(ArrowBackIcon)
className="backIcon enabled"
/>
</WithStyles(IconButton)>
</div>
</WithStyles(Tooltip)>
<span
className="pageName ellipsis"
Expand Down

0 comments on commit f59c226

Please sign in to comment.