From a775cecf10b2437116ae25687efb016c97fd4cdf Mon Sep 17 00:00:00 2001 From: Oliver Sanders Date: Fri, 17 Jan 2025 13:01:06 +0000 Subject: [PATCH] tui: display flow numbers, statuses and attributes * Add the "remove" operation to the task context menu. * Dim no-flow tasks to make remove operations clear to the user. Closes https://github.com/cylc/cylc-flow/issues/6542 * Show workflow status in the context menu. * Show task status, attributes and task flow numbers (if not {1}) in the task context menu. * Show job status in the context menu. --- cylc/flow/tui/app.py | 1 + cylc/flow/tui/data.py | 2 + cylc/flow/tui/overlay.py | 46 ++++++++-- cylc/flow/tui/util.py | 39 +++++++-- .../test_auto_expansion.later-time.html | 12 +-- .../test_auto_expansion.on-load.html | 8 +- ...navigation.cursor-at-bottom-of-screen.html | 18 ++-- .../test_navigation.family-A-collapsed.html | 18 ++-- .../test_navigation.workflow-expanded.html | 22 ++--- ..._offline_mutation.clean-command-error.html | 8 +- ...line_mutation.clean-mutation-selected.html | 6 +- ..._mutation.command-failed-client-error.html | 10 +-- ...ation.command-failed-workflow-stopped.html | 10 +-- ...nline_mutation.hold-mutation-selected.html | 10 +-- .../test_online_mutation.task-selected.html | 4 +- ..._restart_reconnect.1-workflow-running.html | 4 +- ...estart_reconnect.3-workflow-restarted.html | 4 +- ...est_set_mutation.set-command-selected.html | 14 +-- .../test_set_mutation.task-state-updated.html | 6 +- .../tui/screenshots/test_show.fail.html | 8 +- .../tui/screenshots/test_show.success.html | 4 +- ...test_subscribe_unsubscribe.subscribed.html | 4 +- ..._states.filter-not-waiting-or-expired.html | 24 ++--- .../test_task_states.filter-not-waiting.html | 28 +++--- .../test_task_states.filter-submitted.html | 6 +- ...task_states.filter-waiting-or-expired.html | 22 ++--- .../test_task_states.unfiltered.html | 42 ++++----- tests/integration/tui/test_app.py | 87 +++++++++++++++++++ tests/integration/tui/test_mutations.py | 2 +- tests/integration/tui/test_show.py | 4 +- tests/unit/tui/test_overlay.py | 3 +- tests/unit/tui/test_util.py | 42 +++++---- 32 files changed, 339 insertions(+), 179 deletions(-) diff --git a/cylc/flow/tui/app.py b/cylc/flow/tui/app.py index eb9f8dec09c..63814bcac79 100644 --- a/cylc/flow/tui/app.py +++ b/cylc/flow/tui/app.py @@ -250,6 +250,7 @@ class TuiApp: ('header', 'dark gray', BACK), ('header_key', 'dark gray, bold', BACK), ('overlay', 'black', 'light gray'), + ('diminished', 'dark gray', BACK), # cylc logo colours ('R', 'light red, bold', BACK), ('Y', 'yellow, bold', BACK), diff --git a/cylc/flow/tui/data.py b/cylc/flow/tui/data.py index a6cd60c6bb9..97d5c36982c 100644 --- a/cylc/flow/tui/data.py +++ b/cylc/flow/tui/data.py @@ -47,6 +47,7 @@ isHeld isQueued isRunahead + flowNums firstParent { id name @@ -116,6 +117,7 @@ 'trigger', 'poll', 'set', + 'remove', ], 'job': [ 'kill', diff --git a/cylc/flow/tui/overlay.py b/cylc/flow/tui/overlay.py index b4759e27e78..fc893990478 100644 --- a/cylc/flow/tui/overlay.py +++ b/cylc/flow/tui/overlay.py @@ -59,6 +59,7 @@ ) from cylc.flow.tui.util import ( ListBoxPlus, + format_flow_nums, get_task_icon, get_text_dimensions, ) @@ -154,7 +155,7 @@ def filter_task_state(app): checkboxes = [ urwid.CheckBox( - get_task_icon(state) + get_task_icon(state, colour='overlay') + [' ' + state], state=is_on, on_state_change=partial(_toggle_filter, app, 'tasks', state) @@ -237,7 +238,7 @@ def help_info(app): for state in TASK_STATUSES_ORDERED: items.append( urwid.Text( - get_task_icon(state) + get_task_icon(state, colour='overlay') + [' ', state] ) ) @@ -245,19 +246,27 @@ def help_info(app): items.append(urwid.Text('Special States:')) items.append( urwid.Text( - get_task_icon(TASK_STATUS_WAITING, is_held=True) + get_task_icon(TASK_STATUS_WAITING, is_held=True, colour='overlay') + [' ', 'held'] ) ) items.append( urwid.Text( - get_task_icon(TASK_STATUS_WAITING, is_queued=True) + get_task_icon( + TASK_STATUS_WAITING, + is_queued=True, + colour='overlay', + ) + [' ', 'queued'] ) ) items.append( urwid.Text( - get_task_icon(TASK_STATUS_WAITING, is_runahead=True) + get_task_icon( + TASK_STATUS_WAITING, + is_runahead=True, + colour='overlay', + ) + [' ', 'runahead'] ) ) @@ -317,11 +326,36 @@ def _mutate(mutation, _): # determine the ID to display for the context menu display_id = _get_display_id(value['id_']) + header = [f'id: {display_id}'] + attrs = [] + + # workflow state info + if value['data'].get('status'): + attrs.append(value['data']['status']) + + # task state info + if value['data'].get('state'): + attrs.append( + value['data']['state'] + + ( + ' (held)' if value['data'].get('isHeld') + else ' (queued)' if value['data'].get('isQueued') + else '(runahead)' if value['data'].get('isRunahead') + else '' + ) + ) + + # task flow info + if value['data'].get('flowNums', '[1]') != '[1]': + attrs.append(f'flows={format_flow_nums(value["data"]["flowNums"])}') + + if attrs: + header.append(', '.join(attrs)) widget = urwid.ListBox( urwid.SimpleFocusListWalker( [ - urwid.Text(f'id: {display_id}'), + urwid.Text('\n'.join(header)), urwid.Divider(), urwid.Text('Action'), urwid.Button( diff --git a/cylc/flow/tui/util.py b/cylc/flow/tui/util.py index d0ea2a651c6..7950d9c87ec 100644 --- a/cylc/flow/tui/util.py +++ b/cylc/flow/tui/util.py @@ -26,6 +26,7 @@ import urwid from cylc.flow import LOG +from cylc.flow.flow_mgr import stringify_flow_nums from cylc.flow.id import Tokens from cylc.flow.task_state import ( TASK_STATUS_RUNNING @@ -36,6 +37,7 @@ TASK_ICONS, TASK_MODIFIERS ) +from cylc.flow.util import deserialise_set from cylc.flow.wallclock import get_unix_time_from_time_string @@ -69,8 +71,9 @@ def get_task_icon( is_held=False, is_queued=False, is_runahead=False, + colour='body', start_time=None, - mean_time=None + mean_time=None, ): """Return a Unicode string to represent a task. @@ -83,6 +86,9 @@ def get_task_icon( True if the task is queued. is_runahead (bool): True if the task is runahead limited. + colour (str): + Set the icon colour. If not provided, the default foreground text + colour will be used. start_time (str): Start date time string. mean_time (int): @@ -95,11 +101,11 @@ def get_task_icon( """ ret = [] if is_held: - ret.append(TASK_MODIFIERS['held']) + ret.append((colour, TASK_MODIFIERS['held'])) elif is_runahead: - ret.append(TASK_MODIFIERS['runahead']) + ret.append((colour, TASK_MODIFIERS['runahead'])) elif is_queued: - ret.append(TASK_MODIFIERS['queued']) + ret.append((colour, TASK_MODIFIERS['queued'])) if ( status == TASK_STATUS_RUNNING and start_time @@ -115,7 +121,7 @@ def get_task_icon( status = f'{TASK_STATUS_RUNNING}:25' else: status = f'{TASK_STATUS_RUNNING}:0' - ret.append(TASK_ICONS[status]) + ret.append((colour, TASK_ICONS[status])) return ret @@ -517,12 +523,20 @@ def _render_task(node, data): start_time = first_child.get_value()['data']['startedTime'] mean_time = data['task']['meanElapsedTime'] + if data['flowNums'] == '[]': + # grey out no-flow tasks + colour = 'diminished' + else: + # default foreground colour for everything else + colour = 'body' + # the task icon ret = get_task_icon( data['state'], is_held=data['isHeld'], is_queued=data['isQueued'], is_runahead=data['isRunahead'], + colour=colour, start_time=start_time, mean_time=mean_time ) @@ -534,7 +548,7 @@ def _render_task(node, data): ret += [(f'job_{state}', f'{JOB_ICON}'), ' '] # the task name - ret.append(f'{data["name"]}') + ret.append((colour, f'{data["name"]}')) return ret @@ -690,3 +704,16 @@ def keypress(self, size, key): target = new_target else: return super().keypress(size, key) + + +def format_flow_nums(serialised_flow_nums: str) -> str: + """Return a user-facing representation of task serialised flow nums. + + Examples: + >>> format_flow_nums('[1,2]') + '1,2' + >>> format_flow_nums('[]') + 'None' + + """ + return stringify_flow_nums(deserialise_set(serialised_flow_nums)) or 'None' diff --git a/tests/integration/tui/screenshots/test_auto_expansion.later-time.html b/tests/integration/tui/screenshots/test_auto_expansion.later-time.html index 6e6490ebc05..b774fae1541 100644 --- a/tests/integration/tui/screenshots/test_auto_expansion.later-time.html +++ b/tests/integration/tui/screenshots/test_auto_expansion.later-time.html @@ -2,12 +2,12 @@ - ~cylc - one - paused 1■ - - ● 1 - ● b - - ̿○ 2 - - ̿○ A - ̿○ a - ○ b + - 1 + b + - ̿○ 2 + - ̿○ A + ̿○ a + b diff --git a/tests/integration/tui/screenshots/test_auto_expansion.on-load.html b/tests/integration/tui/screenshots/test_auto_expansion.on-load.html index d8f3ca712b8..4b251ff117e 100644 --- a/tests/integration/tui/screenshots/test_auto_expansion.on-load.html +++ b/tests/integration/tui/screenshots/test_auto_expansion.on-load.html @@ -2,10 +2,10 @@ - ~cylc - one - paused - - ̿○ 1 - - ̿○ A - ̿○ a - ○ b + - ̿○ 1 + - ̿○ A + ̿○ a + b diff --git a/tests/integration/tui/screenshots/test_navigation.cursor-at-bottom-of-screen.html b/tests/integration/tui/screenshots/test_navigation.cursor-at-bottom-of-screen.html index c25e28ebd11..a0f6aa7a3e4 100644 --- a/tests/integration/tui/screenshots/test_navigation.cursor-at-bottom-of-screen.html +++ b/tests/integration/tui/screenshots/test_navigation.cursor-at-bottom-of-screen.html @@ -2,15 +2,15 @@ - ~cylc - one - paused - - ̿○ 1 - + ̿○ A - - ̿○ B - - ̿○ B1 - ̿○ b11 - ̿○ b12 - - ̿○ B2 - ̿○ b21 - ̿○ b22 + - ̿○ 1 + + ̿○ A + - ̿○ B + - ̿○ B1 + ̿○ b11 + ̿○ b12 + - ̿○ B2 + ̿○ b21 + ̿○ b22 diff --git a/tests/integration/tui/screenshots/test_navigation.family-A-collapsed.html b/tests/integration/tui/screenshots/test_navigation.family-A-collapsed.html index 4c988d41792..0fa35b40141 100644 --- a/tests/integration/tui/screenshots/test_navigation.family-A-collapsed.html +++ b/tests/integration/tui/screenshots/test_navigation.family-A-collapsed.html @@ -2,15 +2,15 @@ - ~cylc - one - paused - - ̿○ 1 - + ̿○ A - - ̿○ B - - ̿○ B1 - ̿○ b11 - ̿○ b12 - - ̿○ B2 - ̿○ b21 - ̿○ b22 + - ̿○ 1 + + ̿○ A + - ̿○ B + - ̿○ B1 + ̿○ b11 + ̿○ b12 + - ̿○ B2 + ̿○ b21 + ̿○ b22 diff --git a/tests/integration/tui/screenshots/test_navigation.workflow-expanded.html b/tests/integration/tui/screenshots/test_navigation.workflow-expanded.html index e91225fef23..427d67b21be 100644 --- a/tests/integration/tui/screenshots/test_navigation.workflow-expanded.html +++ b/tests/integration/tui/screenshots/test_navigation.workflow-expanded.html @@ -2,17 +2,17 @@ - ~cylc - one - paused - - ̿○ 1 - - ̿○ A - ̿○ a1 - ̿○ a2 - - ̿○ B - - ̿○ B1 - ̿○ b11 - ̿○ b12 - - ̿○ B2 - ̿○ b21 - ̿○ b22 + - ̿○ 1 + - ̿○ A + ̿○ a1 + ̿○ a2 + - ̿○ B + - ̿○ B1 + ̿○ b11 + ̿○ b12 + - ̿○ B2 + ̿○ b21 + ̿○ b22 diff --git a/tests/integration/tui/screenshots/test_offline_mutation.clean-command-error.html b/tests/integration/tui/screenshots/test_offline_mutation.clean-command-error.html index 88defab9486..1592ee2e0f6 100644 --- a/tests/integration/tui/screenshots/test_offline_mutation.clean-command-error.html +++ b/tests/integration/tui/screenshots/test_offline_mutation.clean-command-error.html @@ -1,15 +1,15 @@
Cylc Tui   work────────────────────────────────────────────────────          
                  id  Error                                                   
