-
Notifications
You must be signed in to change notification settings - Fork 27
Workflow Component
The workflow component is used by the Workflow
view. This component uses
Lumino to display other components inside "widgets".
A widget in Cylc UI is simply a Vue component that is displayed within a Lumino widget, and appears as a tab in the workflow view. Users can add many instances of the same widget type. Widgets can be moved around, changing the layout of the workflow view, or removed from the view.
The easiest way to write a widget, is by creating a view (e.g. src/views/MyNewWidgetTemp.vue
with a minimal
structure like:
<template>
<div>
<comp
:workflows="workflowTree"
></comp>
</div>
</template>
<script>
import Comp from '@/components/cylc/comp/Comp.vue'
export default {
name: 'MyNewWidgetTemp',
props: {
workflowName: {
type: String,
required: true
}
},
components: {
Comp
},
metaInfo () {
return {
title: 'Temp View'
}
},
data: () => ({}),
// ...
}
</script>
This view simply loads the component from '@/components/cylc/comp/Comp.vue'
which you have created,
and displays for you in the UI. This is useful for development, but this view must be deleted before
you create a new pull request (unless it is supposed to be kept afterwards, check in the chat-room
with other team members).
In order for the view to be accessed from a URL, you also need to bind the component to a route
(which makes the component into a view). Modify the file src/router/paths.js
to create your view.
If your component needs the workflow data from a GraphQL subscription, you may want to look at the Tree component for the required code to start a subscription and to populate the JS objects.
Once you have your widget displaying the data as expected, the next step is choosing when your widget is created.
Widgets are added in the Workflow.vue
view. This view is bound to a VueRouter route, so it has the lifecycles
of both a Vue Component (e.g. beforeUpdate
), and of a VueRouter route (e.g. beforeRouteEnter
).
By default a Tree
widget is created and added to the view when it is loaded (beforeRouteEnter
of a VueRouter
route). Other widgets are created when the user clicks on a button in the UI.
The buttons where the user clicks to add new widgets are not in the Workflow.vue
view, but in the
cylc/workflow/Toolbar.vue
component. This component is displayed at the top of the Workflow
view, and
has a drop down with the valid widgets to be added to a workflow.
You can now choose whether your new widget is created when the page is loaded, or when the user clicks on a widget type. Check how other widgets are created, and just copy-paste and adjust it for your component.
You have created a new component to display in the widget. Maybe a view to preview the component. And have also chosen when the component is created.
Now you must be ready to add the new widget to Workflow.vue
. Start by importing the component.
import Comp from '@/components/cylc/comp/Comp.vue'
...
components: {
//,
Comp
}
...
Now add a computed variable to hold the list of widgets for this new component type.
computed: {
...
compWidgets () {
return Object
.entries(this.widgets)
.filter(([id, type]) => type === Comp.name)
.map(([id, type]) => id)
}
},
Add a method to add the widget.
methods: {
...
addCompWidget () {
Vue.set(this.widgets, (new Date()).getTime(), Comp.name) // or another unique ID instead of timestamp
}
}
Finally, update the template to add the widgets holding your component.
<template>
...
<lumino
ref="lumino"
v-on:lumino:deleted="onWidgetDeletedEvent"
tab-title-prop="tab-title"
>
<comp
v-for="widgetId of compWidgets"
:key="widgetId"
:id="widgetId"
:workflow-name="workflowName"
:other-props-as-required="String/Object/etc"
tab-title="Super-COMP!"
/>
</lumino>
...
</template>
You are almost done. Remember that now you have to either add the widget from one of the lifecycle methods,
or from a button in the workflow/Toolbar.vue
component. For the latter, you will need to update the component
template to include a new list item and call @click="$listeners['add-comp']"
.
The $listeners
is passed down to the Toolbar.vue
component from the Workflow.vue
view. Go back to the
Workflow.vue
, and look where the toolbar
component is used. You need to add a new entry to the listener
linking your new method with the click event, e.g.:
<toolbar
...
v-on:add-tree="this.addCompWidget"
></toolbar>
The name displayed in the tab is, by default, the Vue component name
. But that can be customized when the
component is used in a template.
For example, the Tree.vue
component name is “Tree”. Here's how we use this component in the Workflow.vue
view template.
<v-skeleton-loader
v-for="widgetId of treeWidgets"
:key="widgetId"
:id="widgetId"
:loading="isLoading"
type="list-item-three-line"
tab-title="tree"
>
<tree-component
:workflows="tree.root.children"
/>
</v-skeleton-loader>
Note that we are already defining a title for the tree component tab, as “tree” (lower cased).