Skip to content
Open
Show file tree
Hide file tree
Changes from 17 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
529 changes: 513 additions & 16 deletions src/components/cylc/Toolbar.vue

Large diffs are not rendered by default.

559 changes: 0 additions & 559 deletions src/components/cylc/workspace/Toolbar.vue

This file was deleted.

11 changes: 5 additions & 6 deletions src/layouts/Default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<template>
<div>
<ConnectionStatus :is-offline="offline" />
<Toolbar v-if="showToolbar" />
<Drawer v-if="showSidebar" />
<CommandMenu/>

<v-main>
<Toolbar v-if="showToolbar" />
<alert />
<div
id="core-view"
Expand All @@ -45,7 +45,7 @@ import { Alert as AlertModel } from '@/model/Alert.model'
import Alert from '@/components/core/Alert.vue'
import Drawer from '@/components/cylc/Drawer.vue'
import Toolbar from '@/components/cylc/Toolbar.vue'
import { useNavBtn, toolbarHeight } from '@/utils/toolbar'
import { toolbarHeight } from '@/utils/toolbar'
import ConnectionStatus from '@/components/cylc/ConnectionStatus.vue'
import CommandMenu from '@/components/cylc/commandMenu/Menu.vue'

Expand All @@ -66,15 +66,14 @@ export default {
...allViews.keys(),
'Workspace',
]
const { showNavBtn } = useNavBtn()

/** Whether to show app toolbar (not the workspace view toolbar). */
const showToolbar = computed(
() => showNavBtn.value && !workflowViews.includes(route.name)
() => !workflowViews.includes(route.name)
)
const coreViewStyle = computed(() => ({
marginTop: showToolbar.value ? `${toolbarHeight}px` : 0,
height: showToolbar.value ? `calc(100vh - ${toolbarHeight}px)` : '100vh',
marginTop: '0px',
height: showToolbar.value ? `calc(100vh - ${toolbarHeight}px)` : '100vh'
}))