-- ~cylc                                                                      
-   + one - stop  Ac  Error in command cylc clean --yes one                   
-                 <   mock-stderr                                             
+- ~cylc          st                                                          
+   + one - stop      Error in command cylc clean --yes one                   
+                 Ac  mock-stderr                                             
+                 <                                                           
                                                                              
                  <                                                           
                  <                                                           
                  <                                                           
                  <                                                           
                                                                              
-                                                                             
                                                                              
 quit: q  help:  q t q to close                                     ome End   
 filter tasks: T────────────────────────────────────────────────────          
diff --git a/tests/integration/tui/screenshots/test_offline_mutation.clean-mutation-selected.html b/tests/integration/tui/screenshots/test_offline_mutation.clean-mutation-selected.html
index 5590254a28d..982759fd480 100644
--- a/tests/integration/tui/screenshots/test_offline_mutation.clean-mutation-selected.html
+++ b/tests/integration/tui/screenshots/test_offline_mutation.clean-mutation-selected.html
@@ -1,7 +1,8 @@
 
Cylc Tui   work────────────────────────────────────────────────               
                  id: ~cylc/one                                                
-- ~cylc                                                                       
-   + one - stop  Action                                                       
+- ~cylc          stopped                                                      
+   + one - stop                                                               
+                 Action                                                       
                  < (cancel)                                 >                 
                                                                               
                  < clean                                    >                 
