This PR disables resizing the TUI. Unfortunately this is a regression from the old ceo. But trying to preserve state when destroying and creating new views in asciimatics proved to be very difficult. Co-authored-by: Max Erenberg <> Reviewed-on: #21 Co-authored-by: Max Erenberg <merenber@csclub.uwaterloo.ca> Co-committed-by: Max Erenberg <merenber@csclub.uwaterloo.ca>
This commit is contained in:
parent
7edc01e42b
commit
3e1131c4e4
|
@ -125,7 +125,7 @@ cn: regular1
|
||||||
gidNumber: 20002
|
gidNumber: 20002
|
||||||
|
|
||||||
dn: uid=exec1,ou=People,dc=csclub,dc=internal
|
dn: uid=exec1,ou=People,dc=csclub,dc=internal
|
||||||
cn: Regular One
|
cn: Exec One
|
||||||
userPassword: {SASL}exec1@CSCLUB.INTERNAL
|
userPassword: {SASL}exec1@CSCLUB.INTERNAL
|
||||||
loginShell: /bin/bash
|
loginShell: /bin/bash
|
||||||
homeDirectory: /users/exec1
|
homeDirectory: /users/exec1
|
||||||
|
|
|
@ -47,201 +47,6 @@ objectClass: top
|
||||||
uid: regular2
|
uid: regular2
|
||||||
mail: regular2@uwaterloo.internal
|
mail: regular2@uwaterloo.internal
|
||||||
|
|
||||||
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Exec One
|
|
||||||
givenName: Exec
|
|
||||||
sn: One
|
|
||||||
cn: Exec One
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: exec1@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: exec1
|
|
||||||
mail: exec1@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=exec2,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Exec Two
|
|
||||||
givenName: Exec
|
|
||||||
sn: Two
|
|
||||||
cn: Exec Two
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: exec2@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: exec2
|
|
||||||
mail: exec2@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Calum Dalek
|
|
||||||
givenName: Calum
|
|
||||||
sn: Dalek
|
|
||||||
cn: Calum Dalek
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: ctdalek@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: ctdalek
|
|
||||||
mail: ctdalek@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Regular One
|
|
||||||
givenName: Regular
|
|
||||||
sn: One
|
|
||||||
cn: Regular One
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: regular1@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: regular1
|
|
||||||
mail: regular1@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Regular Two
|
|
||||||
givenName: Regular
|
|
||||||
sn: Two
|
|
||||||
cn: Regular Two
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: regular2@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: regular2
|
|
||||||
mail: regular2@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Exec One
|
|
||||||
givenName: Exec
|
|
||||||
sn: One
|
|
||||||
cn: Exec One
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: exec1@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: exec1
|
|
||||||
mail: exec1@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Calum Dalek
|
|
||||||
givenName: Calum
|
|
||||||
sn: Dalek
|
|
||||||
cn: Calum Dalek
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: ctdalek@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: ctdalek
|
|
||||||
mail: ctdalek@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Regular One
|
|
||||||
givenName: Regular
|
|
||||||
sn: One
|
|
||||||
cn: Regular One
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: regular1@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: regular1
|
|
||||||
mail: regular1@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Regular Two
|
|
||||||
givenName: Regular
|
|
||||||
sn: Two
|
|
||||||
cn: Regular Two
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: regular2@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: regular2
|
|
||||||
mail: regular2@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=exec1,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Exec One
|
|
||||||
givenName: Exec
|
|
||||||
sn: One
|
|
||||||
cn: Exec One
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: exec1@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: exec1
|
|
||||||
mail: exec1@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=ctdalek,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Calum Dalek
|
|
||||||
givenName: Calum
|
|
||||||
sn: Dalek
|
|
||||||
cn: Calum Dalek
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: ctdalek@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: ctdalek
|
|
||||||
mail: ctdalek@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular1,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Regular One
|
|
||||||
givenName: Regular
|
|
||||||
sn: One
|
|
||||||
cn: Regular One
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: regular1@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: regular1
|
|
||||||
mail: regular1@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular2,ou=UWLDAP,dc=csclub,dc=internal
|
|
||||||
displayName: Regular Two
|
|
||||||
givenName: Regular
|
|
||||||
sn: Two
|
|
||||||
cn: Regular Two
|
|
||||||
ou: MAT/Mathematics Computer Science
|
|
||||||
mailLocalAddress: regular2@uwaterloo.internal
|
|
||||||
objectClass: inetLocalMailRecipient
|
|
||||||
objectClass: inetOrgPerson
|
|
||||||
objectClass: organizationalPerson
|
|
||||||
objectClass: person
|
|
||||||
objectClass: top
|
|
||||||
uid: regular2
|
|
||||||
mail: regular2@uwaterloo.internal
|
|
||||||
|
|
||||||
dn: uid=regular3,ou=UWLDAP,dc=csclub,dc=internal
|
dn: uid=regular3,ou=UWLDAP,dc=csclub,dc=internal
|
||||||
displayName: Regular Three
|
displayName: Regular Three
|
||||||
givenName: Regular
|
givenName: Regular
|
||||||
|
|
|
@ -12,11 +12,9 @@ class CeoFrame(Frame):
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
model,
|
model,
|
||||||
name, # key in model.viewdata
|
name,
|
||||||
on_load=None,
|
on_load=None,
|
||||||
title=None,
|
title=None,
|
||||||
save_data=False, # whether to save widget state for resizing
|
|
||||||
has_dynamic_layouts=False, # whether layouts are created on load
|
|
||||||
escape_on_q=False, # whether to quit when 'q' is pressed
|
escape_on_q=False, # whether to quit when 'q' is pressed
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
@ -28,70 +26,43 @@ class CeoFrame(Frame):
|
||||||
title=title,
|
title=title,
|
||||||
on_load=self._ceoframe_on_load,
|
on_load=self._ceoframe_on_load,
|
||||||
)
|
)
|
||||||
self._save_data = save_data
|
self._custom_on_load = on_load
|
||||||
self._extra_on_load = on_load
|
|
||||||
self._model = model
|
self._model = model
|
||||||
self._name = name
|
self._name = name
|
||||||
self._has_dynamic_layouts = has_dynamic_layouts
|
# If a view has a custom on_load function, all layouts should
|
||||||
|
# be created on load (*not* in the constructor)
|
||||||
|
self._has_dynamic_layouts = on_load is not None
|
||||||
self._quit_keys = [Screen.KEY_ESCAPE]
|
self._quit_keys = [Screen.KEY_ESCAPE]
|
||||||
if escape_on_q:
|
if escape_on_q:
|
||||||
self._quit_keys.append(ord('q'))
|
self._quit_keys.append(ord('q'))
|
||||||
# sanity check
|
|
||||||
if save_data:
|
|
||||||
assert name in model.viewdata
|
|
||||||
# child classes may override this as a last resort
|
# child classes may override this as a last resort
|
||||||
self.do_not_reload = False
|
self.skip_reload = False
|
||||||
|
|
||||||
def _ceoframe_on_load(self):
|
def _ceoframe_on_load(self):
|
||||||
if self.do_not_reload:
|
if self.skip_reload:
|
||||||
self.do_not_reload = False
|
self.skip_reload = False
|
||||||
return
|
return
|
||||||
self.do_not_reload = True
|
|
||||||
if self._has_dynamic_layouts:
|
|
||||||
# We arrive here after a user pressed 'Back' then 'Next'.
|
|
||||||
# The data may have changed, so we need to redraw everything,
|
|
||||||
# via self._extra_on_load().
|
|
||||||
self.clear_layouts()
|
|
||||||
if self._model.title is not None:
|
if self._model.title is not None:
|
||||||
self.title = self._model.title
|
self.title = self._model.title
|
||||||
self._model.title = None
|
self._model.title = None
|
||||||
if self._save_data:
|
if self._has_dynamic_layouts and self._model.nav_direction == 'forward':
|
||||||
# restore the saved input fields' values
|
# We arrive here after a user pressed 'Back' then 'Next',
|
||||||
self.data = self._model.viewdata[self._name]
|
# or after we returned to the Welcome screen.
|
||||||
if self._extra_on_load is not None:
|
# The data may have changed, so we need to redraw everything,
|
||||||
self._extra_on_load()
|
# via self._custom_on_load().
|
||||||
|
self.clear_layouts()
|
||||||
def _ceoframe_on_unload(self):
|
self._custom_on_load()
|
||||||
"""
|
|
||||||
This should be called just after the screen gets resized,
|
|
||||||
but before the new scenes are constructed.
|
|
||||||
The idea is to save the user's data in the input fields
|
|
||||||
so that we can restore them in the new scenes.
|
|
||||||
"""
|
|
||||||
if not self._save_data:
|
|
||||||
return
|
|
||||||
self.save()
|
|
||||||
self._model.viewdata[self._name] = self.data
|
|
||||||
|
|
||||||
|
# may be overridden by child classes
|
||||||
def _ceoframe_on_reset(self):
|
def _ceoframe_on_reset(self):
|
||||||
"""
|
"""
|
||||||
This needs to be called whenever we return to the home screen
|
This is called whenever we return to the home screen
|
||||||
after some kind of operation was completed.
|
after some kind of operation was completed.
|
||||||
Currently this is called from Model.reset().
|
This is called from Model.reset().
|
||||||
"""
|
"""
|
||||||
# We want a fresh slate once we return to the home screen, so we
|
pass
|
||||||
# want on_load() to be called for the scenes.
|
|
||||||
self.do_not_reload = False
|
|
||||||
if self._has_dynamic_layouts:
|
|
||||||
# We don't want layouts to accumulate.
|
|
||||||
self.clear_layouts()
|
|
||||||
|
|
||||||
def clear_layouts(self):
|
def clear_layouts(self):
|
||||||
# OK so this a *really* bad thing to do, since we're reaching
|
|
||||||
# into the private variables of a third-party library.
|
|
||||||
# Unfortunately asciimatics doesn't allow us to clear the layouts
|
|
||||||
# of an existing frame, and we need this to be able to re-use
|
|
||||||
# frames which create layouts dynamically.
|
|
||||||
self._layouts.clear()
|
self._layouts.clear()
|
||||||
|
|
||||||
def force_update(self):
|
def force_update(self):
|
||||||
|
@ -126,12 +97,14 @@ class CeoFrame(Frame):
|
||||||
layout.add_widget(Divider())
|
layout.add_widget(Divider())
|
||||||
|
|
||||||
def _back():
|
def _back():
|
||||||
|
self._model.nav_direction = 'backward'
|
||||||
last_scene = self._model.scene_stack.pop()
|
last_scene = self._model.scene_stack.pop()
|
||||||
if last_scene == 'Welcome':
|
if last_scene == 'Welcome':
|
||||||
self._model.reset()
|
self._model.reset()
|
||||||
raise NextScene(last_scene)
|
raise NextScene(last_scene)
|
||||||
|
|
||||||
def _next():
|
def _next():
|
||||||
|
self._model.nav_direction = 'forward'
|
||||||
if on_next_excl is not None:
|
if on_next_excl is not None:
|
||||||
on_next_excl()
|
on_next_excl()
|
||||||
return
|
return
|
||||||
|
|
|
@ -8,7 +8,6 @@ class ConfirmView(CeoFrame):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'Confirm',
|
screen, height, width, model, 'Confirm',
|
||||||
on_load=self._confirmview_on_load, title='Confirmation',
|
on_load=self._confirmview_on_load, title='Confirmation',
|
||||||
has_dynamic_layouts=True,
|
|
||||||
escape_on_q=True,
|
escape_on_q=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,6 +45,11 @@ class ConfirmView(CeoFrame):
|
||||||
kwargs['on_next_excl'] = self._next
|
kwargs['on_next_excl'] = self._next
|
||||||
self.add_buttons(**kwargs)
|
self.add_buttons(**kwargs)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
# OK so there's some weird bug somewhere which causes the buttons to be unselectable
|
||||||
|
# if we add a new user, return to the Welcome screen, then try to renew a user.
|
||||||
|
# This is a workaround for that.
|
||||||
|
self.skip_reload = True
|
||||||
|
self.reset()
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
self.flash_message('Sending request...', force_update=True)
|
self.flash_message('Sending request...', force_update=True)
|
||||||
|
|
|
@ -9,7 +9,6 @@ class ErrorView(CeoFrame):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'Error',
|
screen, height, width, model, 'Error',
|
||||||
on_load=self._errorview_on_load, title='Error',
|
on_load=self._errorview_on_load, title='Error',
|
||||||
has_dynamic_layouts=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def _errorview_on_load(self):
|
def _errorview_on_load(self):
|
||||||
|
|
|
@ -18,66 +18,12 @@ class Model:
|
||||||
self.result_view_name = None
|
self.result_view_name = None
|
||||||
self.txn_view_name = None
|
self.txn_view_name = None
|
||||||
self.error_message = None
|
self.error_message = None
|
||||||
# View-specific data, to be used when e.g. resizing the window.
|
self.nav_direction = 'forward'
|
||||||
# For the views where save_data=True was passed to the CeoFrame
|
# View-specific data
|
||||||
# constructor, the keys correspond to the names of text fields.
|
|
||||||
self._initial_viewdata = {
|
self._initial_viewdata = {
|
||||||
'AddUser': {
|
|
||||||
'uid': '',
|
|
||||||
'cn': '',
|
|
||||||
'program': '',
|
|
||||||
'forwarding_address': '',
|
|
||||||
'num_terms': '1',
|
|
||||||
},
|
|
||||||
'RenewUser': {
|
|
||||||
'uid': '',
|
|
||||||
'num_terms': '1',
|
|
||||||
},
|
|
||||||
'Transaction': {
|
|
||||||
'op_layout': None,
|
|
||||||
'msg_layout': None,
|
|
||||||
'labels': {},
|
|
||||||
'status': 'not started',
|
|
||||||
},
|
|
||||||
'GetUser': {
|
|
||||||
'uid': '',
|
|
||||||
},
|
|
||||||
'ResetPassword': {
|
'ResetPassword': {
|
||||||
'uid': '',
|
'uid': '',
|
||||||
},
|
},
|
||||||
'ChangeLoginShell': {
|
|
||||||
'uid': '',
|
|
||||||
'login_shell': '',
|
|
||||||
},
|
|
||||||
'SetForwardingAddresses': {
|
|
||||||
'uid': '',
|
|
||||||
'forwarding_addresses': [''],
|
|
||||||
},
|
|
||||||
'AddGroup': {
|
|
||||||
'cn': '',
|
|
||||||
'description': '',
|
|
||||||
},
|
|
||||||
'GetGroup': {
|
|
||||||
'cn': '',
|
|
||||||
},
|
|
||||||
'AddMemberToGroup': {
|
|
||||||
'cn': '',
|
|
||||||
'uid': '',
|
|
||||||
'subscribe': True,
|
|
||||||
},
|
|
||||||
'RemoveMemberFromGroup': {
|
|
||||||
'cn': '',
|
|
||||||
'uid': '',
|
|
||||||
'unsubscribe': True,
|
|
||||||
},
|
|
||||||
'CreateDatabase': {
|
|
||||||
'uid': '',
|
|
||||||
},
|
|
||||||
'ResetDatabasePassword': {
|
|
||||||
'uid': '',
|
|
||||||
},
|
|
||||||
# This one needs to be filled in dynamically
|
|
||||||
'SetPositions': {},
|
|
||||||
}
|
}
|
||||||
for pos in cfg.get('positions_available'):
|
for pos in cfg.get('positions_available'):
|
||||||
self._initial_viewdata[pos] = ''
|
self._initial_viewdata[pos] = ''
|
||||||
|
|
|
@ -10,7 +10,6 @@ class ResultView(CeoFrame):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'Result',
|
screen, height, width, model, 'Result',
|
||||||
on_load=self._resultview_on_load, title='Result',
|
on_load=self._resultview_on_load, title='Result',
|
||||||
has_dynamic_layouts=True,
|
|
||||||
escape_on_q=True,
|
escape_on_q=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,9 @@ class TransactionView(CeoFrame):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'Transaction',
|
screen, height, width, model, 'Transaction',
|
||||||
on_load=self._txnview_on_load, title='Running Transaction',
|
on_load=self._txnview_on_load, title='Running Transaction',
|
||||||
has_dynamic_layouts=True,
|
|
||||||
)
|
)
|
||||||
# map operation names to label widgets
|
# map operation names to label widgets
|
||||||
self._labels = model.viewdata['Transaction']['labels']
|
self._labels = {}
|
||||||
|
|
||||||
def _add_buttons(self):
|
def _add_buttons(self):
|
||||||
layout = Layout([100])
|
layout = Layout([100])
|
||||||
|
@ -28,10 +27,6 @@ class TransactionView(CeoFrame):
|
||||||
layout = Layout([1, 1])
|
layout = Layout([1, 1])
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
self._next_btn = Button('Next', self._next)
|
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)
|
layout.add_widget(self._next_btn, 1)
|
||||||
|
|
||||||
def _add_blank_line(self):
|
def _add_blank_line(self):
|
||||||
|
@ -39,47 +34,30 @@ class TransactionView(CeoFrame):
|
||||||
self._op_layout.add_widget(Label(''), 2)
|
self._op_layout.add_widget(Label(''), 2)
|
||||||
|
|
||||||
def _txnview_on_load(self):
|
def _txnview_on_load(self):
|
||||||
d = self._model.viewdata['Transaction']
|
self._op_layout = Layout([12, 1, 10])
|
||||||
if d['op_layout'] is None:
|
self.add_layout(self._op_layout)
|
||||||
first_time = True
|
# store the layouts so that we can re-use them when the screen
|
||||||
self._op_layout = Layout([12, 1, 10])
|
# gets resized
|
||||||
self.add_layout(self._op_layout)
|
for _ in range(2):
|
||||||
# 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()
|
self._add_blank_line()
|
||||||
# this is the where success/failure messages etc. get placed
|
for operation in self._model.operations:
|
||||||
self._msg_layout = Layout([100])
|
desc = op_desc[operation]
|
||||||
self.add_layout(self._msg_layout)
|
self._op_layout.add_widget(Label(desc + '...', align='>'), 0)
|
||||||
d['msg_layout'] = self._msg_layout
|
desc_label = Label('', align='<')
|
||||||
else:
|
self._op_layout.add_widget(desc_label, 2)
|
||||||
# we arrive here when the screen has been resized
|
self._labels[operation] = desc_label
|
||||||
first_time = False
|
self._add_blank_line()
|
||||||
# restore the layouts which we saved
|
# this is the where success/failure messages etc. get placed
|
||||||
self._op_layout = d['op_layout']
|
self._msg_layout = Layout([100])
|
||||||
self.add_layout(self._op_layout)
|
self.add_layout(self._msg_layout)
|
||||||
self._msg_layout = d['msg_layout']
|
|
||||||
self.add_layout(self._msg_layout)
|
|
||||||
# fill up the rest of the space
|
# fill up the rest of the space
|
||||||
self.add_layout(Layout([100], fill_frame=True))
|
self.add_layout(Layout([100], fill_frame=True))
|
||||||
|
|
||||||
self._add_buttons()
|
self._add_buttons()
|
||||||
self.fix()
|
self.fix()
|
||||||
# only send the API request the first time we arrive at this
|
Thread(target=self._do_txn).start()
|
||||||
# scene, not when the screen gets resized
|
|
||||||
if first_time:
|
|
||||||
Thread(target=self._do_txn).start()
|
|
||||||
|
|
||||||
def _do_txn(self):
|
def _do_txn(self):
|
||||||
self._model.viewdata['Transaction']['status'] = 'in progress'
|
|
||||||
resp = self._model.deferred_req()
|
resp = self._model.deferred_req()
|
||||||
handler = TUIStreamResponseHandler(
|
handler = TUIStreamResponseHandler(
|
||||||
model=self._model,
|
model=self._model,
|
||||||
|
@ -99,10 +77,8 @@ class TransactionView(CeoFrame):
|
||||||
# If we don't reset, the button isn't selectable, even though we
|
# If we don't reset, the button isn't selectable, even though we
|
||||||
# enabled it.
|
# enabled it.
|
||||||
# We don't want to reload, though (which reset() will trigger).
|
# We don't want to reload, though (which reset() will trigger).
|
||||||
self.do_not_reload = True
|
self.skip_reload = True
|
||||||
self.reset()
|
self.reset()
|
||||||
# save the fact that the transaction is completed
|
|
||||||
self._model.viewdata['Transaction']['status'] = 'completed'
|
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
self._model.reset()
|
self._model.reset()
|
||||||
|
|
|
@ -8,7 +8,6 @@ class CreateDatabaseView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'CreateDatabase',
|
screen, height, width, model, 'CreateDatabase',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -19,6 +18,10 @@ class CreateDatabaseView(CeoFrame):
|
||||||
on_next=self._next)
|
on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
|
||||||
def _target(self):
|
def _target(self):
|
||||||
username = self._username.value
|
username = self._username.value
|
||||||
db_type = self._model.db_type
|
db_type = self._model.db_type
|
||||||
|
|
|
@ -8,7 +8,6 @@ class ResetDatabasePasswordView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'ResetDatabasePassword',
|
screen, height, width, model, 'ResetDatabasePassword',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -19,6 +18,10 @@ class ResetDatabasePasswordView(CeoFrame):
|
||||||
on_next=self._next)
|
on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
|
||||||
def _target(self):
|
def _target(self):
|
||||||
username = self._username.value
|
username = self._username.value
|
||||||
db_type = self._model.db_type
|
db_type = self._model.db_type
|
||||||
|
|
|
@ -9,7 +9,6 @@ class AddGroupView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'AddGroup',
|
screen, height, width, model, 'AddGroup',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -23,6 +22,11 @@ class AddGroupView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._cn.value = None
|
||||||
|
self._description.value = None
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
cn = self._cn.value
|
cn = self._cn.value
|
||||||
description = self._description.value
|
description = self._description.value
|
||||||
|
|
|
@ -9,7 +9,6 @@ class AddMemberToGroupView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'AddMemberToGroup',
|
screen, height, width, model, 'AddMemberToGroup',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -28,6 +27,12 @@ class AddMemberToGroupView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._cn.value = None
|
||||||
|
self._username.value = None
|
||||||
|
self._checkbox.value = True
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
cn = self._cn.value
|
cn = self._cn.value
|
||||||
uid = self._username.value
|
uid = self._username.value
|
||||||
|
|
|
@ -8,7 +8,6 @@ class GetGroupView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'GetGroup',
|
screen, height, width, model, 'GetGroup',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -21,9 +20,12 @@ class GetGroupView(CeoFrame):
|
||||||
next_scene='GetGroupResult', on_next=self._next)
|
next_scene='GetGroupResult', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._cn.value = None
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
cn = self._cn.value
|
cn = self._cn.value
|
||||||
self._model.viewdata['GetGroup']['cn'] = cn
|
|
||||||
self.flash_message('Looking up group...', force_update=True)
|
self.flash_message('Looking up group...', force_update=True)
|
||||||
try:
|
try:
|
||||||
self._model.resp = http_get(f'/api/groups/{cn}')
|
self._model.resp = http_get(f'/api/groups/{cn}')
|
||||||
|
|
|
@ -9,7 +9,6 @@ class RemoveMemberFromGroupView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'RemoveMemberFromGroup',
|
screen, height, width, model, 'RemoveMemberFromGroup',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -28,6 +27,11 @@ class RemoveMemberFromGroupView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._cn.value = None
|
||||||
|
self._username.value = None
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
cn = self._cn.value
|
cn = self._cn.value
|
||||||
uid = self._username.value
|
uid = self._username.value
|
||||||
|
|
|
@ -12,7 +12,6 @@ class AddUserView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'AddUser',
|
screen, height, width, model, 'AddUser',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
self._username_changed = False
|
self._username_changed = False
|
||||||
|
|
||||||
|
@ -33,6 +32,7 @@ class AddUserView(CeoFrame):
|
||||||
self._num_terms = Text(
|
self._num_terms = Text(
|
||||||
"Number of terms:", "num_terms",
|
"Number of terms:", "num_terms",
|
||||||
validator=lambda s: s.isdigit() and s[0] != '0')
|
validator=lambda s: s.isdigit() and s[0] != '0')
|
||||||
|
self._num_terms.value = '1'
|
||||||
layout.add_widget(self._num_terms)
|
layout.add_widget(self._num_terms)
|
||||||
|
|
||||||
self.add_flash_message_layout()
|
self.add_flash_message_layout()
|
||||||
|
@ -41,6 +41,14 @@ class AddUserView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
self._full_name.value = None
|
||||||
|
self._program.value = None
|
||||||
|
self._forwarding_address.value = None
|
||||||
|
self._num_terms.value = '1'
|
||||||
|
|
||||||
def _on_username_change(self):
|
def _on_username_change(self):
|
||||||
self._username_changed = True
|
self._username_changed = True
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ class ChangeLoginShellView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'ChangeLoginShell',
|
screen, height, width, model, 'ChangeLoginShell',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
self._username_changed = False
|
self._username_changed = False
|
||||||
|
|
||||||
|
@ -31,6 +30,11 @@ class ChangeLoginShellView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
self._login_shell.value = None
|
||||||
|
|
||||||
# TODO: deduplicate this from AddUserView
|
# TODO: deduplicate this from AddUserView
|
||||||
def _on_username_change(self):
|
def _on_username_change(self):
|
||||||
self._username_changed = True
|
self._username_changed = True
|
||||||
|
|
|
@ -8,7 +8,6 @@ class GetUserView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'GetUser',
|
screen, height, width, model, 'GetUser',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -21,6 +20,10 @@ class GetUserView(CeoFrame):
|
||||||
next_scene='GetUserResult', on_next=self._next)
|
next_scene='GetUserResult', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
uid = self._username.value
|
uid = self._username.value
|
||||||
self.flash_message('Looking up user...', force_update=True)
|
self.flash_message('Looking up user...', force_update=True)
|
||||||
|
|
|
@ -9,7 +9,6 @@ class RenewUserView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'RenewUser',
|
screen, height, width, model, 'RenewUser',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
self._model = model
|
self._model = model
|
||||||
|
|
||||||
|
@ -20,6 +19,7 @@ class RenewUserView(CeoFrame):
|
||||||
self._num_terms = Text(
|
self._num_terms = Text(
|
||||||
"Number of terms:", "num_terms",
|
"Number of terms:", "num_terms",
|
||||||
validator=lambda s: s.isdigit() and s[0] != '0')
|
validator=lambda s: s.isdigit() and s[0] != '0')
|
||||||
|
self._num_terms.value = '1'
|
||||||
layout.add_widget(self._num_terms)
|
layout.add_widget(self._num_terms)
|
||||||
|
|
||||||
self.add_flash_message_layout()
|
self.add_flash_message_layout()
|
||||||
|
@ -28,6 +28,11 @@ class RenewUserView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
self._num_terms.value = '1'
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
uid = self._username.value
|
uid = self._username.value
|
||||||
self.flash_message('Looking up user...', force_update=True)
|
self.flash_message('Looking up user...', force_update=True)
|
||||||
|
|
|
@ -8,7 +8,6 @@ class ResetPasswordView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'ResetPassword',
|
screen, height, width, model, 'ResetPassword',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
@ -21,6 +20,10 @@ class ResetPasswordView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
uid = self._username.value
|
uid = self._username.value
|
||||||
self._model.viewdata['ResetPassword']['uid'] = uid
|
self._model.viewdata['ResetPassword']['uid'] = uid
|
||||||
|
|
|
@ -10,7 +10,6 @@ class SetForwardingAddressesView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'SetForwardingAddresses',
|
screen, height, width, model, 'SetForwardingAddresses',
|
||||||
save_data=True,
|
|
||||||
)
|
)
|
||||||
self._username_changed = False
|
self._username_changed = False
|
||||||
|
|
||||||
|
@ -34,6 +33,11 @@ class SetForwardingAddressesView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
self._username.value = None
|
||||||
|
self._forwarding_addresses.value = None
|
||||||
|
|
||||||
# TODO: deduplicate this from AddUserView
|
# TODO: deduplicate this from AddUserView
|
||||||
def _on_username_change(self):
|
def _on_username_change(self):
|
||||||
self._username_changed = True
|
self._username_changed = True
|
||||||
|
|
|
@ -27,8 +27,11 @@ class GetPositionsView(CeoFrame):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'GetPositions',
|
screen, height, width, model, 'GetPositions',
|
||||||
escape_on_q=True,
|
escape_on_q=True,
|
||||||
on_load=self._on_load)
|
on_load=self._on_load
|
||||||
|
)
|
||||||
|
self._position_widgets = {}
|
||||||
|
|
||||||
|
def _on_load(self):
|
||||||
cfg = component.getUtility(IConfig)
|
cfg = component.getUtility(IConfig)
|
||||||
avail = cfg.get('positions_available')
|
avail = cfg.get('positions_available')
|
||||||
|
|
||||||
|
@ -39,7 +42,6 @@ class GetPositionsView(CeoFrame):
|
||||||
self._main_layout = Layout([10, 1, 10], fill_frame=True)
|
self._main_layout = Layout([10, 1, 10], fill_frame=True)
|
||||||
self.add_layout(self._main_layout)
|
self.add_layout(self._main_layout)
|
||||||
|
|
||||||
self._position_widgets = {}
|
|
||||||
for pos in avail:
|
for pos in avail:
|
||||||
self._position_widgets[pos] = self._add_pair(position_names[pos], '')
|
self._position_widgets[pos] = self._add_pair(position_names[pos], '')
|
||||||
|
|
||||||
|
@ -47,18 +49,6 @@ class GetPositionsView(CeoFrame):
|
||||||
self.add_buttons(back_btn=True)
|
self.add_buttons(back_btn=True)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
def _add_blank_line(self):
|
|
||||||
self._main_layout.add_widget(Label(' ', 0))
|
|
||||||
self._main_layout.add_widget(Label(' ', 2))
|
|
||||||
|
|
||||||
def _add_pair(self, key: str, val: str):
|
|
||||||
key_widget = Label(key + ':', align='>')
|
|
||||||
value_widget = Label(val, align='<')
|
|
||||||
self._main_layout.add_widget(key_widget, 0)
|
|
||||||
self._main_layout.add_widget(value_widget, 2)
|
|
||||||
return value_widget
|
|
||||||
|
|
||||||
def _on_load(self):
|
|
||||||
def target():
|
def target():
|
||||||
self.flash_message('Looking up positions...')
|
self.flash_message('Looking up positions...')
|
||||||
try:
|
try:
|
||||||
|
@ -72,6 +62,17 @@ class GetPositionsView(CeoFrame):
|
||||||
self.clear_flash_message(force_update=True)
|
self.clear_flash_message(force_update=True)
|
||||||
Thread(target=target).start()
|
Thread(target=target).start()
|
||||||
|
|
||||||
|
def _add_blank_line(self):
|
||||||
|
self._main_layout.add_widget(Label(' ', 0))
|
||||||
|
self._main_layout.add_widget(Label(' ', 2))
|
||||||
|
|
||||||
|
def _add_pair(self, key: str, val: str):
|
||||||
|
key_widget = Label(key + ':', align='>')
|
||||||
|
value_widget = Label(val, align='<')
|
||||||
|
self._main_layout.add_widget(key_widget, 0)
|
||||||
|
self._main_layout.add_widget(value_widget, 2)
|
||||||
|
return value_widget
|
||||||
|
|
||||||
def _ceoframe_on_reset(self):
|
def _ceoframe_on_reset(self):
|
||||||
super()._ceoframe_on_reset()
|
super()._ceoframe_on_reset()
|
||||||
# clear the labels
|
# clear the labels
|
||||||
|
|
|
@ -12,16 +12,18 @@ class SetPositionsView(CeoFrame):
|
||||||
def __init__(self, screen, width, height, model):
|
def __init__(self, screen, width, height, model):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
screen, height, width, model, 'SetPositions',
|
screen, height, width, model, 'SetPositions',
|
||||||
save_data=True)
|
)
|
||||||
cfg = component.getUtility(IConfig)
|
cfg = component.getUtility(IConfig)
|
||||||
avail = cfg.get('positions_available')
|
avail = cfg.get('positions_available')
|
||||||
required = cfg.get('positions_required')
|
required = cfg.get('positions_required')
|
||||||
|
|
||||||
layout = Layout([100], fill_frame=True)
|
layout = Layout([100], fill_frame=True)
|
||||||
self.add_layout(layout)
|
self.add_layout(layout)
|
||||||
|
self._widgets = []
|
||||||
for pos in avail:
|
for pos in avail:
|
||||||
suffix = ' (*)' if pos in required else ''
|
suffix = ' (*)' if pos in required else ''
|
||||||
widget = Text(position_names[pos] + suffix, pos)
|
widget = Text(position_names[pos] + suffix, pos)
|
||||||
|
self._widgets.append(widget)
|
||||||
layout.add_widget(widget)
|
layout.add_widget(widget)
|
||||||
|
|
||||||
layout = Layout([100])
|
layout = Layout([100])
|
||||||
|
@ -34,6 +36,11 @@ class SetPositionsView(CeoFrame):
|
||||||
next_scene='Confirm', on_next=self._next)
|
next_scene='Confirm', on_next=self._next)
|
||||||
self.fix()
|
self.fix()
|
||||||
|
|
||||||
|
def _ceoframe_on_reset(self):
|
||||||
|
super()._ceoframe_on_reset()
|
||||||
|
for widget in self._widgets:
|
||||||
|
widget.value = None
|
||||||
|
|
||||||
def _next(self):
|
def _next(self):
|
||||||
self.save()
|
self.save()
|
||||||
body = {pos: username for pos, username in self.data.items() if username}
|
body = {pos: username for pos, username in self.data.items() if username}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from asciimatics.exceptions import ResizeScreenError
|
from asciimatics.exceptions import ResizeScreenError
|
||||||
|
@ -37,10 +38,6 @@ views = []
|
||||||
|
|
||||||
def screen_wrapper(screen, last_scene, model):
|
def screen_wrapper(screen, last_scene, model):
|
||||||
global views
|
global views
|
||||||
# unload the old views
|
|
||||||
for name, view in views:
|
|
||||||
if hasattr(view, '_ceoframe_on_unload'):
|
|
||||||
view._ceoframe_on_unload()
|
|
||||||
width = min(screen.width, 90)
|
width = min(screen.width, 90)
|
||||||
height = min(screen.height, 24)
|
height = min(screen.height, 24)
|
||||||
views = [
|
views = [
|
||||||
|
@ -83,9 +80,10 @@ def screen_wrapper(screen, last_scene, model):
|
||||||
def main():
|
def main():
|
||||||
last_scene = None
|
last_scene = None
|
||||||
model = Model()
|
model = Model()
|
||||||
while True:
|
try:
|
||||||
try:
|
Screen.wrapper(screen_wrapper, arguments=[last_scene, model])
|
||||||
Screen.wrapper(screen_wrapper, arguments=[last_scene, model])
|
sys.exit(0)
|
||||||
sys.exit(0)
|
except ResizeScreenError:
|
||||||
except ResizeScreenError as e:
|
os.system('reset')
|
||||||
last_scene = e.scene
|
print('Unfortunately, ceo does not currently support dynamic resizing.')
|
||||||
|
sys.exit(1)
|
||||||
|
|
|
@ -146,7 +146,7 @@ def generic_handle_stream_response(
|
||||||
"""
|
"""
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
handler.handle_non_200(resp)
|
handler.handle_non_200(resp)
|
||||||
return
|
return [{'status': 'error'}]
|
||||||
handler.begin()
|
handler.begin()
|
||||||
idx = 0
|
idx = 0
|
||||||
data = []
|
data = []
|
||||||
|
@ -155,7 +155,7 @@ def generic_handle_stream_response(
|
||||||
data.append(d)
|
data.append(d)
|
||||||
if d['status'] == 'aborted':
|
if d['status'] == 'aborted':
|
||||||
handler.handle_aborted(d['error'])
|
handler.handle_aborted(d['error'])
|
||||||
return
|
return data
|
||||||
elif d['status'] == 'completed':
|
elif d['status'] == 'completed':
|
||||||
while idx < len(operations):
|
while idx < len(operations):
|
||||||
handler.handle_skipped_operation()
|
handler.handle_skipped_operation()
|
||||||
|
|
Loading…
Reference in New Issue