Add ticket and note panes to new TUI
This commit is contained in:
parent
9b51bcbdc3
commit
0bcdde0ffb
5 changed files with 102 additions and 41 deletions
|
|
@ -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]:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue