mirror of
https://gitflic.ru/project/maks1ms/ocab.git
synced 2025-01-11 17:28:12 +03:00
wip
This commit is contained in:
parent
d52864a231
commit
34c365178b
14
poetry.lock
generated
14
poetry.lock
generated
@ -2053,18 +2053,18 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "71.0.1"
|
||||
version = "71.0.4"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "setuptools-71.0.1-py3-none-any.whl", hash = "sha256:1eb8ef012efae7f6acbc53ec0abde4bc6746c43087fd215ee09e1df48998711f"},
|
||||
{file = "setuptools-71.0.1.tar.gz", hash = "sha256:c51d7fd29843aa18dad362d4b4ecd917022131425438251f4e3d766c964dd1ad"},
|
||||
{file = "setuptools-71.0.4-py3-none-any.whl", hash = "sha256:ed2feca703be3bdbd94e6bb17365d91c6935c6b2a8d0bb09b66a2c435ba0b1a5"},
|
||||
{file = "setuptools-71.0.4.tar.gz", hash = "sha256:48297e5d393a62b7cb2a10b8f76c63a73af933bd809c9e0d0d6352a1a0135dd8"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (<7.4)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||
|
||||
[[package]]
|
||||
@ -2230,13 +2230,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.30.1"
|
||||
version = "0.30.3"
|
||||
description = "The lightning-fast ASGI server."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"},
|
||||
{file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"},
|
||||
{file = "uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503"},
|
||||
{file = "uvicorn-0.30.3.tar.gz", hash = "sha256:0d114d0831ff1adbf231d358cbf42f17333413042552a624ea6a9b4c33dcfd81"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -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"),
|
||||
)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user