diff --git a/frontend/src/components/SideNav.test.tsx b/frontend/src/components/SideNav.test.tsx index 15719d492d1..139fa18a04a 100644 --- a/frontend/src/components/SideNav.test.tsx +++ b/frontend/src/components/SideNav.test.tsx @@ -48,13 +48,13 @@ describe('SideNav', () => { expect(tree).toMatchSnapshot(); }); - it('renders experiments as active page', () => { - const tree = shallow(); + it('renders Pipelines as active when on PipelineDetails page', () => { + const tree = shallow(); expect(tree).toMatchSnapshot(); }); - it('renders Pipelines as active when on PipelineDetails page', () => { - const tree = shallow(); + it('renders experiments as active page', () => { + const tree = shallow(); expect(tree).toMatchSnapshot(); }); @@ -63,11 +63,36 @@ describe('SideNav', () => { expect(tree).toMatchSnapshot(); }); - it('renders nothing as active page', () => { + it('renders experiments as active page when on NewExperiment page', () => { + const tree = shallow(); + expect(tree).toMatchSnapshot(); + }); + + it('renders experiments as active page when on Compare page', () => { const tree = shallow(); expect(tree).toMatchSnapshot(); }); + it('renders experiments as active page when on AllRuns page', () => { + const tree = shallow(); + expect(tree).toMatchSnapshot(); + }); + + it('renders experiments as active page when on RunDetails page', () => { + const tree = shallow(); + expect(tree).toMatchSnapshot(); + }); + + it('renders experiments as active page when on RecurringRunDetails page', () => { + const tree = shallow(); + expect(tree).toMatchSnapshot(); + }); + + it('renders experiments as active page when on NewRun page', () => { + const tree = shallow(); + expect(tree).toMatchSnapshot(); + }); + it('show jupyterhub link if accessible', () => { const tree = shallow(); tree.setState({ jupyterHubAvailable: true }); diff --git a/frontend/src/components/SideNav.tsx b/frontend/src/components/SideNav.tsx index a97b4247941..8e6953e64d8 100644 --- a/frontend/src/components/SideNav.tsx +++ b/frontend/src/components/SideNav.tsx @@ -184,9 +184,9 @@ class SideNav extends React.Component { @@ -209,6 +209,15 @@ class SideNav extends React.Component { ); } + private _highlightExperimentsButton(page: string): boolean { + return page.startsWith(RoutePage.EXPERIMENTS) + || page.startsWith(RoutePage.RUNS) + // TODO: Router should have a constant for this, but it doesn't follow the naming convention + // of the other pages + || page.startsWith('/recurringrun') + || page.startsWith(RoutePage.COMPARE); + } + private _toggleNavClicked() { this.setState({ collapsed: !this.state.collapsed, diff --git a/frontend/src/components/__snapshots__/SideNav.test.tsx.snap b/frontend/src/components/__snapshots__/SideNav.test.tsx.snap index 832f26fc2e6..cbda7ea9eb4 100644 --- a/frontend/src/components/__snapshots__/SideNav.test.tsx.snap +++ b/frontend/src/components/__snapshots__/SideNav.test.tsx.snap @@ -360,7 +360,7 @@ exports[`SideNav renders experiments as active page 1`] = ` `; -exports[`SideNav renders experiments as active when on ExperimentDetails page 1`] = ` +exports[`SideNav renders experiments as active page when on AllRuns page 1`] = `
`; -exports[`SideNav renders nothing as active page 1`] = ` +exports[`SideNav renders experiments as active page when on Compare page 1`] = `
+ + + + Experiments + + + +
+ + + +
+`; + +exports[`SideNav renders experiments as active page when on NewExperiment page 1`] = ` +
+
+ + + Kubeflow + +
+ + + + Pipelines + + + + + + + Experiments + + + +
+ + + +
+`; + +exports[`SideNav renders experiments as active page when on NewRun page 1`] = ` +
+
+ + + Kubeflow + +
+ + + + + Pipelines + + + + + + @@ -504,7 +648,7 @@ exports[`SideNav renders nothing as active page 1`] = `
`; -exports[`SideNav show jupyterhub link if accessible 1`] = ` +exports[`SideNav renders experiments as active page when on RecurringRunDetails page 1`] = `
+ + + + Experiments + + + +
+ + + +
+`; + +exports[`SideNav renders experiments as active page when on RunDetails page 1`] = ` +
+
+ + + Kubeflow + +
+ + + + Pipelines + + + + + + + Experiments + + + +
+ + + +
+`; + +exports[`SideNav renders experiments as active when on ExperimentDetails page 1`] = ` +
+
+ + + Kubeflow + +
+ + + + + Pipelines + + + + + + + + Experiments + + + +
+ + + +
+`; + +exports[`SideNav show jupyterhub link if accessible 1`] = ` +
+
+ + + Kubeflow + +
+ + + + + Pipelines + + + + + + diff --git a/frontend/src/pages/AllRunsList.tsx b/frontend/src/pages/AllRunsList.tsx index 825f79c2d15..529eb4b38dc 100644 --- a/frontend/src/pages/AllRunsList.tsx +++ b/frontend/src/pages/AllRunsList.tsx @@ -15,6 +15,7 @@ */ import * as React from 'react'; +import AddIcon from '@material-ui/icons/Add'; import RunList from './RunList'; import { Page } from './Page'; import { RoutePage } from '../components/Router'; @@ -40,31 +41,34 @@ class AllRunsList extends Page<{}, AllRunsListState> { public getInitialToolbarState() { return { - actions: [ - { - action: this._compareRuns.bind(this), - disabled: true, - disabledTitle: 'Select multiple runs to compare', - id: 'compareBtn', - title: 'Compare runs', - tooltip: 'Compare up to 10 selected runs', - }, - { - action: this._cloneRun.bind(this), - disabled: true, - disabledTitle: 'Select a run to clone', - id: 'cloneBtn', - title: 'Clone run', - tooltip: 'Create a copy from this run\s initial state', - }, - { - action: this.refresh.bind(this), - id: 'refreshBtn', - title: 'Refresh', - tooltip: 'Refresh', - }, - ], - breadcrumbs: [{ displayName: 'All runs', href: '' }], + actions: [{ + action: this._newExperimentClicked.bind(this), + icon: AddIcon, + id: 'newExperimentBtn', + outlined: true, + title: 'Create experiment', + tooltip: 'Create a new experiment', + }, { + action: this._compareRuns.bind(this), + disabled: true, + disabledTitle: 'Select multiple runs to compare', + id: 'compareBtn', + title: 'Compare runs', + tooltip: 'Compare up to 10 selected runs', + }, { + action: this._cloneRun.bind(this), + disabled: true, + disabledTitle: 'Select a run to clone', + id: 'cloneBtn', + title: 'Clone run', + tooltip: 'Create a copy from this run\s initial state', + }, { + action: this.refresh.bind(this), + id: 'refreshBtn', + title: 'Refresh', + tooltip: 'Refresh the list of runs', + }], + breadcrumbs: [{ displayName: 'Experiments', href: '' }], }; } @@ -84,6 +88,10 @@ class AllRunsList extends Page<{}, AllRunsListState> { } } + private _newExperimentClicked() { + this.props.history.push(RoutePage.NEW_EXPERIMENT); + } + private _compareRuns() { const indices = this.state.selectedIds; if (indices.length > 1 && indices.length <= 10) { @@ -98,9 +106,9 @@ class AllRunsList extends Page<{}, AllRunsListState> { private _selectionChanged(selectedIds: string[]) { const toolbarActions = [...this.props.toolbarProps.actions]; // Compare runs button - toolbarActions[0].disabled = selectedIds.length <= 1 || selectedIds.length > 10; + toolbarActions[1].disabled = selectedIds.length <= 1 || selectedIds.length > 10; // Clone run button - toolbarActions[1].disabled = selectedIds.length !== 1; + toolbarActions[2].disabled = selectedIds.length !== 1; this.props.updateToolbar({ breadcrumbs: this.props.toolbarProps.breadcrumbs, actions: toolbarActions }); this.setState({ selectedIds }); } diff --git a/frontend/src/pages/ExperimentList.tsx b/frontend/src/pages/ExperimentList.tsx index 58ecb9cf8fd..94824aaf332 100644 --- a/frontend/src/pages/ExperimentList.tsx +++ b/frontend/src/pages/ExperimentList.tsx @@ -87,7 +87,7 @@ class ExperimentList extends Page<{}, ExperimentListState> { title: 'Refresh', tooltip: 'Refresh the list of experiments', }], - breadcrumbs: [{ displayName: 'Experiments', href: RoutePage.EXPERIMENTS }], + breadcrumbs: [{ displayName: 'Experiments', href: '' }], }; } diff --git a/frontend/src/pages/__snapshots__/AllRunsList.test.tsx.snap b/frontend/src/pages/__snapshots__/AllRunsList.test.tsx.snap index ef8d03970eb..0f8ff0ce198 100644 --- a/frontend/src/pages/__snapshots__/AllRunsList.test.tsx.snap +++ b/frontend/src/pages/__snapshots__/AllRunsList.test.tsx.snap @@ -25,6 +25,14 @@ exports[`AllRunsList disables clone button and enables compare button when multi Array [ Object { "actions": Array [ + Object { + "action": [Function], + "icon": [Function], + "id": "newExperimentBtn", + "outlined": true, + "title": "Create experiment", + "tooltip": "Create a new experiment", + }, Object { "action": [Function], "disabled": false, @@ -45,12 +53,12 @@ exports[`AllRunsList disables clone button and enables compare button when multi "action": [Function], "id": "refreshBtn", "title": "Refresh", - "tooltip": "Refresh", + "tooltip": "Refresh the list of runs", }, ], "breadcrumbs": Array [ Object { - "displayName": "All runs", + "displayName": "Experiments", "href": "", }, ], @@ -59,6 +67,14 @@ exports[`AllRunsList disables clone button and enables compare button when multi Array [ Object { "actions": Array [ + Object { + "action": [Function], + "icon": [Function], + "id": "newExperimentBtn", + "outlined": true, + "title": "Create experiment", + "tooltip": "Create a new experiment", + }, Object { "action": [Function], "disabled": true, @@ -79,12 +95,12 @@ exports[`AllRunsList disables clone button and enables compare button when multi "action": [Function], "id": "refreshBtn", "title": "Refresh", - "tooltip": "Refresh", + "tooltip": "Refresh the list of runs", }, ], "breadcrumbs": Array [ Object { - "displayName": "All runs", + "displayName": "Experiments", "href": "", }, ], @@ -122,6 +138,14 @@ exports[`AllRunsList enables clone button when one run is selected 1`] = ` Array [ Object { "actions": Array [ + Object { + "action": [Function], + "icon": [Function], + "id": "newExperimentBtn", + "outlined": true, + "title": "Create experiment", + "tooltip": "Create a new experiment", + }, Object { "action": [Function], "disabled": true, @@ -142,12 +166,12 @@ exports[`AllRunsList enables clone button when one run is selected 1`] = ` "action": [Function], "id": "refreshBtn", "title": "Refresh", - "tooltip": "Refresh", + "tooltip": "Refresh the list of runs", }, ], "breadcrumbs": Array [ Object { - "displayName": "All runs", + "displayName": "Experiments", "href": "", }, ], @@ -156,6 +180,14 @@ exports[`AllRunsList enables clone button when one run is selected 1`] = ` Array [ Object { "actions": Array [ + Object { + "action": [Function], + "icon": [Function], + "id": "newExperimentBtn", + "outlined": true, + "title": "Create experiment", + "tooltip": "Create a new experiment", + }, Object { "action": [Function], "disabled": true, @@ -176,12 +208,12 @@ exports[`AllRunsList enables clone button when one run is selected 1`] = ` "action": [Function], "id": "refreshBtn", "title": "Refresh", - "tooltip": "Refresh", + "tooltip": "Refresh the list of runs", }, ], "breadcrumbs": Array [ Object { - "displayName": "All runs", + "displayName": "Experiments", "href": "", }, ], @@ -212,6 +244,14 @@ exports[`AllRunsList renders all runs 1`] = ` toolbarProps={ Object { "actions": Array [ + Object { + "action": [Function], + "icon": [Function], + "id": "newExperimentBtn", + "outlined": true, + "title": "Create experiment", + "tooltip": "Create a new experiment", + }, Object { "action": [Function], "disabled": true, @@ -232,12 +272,12 @@ exports[`AllRunsList renders all runs 1`] = ` "action": [Function], "id": "refreshBtn", "title": "Refresh", - "tooltip": "Refresh", + "tooltip": "Refresh the list of runs", }, ], "breadcrumbs": Array [ Object { - "displayName": "All runs", + "displayName": "Experiments", "href": "", }, ],