@@ -9,7 +10,6 @@
                  < play                                     >                 
                  < reinstall-reload                         >                 
                                                                               
-                                                                              
                                                                               
 quit: q  help:  q to close                                     ↥ ↧ Home End   
 filter tasks: T────────────────────────────────────────────────               
diff --git a/tests/integration/tui/screenshots/test_online_mutation.command-failed-client-error.html b/tests/integration/tui/screenshots/test_online_mutation.command-failed-client-error.html
index 895856c6ea2..106c447e62f 100644
--- a/tests/integration/tui/screenshots/test_online_mutation.command-failed-client-error.html
+++ b/tests/integration/tui/screenshots/test_online_mutation.command-failed-client-error.html
@@ -1,10 +1,10 @@
 
Cylc Tui   work────────────────────────────────────────────────────          
                  id  Error                                                   
-- ~cylc                                                                      
-   - one - paus  Ac  Error connecting to workflow: mock error                
-      - ̿○ 1      <                                                           
-           ̿○ on                                                              
-                 <                                                           
+- ~cylc          wa                                                          
+   - one - paus      Error connecting to workflow: mock error                
+      - ̿○ 1      Ac                                                          
+           ̿○ on  <                                                           
+                                                                             
                  <                                                           
                  <                                                           
                  <                                                           
