Reimplement compose and add tiling windows
This commit is contained in:
224
core/settings_navigation.py
Normal file
224
core/settings_navigation.py
Normal file
@@ -0,0 +1,224 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
SETTINGS_NAVIGATION_TREE = (
|
||||
{
|
||||
"key": "general",
|
||||
"label": "General",
|
||||
"href_name": "notifications_settings",
|
||||
"children": (
|
||||
{
|
||||
"key": "notifications",
|
||||
"label": "Notifications",
|
||||
"href_name": "notifications_settings",
|
||||
"route_names": ("notifications_settings", "notifications_update"),
|
||||
},
|
||||
{
|
||||
"key": "system",
|
||||
"label": "System",
|
||||
"href_name": "system_settings",
|
||||
"route_names": ("system_settings",),
|
||||
},
|
||||
{
|
||||
"key": "accessibility",
|
||||
"label": "Accessibility",
|
||||
"href_name": "accessibility_settings",
|
||||
"route_names": ("accessibility_settings",),
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
"key": "security",
|
||||
"label": "Security",
|
||||
"href_name": "encryption_settings",
|
||||
"children": (
|
||||
{
|
||||
"key": "encryption",
|
||||
"label": "Encryption",
|
||||
"href_name": "encryption_settings",
|
||||
"route_names": ("security_settings", "encryption_settings"),
|
||||
},
|
||||
{
|
||||
"key": "permissions",
|
||||
"label": "Permissions",
|
||||
"href_name": "permission_settings",
|
||||
"route_names": ("permission_settings",),
|
||||
},
|
||||
{
|
||||
"key": "security_2fa",
|
||||
"label": "2FA",
|
||||
"href_name": "security_2fa",
|
||||
"route_names": (
|
||||
"security_2fa",
|
||||
"profile",
|
||||
"setup",
|
||||
"backup_tokens",
|
||||
"disable",
|
||||
"phone_create",
|
||||
"phone_delete",
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
"key": "ai",
|
||||
"label": "AI",
|
||||
"href_name": "ai_models",
|
||||
"children": (
|
||||
{
|
||||
"key": "ai_models",
|
||||
"label": "Models",
|
||||
"href_name": "ai_models",
|
||||
"route_names": (
|
||||
"ai_settings",
|
||||
"ai_models",
|
||||
"ais",
|
||||
"ai_create",
|
||||
"ai_update",
|
||||
"ai_delete",
|
||||
),
|
||||
},
|
||||
{
|
||||
"key": "ai_traces",
|
||||
"label": "Traces",
|
||||
"href_name": "ai_execution_log",
|
||||
"route_names": (
|
||||
"ai_execution_log",
|
||||
"ai_execution_run_detail",
|
||||
"ai_execution_run_detail_tab",
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
"key": "modules",
|
||||
"label": "Modules",
|
||||
"href_name": "command_routing",
|
||||
"children": (
|
||||
{
|
||||
"key": "command_routing",
|
||||
"label": "Commands",
|
||||
"href_name": "command_routing",
|
||||
"route_names": ("modules_settings", "command_routing"),
|
||||
},
|
||||
{
|
||||
"key": "business_plans",
|
||||
"label": "Business Plans",
|
||||
"href_name": "business_plan_inbox",
|
||||
"route_names": ("business_plan_inbox", "business_plan_editor"),
|
||||
},
|
||||
{
|
||||
"key": "tasks",
|
||||
"label": "Task Automation",
|
||||
"href_name": "tasks_settings",
|
||||
"route_names": ("tasks_settings",),
|
||||
},
|
||||
{
|
||||
"key": "translation",
|
||||
"label": "Translation",
|
||||
"href_name": "translation_settings",
|
||||
"route_names": ("translation_settings", "translation_preview"),
|
||||
},
|
||||
{
|
||||
"key": "behavioral",
|
||||
"label": "Behavioral Signals",
|
||||
"href_name": "behavioral_signals_settings",
|
||||
"route_names": (
|
||||
"availability_settings",
|
||||
"behavioral_signals_settings",
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def _route_names_for_node(node: dict) -> set[str]:
|
||||
route_names = {
|
||||
str(value).strip()
|
||||
for value in tuple(node.get("route_names") or ())
|
||||
if str(value).strip()
|
||||
}
|
||||
for child in tuple(node.get("children") or ()):
|
||||
route_names.update(_route_names_for_node(child))
|
||||
return route_names
|
||||
|
||||
|
||||
def _tab(label: str, href_name: str, active: bool) -> dict:
|
||||
return {
|
||||
"label": str(label or "").strip(),
|
||||
"href": reverse(href_name),
|
||||
"active": bool(active),
|
||||
}
|
||||
|
||||
|
||||
def _find_active_path(nodes, url_name: str) -> list[dict]:
|
||||
for node in tuple(nodes or ()):
|
||||
node_routes = _route_names_for_node(node)
|
||||
if url_name in node_routes:
|
||||
child_path = _find_active_path(node.get("children") or (), url_name)
|
||||
return [node, *child_path]
|
||||
return []
|
||||
|
||||
|
||||
def build_settings_navigation(url_name: str) -> dict | None:
|
||||
current_route = str(url_name or "").strip()
|
||||
if not current_route:
|
||||
return None
|
||||
|
||||
active_path = _find_active_path(SETTINGS_NAVIGATION_TREE, current_route)
|
||||
if not active_path:
|
||||
return None
|
||||
|
||||
active_group = active_path[0]
|
||||
navigation = {
|
||||
"title": str(active_group.get("label") or "Settings"),
|
||||
"groups": [
|
||||
_tab(
|
||||
group.get("label") or "",
|
||||
group.get("href_name") or "",
|
||||
bool(group.get("key")) == bool(active_group.get("key"))
|
||||
and str(group.get("key") or "") == str(active_group.get("key") or ""),
|
||||
)
|
||||
for group in SETTINGS_NAVIGATION_TREE
|
||||
],
|
||||
"tabs": [],
|
||||
"rows": [],
|
||||
}
|
||||
|
||||
nodes = tuple(active_group.get("children") or ())
|
||||
depth = 1
|
||||
while nodes:
|
||||
active_key = ""
|
||||
if depth < len(active_path):
|
||||
active_key = str(active_path[depth].get("key") or "")
|
||||
tabs = [
|
||||
_tab(
|
||||
node.get("label") or "",
|
||||
node.get("href_name") or "",
|
||||
str(node.get("key") or "") == active_key,
|
||||
)
|
||||
for node in nodes
|
||||
]
|
||||
navigation["rows"].append(
|
||||
{
|
||||
"depth": depth,
|
||||
"tabs": tabs,
|
||||
}
|
||||
)
|
||||
if depth == 1:
|
||||
navigation["tabs"] = tabs
|
||||
current = next(
|
||||
(
|
||||
node
|
||||
for node in nodes
|
||||
if str(node.get("key") or "") == active_key
|
||||
),
|
||||
None,
|
||||
)
|
||||
nodes = tuple((current or {}).get("children") or ())
|
||||
depth += 1
|
||||
|
||||
return navigation
|
||||
Reference in New Issue
Block a user