Skip to content

Commit

Permalink
tui: display flow numbers, statuses and attributes
Browse files Browse the repository at this point in the history
* Add the "remove" operation to the task context menu.
* Dim no-flow tasks to make remove operations clear to the user.
  Closes cylc#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.
  • Loading branch information
oliver-sanders committed Jan 17, 2025
1 parent e05c8c1 commit 4d527a1
Show file tree
Hide file tree
Showing 31 changed files with 252 additions and 179 deletions.
1 change: 1 addition & 0 deletions cylc/flow/tui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 2 additions & 0 deletions cylc/flow/tui/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
isHeld
isQueued
isRunahead
flowNums
firstParent {
id
name
Expand Down Expand Up @@ -116,6 +117,7 @@
'trigger',
'poll',
'set',
'remove',
],
'job': [
'kill',
Expand Down
46 changes: 40 additions & 6 deletions cylc/flow/tui/overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
)
from cylc.flow.tui.util import (
ListBoxPlus,
format_flow_nums,
get_task_icon,
get_text_dimensions,
)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -237,27 +238,35 @@ 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]
)
)
items.append(urwid.Divider())
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']
)
)
Expand Down Expand Up @@ -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(
Expand Down
39 changes: 33 additions & 6 deletions cylc/flow/tui/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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


Expand Down Expand Up @@ -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.
Expand All @@ -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):
Expand All @@ -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
Expand All @@ -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


Expand Down Expand Up @@ -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
)
Expand All @@ -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


Expand Down Expand Up @@ -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'
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<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">~cylc </span>
<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>
<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>
<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><span style="color:#000000;background:#e5e5e5">-</span><span style="color:#000000;background:#e5e5e5"> </span><span style="color:#000000;background:#e5e5e5">̿○ 2 </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><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><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><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>
<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>
<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>
<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><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>
<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>
<span style="color:#000000;background:#e5e5e5"> </span>
<span style="color:#000000;background:#e5e5e5"> </span>
<span style="color:#000000;background:#e5e5e5"> </span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,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">~cylc </span>
<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:#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>
<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><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><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><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>
<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><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>
<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>
<span style="color:#000000;background:#e5e5e5"> </span>
<span style="color:#000000;background:#e5e5e5"> </span>
<span style="color:#000000;background:#e5e5e5"> </span>
Expand Down
Loading

0 comments on commit 4d527a1

Please sign in to comment.