Skip to content

Commit

Permalink
Merge pull request #1318 from cylc/1.6.x-deconflict
Browse files Browse the repository at this point in the history
Use dynamic async components for workspace view tabs + 1.6.x -> master (SimpleTree view)
  • Loading branch information
oliver-sanders authored Jun 12, 2023
2 parents 9f66f97 + 167eba1 commit 8295187
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 115 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = {
objects: 'only-multiline',
imports: 'only-multiline',
exports: 'only-multiline',
functions: 'never',
functions: 'only-multiline',
},
],
'template-curly-spacing': [
Expand Down
75 changes: 21 additions & 54 deletions src/components/cylc/workflow/Lumino.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div ref="main" class="main pa-2 fill-height">
<!-- Lumino box panel gets inserted here -->
</div>
<div v-show="false">
<!-- Hidden div acts as staging area for views before they are
moved into a lumino widget -->
<component
v-for="(item, id) of views"
:key="id"
:ref="(ref) => setViewRef(id, ref)"
:is="item.view"
:tab-title="getTabTitle(item.view)"
:workflow-name="workflowName"
:initialOptions="item.initialOptions"
class="h-100"
/>
</div>
<template
v-for="(item, id) in views"
:key="id"
>
<Teleport :to="`#${id}`">
<component
:is="item.view"
:workflow-name="workflowName"
:initialOptions="item.initialOptions"
class="h-100"
/>
</Teleport>
</template>
</template>

<script>
import { startCase } from 'lodash'
import LuminoWidget from '@/components/cylc/workflow/lumino-widget'
import { BoxPanel, DockPanel, Widget } from '@lumino/widgets'

Expand Down Expand Up @@ -74,27 +74,17 @@ export default {
type: Array,
required: true
},
/**
* Prop to customize the tab title. Defaults to name.
* If a component does not have the $component.$tabTitleProp
* set, then we still revert to the old default $component.name.
*/
tabTitleProp: {
type: String,
default: 'name'
}
},

emits: [
'lumino:activated',
'lumino:deleted'
],

