0
0
mirror of https://gitflic.ru/project/maks1ms/ocab.git synced 2025-12-23 21:49:55 +03:00
This commit is contained in:
2024-07-21 20:01:50 +03:00
parent d52864a231
commit 34c365178b
4 changed files with 102 additions and 70 deletions

View File

@@ -1,3 +1,4 @@
import time
from typing import Any, Dict, List, Optional, Union
import yaml
@@ -6,7 +7,7 @@ import yaml
try:
import dash_bootstrap_components as dbc
from dash_extensions.enrich import Input, Output, dcc, html
from dash_extensions.enrich import ALL, Input, Output, State, dcc, html
DASH_AVAILABLE = True
except ImportError:
@@ -102,9 +103,10 @@ class ConfigManager:
self.set_nested_setting(self._config, key, value)
self.save_config()
def get_settings_layout(self):
def get_settings_layout(self, prefix):
from dash_extensions.enrich import DashBlueprint
self._prefix = prefix
bp = DashBlueprint()
def create_layout():
@@ -138,22 +140,28 @@ class ConfigManager:
if not meta.get("is_private"):
row = []
label_text = meta.get("pretty_name", key)
if not label_text:
label_text = key
if meta.get("type") != "checkbox":
row.append(dbc.Label(label_text))
component_id = {
"type": "setting",
"key": "-".join(current_key_list),
"key": "::".join(current_key_list),
}
if meta.get("type") == "string":
component = dbc.Input(
id=component_id, type="text", value=value
id=component_id,
type="text",
value=value,
)
elif meta.get("type") == "number":
component = dbc.Input(
id=component_id, type="number", value=value
id=component_id,
type="number",
value=value,
)
elif meta.get("type") == "checkbox":
component = dbc.Col(
@@ -161,11 +169,7 @@ class ConfigManager:
dbc.Checkbox(
id=component_id,
value=value,
label=dbc.Label(
label_text,
style={"margin-right": "10px"},
check=True,
),
label=label_text,
)
]
)
@@ -175,7 +179,9 @@ class ConfigManager:
for opt in meta.get("options", [])
]
component = dcc.Dropdown(
id=component_id, options=options, value=value
id=component_id,
options=options,
value=value,
)
else:
continue
@@ -195,17 +201,15 @@ class ConfigManager:
[
html.H1("Настройки"),
dbc.Form(settings_components),
html.Div(id="save-confirmation"),
dbc.Button(
"Сохранить",
id="save-settings",
color="primary",
className="mt-3",
className="mt-3 w-100",
n_clicks=0,
),
html.Div(id="settings-update-trigger", style={"display": "none"}),
html.Span(
id="save-confirmation", style={"verticalAlign": "middle"}
),
dcc.Store(id="settings-store"),
],
style={
@@ -221,39 +225,76 @@ class ConfigManager:
return bp
def setup_callbacks(self, app):
# ws = WebSocket(app, url="/ws")
@app.callback(
Output("save-confirmation", "children"),
# Output("settings-store", "data"),
Output("save-confirmation", "children", allow_duplicate=True),
Output("settings-store", "data"),
Input("save-settings", "n_clicks"),
# State({"type": "setting", "key": ALL}, "value"),
# State({"type": "setting", "key": ALL}, "id"),
running=[(Output("save-settings", "disabled"), True, False)],
State({"type": "setting", "key": ALL}, "value"),
State({"type": "setting", "key": ALL}, "id"),
prevent_initial_call=True,
allow_duplicate=True,
# https://github.com/emilhe/dash-extensions/issues/344
# running=[
# (
# Output({
# id: "save-settings",
# 'n_clicks': MATCH
# }, "disabled"), True, False
# )
# ]
)
def save_settings(n_clicks, values, ids):
def save_settings(n_clicks, values, keys):
time.sleep(3)
if n_clicks > 0:
# updated_settings = {}
# print(ids)
# for value, id_dict in zip(values, ids):
# key = id_dict["key"]
# self.update_setting(key.split("-"), value)
# updated_settings[key] = value
updated_settings = {}
return "Настройки сохранены!" # , json.dumps(updated_settings)
return "" # , None
for value, id_dict in zip(values, keys):
key: str = id_dict["key"]
if self._prefix:
key = key.removeprefix(f"{self._prefix}-")
# @app.callback(
# Output({"type": "setting", "key": ALL}, "value"),
# Input("settings-store", "data"),
# )
# def update_settings_from_store(data):
# if data:
# updated_settings = json.loads(data)
# print(
# [current_value for key, current_value in updated_settings.items()]
# )
# return [
# current_value for key, current_value in updated_settings.items()
# ]
# raise dash.exceptions.PreventUpdate()
self.update_setting(key.split("::"), value)
updated_settings[key] = value
import datetime
import locale
locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8")
now = datetime.datetime.now()
date_str = now.strftime("%H:%M:%S")
return (
dbc.Alert(
f"Настройки сохранены в {date_str}",
color="success",
duration=10000,
),
date_str,
)
app.clientside_callback(
"""
function(n_clicks) {
const buttonSelector = '#%s-save-settings';
if (n_clicks > 0) {
document.querySelector(buttonSelector).disabled = true;
}
}
"""
% (self._prefix),
Input("save-settings", "n_clicks"),
)
app.clientside_callback(
"""
function(data) {
const buttonSelector = '#%s-save-settings';
if (data) {
document.querySelector(buttonSelector).disabled = false;
}
}
"""
% (self._prefix),
Input("settings-store", "data"),
)

View File

@@ -6,21 +6,11 @@ from .config import config
def register_settings_page():
try:
register_page = get_module("standard.miniapp", "register_page")
#
# def setup_callbacks_wrapper(config_manager):
# def setup(app):
# config_manager.setup_callbacks(app)
#
# return setup
#
# register_page(
# name="Настройки",
# path="/settings",
# layout=config.get_settings_layout(),
# setup_callbacks=setup_callbacks_wrapper(config),
# )
register_page(
name="Настройки", path="/settings", blueprint=config.get_settings_layout()
name="Настройки",
path="/settings",
blueprint=config.get_settings_layout("settings"),
prefix="settings",
)
pass

View File

@@ -9,10 +9,11 @@ from flask import Flask
pages = OrderedDict()
def register_page(name, path, blueprint):
def register_page(name, path, blueprint, prefix=""):
pages[path] = {
"name": name,
"blueprint": blueprint,
"prefix": prefix,
}
@@ -53,7 +54,7 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
# Register pages
for path, page in pages.items():
# dash.register_page(page["name"], path=path, layout=page["layout"])
page["blueprint"].register(app, path, prefix="a")
page["blueprint"].register(app, path, prefix=page["prefix"])
# Create sidebar
sidebar = dbc.Offcanvas(
@@ -97,7 +98,7 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
app.layout = html.Div(
[
dcc.Location(id="url", refresh=False),
dcc.Store(id="user-data", storage_type="session"),
# dcc.Store(id="user-data", storage_type="session"),
dcc.Interval(
id="init-telegram-interval",
interval=100,
@@ -154,7 +155,7 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
Input("open-offcanvas", "n_clicks"),
)
# Закрываем offcanvas при клике на ссылку в меню
# # Закрываем offcanvas при клике на ссылку в меню
app.clientside_callback(
"""
function(n_clicks) {