@@ -38,15 +38,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
3838 <div class =" c-gscan-workflow-name flex-grow-1" >
3939 <span >
4040 {{ node.name || node.id }}
41- <v-tooltip
42- location =" top"
43- style =" overflow-wrap : anywhere;"
44- >
41+ <v-tooltip style =" overflow-wrap : anywhere;" >
4542 {{ node.id }}
4643 </v-tooltip >
4744 </span >
4845 </div >
49- <div class =" d-flex c-gscan-workflow-states flex-grow-0" >
46+ <div class =" d-flex c-gscan-workflow-states flex-grow-0 align-center" >
47+ <v-icon
48+ v-for =" modifier in statesInfo.modifiers"
49+ :key =" modifier"
50+ :icon =" modifierIcons[modifier]"
51+ v-tooltip =" `Has ${modifier} tasks.`"
52+ size =" 1em"
53+ class =" modifier-badge"
54+ :class =" modifier"
55+ />
5056 <TaskStateBadge
5157 v-for =" (value, state) in statesInfo.stateTotals"
5258 :key =" state"
@@ -85,6 +91,7 @@ import WarningIcon from '@/components/cylc/WarningIcon.vue'
8591import TaskState from ' @/model/TaskState.model'
8692import { WorkflowState } from ' @/model/WorkflowState.model'
8793import { useWorkflowWarnings } from ' @/composables/localStorage'
94+ import { taskHeld , taskRetry } from ' @/utils/icons'
8895
8996const nodeTypes = [' workflow-part' , ' workflow' ]
9097
@@ -96,32 +103,38 @@ const taskStatesOrdered = [
96103 TaskState .RUNNING .name ,
97104]
98105
106+ const modifierIcons = {
107+ held: taskHeld,
108+ retrying: taskRetry,
109+ }
110+
99111/**
100112 * Get aggregated task state totals for all descendents of a node.
101113 *
102114 * Also get latest state tasks for workflow nodes.
103115 *
104116 * @param {Object} node
105117 * @param {Record<string, number>} stateTotals - Accumulator for state totals.
118+ * @param {Set<string>} modifiers - Accumulator for modifier states.
106119 */
107- function getStatesInfo (node , stateTotals = {}) {
120+ function getStatesInfo (node , stateTotals = {}, modifiers = new Set () ) {
108121 const latestTasks = {}
109122 // if we aren't at the end of the node tree, continue recurse until we hit something other then a workflow part
110123 if (node .type === ' workflow-part' && node .children ) {
111124 // at every branch, recurse all child nodes except stopped workflows
112125 for (const child of node .children ) {
113126 if (child .node .status !== WorkflowState .STOPPED .name ) {
114- getStatesInfo (child, stateTotals, latestTasks )
127+ getStatesInfo (child, stateTotals, modifiers )
115128 }
116129 }
117130 } else if (node .type === ' workflow' && node .node .stateTotals ) {
118131 // if we hit a workflow node, stop and merge state
119132
120133 if (node .node .containsHeld ) {
121- stateTotals . held = true
134+ modifiers . add ( ' held' )
122135 }
123136 if (node .node .containsRetry ) {
124- stateTotals . retry = true
137+ modifiers . add ( ' retrying ' )
125138 }
126139
127140 // the non-zero state totals from this node with all the others from the tree
@@ -143,7 +156,7 @@ function getStatesInfo (node, stateTotals = {}) {
143156 }
144157 }
145158 }
146- return { stateTotals, latestTasks }
159+ return { stateTotals, latestTasks, modifiers }
147160}
148161
149162const workflowWarnings = useWorkflowWarnings ()
0 commit comments