Skip to content
Merged

Dash #42

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions DataService/sql/FrontEnd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip setuptools wheel
pip install -r requirements.txt

gunicorn DataServiceFrontEnd:server --bind 0.0.0.0:8050
156 changes: 156 additions & 0 deletions DataService/sql/FrontEnd/assets/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
body {
font-size: 14px;
}

.card {
border-radius: 2px !important;
}

.form-control {
border-radius: 2px !important;
font-size: 14px !important;
padding: 2px 6px !important;
min-height: 26px !important;
}

/* Accordion container */
.accordion {
background-color: #0e2537 !important; /* dark container */
}

/* Each panel item */
.accordion-item {
background-color: #0e2537 !important;
border: 0px solid #2a2f42 !important;
}

/* Header / button */
.accordion-button {
background-color: #0e2537 !important;
color: #f09d08 !important;
border: 0px solid #2a2f42 !important;
}

/* Expanded header */
.accordion-button:not(.collapsed) {
background-color: #0f1118 !important;
color: white !important;
}

/* Hover */
.accordion-button:hover {
color: white !important;
}

/* Body content */
.accordion-body {
background-color: #0e2537 !important;
color: #cccccc !important;
padding: 2px !important;
}

/* Arrow icon */
.accordion-button::after {
filter: invert(65%) !important;
}

/* Remove focus outline */
.accordion-button:focus {
outline: none !important;
box-shadow: none !important;
}

/* =========================================================
Global Buttons
========================================================= */

button {
background-color: #343a40;
color: white;
border: 1px solid #555;
border-radius: 4px;
padding: 6px 16px;
cursor: pointer;
}

button:hover {
background-color: #495057;
}

button:active {
background-color: #212529;
}

button:disabled {
opacity: 0.5;
cursor: not-allowed;
}


/* =========================================================
Global Inputs
========================================================= */

input,
textarea,
select {
background-color: #343a40 !important;
color: white !important;
border: 1px solid #555 !important;
border-radius: 4px;
}

input::placeholder,
textarea::placeholder {
color: #adb5bd !important;
opacity: 1;
}

input:focus,
textarea:focus,
select:focus {
background-color: #343a40 !important;
color: white !important;
border-color: #777 !important;
box-shadow: none !important;
outline: none;
}


/* =========================================================
Labels
========================================================= */

label {
color: white;
}


/* =========================================================
Common layout helpers
========================================================= */

.input-container {
margin-top: 10px;
}

.button-container {
display: flex;
justify-content: flex-end;
margin-top: 8px;
}

.error-message {
color: #dc3545;
margin-top: 5px;
}

.ag-theme-quartz {
--ag-font-size: 14px;
--ag-row-height: 30px;
--ag-header-height: 32px;
}

.ag-root-wrapper {
border-radius: 0 !important;
}
78 changes: 78 additions & 0 deletions DataService/sql/FrontEnd/components/instrument_details_panel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright (c) Mike Kipnis - DistributedATS
import json
import logging
import dash_ag_grid as dag
from dash import html, dash, Output, Input

import db_connection

logger = logging.getLogger("InstrumentDetailsPanel")

class InstrumentDetailsPanel(object):

def __init__(self, app: dash.Dash):

self.app = app

column_defs = [
{"field": "key", "headerName": "Key", "flex": 2},
{"field": "value", "headerName": "value", "flex": 2},
]

self.instrument_details_grid = dag.AgGrid(
id="instrument_details_grid_id",
columnDefs=column_defs,
rowData=[],
defaultColDef={"minWidth": 100, "resizable": True},
style={"height": "400px", "width": "100%"},
className="ag-theme-quartz",
dashGridOptions={
"rowSelection": "single",
"animateRows": True,
"suppressMaintainUnsortedOrder": True
},
)

self._register_callbacks()

pass

def layout(self):
return html.Div(
children=[self.instrument_details_grid],
**{"data-ag-theme-mode": "dark"} # Unpacks the dictionary as an HTML keyword attribute
)

def _register_callbacks(self):
@self.app.callback(
Output("instrument_details_grid_id", "rowData"),
Input("database-sqlite", "children"),
Input("selected-instrument", "data"),
prevent_initial_call=True,
)
def select_instrument(database_sqlite, selected_instrument):

if not selected_instrument:
return []

logger.info(f"select_instrument: {selected_instrument}")

instrument = selected_instrument[0]

instruments = db_connection.get_details_for_instrument(database_sqlite, instrument['instrument_name'])

if len(instruments) == 0:
return []

instrument_data_with_properties = instruments[0]
instrument_properties = json.loads(instrument_data_with_properties.get('properties',{}))
ref_data = {}
if 'ref_data' in instrument_properties:
ref_data = json.loads(instrument_properties.get('ref_data',{}))

ref_data_out = []
for key, value in ref_data.items():
ref_data_out.append({'key': key, 'value': value})


return ref_data_out
Loading
Loading