diff --git a/tests/integration/tui/screenshots/test_online_mutation.command-failed-workflow-stopped.html b/tests/integration/tui/screenshots/test_online_mutation.command-failed-workflow-stopped.html
index 6f9954926ef..6d9a1f40eab 100644
--- a/tests/integration/tui/screenshots/test_online_mutation.command-failed-workflow-stopped.html
+++ b/tests/integration/tui/screenshots/test_online_mutation.command-failed-workflow-stopped.html
@@ -1,10 +1,10 @@
 
Cylc Tui   work────────────────────────────────────────────────────          
                  id  Error                                                   
-- ~cylc                                                                      
-   - one - paus  Ac  Cannot peform command hold on a stopped                 
-      - ̿○ 1      <   workflow                                                
-           ̿○ on                                                              
-                 <                                                           
+- ~cylc          wa                                                          
+   - one - paus      Cannot peform command hold on a stopped                 
+      - ̿○ 1      Ac  workflow                                                
+           ̿○ on  <                                                           
+                                                                             
                  <                                                           
                  <                                                           
                  <                                                           
diff --git a/tests/integration/tui/screenshots/test_online_mutation.hold-mutation-selected.html b/tests/integration/tui/screenshots/test_online_mutation.hold-mutation-selected.html
index 8bfe41ea904..f1624ddc0ca 100644
--- a/tests/integration/tui/screenshots/test_online_mutation.hold-mutation-selected.html
+++ b/tests/integration/tui/screenshots/test_online_mutation.hold-mutation-selected.html
@@ -1,15 +1,15 @@
 
Cylc Tui   work────────────────────────────────────────────────               
                  id: 1/one                                                    
-- ~cylc                                                                       
-   - one - paus  Action                                                       
-      - ̿○ 1      < (cancel)                                 >                 
-           ̿○ on                                                               
+- ~cylc          waiting (queued)                                             
+   - one - paus                                                               
+      - ̿○ 1      Action                                                       
+           ̿○ on  < (cancel)                                 >                 
+                                                                              
                  < hold                                     >                 
                  < kill                                     >                 
                  < log                                      >                 
                  < poll                                     >                 
                  < release                                  >                 
-                 < set                                      >                 
                                                                               
 quit: q  help:  q to close                                     ↥ ↧ Home End   
 filter tasks: T────────────────────────────────────────────────               
diff --git a/tests/integration/tui/screenshots/test_online_mutation.task-selected.html b/tests/integration/tui/screenshots/test_online_mutation.task-selected.html
index df7a917ff60..4c06cd4eca3 100644
--- a/tests/integration/tui/screenshots/test_online_mutation.task-selected.html
+++ b/tests/integration/tui/screenshots/test_online_mutation.task-selected.html
@@ -2,8 +2,8 @@
                                                                                 
 - ~cylc                                                                         
    - one - paused                                                               
-      - ̿○ 1                                                                     
-           ̿○ one                                                                
+      - ̿○ 1                                                                     
+           ̿○ one                                                                
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_restart_reconnect.1-workflow-running.html b/tests/integration/tui/screenshots/test_restart_reconnect.1-workflow-running.html
index aabddcc9cf6..56cc2d76af3 100644
--- a/tests/integration/tui/screenshots/test_restart_reconnect.1-workflow-running.html
+++ b/tests/integration/tui/screenshots/test_restart_reconnect.1-workflow-running.html
@@ -2,8 +2,8 @@
                                                                                 
 - ~cylc                                                                         
    - one - paused                                                               
-      - ̿○ 1                                                                     
-           ̿○ one                                                                
+      - ̿○ 1                                                                     
+           ̿○ one                                                                
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_restart_reconnect.3-workflow-restarted.html b/tests/integration/tui/screenshots/test_restart_reconnect.3-workflow-restarted.html
index aabddcc9cf6..56cc2d76af3 100644
--- a/tests/integration/tui/screenshots/test_restart_reconnect.3-workflow-restarted.html
+++ b/tests/integration/tui/screenshots/test_restart_reconnect.3-workflow-restarted.html
@@ -2,8 +2,8 @@
                                                                                 
 - ~cylc                                                                         
    - one - paused                                                               
