Skip to content

Commit dd468d6

Browse files
tui: display flow numbers, statuses and attributes (#6561)
* Add the "remove" operation to the task context menu. * Dim no-flow tasks to make remove operations clear to the user. Closes #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.
1 parent a49b4cd commit dd468d6

39 files changed

+436
-179
lines changed

changes.d/6561.feat.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Tui now displays task states and flow numbers in context menus. Tasks in flow=None will be displayed in gray.

cylc/flow/tui/app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class TuiApp:
250250
('header', 'dark gray', BACK),
251251
('header_key', 'dark gray, bold', BACK),
252252
('overlay', 'black', 'light gray'),
253+
('diminished', 'dark gray', BACK),
253254
# cylc logo colours
254255
('R', 'light red, bold', BACK),
255256
('Y', 'yellow, bold', BACK),

cylc/flow/tui/data.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
isHeld
4848
isQueued
4949
isRunahead
50+
flowNums
5051
firstParent {
5152
id
5253
name
@@ -116,6 +117,7 @@
116117
'trigger',
117118
'poll',
118119
'set',
120+
'remove',
119121
],
120122
'job': [
121123
'kill',

cylc/flow/tui/overlay.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
)
6060
from cylc.flow.tui.util import (
6161
ListBoxPlus,
62+
format_flow_nums,
6263
get_task_icon,
6364
get_text_dimensions,
6465
)
@@ -154,7 +155,7 @@ def filter_task_state(app):
154155

155156
checkboxes = [
156157
urwid.CheckBox(
157-
get_task_icon(state)
158+
get_task_icon(state, colour='overlay')
158159
+ [' ' + state],
159160
state=is_on,
160161
on_state_change=partial(_toggle_filter, app, 'tasks', state)
@@ -237,27 +238,35 @@ def help_info(app):
237238
for state in TASK_STATUSES_ORDERED:
238239
items.append(
239240
urwid.Text(
240-
get_task_icon(state)
241+
get_task_icon(state, colour='overlay')
241242
+ [' ', state]
242243
)
243244
)
244245
items.append(urwid.Divider())
245246
items.append(urwid.Text('Special States:'))
246247
items.append(
247248
urwid.Text(
248-
get_task_icon(TASK_STATUS_WAITING, is_held=True)
249+
get_task_icon(TASK_STATUS_WAITING, is_held=True, colour='overlay')
249250
+ [' ', 'held']
250251
)
251252
)
252253
items.append(
253254
urwid.Text(
254-
get_task_icon(TASK_STATUS_WAITING, is_queued=True)
255+
get_task_icon(
256+
TASK_STATUS_WAITING,
257+
is_queued=True,
258+
colour='overlay',
259+
)
255260
+ [' ', 'queued']
256261
)
257262
)
258263
items.append(
259264
urwid.Text(
260-
get_task_icon(TASK_STATUS_WAITING, is_runahead=True)
265+
get_task_icon(
266+
TASK_STATUS_WAITING,
267+
is_runahead=True,
268+
colour='overlay',
269+
)
261270
+ [' ', 'runahead']
262271
)
263272
)
@@ -317,11 +326,36 @@ def _mutate(mutation, _):
317326

318327
# determine the ID to display for the context menu
319328
display_id = _get_display_id(value['id_'])
329+
header = [f'id: {display_id}']
330+
attrs = []
331+
332+
# workflow state info
333+
if value['data'].get('status'):
334+
attrs.append(value['data']['status'])
335+
336+
# task state info
337+
if value['data'].get('state'):
338+
attrs.append(
339+
value['data']['state']
340+
+ (
341+
' (held)' if value['data'].get('isHeld')
342+
else ' (queued)' if value['data'].get('isQueued')
343+
else '(runahead)' if value['data'].get('isRunahead')
344+
else ''
345+
)
346+
)
347+
348+
# task flow info
349+
if value['data'].get('flowNums', '[1]') != '[1]':
350+
attrs.append(f'flows={format_flow_nums(value["data"]["flowNums"])}')
351+
352+
if attrs:
353+
header.append(', '.join(attrs))
320354

321355
widget = urwid.ListBox(
322356
urwid.SimpleFocusListWalker(
323357
[
324-
urwid.Text(f'id: {display_id}'),
358+
urwid.Text('\n'.join(header)),
325359
urwid.Divider(),
326360
urwid.Text('Action'),
327361
urwid.Button(

cylc/flow/tui/util.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import urwid
2727

2828
from cylc.flow import LOG
29+
from cylc.flow.flow_mgr import stringify_flow_nums
2930
from cylc.flow.id import Tokens
3031
from cylc.flow.task_state import (
3132
TASK_STATUS_RUNNING
@@ -36,6 +37,7 @@
3637
TASK_ICONS,
3738
TASK_MODIFIERS
3839
)
40+
from cylc.flow.util import deserialise_set
3941
from cylc.flow.wallclock import get_unix_time_from_time_string
4042

4143

@@ -69,8 +71,9 @@ def get_task_icon(
6971
is_held=False,
7072
is_queued=False,
7173
is_runahead=False,
74+
colour='body',
7275
start_time=None,
73-
mean_time=None
76+
mean_time=None,
7477
):
7578
"""Return a Unicode string to represent a task.
7679
@@ -83,6 +86,9 @@ def get_task_icon(
8386
True if the task is queued.
8487
is_runahead (bool):
8588
True if the task is runahead limited.
89+
colour (str):
90+
Set the icon colour. If not provided, the default foreground text
91+
colour will be used.
8692
start_time (str):
8793
Start date time string.
8894
mean_time (int):
@@ -95,11 +101,11 @@ def get_task_icon(
95101
"""
96102
ret = []
97103
if is_held:
98-
ret.append(TASK_MODIFIERS['held'])
104+
ret.append((colour, TASK_MODIFIERS['held']))
99105
elif is_runahead:
100-
ret.append(TASK_MODIFIERS['runahead'])
106+
ret.append((colour, TASK_MODIFIERS['runahead']))
101107
elif is_queued:
102-
ret.append(TASK_MODIFIERS['queued'])
108+
ret.append((colour, TASK_MODIFIERS['queued']))
103109
if (
104110
status == TASK_STATUS_RUNNING
105111
and start_time
@@ -115,7 +121,7 @@ def get_task_icon(
115121
status = f'{TASK_STATUS_RUNNING}:25'
116122
else:
117123
status = f'{TASK_STATUS_RUNNING}:0'
118-
ret.append(TASK_ICONS[status])
124+
ret.append((colour, TASK_ICONS[status]))
119125
return ret
120126

121127

@@ -517,12 +523,20 @@ def _render_task(node, data):
517523
start_time = first_child.get_value()['data']['startedTime']
518524
mean_time = data['task']['meanElapsedTime']
519525

526+
if data['flowNums'] == '[]':
527+
# grey out no-flow tasks
528+
colour = 'diminished'
529+
else:
530+
# default foreground colour for everything else
531+
colour = 'body'
532+
520533
# the task icon
521534
ret = get_task_icon(
522535
data['state'],
523536
is_held=data['isHeld'],
524537
is_queued=data['isQueued'],
525538
is_runahead=data['isRunahead'],
539+
colour=colour,
526540
start_time=start_time,
527541
mean_time=mean_time
528542
)
@@ -534,7 +548,7 @@ def _render_task(node, data):
534548
ret += [(f'job_{state}', f'{JOB_ICON}'), ' ']
535549

536550
# the task name
537-
ret.append(f'{data["name"]}')
551+
ret.append((colour, f'{data["name"]}'))
538552
return ret
539553

540554

@@ -690,3 +704,16 @@ def keypress(self, size, key):
690704
target = new_target
691705
else:
692706
return super().keypress(size, key)
707+
708+
709+
def format_flow_nums(serialised_flow_nums: str) -> str:
710+
"""Return a user-facing representation of task serialised flow nums.
711+
712+
Examples:
713+
>>> format_flow_nums('[1,2]')
714+
'1,2'
715+
>>> format_flow_nums('[]')
716+
'None'
717+
718+
"""
719+
return stringify_flow_nums(deserialise_set(serialised_flow_nums)) or 'None'

tests/integration/tui/screenshots/test_auto_expansion.later-time.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
<span style="color:#000000;background:#e5e5e5"> </span>
33
<span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">~cylc </span>
44
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#e5e5e5;background:#000000">-</span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5;font-weight:bold">one</span><span style="color:#000000;background:#e5e5e5"> - </span><span style="color:#cdcd00;background:#e5e5e5">paused</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#00cd00;background:#e5e5e5">1■</span><span style="color:#000000;background:#e5e5e5"> </span>
5-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">● 1 </span>
6-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> b </span>
7-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ 2 </span>
8-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ A </span>
9-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ a </span>
10-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> b </span>
5+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#000000;background:#e5e5e5"> 1 </span>
6+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">b</span><span style="color:#000000;background:#e5e5e5"> </span>
7+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○</span><span style="color:#000000;background:#e5e5e5"> 2 </span>
8+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○</span><span style="color:#000000;background:#e5e5e5"> A </span>
9+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">a</span><span style="color:#000000;background:#e5e5e5"> </span>
10+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">b</span><span style="color:#000000;background:#e5e5e5"> </span>
1111
<span style="color:#000000;background:#e5e5e5"> </span>
1212
<span style="color:#000000;background:#e5e5e5"> </span>
1313
<span style="color:#000000;background:#e5e5e5"> </span>

tests/integration/tui/screenshots/test_auto_expansion.on-load.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
<span style="color:#000000;background:#e5e5e5"> </span>
33
<span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">~cylc </span>
44
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#e5e5e5;background:#000000">-</span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5;font-weight:bold">one</span><span style="color:#000000;background:#e5e5e5"> - </span><span style="color:#cdcd00;background:#e5e5e5">paused</span><span style="color:#000000;background:#e5e5e5"> </span>
5-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ 1 </span>
6-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ A </span>
7-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ a </span>
8-
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> b </span>
5+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○</span><span style="color:#000000;background:#e5e5e5"> 1 </span>
6+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○</span><span style="color:#000000;background:#e5e5e5"> A </span>
7+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">a</span><span style="color:#000000;background:#e5e5e5"> </span>
8+
<span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5"></span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">b</span><span style="color:#000000;background:#e5e5e5"> </span>
99
<span style="color:#000000;background:#e5e5e5"> </span>
1010
<span style="color:#000000;background:#e5e5e5"> </span>
1111
<span style="color:#000000;background:#e5e5e5"> </span>

0 commit comments

Comments
 (0)