diff --git a/nucypher/network/status/assets/stylesheet.css b/nucypher/network/status/assets/stylesheet.css index 28f0a4427..f8832069d 100644 --- a/nucypher/network/status/assets/stylesheet.css +++ b/nucypher/network/status/assets/stylesheet.css @@ -1,5 +1,5 @@ body{ - font-size: 1.5em; + font-size: 14px; line-height: 1.6; font-weight: 400; font-family: Arial,sans-serif; @@ -33,16 +33,26 @@ body{ } .nucypher-nickname-icon { - border-width: 10px; + border-width: 1px; border-style: solid; margin: 3px; padding: 3px; text-align: center; box-shadow: 1px 1px black, -1px -1px black; - width: 100px; - height: 130px; + width: 70px; + height: 70px; } +#node-table { + width: 100%; +} + + +#node-table.row { + height: 2em; +} + + .small { float: left; width: 100%; @@ -57,9 +67,10 @@ body{ } .single-symbol { - font-size: 3em; + font-size: 20px; color: black; text-shadow: 1px 1px black, -1px -1px black; + margin-right: 2px; } .address, .small-address { @@ -72,4 +83,4 @@ body{ .state { float:left; -} \ No newline at end of file +} diff --git a/nucypher/network/status/moe.html b/nucypher/network/status/moe.html new file mode 100644 index 000000000..79b3b7fa9 --- /dev/null +++ b/nucypher/network/status/moe.html @@ -0,0 +1,52 @@ + + + + {%metas%} + {%title%} + {%favicon%} + {%css%} + + + {%app_entry%} + + + + + \ No newline at end of file diff --git a/nucypher/network/status/status_page.py b/nucypher/network/status/status_page.py index d230ba45c..ba2a02903 100644 --- a/nucypher/network/status/status_page.py +++ b/nucypher/network/status/status_page.py @@ -1,4 +1,5 @@ import os +from os.path import dirname, abspath import dash_core_components as dcc import dash_dangerously_set_inner_html @@ -24,7 +25,7 @@ class NetworkStatusPage: server=flask_server, assets_folder=self.assets_path, url_base_pathname=route_url, - suppress_callback_exceptions=True) + suppress_callback_exceptions=False) # TODO: Set to True by default or make configurable self.dash_app.title = title @property @@ -45,8 +46,7 @@ class NetworkStatusPage: ]), ]) - @staticmethod - def previous_states(learner: Learner) -> html.Div: + def previous_states(self, learner: Learner) -> html.Div: domains = learner.learning_domains states_dict = learner.known_nodes.abridged_states_dict() return html.Div([ @@ -57,24 +57,23 @@ class NetworkStatusPage: html.Div([ html.H2('Previous States'), html.Div([ - NetworkStatusPage.states_table(states_dict) + self.states_table(states_dict) ]), ], className='row') ]) - @staticmethod - def states_table(states_dict) -> html.Table: + def states_table(self, states_dict) -> html.Table: previous_states = list(states_dict.values())[:5] # only latest 5 row = [] for state in previous_states: # store previous states in reverse order - row.insert(0, html.Td(NetworkStatusPage.state_detail(state))) + row.insert(0, html.Td(self.state_detail(state))) return html.Table([html.Tr(row, id='state-table', className='row')]) @staticmethod def state_detail(state) -> html.Div: return html.Div([ - html.H5(state['nickname']), + html.Span(state['nickname']), html.Div([ html.Div(state['symbol'], className='single-symbol'), html.Span(state['updated'], className='small'), @@ -83,7 +82,6 @@ class NetworkStatusPage: def known_nodes(self, learner: Learner, title='Network Nodes') -> html.Div: nodes = list() - nodes_dict = learner.known_nodes.abridged_nodes_dict() teacher_node = learner.current_teacher_node() teacher_index = None @@ -91,34 +89,25 @@ class NetworkStatusPage: node_data = nodes_dict[checksum] if checksum == teacher_node.checksum_address: teacher_index = len(nodes) - nodes.append(node_data) return html.Div([ html.H2(title), - html.Div([ - html.Div('* Current Teacher', - style={'backgroundColor': '#1E65F3', 'color': 'white'}, - className='two columns'), - ], className='row'), - html.Br(), - html.Div([ - self.nodes_table(nodes, teacher_index) - ], className='row') + html.Div([self.nodes_table(nodes, teacher_index)], className='row') ], className='row') def nodes_table(self, nodes, teacher_index) -> html.Table: rows = [] for index, node_info in enumerate(nodes): row = [] - for col in NetworkStatusPage.COLUMNS: + for col in self.COLUMNS: cell = self.generate_cell(column_name=col, node_info=node_info) if cell is not None: row.append(cell) style_dict = {'overflowY': 'scroll'} + # highlight teacher if index == teacher_index: - # highlight teacher style_dict['backgroundColor'] = '#1E65F3' style_dict['color'] = 'white' @@ -126,7 +115,7 @@ class NetworkStatusPage: table = html.Table( # header - [html.Tr([html.Th(col) for col in NetworkStatusPage.COLUMNS], className='row')] + + [html.Tr([html.Th(col) for col in self.COLUMNS], className='row')] + rows, id='node-table' ) @@ -154,7 +143,7 @@ class NetworkStatusPage: fleet_state_div = [] fleet_state_icon = node_info['fleet_state_icon'] if fleet_state_icon is not UNKNOWN_FLEET_STATE: - icon_list = [dash_dangerously_set_inner_html.DangerouslySetInnerHTML(node_info['fleet_state_icon'])] + icon_list = node_info['fleet_state_icon'] fleet_state_div = icon_list fleet_state = html.Td(children=html.Div(fleet_state_div)) @@ -178,63 +167,13 @@ class MoeStatusPage(NetworkStatusPage): def __init__(self, moe: Learner, ws_port: int, *args, **kwargs): super().__init__(*args, **kwargs) + self.ws_port = ws_port # modify index_string page template so that the websocket port for hendrix # updates can be directly provided included in javascript snippet - self.dash_app.index_string = r''' - - - - {%metas%} - {%title%} - {%favicon%} - {%css%} - - - {%app_entry%} - - - - - - ''' + template_path = os.path.join(abspath(dirname(__file__)), 'moe.html') + with open(template_path, 'r') as file: + self.dash_app.index_string = file.read() self.dash_app.layout = html.Div([ # hidden update buttons for hendrix notifications @@ -251,13 +190,13 @@ class MoeStatusPage(NetworkStatusPage): @self.dash_app.callback(Output('header', 'children'), [Input('url', 'pathname')]) # on page-load def header(pathname): - return NetworkStatusPage.header(self.title) + return self.header(self.title) @self.dash_app.callback(Output('prev-states', 'children'), [Input('url', 'pathname')], # on page-load events=[Event('hidden-state-button', 'click')]) # when notified by websocket message def state(pathname): - return NetworkStatusPage.previous_states(moe) + return self.previous_states(moe) @self.dash_app.callback(Output('known-nodes', 'children'), [Input('url', 'pathname')], # on page-load