-      - ̿○ 1                                                                     
-           ̿○ one                                                                
+      - ̿○ 1                                                                     
+           ̿○ one                                                                
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_set_mutation.set-command-selected.html b/tests/integration/tui/screenshots/test_set_mutation.set-command-selected.html
index 8f27deac20e..5b1eb3492c5 100644
--- a/tests/integration/tui/screenshots/test_set_mutation.set-command-selected.html
+++ b/tests/integration/tui/screenshots/test_set_mutation.set-command-selected.html
@@ -1,14 +1,14 @@
 
Cylc Tui   work────────────────────────────────────────────────               
-                 id: 1/a                                                      
-- ~cylc                                                                       
-   - one - paus  Action                                                       
-      - ̿○ 1      < (cancel)                                 >                 
-           ̿○ a                                                                
-           ○ z   < hold                                     >                 
-                 < kill                                     >                 
+                                                                              
+- ~cylc          Action                                                       
+   - one - paus  < (cancel)                                 >                 
+      - ̿○ 1                                                                   
+           ̿○ a   < hold                                     >                 
+            z   < kill                                     >                 
                  < log                                      >                 
                  < poll                                     >                 
                  < release                                  >                 
+                 < remove                                   >                 
                  < set                                      >                 
                                                                               
 quit: q  help:  q to close                                     ↥ ↧ Home End   
diff --git a/tests/integration/tui/screenshots/test_set_mutation.task-state-updated.html b/tests/integration/tui/screenshots/test_set_mutation.task-state-updated.html
index b99e16cf6ea..818e423fecf 100644
--- a/tests/integration/tui/screenshots/test_set_mutation.task-state-updated.html
+++ b/tests/integration/tui/screenshots/test_set_mutation.task-state-updated.html
@@ -2,9 +2,9 @@
                                                                                 
 - ~cylc                                                                         
    - one - paused 1■                                                            
-      - ̿○ 1                                                                     
-           ● a                                                                  
-           ̿○ z                                                                  
+      - ̿○ 1                                                                     
+            a                                                                  
+           ̿○ z                                                                  
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_show.fail.html b/tests/integration/tui/screenshots/test_show.fail.html
index 66a4836bc01..35efaf63f78 100644
--- a/tests/integration/tui/screenshots/test_show.fail.html
+++ b/tests/integration/tui/screenshots/test_show.fail.html
@@ -2,14 +2,15 @@
                       Error                                                   
 - ~cylc                                                                       
    - one - paused     :(                                                      
-      - ̿○ 1                                                                   
-           ̿○ foo                                                              
+      - ̿○ 1                                                                   
+           ̿○ foo                                                              
                                                                               
                                                                               
                                                                               
                                                                               
                ────                                                          
                  id                                                          
+                 wa                                                          
                                                                              
                  Ac                                                          
                  <                                                           
@@ -22,8 +23,7 @@
                  <                                                           
                  <                                                           
                  <                                                           
-                                                                             
-                                                                             
+                 <                                                           
                                                                              
                                                                              
                 q t                                                          
diff --git a/tests/integration/tui/screenshots/test_show.success.html b/tests/integration/tui/screenshots/test_show.success.html
index 7f1caebe49d..c0aaf20a9e7 100644
--- a/tests/integration/tui/screenshots/test_show.success.html
+++ b/tests/integration/tui/screenshots/test_show.success.html
@@ -2,8 +2,8 @@
                                                                                 
 - ~cylc                                                                         
    - one - paused                                                               
-      - ̿○ 1                                                                     
-           ̿○ foo                                                                
+      - ̿○ 1                                                                     
+           ̿○ foo                                                                
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_subscribe_unsubscribe.subscribed.html b/tests/integration/tui/screenshots/test_subscribe_unsubscribe.subscribed.html
index 7d190cb6f4d..0de8198a3b9 100644
--- a/tests/integration/tui/screenshots/test_subscribe_unsubscribe.subscribed.html
+++ b/tests/integration/tui/screenshots/test_subscribe_unsubscribe.subscribed.html
@@ -2,8 +2,8 @@
                                                                                 
 - ~cylc                                                                         
    - one - paused                                                               
-      - ̿○ 1                                                                     
-           ̿○ one                                                                
+      - ̿○ 1                                                                     
+           ̿○ one                                                                
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_task_states.filter-not-waiting-or-expired.html b/tests/integration/tui/screenshots/test_task_states.filter-not-waiting-or-expired.html
index 8cc7056da94..a843a299268 100644
--- a/tests/integration/tui/screenshots/test_task_states.filter-not-waiting-or-expired.html
+++ b/tests/integration/tui/screenshots/test_task_states.filter-not-waiting-or-expired.html
@@ -3,18 +3,18 @@
                                                                                 
 - ~cylc                                                                         
    - test_task_states - paused 1■ 1■ 1■ 1■ 1■                                   
-      - ̿⊗ 1                                                                     
-         - ̿● X                                                                  
-              ̿● a                                                               
-         - ̿⊗ Y                                                                  
-              ̿⊗ b                                                               
-      - ̎⊘ 2                                                                     
-         - ̿⊙ X                                                                  
-              ̿⊙ a                                                               
-         - ̎⊘ Y                                                                  
-            - ̎⊘ Y1                                                              
-                 ̎⊘ c                                                            
-              ̎⊙ b                                                               
+      - ̿⊗ 1                                                                     
+         - ̿● X                                                                  
+              ̿● a                                                               
+         - ̿⊗ Y                                                                  
+              ̿⊗ b                                                               
+      - ̎⊘ 2                                                                     
+         - ̿⊙ X                                                                  
+              ̿⊙ a                                                               
+         - ̎⊘ Y                                                                  
+            - ̎⊘ Y1                                                              
+                 ̎⊘ c                                                            
+              ̎⊙ b                                                               
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_task_states.filter-not-waiting.html b/tests/integration/tui/screenshots/test_task_states.filter-not-waiting.html
index f2ba4116623..39bfe584e69 100644
--- a/tests/integration/tui/screenshots/test_task_states.filter-not-waiting.html
+++ b/tests/integration/tui/screenshots/test_task_states.filter-not-waiting.html
@@ -3,20 +3,20 @@
                                                                                 
 - ~cylc                                                                         
    - test_task_states - paused 1■ 1■ 1■ 1■ 1■                                   
-      - ̿⊗ 1                                                                     
-         - ̿● X                                                                  
-              ̿● a                                                               
-         - ̿⊗ Y                                                                  
-            - ◌ Y1                                                              
-                 ◌ c                                                            
-              ̿⊗ b                                                               
-      - ̎⊘ 2                                                                     
-         - ̿⊙ X                                                                  
-              ̿⊙ a                                                               
-         - ̎⊘ Y                                                                  
-            - ̎⊘ Y1                                                              
-                 ̎⊘ c                                                            
-              ̎⊙ b                                                               
+      - ̿⊗ 1                                                                     
+         - ̿● X                                                                  
+              ̿● a                                                               
+         - ̿⊗ Y                                                                  
+            -  Y1                                                              
+                  c                                                            
+              ̿⊗ b                                                               
+      - ̎⊘ 2                                                                     
+         - ̿⊙ X                                                                  
+              ̿⊙ a                                                               
+         - ̎⊘ Y                                                                  
+            - ̎⊘ Y1                                                              
+                 ̎⊘ c                                                            
+              ̎⊙ b                                                               
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_task_states.filter-submitted.html b/tests/integration/tui/screenshots/test_task_states.filter-submitted.html
index 2cf989253d4..167154ef701 100644
--- a/tests/integration/tui/screenshots/test_task_states.filter-submitted.html
+++ b/tests/integration/tui/screenshots/test_task_states.filter-submitted.html
@@ -3,9 +3,9 @@
                                                                                 
 - ~cylc                                                                         
    - test_task_states - paused 1■ 1■ 1■ 1■ 1■                                   
-      - ̎⊘ 2                                                                     
-         - ̿⊙ X                                                                  
-              ̿⊙ a                                                               
+      - ̎⊘ 2                                                                     
+         - ̿⊙ X                                                                  
+              ̿⊙ a                                                               
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_task_states.filter-waiting-or-expired.html b/tests/integration/tui/screenshots/test_task_states.filter-waiting-or-expired.html
index e97bf21bcd2..991f5dcbbb3 100644
--- a/tests/integration/tui/screenshots/test_task_states.filter-waiting-or-expired.html
+++ b/tests/integration/tui/screenshots/test_task_states.filter-waiting-or-expired.html
@@ -3,17 +3,17 @@
                                                                                 
 - ~cylc                                                                         
    - test_task_states - paused 1■ 1■ 1■ 1■ 1■                                   
-      - ̿⊗ 1                                                                     
-         - ̿⊗ Y                                                                  
-            - ◌ Y1                                                              
-                 ◌ c                                                            
-      - ̊○ 3                                                                     
-         - ̊○ X                                                                  
-              ̊○ a                                                               
-         - ̊○ Y                                                                  
-            - ̊○ Y1                                                              
-                 ̊○ c                                                            
-              ̊○ b                                                               
+      - ̿⊗ 1                                                                     
+         - ̿⊗ Y                                                                  
+            -  Y1                                                              
+                  c                                                            
+      - ̊○ 3                                                                     
+         - ̊○ X                                                                  
+              ̊○ a                                                               
+         - ̊○ Y                                                                  
+            - ̊○ Y1                                                              
+                 ̊○ c                                                            
+              ̊○ b                                                               
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/screenshots/test_task_states.unfiltered.html b/tests/integration/tui/screenshots/test_task_states.unfiltered.html
index 5b6312dddc7..8dd4f63b86b 100644
--- a/tests/integration/tui/screenshots/test_task_states.unfiltered.html
+++ b/tests/integration/tui/screenshots/test_task_states.unfiltered.html
@@ -2,27 +2,27 @@
                                                                                 
 - ~cylc                                                                         
    - test_task_states - paused 1■ 1■ 1■ 1■ 1■                                   
-      - ̿⊗ 1                                                                     
-         - ̿● X                                                                  
-              ̿● a                                                               
-         - ̿⊗ Y                                                                  
-            - ◌ Y1                                                              
-                 ◌ c                                                            
-              ̿⊗ b                                                               
-      - ̎⊘ 2                                                                     
-         - ̿⊙ X                                                                  
-              ̿⊙ a                                                               
-         - ̎⊘ Y                                                                  
-            - ̎⊘ Y1                                                              
-                 ̎⊘ c                                                            
-              ̎⊙ b                                                               
-      - ̊○ 3                                                                     
-         - ̊○ X                                                                  
-              ̊○ a                                                               
-         - ̊○ Y                                                                  
-            - ̊○ Y1                                                              
-                 ̊○ c                                                            
-              ̊○ b                                                               
+      - ̿⊗ 1                                                                     
+         - ̿● X                                                                  
+              ̿● a                                                               
+         - ̿⊗ Y                                                                  
+            -  Y1                                                              
+                  c                                                            
+              ̿⊗ b                                                               
+      - ̎⊘ 2                                                                     
+         - ̿⊙ X                                                                  
+              ̿⊙ a                                                               
+         - ̎⊘ Y                                                                  
+            - ̎⊘ Y1                                                              
+                 ̎⊘ c                                                            
+              ̎⊙ b                                                               
+      - ̊○ 3                                                                     
+         - ̊○ X                                                                  
+              ̊○ a                                                               
+         - ̊○ Y                                                                  
+            - ̊○ Y1                                                              
+                 ̊○ c                                                            
+              ̊○ b                                                               
                                                                                 
                                                                                 
                                                                                 
diff --git a/tests/integration/tui/test_app.py b/tests/integration/tui/test_app.py
index bc38ef52fdb..3e909a3370a 100644
--- a/tests/integration/tui/test_app.py
+++ b/tests/integration/tui/test_app.py
@@ -27,6 +27,7 @@
     TASK_STATUS_SUBMITTED,
     TASK_STATUS_SUBMIT_FAILED,
     TASK_STATUS_SUCCEEDED,
+    TASK_STATUS_WAITING,
 )
 from cylc.flow.workflow_status import StopMode
 