return {
Expand Down
2 changes: 1 addition & 1 deletion src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ router.beforeEach(async (to, from) => {
document.title = getPageTitle(to)

// Set toolbar title:
let title = to.name
let title = to.meta.title || to.name
if (to.meta.toolbar) {
// When a workflow is being displayed, we set the title to a
// different value.
Expand Down
7 changes: 0 additions & 7 deletions src/views/UserProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<v-container fluid class="c-user-profile">
<v-row class="wrap">
<v-col cols="12">
<v-alert
:icon="$options.icons.settings"
prominent
color="grey-lighten-3"
>
<h3 class="text-h5">{{ $t('UserProfile.title') }}</h3>
</v-alert>
<v-form>
<v-defaults-provider :defaults="$options.vuetifyDefaults">
<v-container py-0>
Expand Down
12 changes: 2 additions & 10 deletions src/views/WorkflowsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<v-container
fill-height
fluid
grid-list-xl
class="pa-0"
>
<v-row class="align-self-start">
<v-row no-gutters>
<v-col>
<!-- TODO: this is not really an alert, it's a heading -->
<v-alert
:icon="icons.mdiTable"
prominent
color="grey-lighten-3"
>
<h3 class="text-h5">{{ $t('Workflows.tableHeader') }}</h3>
</v-alert>
<v-data-table
:headers="$options.headers"
:items="workflowsTable"
Expand Down
2 changes: 1 addition & 1 deletion src/views/Workspace.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import graphqlMixin from '@/mixins/graphql'
import subscriptionMixin from '@/mixins/subscription'
import ViewState from '@/model/ViewState.model'
import Lumino from '@/components/cylc/workspace/Lumino.vue'
import Toolbar from '@/components/cylc/workspace/Toolbar.vue'
import Toolbar from '@/components/cylc/Toolbar.vue'
import { toolbarHeight } from '@/utils/toolbar'

export default {
Expand Down
19 changes: 18 additions & 1 deletion tests/e2e/specs/toolbar.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,29 @@ describe('Toolbar component', () => {
.get('#core-app-bar')
.should('exist')
})
it('Is NOT displayed when looking at the dashboard', () => {
it('Is NOT displayed when using a standalone view', () => {
cy.visit('/#/')
cy
.get('#core-app-bar')
.should('not.exist')
})
Comment on lines 25 to 35
Copy link
Copy Markdown
Member

@MetRonnie MetRonnie May 18, 2026

Choose a reason for hiding this comment

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

Testing it is not displayed when looking at the dashboard... immediately followed by testing it is displayed when looking at the dashboard (below).

(The reason this one is passing is probably the page has not fully loaded by the time this assertion is made - which is a gotcha with Cypress.)

Your new test below can replace both of these two above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we should still keep it for completeness sake.
But I have amended the test to actually test the thing it's supposed to test.
(Also, what is the proper way to get cypress to wait? The linter doesn't likecy.wait())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(Also, what is the proper way to get cypress to wait? The linter doesn't likecy.wait())

Like what you've done, I think the best you can do is check for the existence of a nearby element

it('displays workflow controls for existing workflows and hidden otherwise', () => {
// Start at the dashboard
cy.visit('/#/')
// The toolbar workflow controls are not visible on the dashboard
cy.get('#core-app-bar').should('exist')
cy.get('.c-workflow-controls').should('not.exist')

// Navigate to an existing workflow
cy.visit('/#/workspace/one')
cy.get('#core-app-bar').should('be.visible')
cy.get('.c-workflow-controls').should('be.visible')

// Navigate to a non-existent workflow
cy.visit('/#/workspace/non-exist')
cy.get('#core-app-bar').should('be.visible')
cy.get('.c-workflow-controls').should('not.exist')
})
it('Contains an avatar displaying user icon', () => {
cy.visit('/#/workspace/one')
cy
Expand Down
108 changes: 91 additions & 17 deletions tests/unit/components/cylc/toolbar.vue.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,34 @@
import { mount } from '@vue/test-utils'
import { createVuetify } from 'vuetify'
import { createStore } from 'vuex'
import storeOptions from '@/store/options'
import Toolbar from '@/components/cylc/Toolbar.vue'
import WorkflowState from '@/model/WorkflowState.model'
import storeOptions from '@/store/options'

import CommandMenuPlugin from '@/components/cylc/commandMenu/plugin'
import sinon from 'sinon'
import WorkflowService from '@/services/workflow.service'
import { useDrawer } from '@/utils/toolbar'
import { vuetifyOptions } from '@/plugins/vuetify'
import { mdiViewList, mdiBackburger } from '@mdi/js'

const vuetify = createVuetify(vuetifyOptions)

describe('Toolbar component', () => {
const vuetify = createVuetify({
display: {}
})
const $route = {
name: 'testRoute'
}
let store
let mountFunction
let $workflowService
const { drawer: drawerState } = useDrawer()

beforeEach(() => {
store = createStore(storeOptions)
mountFunction = () => mount(Toolbar, {
global: {
plugins: [vuetify, store],
mocks: { $route }
}
store.commit('user/SET_USER', {
owner: 'rincewind',
permissions: ['play', 'pause', 'resume', 'stop', 'setGraphWindowExtent'],
initials: 'RW',
username: 'rincewind',
})

drawerState.value = false
$workflowService = sinon.createStubInstance(WorkflowService)
store.state.workflows.workflows = [
{
id: 'user/id',
Expand All @@ -50,9 +55,78 @@ describe('Toolbar component', () => {
]
})

it('should mount the component', async () => {
const wrapper = mountFunction()
it('shows backburger icon when drawer is open and list icon when closed', async () => {
const wrapper = mount(Toolbar, {
global: {
plugins: [store, vuetify, CommandMenuPlugin],
mocks: { $workflowService },
provide: { versionInfo: null },
},
props: {
views: new Map(),
workflowName: 'strewth',
},
})
// Drawer closed -> list icon
drawerState.value = false
await wrapper.vm.$nextTick()
const btn = wrapper.find('#toggle-drawer')
expect(btn.find('svg path').attributes('d')).to.equal(mdiViewList)
// Drawer open -> backburger icon
drawerState.value = true
await wrapper.vm.$nextTick()
expect(btn.find('svg path').attributes('d')).to.equal(mdiBackburger)
})

it('toggles drawer on button click', async () => {
const wrapper = mount(Toolbar, {
global: {
plugins: [store, vuetify, CommandMenuPlugin],
mocks: { $workflowService },
provide: { versionInfo: null },
},
props: {
views: new Map(),
workflowName: 'strewth',
},
})
expect(drawerState.value).to.equal(false)
await wrapper.find('#toggle-drawer').trigger('click')
expect(drawerState.value).to.equal(true)
await wrapper.find('#toggle-drawer').trigger('click')
expect(drawerState.value).to.equal(false)
})

it('does not show workflow controls without workflowName', async () => {
const wrapper = mount(Toolbar, {
global: {
plugins: [store, vuetify, CommandMenuPlugin],
mocks: { $workflowService },
provide: { versionInfo: null },
},
props: {
views: new Map(),
},
})
await wrapper.vm.$nextTick()
// Burger button and title should still be present
expect(wrapper.find('#toggle-drawer').exists()).to.equal(true)
expect(wrapper.find('.c-toolbar-title').exists()).to.equal(true)
})
Comment thread
ChrisPaulBennett marked this conversation as resolved.
Outdated

it('displays the title from the store', async () => {
store.commit('app/setTitle', "I'm your pain when you can't feel")
const wrapper = mount(Toolbar, {
global: {
plugins: [store, vuetify, CommandMenuPlugin],
mocks: { $workflowService },
provide: { versionInfo: null },
},
props: {
views: new Map(),
},
})
await wrapper.vm.$nextTick()
expect(wrapper.vm.$el).to.exist
expect(wrapper.find('.c-toolbar-title').text()).to.include("I'm your pain when you can't feel")
})
})
68 changes: 0 additions & 68 deletions tests/unit/components/cylc/workspace/toolbar.vue.spec.js

This file was deleted.