data () {
return {
/** Keep track of views' refs separate from $refs in order to access
* by ID */
viewRefs: {}
beforeCreate () {
// Populate components
for (const { name, component } of this.allViews) {
this.$options.components[name] = component
}
},

Expand All @@ -103,12 +93,6 @@ export default {
* Box panel. In the next tick of Vue, the DOM element and the Vue element/ref are attached.
*/
created () {
// We need to load each view used by this view/component.
// See "local-registration" in Vue.js documentation.
this.allViews.forEach(view => {
this.$options.components[view.name] = view
})

// create a box panel, which holds the dock panel, and controls its layout
this.box = new BoxPanel({ direction: 'left-to-right', spacing: 0 })
// create dock panel, which holds the widgets
Expand Down Expand Up @@ -152,40 +136,27 @@ export default {
},

methods: {
/** Keep track of views' refs separate from $refs, allowing access by ID */
setViewRef (id, ref) {
if (ref) {
this.viewRefs[id] = ref
} else {
delete this.viewRefs[id]
}
},
/**
* Look for newly added views, creating a corresponding Lumino Widget
* for each.
*/
syncWidgets (newVal, oldVal) {
const { tabTitleProp } = this.$props
for (const [id, item] of Object.entries(newVal)) {
if (!(id in oldVal)) {
const view = this.$options.components[item.view]
const name = view[tabTitleProp] ?? view.name
this.addWidget(id, name)
this.addWidget(id, item.view)
}
}
},

/**
* Create a widget, add it to the dock, and move the corresponding view
* from the hidden div into it.
* Create a widget and add it to the dock.
*/
addWidget (id, name, onTop = true) {
const luminoWidget = new LuminoWidget(id, name, /* closable */ true)
const luminoWidget = new LuminoWidget(id, startCase(name), /* closable */ true)
this.dock.addWidget(luminoWidget, { mode: 'tab-after' })
// give time for Lumino's widget DOM element to be created
this.$nextTick(() => {
const widgetEl = document.getElementById(id)
widgetEl.appendChild(this.viewRefs[id].$el)
widgetEl.addEventListener('lumino:activated', this.onWidgetActivated)
widgetEl.addEventListener('lumino:deleted', this.onWidgetDeleted)
if (onTop) {
Expand Down Expand Up @@ -227,10 +198,6 @@ export default {
widgetEl.removeEventListener('lumino:activated', this.onWidgetActivated)
this.$emit('lumino:deleted', customEvent.detail)
},

getTabTitle (viewName) {
return this.$options.components[viewName].data().widget.title
}
}
}
</script>
28 changes: 18 additions & 10 deletions src/components/cylc/workflow/Toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<v-spacer class="mx-0" />

<v-btn
v-if="$route.name === 'workspace'"
class="add-view"
color="primary"
data-cy="add-view-btn"
Expand All @@ -101,20 +102,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<v-menu
activator="parent"
location="bottom"
v-if="$route.name === 'workspace'"
>
<v-list class="pa-0">
>
<v-list>
<v-list-item
:id="`toolbar-add-${ view.name }-view`"
v-for="view in views"
:id="`toolbar-add-${ view.name }-view`"
:key="view.name"
@click="$emit('add', { viewName: view.name })"
class="py-0 px-8 ma-0 c-add-view"
>
<template v-slot:prepend>
<v-icon>{{ view.data().widget.icon }}</v-icon>
<v-icon>{{ view.icon }}</v-icon>
</template>
<v-list-item-title>{{ view.name }}</v-list-item-title>
<v-list-item-title>{{ startCase(view.name) }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
Expand Down Expand Up @@ -148,6 +147,7 @@ import {
mdiStop,
mdiViewList
} from '@mdi/js'
import { startCase } from 'lodash'
import toolbar from '@/mixins/toolbar'
import WorkflowState from '@/model/WorkflowState.model'
import graphql from '@/mixins/graphql'
Expand All @@ -158,20 +158,24 @@ import {

export default {
name: 'Toolbar',

mixins: [
toolbar,
graphql
],

props: {
views: {
type: Array,
required: true
}

},

emits: ['add'],

data: () => ({
extended: false,
// FIXME: remove local state once we have this data in the workflow - https://github.com/cylc/cylc-ui/issues/221
svgPaths: {
add: mdiPlusBoxMultiple,
hold: mdiPause,
Expand All @@ -187,6 +191,7 @@ export default {
stop: null
}
}),

computed: {
...mapState('app', ['title']),
...mapState('user', ['user']),
Expand Down Expand Up @@ -253,6 +258,7 @@ export default {
}
}
},

watch: {
isRunning () {
this.expecting.play = null
Expand All @@ -264,6 +270,7 @@ export default {
this.expecting.stop = null
}
},

methods: {
onClickPlay () {
this.$workflowService.mutate(
Expand All @@ -285,7 +292,7 @@ export default {
}
})
},
async onClickStop () {
onClickStop () {
this.$workflowService.mutate(
'stop',
this.currentWorkflow.id
Expand All @@ -297,7 +304,8 @@ export default {
},
toggleExtended () {
this.extended = !this.extended
}
},
startCase,
}
}
</script>
5 changes: 0 additions & 5 deletions src/views/Analysis.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ import {
platformOptions
} from '@/components/cylc/analysis/filter'
import {
mdiChartLine,
mdiRefresh
} from '@mdi/js'

Expand Down Expand Up @@ -185,10 +184,6 @@ export default {
data () {
const tasks = []
return {
widget: {
title: 'analysis',
icon: mdiChartLine
},
/** Defines controls which get added to the toolbar */
groups: [
{
Expand Down
5 changes: 0 additions & 5 deletions src/views/Graph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ import {
import { Graphviz } from '@hpcc-js/wasm/graphviz'
import svgPanZoom from 'svg-pan-zoom'
import {
mdiGraph,
mdiTimer,
mdiImageFilterCenterFocus,
mdiArrowCollapse,
Expand Down Expand Up @@ -219,10 +218,6 @@ export default {

data () {
return {
widget: {
title: 'graph',
icon: mdiGraph
},
// the graph orientation
orientation: 'TB',
// the auto-refresh timer
Expand Down
6 changes: 0 additions & 6 deletions src/views/Log.vue
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<script>
import {
mdiClockOutline,
mdiFileDocumentMultipleOutline,
mdiFolderRefresh,
mdiPowerPlugOff,
mdiPowerPlug
Expand Down Expand Up @@ -253,11 +252,6 @@ export default {

data () {
return {
// metadata for the workspace view
widget: {
title: 'logs',
icon: mdiFileDocumentMultipleOutline
},
// the log subscription query
query: null,
// list of log files for the selected workflow/task/job
Expand Down
Loading

0 comments on commit 8295187

Please sign in to comment.