@@ -430,3 +431,89 @@ async def test_restart_reconnect(one_conf, flow, scheduler, start, rakiura):
                 '3-workflow-restarted',
                 'the restarted workflow should be expanded',
             )
+
+
+async def test_states(flow, scheduler, start, rakiura):
+    """It should dim no-flow tasks and display state summary in context menus.
+    """
+    id_ = flow(
+        {
+            'scheduling': {
+                'graph': {
+                    'R1': 'a & b & c',
+                },
+            },
+        },
+        name='one',
+    )
+    from cylc.flow.scheduler import Scheduler
+    schd: Scheduler = scheduler(id_)
+
+    async with start(schd):
+        a = schd.pool.get_task(IntegerPoint('1'), 'a')
+        b = schd.pool.get_task(IntegerPoint('1'), 'b')
+        c = schd.pool.get_task(IntegerPoint('1'), 'c')
+        assert a and b and c
+
+        # set task flow numbers
+        assert a.flow_nums == {1}
+        b.flow_nums = {1,2}
+        c.flow_nums = {}
+
+        # set task state
+        a.state_reset(TASK_STATUS_SUCCEEDED, is_held=True)
+        b.state_reset(TASK_STATUS_WAITING, is_queued=True)
+        c.state_reset(TASK_STATUS_WAITING, is_queued=False, is_runahead=True)
+
+        # update data store
+        for task in (a, b, c):
+            schd.data_store_mgr.delta_task_state(task)
+            schd.data_store_mgr.delta_task_flow_nums(task)
+        await schd.update_data_structure()
+
+        with rakiura(schd.tokens.id, size='80,15') as rk:
+            rk.compare_screenshot(
+                'on-load',
+                'the workflow should be expanded,'
+                ' no-flow task 1/c should be dimmed'
+            )
+
+            # workflow node
+            rk.user_input('down', 'enter')
+            rk.compare_screenshot(
+                'workflow-context--paused',
+                'the workflow should show as paused in the context menu',
+            )
+
+            # cycle: 1
+            rk.user_input('q', 'down', 'enter')
+            rk.compare_screenshot(
+                'cycle-context--waiting',
+                'the cycle should show as waiting in the context menu'
+
+
+            )
+
+            # task:a
+            rk.user_input('q', 'down', 'enter')
+            rk.compare_screenshot(
+                'task-context--succeeded+held',
+                'the task should show as succeeded+held in the context menu,'
+                ' no flow numbers should be displayed',
+            )
+
+            # task:b
+            rk.user_input('q', 'down', 'enter')
+            rk.compare_screenshot(
+                'task-context--waiting+queued',
+                'the task should show as waiting+queued in the context menu,'
+                ' the flow numbers 1,2 should be displayed',
+            )
+
+            # task:c
+            rk.user_input('q', 'down', 'enter')
+            rk.compare_screenshot(
+                'task-context--waiting+runahead',
+                'the task should show as waiting+runahead in the context menu,'
+                ' the task should be marked as flows=None'
+            )
diff --git a/tests/integration/tui/test_mutations.py b/tests/integration/tui/test_mutations.py
index b87622bca5f..4daa93e000e 100644
--- a/tests/integration/tui/test_mutations.py
+++ b/tests/integration/tui/test_mutations.py
@@ -253,7 +253,7 @@ async def test_set_mutation(
             rk.force_update()
 
             # select the "set" mutation
-            rk.user_input(*(('down',) * 6))  # 6th command down
+            rk.user_input(*(('down',) * 7))  # 7th command down
 
             rk.compare_screenshot(
                 # take a screenshot to ensure we have focused on the mutation
diff --git a/tests/integration/tui/test_show.py b/tests/integration/tui/test_show.py
index 063fd4b8781..d4242d93f63 100644
--- a/tests/integration/tui/test_show.py
+++ b/tests/integration/tui/test_show.py
@@ -48,7 +48,7 @@ async def test_show(flow, scheduler, start, rakiura, monkeypatch):
             rk.user_input('down', 'down', 'enter')
 
             # select the "show" context option
-            rk.user_input(*(['down'] * 7), 'enter')
+            rk.user_input(*(['down'] * 8), 'enter')
             rk.compare_screenshot(
                 'success',
                 'the show output should be displayed',
@@ -63,7 +63,7 @@ def cli_cmd_fail(*args, **kwargs):
             )
 
             # select the "show" context option
-            rk.user_input('q', 'enter', *(['down'] * 7), 'enter')
+            rk.user_input('q', 'enter', *(['down'] * 8), 'enter')
             rk.compare_screenshot(
                 'fail',
                 'the error should be displayed',
diff --git a/tests/unit/tui/test_overlay.py b/tests/unit/tui/test_overlay.py
index 013e8480c21..5f5d77e6d4a 100644
--- a/tests/unit/tui/test_overlay.py
+++ b/tests/unit/tui/test_overlay.py
@@ -62,7 +62,8 @@ def test_interface(overlay_functions):
                                         'id_': '~u/a',
                                         'type_': 'workflow',
                                         'data': {
-                                            'status': WorkflowStatus.RUNNING,
+                                            'status':
+                                                WorkflowStatus.RUNNING.value,
                                         },
                                     }
                                 )
diff --git a/tests/unit/tui/test_util.py b/tests/unit/tui/test_util.py
index 2b3231e0f7e..9cdac6d6035 100644
--- a/tests/unit/tui/test_util.py
+++ b/tests/unit/tui/test_util.py
@@ -36,7 +36,7 @@
 )
 
 
