112 lines
4.0 KiB
Python
112 lines
4.0 KiB
Python
from threading import Thread
|
|
|
|
from asciimatics.exceptions import NextScene
|
|
from asciimatics.widgets import Frame, Layout, Button, Divider, Label
|
|
|
|
from ..operation_strings import descriptions as op_desc
|
|
from ..utils import generic_handle_stream_response
|
|
from .TUIStreamResponseHandler import TUIStreamResponseHandler
|
|
|
|
|
|
class TransactionView(Frame):
|
|
def __init__(self, screen, width, height, model):
|
|
super().__init__(
|
|
screen,
|
|
height,
|
|
width,
|
|
can_scroll=False,
|
|
on_load=self._txnview_on_load,
|
|
title='Running Transaction',
|
|
)
|
|
self._model = model
|
|
# map operation names to label widgets
|
|
self._labels = model.viewdata['Transaction']['labels']
|
|
# this is an ugly hack to get around the fact that _on_load()
|
|
# will be called again when we reset() in enable_next_btn.
|
|
self._loaded = False
|
|
|
|
def _add_buttons(self):
|
|
layout = Layout([100])
|
|
self.add_layout(layout)
|
|
layout.add_widget(Divider())
|
|
|
|
layout = Layout([1, 1])
|
|
self.add_layout(layout)
|
|
self._next_btn = Button('Next', self._next)
|
|
# we don't want to disable the button if the txn completed
|
|
# and the user just resized the window
|
|
if self._model.viewdata['Transaction']['status'] != 'completed':
|
|
self._next_btn.disabled = True
|
|
layout.add_widget(self._next_btn, 1)
|
|
|
|
def _add_blank_line(self):
|
|
self._op_layout.add_widget(Label(''), 0)
|
|
self._op_layout.add_widget(Label(''), 2)
|
|
|
|
def _txnview_on_load(self):
|
|
if self._loaded:
|
|
return
|
|
self._loaded = True
|
|
|
|
d = self._model.viewdata['Transaction']
|
|
first_time = True
|
|
if d['op_layout'] is None:
|
|
self._op_layout = Layout([12, 1, 10])
|
|
self.add_layout(self._op_layout)
|
|
# store the layouts so that we can re-use them when the screen
|
|
# gets resized
|
|
d['op_layout'] = self._op_layout
|
|
for _ in range(2):
|
|
self._add_blank_line()
|
|
for operation in self._model.operations:
|
|
desc = op_desc[operation]
|
|
self._op_layout.add_widget(Label(desc + '...', align='>'), 0)
|
|
desc_label = Label('', align='<')
|
|
self._op_layout.add_widget(desc_label, 2)
|
|
self._labels[operation] = desc_label
|
|
self._add_blank_line()
|
|
# this is the where success/failure messages etc. get placed
|
|
self._msg_layout = Layout([100])
|
|
self.add_layout(self._msg_layout)
|
|
d['msg_layout'] = self._msg_layout
|
|
else:
|
|
# we arrive here when the screen has been resized
|
|
first_time = False
|
|
# restore the layouts which we saved
|
|
self._op_layout = d['op_layout']
|
|
self.add_layout(self._op_layout)
|
|
self._msg_layout = d['msg_layout']
|
|
self.add_layout(self._msg_layout)
|
|
# fill up the rest of the space
|
|
self.add_layout(Layout([100], fill_frame=True))
|
|
|
|
self._add_buttons()
|
|
self.fix()
|
|
# only send the API request the first time we arrive at this
|
|
# scene, not when the screen gets resized
|
|
if first_time:
|
|
Thread(target=self._do_txn).start()
|
|
|
|
def _do_txn(self):
|
|
self._model.viewdata['Transaction']['status'] = 'in progress'
|
|
resp = self._model.deferred_req()
|
|
handler = TUIStreamResponseHandler(
|
|
model=self._model,
|
|
labels=self._labels,
|
|
msg_layout=self._msg_layout,
|
|
txn_view=self,
|
|
)
|
|
generic_handle_stream_response(resp, self._model.operations, handler)
|
|
|
|
def enable_next_btn(self):
|
|
self._next_btn.disabled = False
|
|
# If we don't reset, the button isn't selectable, even though we
|
|
# enabled it
|
|
self.reset()
|
|
# save the fact that the transaction is completed
|
|
self._model.viewdata['Transaction']['status'] = 'completed'
|
|
|
|
def _next(self):
|
|
self._model.reset()
|
|
raise NextScene('Welcome')
|