fix: resolve empty UI issues when running with --web-conf in Dash 4.0

This commit is contained in:
Florian Bezannier
2026-05-20 18:58:51 +02:00
committed by Florian BEZANNIER
parent 2d3ba3526d
commit ba18eb253e
7 changed files with 37 additions and 39 deletions
Generated
+6 -6
View File
@@ -665,18 +665,18 @@ testing = ["beautifulsoup4 (>=4.8.2)", "cryptography", "dash_testing_stub (>=0.0
[[package]]
name = "dash-bootstrap-components"
version = "1.7.1"
version = "2.0.4"
description = "Bootstrap themed components for use in Plotly Dash"
optional = false
python-versions = "<4,>=3.9"
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "dash_bootstrap_components-1.7.1-py3-none-any.whl", hash = "sha256:5e8eae7ee1d013f69e272c68c1015b53ab71802460152088f33fffa90d245199"},
{file = "dash_bootstrap_components-1.7.1.tar.gz", hash = "sha256:30d48340d6dc89831d6c06e400cd4236f0d5363562c05b2a922f21545695a082"},
{file = "dash_bootstrap_components-2.0.4-py3-none-any.whl", hash = "sha256:767cf0084586c1b2b614ccf50f79fe4525fdbbf8e3a161ed60016e584a14f5d1"},
{file = "dash_bootstrap_components-2.0.4.tar.gz", hash = "sha256:c3206c0923774bbc6a6ddaa7822b8d9aa5326b0d3c1e7cd795cc975025fe2484"},
]
[package.dependencies]
dash = ">=2.0.0"
dash = ">=3.0.4"
[package.extras]
pandas = ["numpy (>=2.0.2)", "pandas (>=2.2.3)"]
@@ -3250,4 +3250,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.11, <4.0.0"
content-hash = "406777f4f9851d08f5654943490f0407792e8e422276e91758fc76963b37a73a"
content-hash = "7490767cda5b9993fe4c8c1e9d2e3ba3b50e36826982d1a0c6737e79441e8684"
+1 -1
View File
@@ -73,7 +73,7 @@ def config_flask(title, base_path, debug: bool, host, port, reloader=False,
app.config["DEBUG"] = debug
if base_path == "/":
application = DispatcherMiddleware(app)
requests_pathname_prefix = None
requests_pathname_prefix = "/"
else:
application = DispatcherMiddleware(Flask('dummy_app'), {base_path: app})
requests_pathname_prefix = base_path + "/"
+14 -21
View File
@@ -7,24 +7,17 @@ class DashCustom(Dash):
self.requests_pathname_external_prefix = self.config.requests_pathname_prefix
def _config(self):
config = super()._config()
# pieces of config needed by the front end
config.update({
"url_base_pathname": self.config.url_base_pathname,
"requests_pathname_prefix": self.requests_pathname_external_prefix,
"ui": self._dev_tools.ui,
"props_check": self._dev_tools.props_check,
"show_undo_redo": self.config.show_undo_redo,
"suppress_callback_exceptions": self.config.suppress_callback_exceptions,
"update_title": self.config.update_title,
})
if self._dev_tools.hot_reload:
config["hot_reload"] = {
# convert from seconds to msec as used by js `setInterval`
"interval": int(self._dev_tools.hot_reload_interval * 1000),
"max_retry": self._dev_tools.hot_reload_max_retry,
}
if self.validation_layout and not self.config.suppress_callback_exceptions:
config["validation_layout"] = self.validation_layout
return config
try:
config = super()._config()
# pieces of config needed by the front end
config.update({
"requests_pathname_prefix": self.requests_pathname_external_prefix,
})
if hasattr(self, "_dev_tools"):
config.update({
"ui": getattr(self._dev_tools, "ui", True),
"props_check": getattr(self._dev_tools, "props_check", False),
})
return config
except Exception:
return self.config
+1 -1
View File
@@ -31,7 +31,7 @@ def get_marks_from_start_end(start, end):
date_f = '%x'
marks = {}
for date in result:
marks[unix_time_millis(date)] = str(date.strftime(date_f))
marks[unix_time_millis(date)] = {"label": str(date.strftime(date_f))}
return marks
return None
+5 -2
View File
@@ -101,8 +101,11 @@ config_otp_layout = dbc.Row(dbc.Col(className="col-md-12 col-lg-2 m-3", children
def log_layout():
with open(LOG_FILE, "r", encoding="utf-8") as f:
log_text = f.read()
try:
with open(LOG_FILE, "r", encoding="utf-8") as f:
log_text = f.read()
except Exception as e:
log_text = f"Can't read log file: {e}"
return html.H3(className="m-2", children=["Log:", dbc.Container(
fluid=True,
style={"height": "80vh",
+9 -7
View File
@@ -71,19 +71,18 @@ def add_header(el):
[Input('url', 'pathname'),
Input('url', 'search')])
def display_page(pathname, search):
pathname = pathname[len(dash_app.requests_pathname_external_prefix) - 1:]
prefix = dash_app.requests_pathname_external_prefix or "/"
pathname = pathname[len(prefix) - 1:]
query_params = parse_qs(urlparse(search).query)
no_header = query_params.get("header", None) == ["false"]
if pathname == "/config":
page = config_layout()
elif pathname == "/config_login":
if not APP.is_good or pathname == "/config_login":
page = config_layout("login")
elif pathname == "/config":
page = config_layout()
elif pathname == "/config_connect":
page = get_oauth_config_layout(query_params["url"][0])
elif pathname == "/log":
page = log_layout()
elif not APP.is_good:
page = dcc.Location(pathname=dash_app.requests_pathname_external_prefix + "config_login", id="config_redirect")
elif pathname == "/config_otp":
page = config_layout("otp")
elif pathname == "/control":
@@ -252,6 +251,7 @@ def serve_layout():
step=step,
marks=marks,
value=[min_millis, max_millis],
allow_direct_input=False,
)
figures.CURRENCY = APP.config.General.currency
figures.EXPORT_FORMAT = APP.config.General.export_format
@@ -281,7 +281,9 @@ def serve_layout():
data_div = html.Div([
*fig_filter.get_store(),
html.Div([
range_slider,
dbc.Row(
children=range_slider
),
dbc.Tabs([
dbc.Tab(label="Summary", tab_id="summary", children=summary_tab),
dbc.Tab(label="Trips", tab_id="trips", id="tab_trips",
+1 -1
View File
@@ -19,7 +19,7 @@ plotly = ">=5"
cryptography = ">=2.6"
Werkzeug = ">=1.0.0"
Flask = ">=1.0.4"
dash-bootstrap-components = ">=1"
dash-bootstrap-components = ">=2"
ConfigUpdater = ">=3.0"
oauth2-client = "^1.3.0"
requests = "^2.27.1"