openadmin-dev 0.7.19__tar.gz → 0.7.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.gitignore +2 -1
- openadmin_dev-0.7.20/PKG-INFO +108 -0
- openadmin_dev-0.7.20/README.md +91 -0
- openadmin_dev-0.7.20/docs/assets/dashboard-screenshot.png +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/introduction/getting-started.md +2 -2
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/authors.py +1 -5
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/books.py +15 -12
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/control_panel.py +17 -28
- openadmin_dev-0.7.20/examples/admin/form_test.py +73 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/health.py +4 -1
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/overview.py +1 -1
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/publishers.py +1 -4
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/tags.py +7 -6
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/weekdays.py +1 -4
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/main.py +4 -1
- openadmin_dev-0.7.20/openadmin/__client__/assets/CardTitle-g-eR1YB7.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/Dashboard-CH62YEWP.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/DialogPortal-sTp649jA.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/FormView-DPqNEejF.js +193 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/LoginView-3isjvo_Q.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/PageView-Dq8SJOqN.js +67 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/SelectValue-WzbxPrgA.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/error-C_Ap5sRv.js +66 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/field-BSJU6_no.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/index-B5AJQb5X.css +2 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/index-BOBko9Fy.js +2 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/openadmin-form-Dp1fg3ME.js +3 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/openadmin-spec-DMXwLYN0.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/theme-CEh0Zsbj.js +1 -0
- openadmin_dev-0.7.20/openadmin/__client__/assets/useForm-DH6J4tEc.js +1 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/index.html +4 -6
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/admin_page.py +3 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/__init__.py +2 -1
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/action.py +0 -4
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/form.py +3 -4
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/page.py +2 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/pyproject.toml +1 -1
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/uv.lock +1 -1
- openadmin_dev-0.7.19/PKG-INFO +0 -333
- openadmin_dev-0.7.19/README.md +0 -316
- openadmin_dev-0.7.19/openadmin/__client__/assets/CardTitle-_-VQGAs4.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/Dashboard-Cbu4jQ6o.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/LoginView-DftiEGqx.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/PageView-3k326RhX.js +0 -67
- openadmin_dev-0.7.19/openadmin/__client__/assets/button-BahsXozd.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/error-BjWDzPTy.js +0 -66
- openadmin_dev-0.7.19/openadmin/__client__/assets/index-B6cWCMDE.js +0 -2
- openadmin_dev-0.7.19/openadmin/__client__/assets/index-DHDnMjXv.css +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/lib-DCDnSbDN.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/openadmin-page-BBinRZu9.js +0 -3
- openadmin_dev-0.7.19/openadmin/__client__/assets/openadmin-spec-B5RYk8O-.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/theme-BbaAAQ0K.js +0 -1
- openadmin_dev-0.7.19/openadmin/__client__/assets/vue-router-CAoMHVFh.js +0 -1
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.claude/launch.json +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/ISSUE_TEMPLATE/bug.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/ISSUE_TEMPLATE/chore.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/ISSUE_TEMPLATE/feature.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/branch-name/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/dependency-cves/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/format/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/license/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/lint/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/security/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/spell-check/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/test/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/typecheck/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/actions/unused-code/action.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/workflows/ci.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/workflows/docs.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.github/workflows/publish.yml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/.python-version +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/LICENSE +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/LICENSES/AGPL-3.0-or-later.txt +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/Makefile +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/REUSE.toml +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/.gitignore +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/assets/logo.png +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/bun.lock +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/config/.vitepress/config.mts +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/config/.vitepress/theme/index.ts +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/config/.vitepress/theme/style.css +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/auth/index.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/action.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/area-chart.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/bar-chart.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/form.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/index.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/line-chart.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/markdown.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/pie-chart.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/stat.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/components/table.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/cookbook/implementing-auth.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/cookbook/implementing-form-with-reference.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/cookbook/implementing-table.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/index.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/content/introduction/what-is-openadmin.md +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/docs/package.json +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/__init__.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/__init__.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/analytics.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/auth.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/docs.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/genres.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/admin/reports.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/lib/__init__.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/lib/database.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/lib/lifespan.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/lib/models.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/examples/lib/seed.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/HomeView-BY92UWl4.js +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-cyrillic-400-normal-DXusLSnH.woff2 +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-cyrillic-400-normal-DkrqoNl2.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-cyrillic-ext-400-normal-ChfpGzr5.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-latin-400-normal-B40WzpMT.woff2 +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-latin-400-normal-akEymXtG.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-latin-ext-400-normal-Bz1pQMyt.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-latin-ext-400-normal-CND6cjiG.woff2 +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-cyrillic-400-normal-C51Di1Mf.woff2 +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-cyrillic-400-normal-CPJFfJgk.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-latin-400-normal-B2yvC1Cq.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-latin-400-normal-DTRLJnHl.woff2 +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-latin-ext-400-normal-CfzLURNc.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-latin-ext-400-normal-DI-rJ0UV.woff2 +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-symbols2-400-normal-DjbiTEEA.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-mono-vietnamese-400-normal-CZEPLOgu.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/geist-vietnamese-400-normal-C8xY9-dI.woff +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/logo-D9vyMJZl.png +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/rolldown-runtime-DK3Fl9T5.js +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/assets/runtime-core.esm-bundler-B4b-2GOK.js +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/favicon.svg +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/__client__/icons.svg +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/__init__.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/admin_auth.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/admin_panel.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/counter.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/deps.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/exc_handler.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/refs.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/req.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/fastapi/utils.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/area_chart.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/bar_chart.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/colors.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/component.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/error.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/http_methods.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/icons.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/json_schema.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/line_chart.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/markdown.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/pie_chart.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/section.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/spec.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/stat.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/openadmin/spec/table.py +0 -0
- {openadmin_dev-0.7.19 → openadmin_dev-0.7.20}/tests/test_hello.py +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: openadmin-dev
|
|
3
|
+
Version: 0.7.20
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Project-URL: Homepage, https://github.com/openadmin-team/openadmin-py
|
|
6
|
+
Project-URL: Issues, https://github.com/openadmin-team/openadmin-py/issues
|
|
7
|
+
Author-email: Mykyta Kasianenko <mykytakasianenko@gmail.com>
|
|
8
|
+
License-Expression: AGPL-3.0-or-later
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.14
|
|
13
|
+
Requires-Dist: fastapi[standard]>=0.136.3
|
|
14
|
+
Requires-Dist: itsdangerous>=2.2.0
|
|
15
|
+
Requires-Dist: typing-extensions>=4.12.0
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
<img src="docs/assets/logo.png" alt="OpenAdmin" width="120" />
|
|
20
|
+
|
|
21
|
+
<h1>OpenAdmin</h1>
|
|
22
|
+
|
|
23
|
+
<p>Admin dashboards as FastAPI routes. No templates, no frontend project, no config files.</p>
|
|
24
|
+
|
|
25
|
+
<a href="https://pypi.org/project/openadmin/"><img src="https://img.shields.io/pypi/v/openadmin?style=flat-square&label=pypi&color=blue" alt="PyPI" /></a>
|
|
26
|
+
<a href="https://python.org"><img src="https://img.shields.io/badge/python-3.14%2B-blue?style=flat-square" alt="Python" /></a>
|
|
27
|
+
<a href="https://fastapi.tiangolo.com"><img src="https://img.shields.io/badge/built%20on-FastAPI-009688?style=flat-square" alt="FastAPI" /></a>
|
|
28
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0--or--later-green?style=flat-square" alt="License" /></a>
|
|
29
|
+
|
|
30
|
+
<p><a href="https://openadmin-team.github.io/openadmin-py/">Documentation</a></p>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<img src="docs/assets/dashboard-screenshot.png" alt="OpenAdmin dashboard" width="100%" />
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
OpenAdmin is a FastAPI-native library for building admin panels. A page is a router, a widget is an endpoint — stats, tables, forms, actions, and charts, defined with typed decorators in plain Python.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from openadmin import spec
|
|
41
|
+
from openadmin.fastapi import AdminPage, AdminPanel
|
|
42
|
+
|
|
43
|
+
page = AdminPage("Dashboard", icon="layout-dashboard")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@page.stat("Total Users")
|
|
47
|
+
async def total_users() -> spec.Stat:
|
|
48
|
+
return 1_024
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@page.table("Recent Users")
|
|
52
|
+
async def recent_users() -> spec.Table:
|
|
53
|
+
return {
|
|
54
|
+
"data": [
|
|
55
|
+
{"id": 1, "name": "Alice", "role": "admin"},
|
|
56
|
+
{"id": 2, "name": "Bob", "role": "viewer"},
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
admin = AdminPanel("My Admin")
|
|
62
|
+
admin.section("General", pages=[page])
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from fastapi import FastAPI
|
|
67
|
+
|
|
68
|
+
app = FastAPI()
|
|
69
|
+
app.mount("/admin", admin.app)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Each decorated function is a normal FastAPI handler — dependency injection, `Query`/`Body` parameters, and OpenAPI docs all work as they would on any route.
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install openadmin
|
|
78
|
+
# or
|
|
79
|
+
uv add openadmin
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Documentation
|
|
83
|
+
|
|
84
|
+
Everything else — the full component reference, authentication, and worked cookbook recipes — lives at:
|
|
85
|
+
|
|
86
|
+
**[openadmin-team.github.io/openadmin-py](https://openadmin-team.github.io/openadmin-py/)**
|
|
87
|
+
|
|
88
|
+
- [Getting Started](https://openadmin-team.github.io/openadmin-py/introduction/getting-started) — build a minimal panel end to end
|
|
89
|
+
- [Components](https://openadmin-team.github.io/openadmin-py/components/) — stats, tables, forms, actions, and charts
|
|
90
|
+
- [Authentication](https://openadmin-team.github.io/openadmin-py/auth/) — gate the panel behind a login screen
|
|
91
|
+
- [Cookbook](https://openadmin-team.github.io/openadmin-py/cookbook/implementing-auth) — recipes for row actions, reference fields, and auth
|
|
92
|
+
|
|
93
|
+
## Development
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Run the example app
|
|
97
|
+
make dev/example
|
|
98
|
+
|
|
99
|
+
# Run all checks (format, lint, types, tests, security)
|
|
100
|
+
make check
|
|
101
|
+
|
|
102
|
+
# Auto-fix formatting and lint issues
|
|
103
|
+
make fix
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
[AGPL-3.0-or-later](LICENSE) — © 2026 OpenAdmin
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="docs/assets/logo.png" alt="OpenAdmin" width="120" />
|
|
3
|
+
|
|
4
|
+
<h1>OpenAdmin</h1>
|
|
5
|
+
|
|
6
|
+
<p>Admin dashboards as FastAPI routes. No templates, no frontend project, no config files.</p>
|
|
7
|
+
|
|
8
|
+
<a href="https://pypi.org/project/openadmin/"><img src="https://img.shields.io/pypi/v/openadmin?style=flat-square&label=pypi&color=blue" alt="PyPI" /></a>
|
|
9
|
+
<a href="https://python.org"><img src="https://img.shields.io/badge/python-3.14%2B-blue?style=flat-square" alt="Python" /></a>
|
|
10
|
+
<a href="https://fastapi.tiangolo.com"><img src="https://img.shields.io/badge/built%20on-FastAPI-009688?style=flat-square" alt="FastAPI" /></a>
|
|
11
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0--or--later-green?style=flat-square" alt="License" /></a>
|
|
12
|
+
|
|
13
|
+
<p><a href="https://openadmin-team.github.io/openadmin-py/">Documentation</a></p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<img src="docs/assets/dashboard-screenshot.png" alt="OpenAdmin dashboard" width="100%" />
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
OpenAdmin is a FastAPI-native library for building admin panels. A page is a router, a widget is an endpoint — stats, tables, forms, actions, and charts, defined with typed decorators in plain Python.
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from openadmin import spec
|
|
24
|
+
from openadmin.fastapi import AdminPage, AdminPanel
|
|
25
|
+
|
|
26
|
+
page = AdminPage("Dashboard", icon="layout-dashboard")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@page.stat("Total Users")
|
|
30
|
+
async def total_users() -> spec.Stat:
|
|
31
|
+
return 1_024
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@page.table("Recent Users")
|
|
35
|
+
async def recent_users() -> spec.Table:
|
|
36
|
+
return {
|
|
37
|
+
"data": [
|
|
38
|
+
{"id": 1, "name": "Alice", "role": "admin"},
|
|
39
|
+
{"id": 2, "name": "Bob", "role": "viewer"},
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
admin = AdminPanel("My Admin")
|
|
45
|
+
admin.section("General", pages=[page])
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from fastapi import FastAPI
|
|
50
|
+
|
|
51
|
+
app = FastAPI()
|
|
52
|
+
app.mount("/admin", admin.app)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Each decorated function is a normal FastAPI handler — dependency injection, `Query`/`Body` parameters, and OpenAPI docs all work as they would on any route.
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install openadmin
|
|
61
|
+
# or
|
|
62
|
+
uv add openadmin
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Documentation
|
|
66
|
+
|
|
67
|
+
Everything else — the full component reference, authentication, and worked cookbook recipes — lives at:
|
|
68
|
+
|
|
69
|
+
**[openadmin-team.github.io/openadmin-py](https://openadmin-team.github.io/openadmin-py/)**
|
|
70
|
+
|
|
71
|
+
- [Getting Started](https://openadmin-team.github.io/openadmin-py/introduction/getting-started) — build a minimal panel end to end
|
|
72
|
+
- [Components](https://openadmin-team.github.io/openadmin-py/components/) — stats, tables, forms, actions, and charts
|
|
73
|
+
- [Authentication](https://openadmin-team.github.io/openadmin-py/auth/) — gate the panel behind a login screen
|
|
74
|
+
- [Cookbook](https://openadmin-team.github.io/openadmin-py/cookbook/implementing-auth) — recipes for row actions, reference fields, and auth
|
|
75
|
+
|
|
76
|
+
## Development
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Run the example app
|
|
80
|
+
make dev/example
|
|
81
|
+
|
|
82
|
+
# Run all checks (format, lint, types, tests, security)
|
|
83
|
+
make check
|
|
84
|
+
|
|
85
|
+
# Auto-fix formatting and lint issues
|
|
86
|
+
make fix
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
[AGPL-3.0-or-later](LICENSE) — © 2026 OpenAdmin
|
|
Binary file
|
|
@@ -10,13 +10,13 @@ This walks through building a minimal admin panel from scratch: one page, one st
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
pip install openadmin
|
|
13
|
+
pip install openadmin
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
or with `uv`:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
uv add openadmin
|
|
19
|
+
uv add openadmin
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## Build a page
|
|
@@ -160,7 +160,6 @@ class AddAuthorBody(BaseModel):
|
|
|
160
160
|
first_name: str
|
|
161
161
|
last_name: str
|
|
162
162
|
bio: str | None = None
|
|
163
|
-
friend: int
|
|
164
163
|
|
|
165
164
|
|
|
166
165
|
@page.form(
|
|
@@ -181,7 +180,4 @@ async def add_author(body: AddAuthorBody, session: AsyncSessionDep) -> spec.Form
|
|
|
181
180
|
await session.commit()
|
|
182
181
|
await session.refresh(author)
|
|
183
182
|
name = f"{author.first_name} {author.last_name}"
|
|
184
|
-
return {
|
|
185
|
-
"message": f"Added author '{name}'",
|
|
186
|
-
"table": {"id": author.id, "name": name},
|
|
187
|
-
}
|
|
183
|
+
return {"toast": f"Added author '{name}'"}
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
import asyncio
|
|
6
6
|
from urllib.parse import quote
|
|
7
7
|
|
|
8
|
-
from fastapi import Query
|
|
8
|
+
from fastapi import Query, UploadFile
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
from sqlalchemy import func, select
|
|
11
11
|
|
|
12
12
|
from openadmin import spec
|
|
13
|
-
from openadmin.fastapi import AdminPage
|
|
13
|
+
from openadmin.fastapi import AdminPage, reference_action
|
|
14
14
|
from openadmin.fastapi.deps import PageDep, SearchDep
|
|
15
15
|
|
|
16
16
|
from ..lib import models
|
|
@@ -44,6 +44,14 @@ async def get_books_without_publisher(session: AsyncSessionDep) -> int:
|
|
|
44
44
|
BOOK_COVER_URL = "https://img.magnific.com/free-photo/beautiful-tropical-beach-sea-ocean-with-white-cloud-blue-sky-copyspace_74190-8663.jpg?semt=ais_hybrid&w=740&q=80"
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
@page.action(
|
|
48
|
+
"Upload cover",
|
|
49
|
+
is_hidden=True,
|
|
50
|
+
)
|
|
51
|
+
async def upload_cover(id: int, cover: UploadFile) -> spec.Action:
|
|
52
|
+
return f"File uploaded {cover.filename} {id=}"
|
|
53
|
+
|
|
54
|
+
|
|
47
55
|
@page.table(
|
|
48
56
|
"All Books",
|
|
49
57
|
description="Browse all books with search and pagination",
|
|
@@ -112,6 +120,9 @@ async def get_all_books(
|
|
|
112
120
|
"reference": {"label": "Link to the book"},
|
|
113
121
|
"attachment": {"label": "Book in pdf"},
|
|
114
122
|
},
|
|
123
|
+
"__actions__": [
|
|
124
|
+
{"action": reference_action(upload_cover), "form": {"id": book.id}}
|
|
125
|
+
],
|
|
115
126
|
}
|
|
116
127
|
for book, author in result.all()
|
|
117
128
|
],
|
|
@@ -161,10 +172,7 @@ async def add_book(body: AddBookBody, session: AsyncSessionDep) -> spec.Form:
|
|
|
161
172
|
session.add(book)
|
|
162
173
|
await session.commit()
|
|
163
174
|
await session.refresh(book)
|
|
164
|
-
return {
|
|
165
|
-
"message": f"Added book '{book.title}'",
|
|
166
|
-
"table": {"id": book.id, "title": book.title},
|
|
167
|
-
}
|
|
175
|
+
return {"toast": f"Added book '{book.title}'"}
|
|
168
176
|
|
|
169
177
|
|
|
170
178
|
@page.action("Delete Book", method="delete", description="Remove a book by ID")
|
|
@@ -177,9 +185,4 @@ async def delete_book(
|
|
|
177
185
|
await session.delete(book)
|
|
178
186
|
await session.commit()
|
|
179
187
|
found = book is not None
|
|
180
|
-
return {
|
|
181
|
-
"message": f"Deleted book #{book_id}"
|
|
182
|
-
if found
|
|
183
|
-
else f"Book #{book_id} not found",
|
|
184
|
-
"table": {"deleted": book_id, "found": found},
|
|
185
|
-
}
|
|
188
|
+
return f"Deleted book #{book_id}" if found else f"Book #{book_id} not found"
|
|
@@ -48,10 +48,8 @@ async def ping_service(
|
|
|
48
48
|
target: str = Query("api", description="Service name to ping"),
|
|
49
49
|
) -> spec.Action:
|
|
50
50
|
return {
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"toast": f"{target} responded in 12ms",
|
|
54
|
-
"message": f"Pinged '{target}' — reachable (example response, nothing was contacted)",
|
|
51
|
+
"toast": f"Pinged '{target}' — reachable in 12ms "
|
|
52
|
+
"(example response, nothing was contacted)"
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
|
|
@@ -93,11 +91,7 @@ async def update_feature_flag(
|
|
|
93
91
|
flag_name: str = Query(..., description="Flag key, e.g. new-dashboard"),
|
|
94
92
|
enabled: bool = Query(..., description="New flag state"),
|
|
95
93
|
) -> spec.Action:
|
|
96
|
-
return {
|
|
97
|
-
"toast": f"{flag_name} -> {enabled}",
|
|
98
|
-
"message": "Preview of the change below (example data, flag was not modified)",
|
|
99
|
-
"table": [{"flag": flag_name, "previous": not enabled, "new": enabled}],
|
|
100
|
-
}
|
|
94
|
+
return {"toast": f"{flag_name} -> {enabled} (example only, flag was not modified)"}
|
|
101
95
|
|
|
102
96
|
|
|
103
97
|
@page.action(
|
|
@@ -124,12 +118,10 @@ async def rotate_api_key(
|
|
|
124
118
|
async def purge_temp_files(
|
|
125
119
|
older_than_days: int = Query(7, ge=0, description="Age threshold in days"),
|
|
126
120
|
) -> spec.Action:
|
|
127
|
-
return
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
)
|
|
132
|
-
}
|
|
121
|
+
return (
|
|
122
|
+
f"Would delete files older than {older_than_days} days "
|
|
123
|
+
"(example — nothing was purged)"
|
|
124
|
+
)
|
|
133
125
|
|
|
134
126
|
|
|
135
127
|
# ---------------------------------------------------------------------------
|
|
@@ -447,17 +439,7 @@ class WebhookBody(BaseModel):
|
|
|
447
439
|
color="teal",
|
|
448
440
|
)
|
|
449
441
|
async def create_webhook(body: WebhookBody) -> spec.Form:
|
|
450
|
-
return {
|
|
451
|
-
"icon": "webhook",
|
|
452
|
-
"color": "teal",
|
|
453
|
-
"toast": "Webhook created",
|
|
454
|
-
"message": f"Would create a webhook for '{body.event}' -> {body.url}",
|
|
455
|
-
"table": {
|
|
456
|
-
"data": [{"id": 1, "url": body.url, "event": body.event}],
|
|
457
|
-
"icon": "webhook",
|
|
458
|
-
"color": "teal",
|
|
459
|
-
},
|
|
460
|
-
}
|
|
442
|
+
return {"toast": f"Would create a webhook for '{body.event}' -> {body.url}"}
|
|
461
443
|
|
|
462
444
|
|
|
463
445
|
class RateLimitBody(BaseModel):
|
|
@@ -475,8 +457,6 @@ class RateLimitBody(BaseModel):
|
|
|
475
457
|
)
|
|
476
458
|
async def update_rate_limit(body: RateLimitBody) -> spec.Form:
|
|
477
459
|
return {
|
|
478
|
-
"icon": "gauge",
|
|
479
|
-
"color": "cyan",
|
|
480
460
|
"toast": f"Rate limit set to {body.requests_per_minute}/min "
|
|
481
461
|
f"(burst {body.burst_size}) — example only, nothing was saved",
|
|
482
462
|
}
|
|
@@ -509,6 +489,15 @@ async def rename_environment(
|
|
|
509
489
|
)
|
|
510
490
|
async def schedule_config_reset(
|
|
511
491
|
config_id: int = Query(..., description="Config entry to reset"),
|
|
492
|
+
environment: str = Query("production", description="Environment to target"),
|
|
493
|
+
reason: str = Query(..., description="Why the reset is needed"),
|
|
494
|
+
scheduled_by: str = Query(..., description="Who is requesting the reset"),
|
|
495
|
+
maintenance_window: str = Query(
|
|
496
|
+
..., description="Maintenance window label, e.g. Sat 02:00 UTC"
|
|
497
|
+
),
|
|
498
|
+
notify_owner: bool = Query(True, description="Notify the config owner beforehand"),
|
|
499
|
+
dry_run: bool = Query(False, description="Preview the reset without scheduling it"),
|
|
500
|
+
retry_count: int = Query(0, description="Number of retries if the reset fails"),
|
|
512
501
|
) -> spec.Form:
|
|
513
502
|
return None
|
|
514
503
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 OpenAdmin
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
from datetime import date, datetime
|
|
6
|
+
from enum import Enum, StrEnum
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
from fastapi import UploadFile
|
|
10
|
+
|
|
11
|
+
from openadmin import spec
|
|
12
|
+
from openadmin.fastapi import AdminPage
|
|
13
|
+
|
|
14
|
+
page = AdminPage("Test forms", icon="test-tube")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Methods(Enum):
|
|
18
|
+
GET = "GET"
|
|
19
|
+
POST = "POST"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MethodsStr(StrEnum):
|
|
23
|
+
GET = "GET"
|
|
24
|
+
POST = "POST"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@page.form(
|
|
28
|
+
"Test all fields",
|
|
29
|
+
method="post",
|
|
30
|
+
icon="university",
|
|
31
|
+
color="green",
|
|
32
|
+
fields={
|
|
33
|
+
"string": {"icon": "type", "color": "blue"},
|
|
34
|
+
"int": {"icon": "hash", "color": "indigo"},
|
|
35
|
+
"float": {"icon": "binary", "color": "violet"},
|
|
36
|
+
"date": {"icon": "calendar-days", "color": "purple"},
|
|
37
|
+
"dates": {"icon": "calendar", "color": "fuchsia"},
|
|
38
|
+
"bool": {"icon": "toggle-left", "color": "pink"},
|
|
39
|
+
"list_of_strings": {"icon": "list", "color": "rose"},
|
|
40
|
+
"list_of_ints": {"icon": "list-ordered", "color": "red"},
|
|
41
|
+
"file": {"icon": "file-up", "color": "orange"},
|
|
42
|
+
"files": {"icon": "files", "color": "amber"},
|
|
43
|
+
"rich_text": {"icon": "pilcrow", "color": "yellow", "style": "rich-text"},
|
|
44
|
+
"literals": {"icon": "list-filter", "color": "lime"},
|
|
45
|
+
"enum": {"icon": "tag", "color": "green"},
|
|
46
|
+
"str_enum": {"icon": "tags", "color": "emerald"},
|
|
47
|
+
"list_literals": {"icon": "list-checks", "color": "teal"},
|
|
48
|
+
"list_enum": {"icon": "layers", "color": "cyan"},
|
|
49
|
+
"list_str_enum": {"icon": "list-tree", "color": "sky"},
|
|
50
|
+
},
|
|
51
|
+
)
|
|
52
|
+
def get_info(
|
|
53
|
+
string: str,
|
|
54
|
+
int: int,
|
|
55
|
+
float: float,
|
|
56
|
+
date: list[datetime],
|
|
57
|
+
dates: list[date],
|
|
58
|
+
bool: bool,
|
|
59
|
+
list_of_strings: list[str],
|
|
60
|
+
list_of_ints: list[int],
|
|
61
|
+
file: UploadFile,
|
|
62
|
+
files: list[UploadFile],
|
|
63
|
+
rich_text: str,
|
|
64
|
+
literals: Literal["get", "post"],
|
|
65
|
+
enum: Methods,
|
|
66
|
+
str_enum: MethodsStr,
|
|
67
|
+
list_literals: list[Literal["get", "post"]],
|
|
68
|
+
list_enum: list[Methods],
|
|
69
|
+
list_str_enum: list[MethodsStr],
|
|
70
|
+
) -> spec.Form:
|
|
71
|
+
return {
|
|
72
|
+
"toast": f"All good ! {rich_text=} {list_literals=} {list_str_enum=} {list_enum=} {enum=} {literals=} {str_enum} {string=} {int=} {float=} {date=} {dates=} {bool=} {list_of_ints=} {list_of_strings=} {file.filename=} {len(files)=}"
|
|
73
|
+
}
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
from openadmin.fastapi import AdminPage
|
|
6
6
|
|
|
7
7
|
page = AdminPage(
|
|
8
|
-
"Health",
|
|
8
|
+
"Health",
|
|
9
|
+
icon="heart-pulse",
|
|
10
|
+
description="System health and infrastructure metrics",
|
|
11
|
+
color="blue",
|
|
9
12
|
)
|
|
10
13
|
|
|
11
14
|
|
|
@@ -86,7 +86,7 @@ Foreign keys are enforced at the application layer.
|
|
|
86
86
|
)
|
|
87
87
|
async def ping_database(session: AsyncSessionDep) -> spec.Action:
|
|
88
88
|
await session.execute(text("SELECT 1"))
|
|
89
|
-
return {"
|
|
89
|
+
return {"toast": "Database is reachable"}
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
async def _all_table_counts(session: AsyncSessionDep) -> list[tuple[str, int]]:
|
|
@@ -99,7 +99,4 @@ async def add_publisher(body: AddPublisherBody, session: AsyncSessionDep) -> spe
|
|
|
99
99
|
session.add(publisher)
|
|
100
100
|
await session.commit()
|
|
101
101
|
await session.refresh(publisher)
|
|
102
|
-
return {
|
|
103
|
-
"message": f"Added publisher '{publisher.name}'",
|
|
104
|
-
"table": {"id": publisher.id, "name": publisher.name},
|
|
105
|
-
}
|
|
102
|
+
return {"toast": f"Added publisher '{publisher.name}'"}
|
|
@@ -12,7 +12,9 @@ from openadmin.fastapi.deps import PageDep
|
|
|
12
12
|
from ..lib import models
|
|
13
13
|
from ..lib.database import AsyncSessionDep
|
|
14
14
|
|
|
15
|
-
page = AdminPage(
|
|
15
|
+
page = AdminPage(
|
|
16
|
+
"Tags", icon="tag", description="Manage and analyze book tags", color="red"
|
|
17
|
+
)
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
@page.stat("Total Tags")
|
|
@@ -97,9 +99,8 @@ async def remove_tag_from_book(
|
|
|
97
99
|
await session.delete(link)
|
|
98
100
|
await session.commit()
|
|
99
101
|
removed = link is not None
|
|
100
|
-
return
|
|
101
|
-
|
|
102
|
+
return (
|
|
103
|
+
f"Removed tag #{tag_id} from book #{book_id}"
|
|
102
104
|
if removed
|
|
103
|
-
else f"No such tag assignment (book #{book_id}, tag #{tag_id})"
|
|
104
|
-
|
|
105
|
-
}
|
|
105
|
+
else f"No such tag assignment (book #{book_id}, tag #{tag_id})"
|
|
106
|
+
)
|
|
@@ -15,10 +15,7 @@ WEEKDAYS: list[dict[str, Any]] = [
|
|
|
15
15
|
{"day": "Friday", "books": 10, "coffe": 9},
|
|
16
16
|
]
|
|
17
17
|
|
|
18
|
-
page = fastapi.AdminPage(
|
|
19
|
-
"Week Days",
|
|
20
|
-
icon="calendar",
|
|
21
|
-
)
|
|
18
|
+
page = fastapi.AdminPage("Week Days", icon="calendar", color="green")
|
|
22
19
|
|
|
23
20
|
|
|
24
21
|
@page.pie_chart(
|
|
@@ -15,6 +15,7 @@ from .admin import (
|
|
|
15
15
|
books,
|
|
16
16
|
control_panel,
|
|
17
17
|
docs,
|
|
18
|
+
form_test,
|
|
18
19
|
genres,
|
|
19
20
|
health,
|
|
20
21
|
overview,
|
|
@@ -62,6 +63,8 @@ admin_panel.section(
|
|
|
62
63
|
icon="server",
|
|
63
64
|
pages=[health.page, reports.page, overview.page, control_panel.page],
|
|
64
65
|
)
|
|
65
|
-
admin_panel.section(
|
|
66
|
+
admin_panel.section(
|
|
67
|
+
"Weekdays", icon="calendar-days", pages=[weekdays.page, form_test.page]
|
|
68
|
+
)
|
|
66
69
|
|
|
67
70
|
app.mount("/admin", admin_panel.app, name="admin_panel")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{On as e,Zn as t,b as n,k as r,mt as i,xt as a}from"./runtime-core.esm-bundler-B4b-2GOK.js";import{Wc as o}from"./error-C_Ap5sRv.js";var s=r({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card`,class:t(e(o)(`bg-card text-card-foreground flex flex-col gap-6 rounded-lg border py-6`,s.class))},[a(r.$slots,`default`)],2))}}),c=r({__name:`CardDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`p`,{"data-slot":`card-description`,class:t(e(o)(`text-muted-foreground text-sm`,s.class))},[a(r.$slots,`default`)],2))}}),l=r({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-header`,class:t(e(o)(`@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6`,s.class))},[a(r.$slots,`default`)],2))}}),u=r({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`h3`,{"data-slot":`card-title`,class:t(e(o)(`leading-none font-semibold`,s.class))},[a(r.$slots,`default`)],2))}});export{s as i,l as n,c as r,u as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{$n as e,D as t,E as n,Ht as r,On as i,St as a,Tn as o,Ut as s,Zn as c,_ as l,b as u,bt as d,ct as f,er as p,et as m,g as h,jt as ee,k as g,mt as _,o as v,qt as y,tr as b,v as x,vn as S,wt as C,xt as w,y as T,z as E}from"./runtime-core.esm-bundler-B4b-2GOK.js";import{Hc as te,Vc as D,Wc as O,eu as ne}from"./error-C_Ap5sRv.js";import{A as re,D as ie,E as k,N as ae,b as oe,g as se,i as A,j,l as ce,m as M,o as N,r as P,y as F}from"./useForm-DH6J4tEc.js";import{c as le,l as I,t as ue}from"./openadmin-spec-DMXwLYN0.js";import{E as de,N as fe,O as L,R,T as pe,a as z,c as me,d as he,f as ge,i as B,k as _e,l as ve,n as ye,r as be,s as xe,t as Se,u as Ce,w as we,z as Te}from"./openadmin-form-Dp1fg3ME.js";import{t as Ee}from"./index-BOBko9Fy.js";import{a as De,i as Oe,n as ke,o as V,r as Ae,t as je}from"./DialogPortal-sTp649jA.js";import{i as Me,n as Ne,t as H}from"./theme-CEh0Zsbj.js";var Pe=I(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),Fe=I(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),Ie=I(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]);function Le(e,t){let n=ie(!1,300);re(()=>{n.value=!1});let r=S(null),i=oe();function a(){r.value=null,n.value=!1}function o(e,t){if(!t)return;let i=e.currentTarget,a={x:e.clientX,y:e.clientY},o=ze(a,Re(a,i.getBoundingClientRect()),1),s=Be(t.getBoundingClientRect()),c=He([...o,...s]);r.value=c,n.value=!0}return s(n=>{if(e.value&&t.value){let r=e=>o(e,t.value),i=t=>o(t,e.value);e.value.addEventListener(`pointerleave`,r),t.value.addEventListener(`pointerleave`,i),n(()=>{e.value?.removeEventListener(`pointerleave`,r),t.value?.removeEventListener(`pointerleave`,i)})}}),s(n=>{if(r.value){let o=n=>{if(!r.value||!(n.target instanceof Element))return;let o=n.target,s={x:n.clientX,y:n.clientY},c=e.value?.contains(o)||t.value?.contains(o),l=!Ve(s,r.value),u=!!o.closest(`[data-grace-area-trigger]`);c?a():(l||u)&&(a(),i.trigger())};e.value?.ownerDocument.addEventListener(`pointermove`,o),n(()=>e.value?.ownerDocument.removeEventListener(`pointermove`,o))}}),{isPointerInTransit:n,onPointerExit:i.on}}function Re(e,t){let n=Math.abs(t.top-e.y),r=Math.abs(t.bottom-e.y),i=Math.abs(t.right-e.x),a=Math.abs(t.left-e.x);switch(Math.min(n,r,i,a)){case a:return`left`;case i:return`right`;case n:return`top`;case r:return`bottom`;default:throw Error(`unreachable`)}}function ze(e,t,n=5){let r=[];switch(t){case`top`:r.push({x:e.x-n,y:e.y+n},{x:e.x+n,y:e.y+n});break;case`bottom`:r.push({x:e.x-n,y:e.y-n},{x:e.x+n,y:e.y-n});break;case`left`:r.push({x:e.x+n,y:e.y-n},{x:e.x+n,y:e.y+n});break;case`right`:r.push({x:e.x-n,y:e.y-n},{x:e.x-n,y:e.y+n})}return r}function Be(e){let{top:t,right:n,bottom:r,left:i}=e;return[{x:i,y:t},{x:n,y:t},{x:n,y:r},{x:i,y:r}]}function Ve(e,t){let{x:n,y:r}=e,i=!1;for(let e=0,a=t.length-1;e<t.length;a=e++){let o=t[e].x,s=t[e].y,c=t[a].x,l=t[a].y;s>r!=l>r&&n<(c-o)*(r-s)/(l-s)+o&&(i=!i)}return i}function He(e){let t=e.slice();return t.sort((e,t)=>e.x<t.x?-1:e.x>t.x?1:e.y<t.y?-1:+(e.y>t.y)),Ue(t)}function Ue(e){if(e.length<=1)return e.slice();let t=[];for(let n=0;n<e.length;n++){let r=e[n];for(;t.length>=2;){let e=t.at(-1),n=t[t.length-2];if((e.x-n.x)*(r.y-n.y)>=(e.y-n.y)*(r.x-n.x))t.pop();else break}t.push(r)}t.pop();let n=[];for(let t=e.length-1;t>=0;t--){let r=e[t];for(;n.length>=2;){let e=n.at(-1),t=n[n.length-2];if((e.x-t.x)*(r.y-t.y)>=(e.y-t.y)*(r.x-t.x))n.pop();else break}n.push(r)}return n.pop(),t.length===1&&n.length===1&&t[0].x===n[0].x&&t[0].y===n[0].y?t:t.concat(n)}var We=g({__name:`DialogDescription`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`p`}},setup(e){let t=e;N();let n=V();return(e,r)=>(_(),x(i(A),m(t,{id:i(n).descriptionId}),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`id`]))}}),Ge=g({__name:`DialogTitle`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`h2`}},setup(e){let t=e,n=V();return N(),(e,r)=>(_(),x(i(A),m(t,{id:i(n).titleId}),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`id`]))}}),Ke={key:0,d:`M0 0L6 6L12 0`},qe={key:1,d:`M0 0L4.58579 4.58579C5.36683 5.36683 6.63316 5.36684 7.41421 4.58579L12 0`},Je=g({__name:`Arrow`,props:{width:{type:Number,required:!1,default:10},height:{type:Number,required:!1,default:5},rounded:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`svg`}},setup(e){let t=e;return N(),(e,n)=>(_(),x(i(A),m(t,{width:e.width,height:e.height,viewBox:e.asChild?void 0:`0 0 12 6`,preserveAspectRatio:e.asChild?void 0:`none`}),{default:y(()=>[w(e.$slots,`default`,{},()=>[e.rounded?(_(),u(`path`,qe)):(_(),u(`path`,Ke))])]),_:3},16,[`width`,`height`,`viewBox`,`preserveAspectRatio`]))}}),Ye={top:`bottom`,right:`left`,bottom:`top`,left:`right`},Xe=g({inheritAttrs:!1,__name:`PopperArrow`,props:{width:{type:Number,required:!1},height:{type:Number,required:!1},rounded:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`svg`}},setup(e){let{forwardRef:n}=N(),r=me(),a=h(()=>Ye[r.placedSide.value]);return(e,o)=>(_(),u(`span`,{ref:e=>{i(r).onArrowChange(e??void 0)},style:p({position:`absolute`,left:i(r).arrowX?.value?`${i(r).arrowX?.value}px`:void 0,top:i(r).arrowY?.value?`${i(r).arrowY?.value}px`:void 0,[a.value]:0,transformOrigin:{top:``,right:`0 0`,bottom:`center 0`,left:`100% 0`}[i(r).placedSide.value],transform:{top:`translateY(100%)`,right:`translateY(50%) rotate(90deg) translateX(-50%)`,bottom:`rotate(180deg)`,left:`translateY(50%) rotate(-90deg) translateX(50%)`}[i(r).placedSide.value],visibility:i(r).shouldHideArrow.value?`hidden`:void 0})},[t(Je,m(e.$attrs,{ref:i(n),style:{display:`block`},as:e.as,"as-child":e.asChild,rounded:e.rounded,width:e.width,height:e.height}),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`as`,`as-child`,`rounded`,`width`,`height`])],4))}}),Ze=g({__name:`BaseSeparator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let t=e,n=[`horizontal`,`vertical`];function r(e){return n.includes(e)}let a=h(()=>r(t.orientation)?t.orientation:`horizontal`),o=h(()=>a.value===`vertical`?t.orientation:void 0),s=h(()=>t.decorative?{role:`none`}:{"aria-orientation":o.value,role:`separator`});return(e,t)=>(_(),x(i(A),m({as:e.as,"as-child":e.asChild,"data-orientation":a.value},s.value),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`as`,`as-child`,`data-orientation`]))}}),Qe=g({__name:`Separator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let n=t;return(t,r)=>(_(),x(Ze,e(E(n)),{default:y(()=>[w(t.$slots,`default`)]),_:3},16))}}),$e=g({__name:`TooltipArrow`,props:{width:{type:Number,required:!1,default:10},height:{type:Number,required:!1,default:5},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`svg`}},setup(t){let n=t;return N(),(t,r)=>(_(),x(i(Xe),e(E(n)),{default:y(()=>[w(t.$slots,`default`)]),_:3},16))}}),[U,et]=R(`TooltipProvider`),tt=g({inheritAttrs:!1,__name:`TooltipProvider`,props:{delayDuration:{type:Number,required:!1,default:700},skipDelayDuration:{type:Number,required:!1,default:300},disableHoverableContent:{type:Boolean,required:!1,default:!1},disableClosingTrigger:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},ignoreNonKeyboardFocus:{type:Boolean,required:!1,default:!1},content:{type:Object,required:!1}},setup(e){let{delayDuration:t,skipDelayDuration:n,disableHoverableContent:r,disableClosingTrigger:i,ignoreNonKeyboardFocus:a,disabled:s,content:c}=o(e);N();let l=S(!0),u=S(!1),{start:d,stop:f}=j(()=>{l.value=!0},n,{immediate:!1});return et({isOpenDelayed:l,delayDuration:t,onOpen(){f(),l.value=!1},onClose(){d()},isPointerInTransitRef:u,disableHoverableContent:r,disableClosingTrigger:i,disabled:s,ignoreNonKeyboardFocus:a,content:c}),(e,t)=>w(e.$slots,`default`)}}),W=`tooltip.open`,[G,nt]=R(`TooltipRoot`),rt=g({__name:`TooltipRoot`,props:{defaultOpen:{type:Boolean,required:!1,default:!1},open:{type:Boolean,required:!1,default:void 0},delayDuration:{type:Number,required:!1,default:void 0},disableHoverableContent:{type:Boolean,required:!1,default:void 0},disableClosingTrigger:{type:Boolean,required:!1,default:void 0},disabled:{type:Boolean,required:!1,default:void 0},ignoreNonKeyboardFocus:{type:Boolean,required:!1,default:void 0}},emits:[`update:open`],setup(e,{emit:t}){let n=e,a=t;N();let o=U(),s=h(()=>n.disableHoverableContent??o.disableHoverableContent.value),c=h(()=>n.disableClosingTrigger??o.disableClosingTrigger.value),l=h(()=>n.disabled??o.disabled.value),u=h(()=>n.delayDuration??o.delayDuration.value),d=h(()=>n.ignoreNonKeyboardFocus??o.ignoreNonKeyboardFocus.value),f=F(n,`open`,a,{defaultValue:n.defaultOpen,passive:n.open===void 0});r(f,e=>{o.onClose&&(e?(o.onOpen(),document.dispatchEvent(new CustomEvent(W))):o.onClose())});let p=S(!1),m=S(),ee=h(()=>f.value?p.value?`delayed-open`:`instant-open`:`closed`),{start:g,stop:v}=j(()=>{p.value=!0,f.value=!0},u,{immediate:!1});function b(){v(),p.value=!1,f.value=!0}function C(){v(),f.value=!1}function T(){g()}return nt({contentId:``,open:f,stateAttribute:ee,trigger:m,onTriggerChange(e){m.value=e},onTriggerEnter(){o.isOpenDelayed.value?T():b()},onTriggerLeave(){s.value?C():v()},onOpen:b,onClose:C,disableHoverableContent:s,disableClosingTrigger:c,disabled:l,ignoreNonKeyboardFocus:d}),(e,t)=>(_(),x(i(Ce),null,{default:y(()=>[w(e.$slots,`default`,{open:i(f)})]),_:3}))}}),K=g({__name:`TooltipContentImpl`,props:{ariaLabel:{type:String,required:!1},asChild:{type:Boolean,required:!1,default:void 0},as:{type:null,required:!1},side:{type:null,required:!1},sideOffset:{type:Number,required:!1},align:{type:null,required:!1},alignOffset:{type:Number,required:!1},avoidCollisions:{type:Boolean,required:!1,default:void 0},collisionBoundary:{type:null,required:!1},collisionPadding:{type:[Number,Object],required:!1},arrowPadding:{type:Number,required:!1},sticky:{type:String,required:!1},hideWhenDetached:{type:Boolean,required:!1,default:void 0},positionStrategy:{type:String,required:!1},updatePositionStrategy:{type:String,required:!1}},emits:[`escapeKeyDown`,`pointerDownOutside`],setup(e,{emit:r}){let a=e,o=r,s=G(),c=U(),{forwardRef:l,currentElement:u}=N(),d=h(()=>a.ariaLabel||u.value?.textContent),p=h(()=>{let{ariaLabel:e,...t}=a;return fe(t,c.content.value??{},{side:`top`,sideOffset:0,align:`center`,avoidCollisions:!0,collisionBoundary:[],collisionPadding:0,arrowPadding:0,sticky:`partial`,hideWhenDetached:!1})});return f(()=>{M(window,`scroll`,e=>{e.target?.contains(s.trigger.value)&&s.onClose()},{capture:!0}),M(document,W,s.onClose)}),(e,r)=>(_(),x(i(we),{"as-child":``,"disable-outside-pointer-events":!1,onEscapeKeyDown:r[0]||=e=>o(`escapeKeyDown`,e),onPointerDownOutside:r[1]||=e=>{i(s).disableClosingTrigger.value&&i(s).trigger.value?.contains(e.target)&&e.preventDefault(),o(`pointerDownOutside`,e)},onFocusOutside:r[2]||=ne(()=>{},[`prevent`]),onDismiss:r[3]||=e=>i(s).onClose()},{default:y(()=>[t(i(xe),m({ref:i(l),"data-state":i(s).stateAttribute.value},{...e.$attrs,...p.value},{style:{"--reka-tooltip-content-transform-origin":`var(--reka-popper-transform-origin)`,"--reka-tooltip-content-available-width":`var(--reka-popper-available-width)`,"--reka-tooltip-content-available-height":`var(--reka-popper-available-height)`,"--reka-tooltip-trigger-width":`var(--reka-popper-anchor-width)`,"--reka-tooltip-trigger-height":`var(--reka-popper-anchor-height)`}}),{default:y(()=>[w(e.$slots,`default`),t(i(he),{id:i(s).contentId,role:`tooltip`},{default:y(()=>[n(b(d.value),1)]),_:1},8,[`id`])]),_:3},16,[`data-state`])]),_:3}))}}),it=g({__name:`TooltipContentHoverable`,props:{ariaLabel:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1},side:{type:null,required:!1},sideOffset:{type:Number,required:!1},align:{type:null,required:!1},alignOffset:{type:Number,required:!1},avoidCollisions:{type:Boolean,required:!1},collisionBoundary:{type:null,required:!1},collisionPadding:{type:[Number,Object],required:!1},arrowPadding:{type:Number,required:!1},sticky:{type:String,required:!1},hideWhenDetached:{type:Boolean,required:!1},positionStrategy:{type:String,required:!1},updatePositionStrategy:{type:String,required:!1}},setup(e){let t=_e(e),{forwardRef:n,currentElement:r}=N(),{trigger:a,onClose:o}=G(),s=U(),{isPointerInTransit:c,onPointerExit:l}=Le(a,r);return s.isPointerInTransitRef=c,l(()=>{o()}),(e,r)=>(_(),x(K,m({ref:i(n)},i(t)),{default:y(()=>[w(e.$slots,`default`)]),_:3},16))}}),at=g({__name:`TooltipContent`,props:{forceMount:{type:Boolean,required:!1},ariaLabel:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1},side:{type:null,required:!1},sideOffset:{type:Number,required:!1},align:{type:null,required:!1},alignOffset:{type:Number,required:!1},avoidCollisions:{type:Boolean,required:!1},collisionBoundary:{type:null,required:!1},collisionPadding:{type:[Number,Object],required:!1},arrowPadding:{type:Number,required:!1},sticky:{type:String,required:!1},hideWhenDetached:{type:Boolean,required:!1},positionStrategy:{type:String,required:!1},updatePositionStrategy:{type:String,required:!1}},emits:[`escapeKeyDown`,`pointerDownOutside`],setup(e,{emit:t}){let n=e,r=t,a=G(),o=L(n,r),{forwardRef:s}=N();return(e,t)=>(_(),x(i(pe),{present:e.forceMount||i(a).open.value},{default:y(()=>[(_(),x(C(i(a).disableHoverableContent.value?K:it),m({ref:i(s)},i(o)),{default:y(()=>[w(e.$slots,`default`)]),_:3},16))]),_:3},8,[`present`]))}}),ot=g({__name:`TooltipPortal`,props:{to:{type:null,required:!1},disabled:{type:Boolean,required:!1},defer:{type:Boolean,required:!1},forceMount:{type:Boolean,required:!1}},setup(t){let n=t;return(t,r)=>(_(),x(i(ge),e(E(n)),{default:y(()=>[w(t.$slots,`default`)]),_:3},16))}}),st=g({__name:`TooltipTrigger`,props:{reference:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(e){let n=e,r=G(),a=U();r.contentId||=de(void 0,`reka-tooltip-content`);let{forwardRef:o,currentElement:s}=N(),c=S(!1),l=S(!1),u=h(()=>r.disabled.value?{}:{click:T,focus:b,pointermove:g,pointerleave:v,pointerdown:p,blur:C});f(()=>{r.onTriggerChange(s.value)});function d(){setTimeout(()=>{c.value=!1},1)}function p(){r.open&&!r.disableClosingTrigger.value&&r.onClose(),c.value=!0,document.addEventListener(`pointerup`,d,{once:!0})}function g(e){e.pointerType!==`touch`&&!l.value&&!a.isPointerInTransitRef.value&&(r.onTriggerEnter(),l.value=!0)}function v(){r.onTriggerLeave(),l.value=!1}function b(e){c.value||r.ignoreNonKeyboardFocus.value&&!e.target.matches?.(`:focus-visible`)||r.onOpen()}function C(){r.onClose()}function T(){r.disableClosingTrigger.value||r.onClose()}return(e,a)=>(_(),x(i(ve),{"as-child":``,reference:e.reference},{default:y(()=>[t(i(A),m({ref:i(o),"aria-describedby":i(r).open.value?i(r).contentId:void 0,"data-state":i(r).stateAttribute.value,as:e.as,"as-child":n.asChild,"data-grace-area-trigger":``},ee(u.value)),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`aria-describedby`,`data-state`,`as`,`as-child`])]),_:3},8,[`reference`]))}}),ct=g({__name:`Sheet`,props:{open:{type:Boolean},defaultOpen:{type:Boolean},modal:{type:Boolean},unmountOnHide:{type:Boolean}},emits:[`update:open`],setup(t,{emit:n}){let r=L(t,n);return(t,n)=>(_(),x(i(De),m({"data-slot":`sheet`},i(r)),{default:y(n=>[w(t.$slots,`default`,e(E(n)))]),_:3},16))}}),lt=g({__name:`SheetOverlay`,props:{forceMount:{type:Boolean},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e,n=k(t,`class`);return(e,r)=>(_(),x(i(ke),m({"data-slot":`sheet-overlay`,class:i(O)(`data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80`,t.class)},i(n)),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`class`]))}}),ut=g({inheritAttrs:!1,__name:`SheetContent`,props:{class:{type:[Boolean,null,String,Object,Array]},side:{default:`right`},forceMount:{type:Boolean},disableOutsidePointerEvents:{type:Boolean},asChild:{type:Boolean},as:{}},emits:[`escapeKeyDown`,`pointerDownOutside`,`focusOutside`,`interactOutside`,`openAutoFocus`,`closeAutoFocus`],setup(e,{emit:n}){let r=e,a=n,o=k(r,`class`,`side`),s=L(o,a);return(n,a)=>(_(),x(i(je),null,{default:y(()=>[t(lt),t(i(Ae),m({"data-slot":`sheet-content`,class:i(O)(`bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500`,e.side===`right`&&`data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm`,e.side===`left`&&`data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm`,e.side===`top`&&`data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b`,e.side===`bottom`&&`data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t`,r.class)},{...n.$attrs,...i(s)}),{default:y(()=>[w(n.$slots,`default`),t(i(Oe),{class:`ring-offset-background focus:ring-ring data-[state=open]:bg-accent absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none`},{default:y(()=>[t(i(le),{class:`size-4`}),a[0]||=l(`span`,{class:`sr-only`},`Close`,-1)]),_:1})]),_:3},16,[`class`])]),_:3}))}}),dt=g({__name:`SheetDescription`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e,n=k(t,`class`);return(e,r)=>(_(),x(i(We),m({"data-slot":`sheet-description`,class:i(O)(`text-muted-foreground text-sm`,t.class)},i(n)),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`class`]))}}),ft=g({__name:`SheetHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`div`,{"data-slot":`sheet-header`,class:c(i(O)(`flex flex-col gap-1.5 p-4`,t.class))},[w(e.$slots,`default`)],2))}}),pt=g({__name:`SheetTitle`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e,n=k(t,`class`);return(e,r)=>(_(),x(i(Ge),m({"data-slot":`sheet-title`,class:i(O)(`text-foreground font-semibold`,t.class)},i(n)),{default:y(()=>[w(e.$slots,`default`)]),_:3},16,[`class`]))}}),q=`sidebar_state`,mt=604800,ht=`16rem`,gt=`18rem`,_t=`3rem`,[J,vt]=R(`Sidebar`),yt={class:`flex h-full w-full flex-col`},bt=[`data-state`,`data-collapsible`,`data-variant`,`data-side`],xt={"data-sidebar":`sidebar`,class:`bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm`},St=g({inheritAttrs:!1,__name:`Sidebar`,props:{side:{default:`left`},variant:{default:`sidebar`},collapsible:{default:`offcanvas`},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let r=e,{isMobile:a,state:o,openMobile:s,setOpenMobile:d}=J();return(f,h)=>e.collapsible===`none`?(_(),u(`div`,m({key:0,"data-slot":`sidebar`,class:i(O)(`bg-sidebar text-sidebar-foreground flex w-(--sidebar-width) flex-col`,r.class)},f.$attrs),[w(f.$slots,`default`)],16)):i(a)?(_(),x(i(ct),m({key:1,open:i(s)},f.$attrs,{"onUpdate:open":i(d)}),{default:y(()=>[t(i(ut),{"data-sidebar":`sidebar`,"data-slot":`sidebar`,"data-mobile":`true`,side:e.side,class:`bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden`,style:p({"--sidebar-width":i(gt)})},{default:y(()=>[t(ft,{class:`sr-only`},{default:y(()=>[t(pt,null,{default:y(()=>[...h[0]||=[n(`Sidebar`,-1)]]),_:1}),t(dt,null,{default:y(()=>[...h[1]||=[n(`Displays the mobile sidebar.`,-1)]]),_:1})]),_:1}),l(`div`,yt,[w(f.$slots,`default`)])]),_:3},8,[`side`,`style`])]),_:3},16,[`open`,`onUpdate:open`])):(_(),u(`div`,{key:2,class:`group peer text-sidebar-foreground hidden md:block`,"data-slot":`sidebar`,"data-state":i(o),"data-collapsible":i(o)===`collapsed`?e.collapsible:``,"data-variant":e.variant,"data-side":e.side},[l(`div`,{class:c(i(O)(`relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear`,`group-data-[collapsible=offcanvas]:w-0`,`group-data-[side=right]:rotate-180`,e.variant===`floating`||e.variant===`inset`?`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon)`))},null,2),l(`div`,m({class:i(O)(`fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex`,e.side===`left`?`left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]`:`right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]`,e.variant===`floating`||e.variant===`inset`?`p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l`,r.class)},f.$attrs),[l(`div`,xt,[w(f.$slots,`default`)])],16)],8,bt))}}),Ct=g({__name:`SidebarContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`div`,{"data-slot":`sidebar-content`,"data-sidebar":`content`,class:c(i(O)(`flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,t.class))},[w(e.$slots,`default`)],2))}}),wt=g({__name:`SidebarFooter`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`div`,{"data-slot":`sidebar-footer`,"data-sidebar":`footer`,class:c(i(O)(`flex flex-col gap-2 p-2`,t.class))},[w(e.$slots,`default`)],2))}}),Tt=g({__name:`SidebarGroup`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`div`,{"data-slot":`sidebar-group`,"data-sidebar":`group`,class:c(i(O)(`relative flex w-full min-w-0 flex-col p-2`,t.class))},[w(e.$slots,`default`)],2))}}),Et=g({__name:`SidebarGroupContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`div`,{"data-slot":`sidebar-group-content`,"data-sidebar":`group-content`,class:c(i(O)(`w-full text-sm`,t.class))},[w(e.$slots,`default`)],2))}}),Dt=g({__name:`SidebarGroupLabel`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(n,r)=>(_(),x(i(A),{"data-slot":`sidebar-group-label`,"data-sidebar":`group-label`,as:e.as,"as-child":e.asChild,class:c(i(O)(`text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0`,`group-data-[collapsible=icon]:pointer-events-none group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:select-none group-data-[collapsible=icon]:opacity-0`,t.class))},{default:y(()=>[w(n.$slots,`default`)]),_:3},8,[`as`,`as-child`,`class`]))}}),Ot=g({__name:`SidebarHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`div`,{"data-slot":`sidebar-header`,"data-sidebar":`header`,class:c(i(O)(`flex flex-col gap-2 p-2`,t.class))},[w(e.$slots,`default`)],2))}}),kt=g({__name:`SidebarInset`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`main`,{"data-slot":`sidebar-inset`,class:c(i(O)(`bg-background relative flex min-w-0 w-full flex-1 flex-col`,`md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2`,t.class))},[w(e.$slots,`default`)],2))}}),Y=g({__name:`SidebarMenu`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`ul`,{"data-slot":`sidebar-menu`,"data-sidebar":`menu`,class:c(i(O)(`flex w-full min-w-0 flex-col gap-1`,t.class))},[w(e.$slots,`default`)],2))}}),At=g({__name:`Tooltip`,props:{defaultOpen:{type:Boolean},open:{type:Boolean},delayDuration:{},disableHoverableContent:{type:Boolean},disableClosingTrigger:{type:Boolean},disabled:{type:Boolean},ignoreNonKeyboardFocus:{type:Boolean}},emits:[`update:open`],setup(t,{emit:n}){let r=L(t,n);return(t,n)=>(_(),x(i(rt),m({"data-slot":`tooltip`},i(r)),{default:y(n=>[w(t.$slots,`default`,e(E(n)))]),_:3},16))}}),jt=g({inheritAttrs:!1,__name:`TooltipContent`,props:{forceMount:{type:Boolean},ariaLabel:{},asChild:{type:Boolean},as:{},side:{},sideOffset:{default:4},align:{},alignOffset:{},avoidCollisions:{type:Boolean},collisionBoundary:{},collisionPadding:{},arrowPadding:{},sticky:{},hideWhenDetached:{type:Boolean},positionStrategy:{},updatePositionStrategy:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`escapeKeyDown`,`pointerDownOutside`],setup(e,{emit:n}){let r=e,a=n,o=k(r,`class`),s=L(o,a);return(e,n)=>(_(),x(i(ot),null,{default:y(()=>[t(i(at),m({"data-slot":`tooltip-content`},{...i(s),...e.$attrs},{class:i(O)(`bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance`,r.class)}),{default:y(()=>[w(e.$slots,`default`),t(i($e),{class:`bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-xs`})]),_:3},16,[`class`])]),_:3}))}}),Mt=g({__name:`TooltipTrigger`,props:{reference:{},asChild:{type:Boolean},as:{}},setup(e){let t=e;return(e,n)=>(_(),x(i(st),m({"data-slot":`tooltip-trigger`},t),{default:y(()=>[w(e.$slots,`default`)]),_:3},16))}}),X=g({__name:`SidebarMenuButtonChild`,props:{variant:{default:`default`},size:{default:`default`},isActive:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]},asChild:{type:Boolean},as:{default:`button`}},setup(e){let t=e;return(n,r)=>(_(),x(i(A),m({"data-slot":`sidebar-menu-button`,"data-sidebar":`menu-button`,"data-size":e.size,"data-active":e.isActive,class:i(O)(i(Lt)({variant:e.variant,size:e.size}),t.class),as:e.as,"as-child":e.asChild},n.$attrs),{default:y(()=>[w(n.$slots,`default`)]),_:3},16,[`data-size`,`data-active`,`class`,`as`,`as-child`]))}}),Z=g({inheritAttrs:!1,__name:`SidebarMenuButton`,props:{variant:{default:`default`},size:{default:`default`},isActive:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]},asChild:{type:Boolean},as:{default:`button`},tooltip:{}},setup(r){let a=r,{isMobile:o,state:s}=J(),c=k(a,`tooltip`);return(a,l)=>r.tooltip?(_(),x(i(At),{key:1},{default:y(()=>[t(i(Mt),{"as-child":``},{default:y(()=>[t(X,e(E({...i(c),...a.$attrs})),{default:y(()=>[w(a.$slots,`default`)]),_:3},16)]),_:3}),t(i(jt),{side:`right`,align:`center`,hidden:i(s)!==`collapsed`||i(o)},{default:y(()=>[typeof r.tooltip==`string`?(_(),u(v,{key:0},[n(b(r.tooltip),1)],64)):(_(),x(C(r.tooltip),{key:1}))]),_:1},8,[`hidden`])]),_:3})):(_(),x(X,e(m({key:0},{...i(c),...a.$attrs})),{default:y(()=>[w(a.$slots,`default`)]),_:3},16))}}),Q=g({__name:`SidebarMenuItem`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`li`,{"data-slot":`sidebar-menu-item`,"data-sidebar":`menu-item`,class:c(i(O)(`group/menu-item relative`,t.class))},[w(e.$slots,`default`)],2))}}),Nt=g({__name:`SidebarProvider`,props:{defaultOpen:{type:Boolean,default:!ce?.cookie.includes(`${q}=false`)},open:{type:Boolean,default:void 0},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:open`],setup(e,{emit:t}){let n=e,r=t,a=se(`(max-width: 768px)`),o=S(!1),s=F(n,`open`,r,{defaultValue:n.defaultOpen??!1,passive:n.open===void 0});function c(e){s.value=e,document.cookie=`${q}=${s.value}; path=/; max-age=${mt}`}function u(e){o.value=e}function d(){return a.value?u(!o.value):c(!s.value)}return M(`keydown`,e=>{e.key===`b`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),d())}),vt({state:h(()=>s.value?`expanded`:`collapsed`),open:s,setOpen:c,isMobile:a,openMobile:o,setOpenMobile:u,toggleSidebar:d}),(e,t)=>(_(),x(i(tt),{"delay-duration":0},{default:y(()=>[l(`div`,m({"data-slot":`sidebar-wrapper`,style:{"--sidebar-width":i(ht),"--sidebar-width-icon":i(_t)},class:i(O)(`group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full`,n.class)},e.$attrs),[w(e.$slots,`default`)],16)]),_:3}))}}),Pt=g({__name:`SidebarRail`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e,{toggleSidebar:n}=J();return(e,r)=>(_(),u(`button`,{"data-sidebar":`rail`,"data-slot":`sidebar-rail`,"aria-label":`Toggle Sidebar`,tabindex:-1,title:`Toggle Sidebar`,class:c(i(O)(`hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 sm:flex`,`in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize`,`[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize`,`hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full`,`[[data-side=left][data-collapsible=offcanvas]_&]:-right-2`,`[[data-side=right][data-collapsible=offcanvas]_&]:-left-2`,t.class)),onClick:r[0]||=(...e)=>i(n)&&i(n)(...e)},[w(e.$slots,`default`)],2))}}),Ft=g({__name:`Separator`,props:{orientation:{default:`horizontal`},decorative:{type:Boolean,default:!0},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e,n=k(t,`class`);return(e,r)=>(_(),x(i(Qe),m({"data-slot":`separator`},i(n),{class:i(O)(`bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,t.class)}),null,16,[`class`]))}}),It=g({__name:`SidebarTrigger`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let n=e,{toggleSidebar:r}=J();return(e,a)=>(_(),x(i(P),{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,size:`icon`,class:c(i(O)(`h-7 w-7`,n.class)),onClick:i(r)},{default:y(()=>[t(i(Fe)),a[0]||=l(`span`,{class:`sr-only`},`Toggle Sidebar`,-1)]),_:1},8,[`class`,`onClick`]))}}),Lt=ae(`peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-sm p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-primary/10 data-[active=true]:font-medium data-[active=true]:text-primary dark:data-[active=true]:bg-primary/15 data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0`,{variants:{variant:{default:`hover:bg-sidebar-accent hover:text-sidebar-accent-foreground`,outline:`bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]`},size:{default:`h-8 text-sm`,sm:`h-7 text-xs`,lg:`h-12 text-sm group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}}),Rt=``+new URL(`logo-D9vyMJZl.png`,import.meta.url).href,zt={class:`flex items-center gap-2 px-2 py-1.5 group-data-[collapsible=icon]:p-0!`},Bt=[`src`],Vt={class:`flex flex-col overflow-hidden group-data-[collapsible=icon]:hidden`},Ht={class:`truncate text-sm font-semibold`},Ut={key:0,class:`text-muted-foreground truncate text-xs`},Wt=g({__name:`Sidebar`,setup(e){let{data:r}=ue(),a=D(),o=te(),{mutate:s}=Me();function f(){s(void 0,{onSuccess:()=>o.push({name:`login`})})}function p(e){return e?z(e).style.value:null}return(e,o)=>(_(),x(i(St),{collapsible:`icon`},{default:y(()=>[t(i(Ot),null,{default:y(()=>[l(`div`,zt,[l(`img`,{src:i(Rt),alt:`Logo`,class:`shrink-0 rounded-md object-contain size-7`},null,8,Bt),l(`div`,Vt,[l(`span`,Ht,b(i(r)?.name??`Admin`),1),i(r)?.description?(_(),u(`span`,Ut,b(i(r).description),1)):T(``,!0)])])]),_:1}),t(i(Ct),null,{default:y(()=>[(_(!0),u(v,null,d(i(r)?.sections??[],e=>(_(),x(i(Tt),{key:e.id},{default:y(()=>[t(i(Dt),null,{default:y(()=>[n(b(e.name),1)]),_:2},1024),t(i(Et),null,{default:y(()=>[t(i(Y),null,{default:y(()=>[(_(!0),u(v,null,d(e.pages,n=>(_(),x(i(Q),{key:n.id},{default:y(()=>[t(i(Z),{"as-child":``,"is-active":i(a).params.sectionId===e.id&&i(a).params.pageId===n.id,tooltip:n.name},{default:y(()=>[t(i(Ee),{to:{name:`page`,params:{sectionId:e.id,pageId:n.id}}},{default:y(()=>[n.icon?(_(),x(i(B),{key:0,icon:`lucide:${n.icon}`,class:c(p(n.color)?.text)},null,8,[`icon`,`class`])):n.color?(_(),u(`span`,{key:1,class:c([p(n.color)?.dot,`size-1.5 rounded-full shrink-0`])},null,2)):T(``,!0),l(`span`,null,b(n.name),1)]),_:2},1032,[`to`])]),_:2},1032,[`is-active`,`tooltip`])]),_:2},1024))),128))]),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1}),t(i(wt),null,{default:y(()=>[t(i(Y),null,{default:y(()=>[t(i(Q),null,{default:y(()=>[t(i(Z),{tooltip:`Logout`,onClick:f},{default:y(()=>[t(i(B),{icon:`lucide:log-out`}),o[0]||=l(`span`,null,`Logout`,-1)]),_:1})]),_:1})]),_:1})]),_:1}),t(i(Pt))]),_:1}))}}),Gt=g({__name:`ThemeToggle`,setup(e){return(e,t)=>(_(),x(i(P),{type:`button`,variant:`ghost`,size:`icon`,"aria-label":i(H)?`Switch to light theme`:`Switch to dark theme`,onClick:t[0]||=e=>i(Ne)()},{default:y(()=>[i(H)?(_(),x(i(Ie),{key:0})):(_(),x(i(Pe),{key:1}))]),_:1},8,[`aria-label`]))}}),Kt=g({__name:`Breadcrumb`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`nav`,{"aria-label":`breadcrumb`,"data-slot":`breadcrumb`,class:c(t.class)},[w(e.$slots,`default`)],2))}}),$=g({__name:`BreadcrumbItem`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`li`,{"data-slot":`breadcrumb-item`,class:c(i(O)(`inline-flex items-center gap-1.5`,t.class))},[w(e.$slots,`default`)],2))}}),qt=g({__name:`BreadcrumbList`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`ol`,{"data-slot":`breadcrumb-list`,class:c(i(O)(`text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5`,t.class))},[w(e.$slots,`default`)],2))}}),Jt=g({__name:`BreadcrumbPage`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(_(),u(`span`,{"data-slot":`breadcrumb-page`,role:`link`,"aria-disabled":`true`,"aria-current":`page`,class:c(i(O)(`text-foreground font-normal`,t.class))},[w(e.$slots,`default`)],2))}}),Yt=g({__name:`BreadcrumbSeparator`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let n=e;return(e,r)=>(_(),u(`li`,{"data-slot":`breadcrumb-separator`,role:`presentation`,"aria-hidden":`true`,class:c(i(O)(`[&>svg]:size-3.5`,n.class))},[w(e.$slots,`default`,{},()=>[t(i(Te))])],2))}}),Xt={class:`flex h-14 shrink-0 items-center gap-2 border-b px-4`},Zt={class:`text-muted-foreground`},Qt=g({__name:`TopPanel`,setup(e){let r=D(),a=h(()=>r.params.sectionId),o=h(()=>r.params.pageId),s=h(()=>r.params.formId||``),{data:d}=be({sectionId:a}),{page:f}=ye({sectionId:a,pageId:o}),{form:p}=Se({sectionId:a,pageId:o,formId:s}),{style:m}=z(()=>p.value?.color||`slate`);return(e,r)=>(_(),u(`header`,Xt,[t(i(It)),t(i(Ft),{orientation:`vertical`,class:`mr-2 h-4`}),i(d)&&i(f)?(_(),x(i(Kt),{key:0},{default:y(()=>[t(i(qt),null,{default:y(()=>[t(i($),null,{default:y(()=>[l(`span`,Zt,b(i(d).name),1)]),_:1}),t(i(Yt)),t(i($),null,{default:y(()=>[t(i(Jt),{class:`flex items-center gap-1.5`},{default:y(()=>[i(f).icon?(_(),x(i(B),{key:0,icon:`lucide:${i(f).icon}`},null,8,[`icon`])):T(``,!0),n(` `+b(i(f).name),1)]),_:1})]),_:1}),i(p)?(_(),x(i(Yt),{key:0})):T(``,!0),i(p)?(_(),x(i($),{key:1},{default:y(()=>[t(i(Jt),{class:`flex items-center gap-1.5`},{default:y(()=>[i(p).icon?(_(),x(i(B),{key:0,icon:`lucide:${i(p).icon}`,class:c(i(m).text)},null,8,[`icon`,`class`])):T(``,!0),n(` `+b(i(p).name),1)]),_:1})]),_:1})):T(``,!0)]),_:1})]),_:1})):T(``,!0),t(Gt,{class:`ml-auto`})]))}}),$t={class:`flex-1 overflow-auto p-4 md:p-6`},en=g({__name:`Dashboard`,setup(e){let n=D();return(e,r)=>{let o=a(`router-view`);return _(),x(i(Nt),null,{default:y(()=>[t(Wt),t(i(kt),null,{default:y(()=>[t(Qt),l(`main`,$t,[(_(),x(o,{key:i(n).fullPath}))])]),_:1})]),_:1})}}});export{en as default};
|