Add ticket and note panes to new TUI

This commit is contained in:
2Shirt 2023-06-17 19:53:05 -07:00
parent 9b51bcbdc3
commit 0bcdde0ffb
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
5 changed files with 102 additions and 41 deletions

View file

@ -1104,8 +1104,10 @@ class State():
# Write to progress file
self.progress_out.write_text('\n'.join(report), encoding='utf-8', errors='ignore')
def update_top_panes(self) -> None:
def update_top_panes(self, note_lines: list | None = None) -> None:
"""(Re)create top source/destination panes."""
if not note_lines:
note_lines = []
source_exists = True
source_str = ''
dest_exists = True
@ -1173,27 +1175,27 @@ class State():
dest_str,
)
# Bail if ticket not selected
if not self.ost:
return
# Ticket Details
# TODO: Fixme
if self.ost and self.ost.ticket_id:
text = ansi.color_string(
[
self.ost.ticket_name,
' ' if self.ost.note else '\n',
f'Ticket #{self.ost.ticket_id}',
f'\n{self.ost.note.splitlines()[0]}' if self.ost.note else '',
],
['CYAN', None, None, 'YELLOW'],
sep='',
self.ui.reset_subtitle_pane()
if self.ost.ticket_id and not self.ui.layout['Subtitle']['Panes']:
self.ui.add_subtitle_pane(
ansi.color_string(
[f'#{self.ost.ticket_id}', str(self.ost.ticket_name)],
[None, 'CYAN'],
),
str(self.ost.ticket_subject),
)
if self.panes.get('Ticket', None):
tmux.respawn_pane(self.panes['Ticket'], text=text)
else:
self.panes['Ticket'] = tmux.split_window(
behind=True,
lines=2,
text=text,
vertical=True,
# Tech note
note_lines = self.ost.note.replace('...', '').splitlines()
if note_lines:
self.ui.add_subtitle_pane(
ansi.color_string('Tech Note', 'YELLOW'),
' | '.join(note_lines),
)
@ -1910,6 +1912,7 @@ def main() -> None:
main_menu.actions[menus.MENU_ACTIONS[2]]['Separator'] = True
else:
main_menu.actions['Add tech note']['Separator'] = True
state.update_top_panes()
try:
state.init_recovery(args)
except (FileNotFoundError, std.GenericAbort):
@ -1937,10 +1940,10 @@ def main() -> None:
# Tech note
if 'tech note' in selection[0]:
state.ost.add_note(
note_lines = state.ost.add_note(
'Please enter any additional information about this recovery',
)
state.update_top_panes()
state.update_top_panes(note_lines=note_lines)
# Start over
if 'Fresh start' in selection[0]:

View file

@ -144,6 +144,7 @@ class State():
# Reset objects
self.disks.clear()
self.test_groups.clear()
self.ui.remove_all_subtitle_panes()
# osTicket
self.ost.init()
@ -859,7 +860,12 @@ def print_countdown(proc, seconds) -> None:
print('')
def run_diags(state, menu, quick_mode=False, test_mode=False) -> None:
def run_diags(
state: State,
menu: cli.Menu,
quick_mode: bool = False,
test_mode: bool = False,
) -> None:
"""Run selected diagnostics."""
aborted = False
atexit.register(state.save_debug_reports)
@ -878,15 +884,24 @@ def run_diags(state, menu, quick_mode=False, test_mode=False) -> None:
# Update top_text
if state.ost.ticket_id:
state.top_text += cli.color_string(
[f' #{state.ost.ticket_id}', state.ost.ticket_name],
[None, 'CYAN'],
)
state.ui.add_subtitle_pane(
cli.color_string(
[f'#{state.ost.ticket_id}', str(state.ost.ticket_name)],
[None, 'CYAN'],
),
str(state.ost.ticket_subject),
)
# Add note
if (state.ost.ticket_id
and menu.toggles['osTicket Tech Note']['Selected']):
state.ost.add_note()
note_lines = state.ost.add_note()
if note_lines:
state.ui.add_subtitle_pane(
cli.color_string('Tech Note', 'YELLOW'),
' | '.join(note_lines),
)
# Run tests
for group in state.test_groups:
@ -927,6 +942,7 @@ def run_diags(state, menu, quick_mode=False, test_mode=False) -> None:
hw_osticket.update_checkboxes(state, NUM_DISK_TESTS)
# Done
state.ui.remove_all_subtitle_panes()
state.save_debug_reports()
atexit.unregister(state.save_debug_reports)
if quick_mode:

View file

@ -38,11 +38,12 @@ class osTicket():
def __init__(self):
self.db_connection = None
self.db_cursor = None
self.disabled = False
self.errors = False
self.note = None
self.ticket_id = None
self.ticket_name = None
self.disabled: bool = False
self.errors: bool = False
self.note: str = ''
self.ticket_id: int | None = None
self.ticket_name: str | None = None
self.ticket_subject: str | None = None
# Ensure connection is closed atexit
atexit.register(self._disconnect)
@ -162,7 +163,7 @@ class osTicket():
LOG.error('Ticket ID not set')
raise RuntimeError('Ticket ID not set')
def add_note(self, prompt=None):
def add_note(self, prompt: str = 'Add note') -> list[str]:
"""Add note to be included in osTicket replies."""
lines = []
if not prompt:
@ -175,18 +176,21 @@ class osTicket():
# Get note
while True:
text = cli.input_text('> ')
text = cli.input_text('> ', allow_empty=True)
if not text:
break
lines.append(text.strip())
# Save note
if lines:
self.note = lines.pop(0)
for line in lines:
self.note = lines[0]
for line in lines[1:]:
self.note += f'\n...{line}'
else:
self.note = None
self.note = ''
# Done
return lines
def init(self):
"""Revert to defaults."""
@ -314,6 +318,7 @@ class osTicket():
if cli.ask('Is this correct?'):
self.ticket_id = _id
self.ticket_name = _name
self.ticket_subject = _subject
# Done
self._disconnect()

View file

@ -67,7 +67,7 @@ def fix_layout(
# Calculate constraints
avail_horizontal, avail_vertical = get_window_size()
avail_vertical -= layout['Current'].get('height', 0)
for group in ('Title', 'Info'):
for group in ('Title', 'Subtitle', 'Info'):
if not layout[group]['Panes']:
continue
avail_vertical -= layout[group].get('height', 0) + 1
@ -95,7 +95,7 @@ def fix_layout(
)
for group, data in layout.items():
num_panes = len(data['Panes'])
if num_panes < 2 or group not in ('Title', 'Info'):
if num_panes < 2 or group not in ('Title', 'Subtitle', 'Info'):
continue
avail_horizontal -= (num_panes - 1)
pane_width, remainder = divmod(avail_horizontal, num_panes)

View file

@ -19,6 +19,7 @@ TMUX_SIDE_WIDTH = 21
TMUX_TITLE_HEIGHT = 2
TMUX_LAYOUT = { # NOTE: This needs to be in order from top to bottom
'Title': {'Panes': [], 'height': TMUX_TITLE_HEIGHT},
'Subtitle': {'Panes': [], 'height': TMUX_TITLE_HEIGHT},
'Info': {'Panes': []},
'Current': {'Panes': [environ.get('TMUX_PANE', None)]},
'Workers': {'Panes': []},
@ -115,6 +116,29 @@ class TUI():
# Add pane
self.layout['Title']['Panes'].append(tmux.split_window(**tmux_args))
def add_subtitle_pane(self, line1: str, line2: str) -> None:
"""Add pane to subtitle row."""
lines = [line1, line2]
tmux_args = {
'behind': True,
'lines': TMUX_TITLE_HEIGHT,
'target_id': None,
'text': '\n'.join(lines),
'vertical': True,
}
if self.layout['Subtitle']['Panes']:
tmux_args.update({
'behind': False,
'percent': 50,
'target_id': self.layout['Subtitle']['Panes'][-1],
'text': '\n'.join(lines),
'vertical': False,
})
tmux_args.pop('lines')
# Add pane
self.layout['Subtitle']['Panes'].append(tmux.split_window(**tmux_args))
def add_worker_pane(
self,
lines: int | None = None,
@ -216,6 +240,12 @@ class TUI():
self.layout['Info']['Panes'].clear()
tmux.kill_pane(*panes)
def remove_all_subtitle_panes(self) -> None:
"""Remove all subtitle panes and update layout."""
panes = self.layout['Subtitle']['Panes'].copy()
self.layout['Subtitle']['Panes'].clear()
tmux.kill_pane(*panes)
def remove_all_worker_panes(self) -> None:
"""Remove all worker panes and update layout."""
self.layout['Workers'].pop('height', None)
@ -237,6 +267,13 @@ class TUI():
self.layout['Title']['Panes'] = panes[:1]
self.set_title(line1, line2, colors)
def reset_subtitle_pane(self) -> None:
"""Remove all extra subtitle panes and update layout."""
panes = self.layout['Subtitle']['Panes'].copy()
if len(panes) > 1:
tmux.kill_pane(*panes[1:])
self.layout['Subtitle']['Panes'] = panes[:1]
def set_current_pane_height(self, height: int) -> None:
"""Set current pane height and update layout."""
self.layout['Current']['height'] = height
@ -318,7 +355,7 @@ def fix_layout(layout, forced: bool = False) -> None:
pass
# Update "group" panes widths
for group in ('Title', 'Info'):
for group in ('Title', 'Subtitle', 'Info'):
num_panes = len(layout[group]['Panes'])
if num_panes <= 1:
continue