-def testrender_node__job_info():
+def test_render_node__job_info():
     """It renders job information nodes."""
     assert render_node(
         None,
@@ -48,7 +48,7 @@ def testrender_node__job_info():
     ]
 
 
-def testrender_node__job():
+def test_render_node__job():
     """It renders job nodes."""
     assert render_node(
         None,
@@ -60,7 +60,7 @@ def testrender_node__job():
     ]
 
 
-def testrender_node__task__succeeded():
+def test_render_node__task__succeeded():
     """It renders tasks."""
     node = Mock()
     node.get_child_node = lambda _: None
@@ -71,17 +71,18 @@ def testrender_node__task__succeeded():
             'state': 'succeeded',
             'isHeld': False,
             'isQueued': False,
-            'isRunahead': False
+            'isRunahead': False,
+            'flowNums': '[1]',
         },
         'task'
     ) == [
-        TASK_ICONS['succeeded'],
+        ('body', TASK_ICONS['succeeded']),
         ' ',
-        'foo'
+        ('body', 'foo'),
     ]
 
 
-def testrender_node__task__running():
+def test_render_node__task__running():
     """It renders running tasks."""
     child = Mock()
     child.get_value = lambda: {'data': {
@@ -98,19 +99,20 @@ def testrender_node__task__running():
             'isHeld': False,
             'isQueued': False,
             'isRunahead': False,
+            'flowNums': '[1]',
             'task': {'meanElapsedTime': 100}
         },
         'task'
     ) == [
-        TASK_ICONS['running'],
+        ('body', TASK_ICONS['running']),
         ' ',
         ('job_running', JOB_ICON),
         ' ',
-        'foo'
+        ('body', 'foo'),
     ]
 
 
-def testrender_node__family():
+def test_render_node__family():
     """It renders families."""
     assert render_node(
         None,
@@ -123,13 +125,13 @@ def testrender_node__family():
         },
         'family'
     ) == [
-        [TASK_ICONS['succeeded']],
+        [('body', TASK_ICONS['succeeded'])],
         ' ',
         'myid'
     ]
 
 
-def testrender_node__cycle_point():
+def test_render_node__cycle_point():
     """It renders cycle points."""
     assert render_node(
         None,
@@ -172,12 +174,18 @@ def test_get_task_icon(
             datetime.utcnow() - timedelta(seconds=start_offset)
         )
     assert (
-        get_task_icon(
-            status, is_held=is_held, is_queued=is_queued,
-            is_runahead=is_runahead, start_time=start_time,
-            mean_time=mean_time
+        (
+            get_task_icon(
+                status,
+                is_held=is_held,
+                is_queued=is_queued,
+                is_runahead=is_runahead,
+                colour='custom',
+                start_time=start_time,
+                mean_time=mean_time,
+            )
         )
-    ) == expected
+    ) == [('custom', char) for char in expected]
 
 
 def test_compute_tree():