django-admin-react 1.0.3__tar.gz → 1.1.0__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.
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/PKG-INFO +26 -1
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/README.md +25 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/conf.py +20 -0
- django_admin_react-1.1.0/django_admin_react/static/admin_react/.vite/manifest.json +23 -0
- django_admin_react-1.1.0/django_admin_react/static/admin_react/assets/JsonViewer-7Pvk14Q0.js +1 -0
- django_admin_react-1.1.0/django_admin_react/static/admin_react/assets/index-BAk9ZaWt.js +8 -0
- django_admin_react-1.1.0/django_admin_react/static/admin_react/assets/index-CAPQqmPH.css +1 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/static/admin_react/index.html +2 -2
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/templates/admin_react/index.html +8 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/views.py +32 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/pyproject.toml +1 -1
- django_admin_react-1.0.3/django_admin_react/static/admin_react/.vite/manifest.json +0 -11
- django_admin_react-1.0.3/django_admin_react/static/admin_react/assets/index-PG1kg1oj.js +0 -8
- django_admin_react-1.0.3/django_admin_react/static/admin_react/assets/index-ezP7Xmz4.css +0 -1
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/LICENSE +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/README.md +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/__init__.py +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/apps.py +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/audit.py +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/pwa.py +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/templates/README.md +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/templates/admin_react/README.md +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/templates/admin_react/login.html +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/templates/admin_react/sw.js +0 -0
- {django_admin_react-1.0.3 → django_admin_react-1.1.0}/django_admin_react/urls.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: django-admin-react
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: A drop-in React single-page admin for Django, driven entirely by ModelAdmin.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: django,admin,react,spa,tailwind
|
|
@@ -298,6 +298,31 @@ urlpatterns = [
|
|
|
298
298
|
]
|
|
299
299
|
```
|
|
300
300
|
|
|
301
|
+
#### Legacy-admin escape hatch (optional)
|
|
302
|
+
|
|
303
|
+
During the rollout, show an in-SPA banner on every page that links to
|
|
304
|
+
**the same page** in the original admin. End-users with muscle memory
|
|
305
|
+
for `/admin/` (or bookmarks pointing at it) can return to the classic
|
|
306
|
+
surface in one click while you close feature gaps in the SPA:
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
# settings.py
|
|
310
|
+
DJANGO_ADMIN_REACT = {
|
|
311
|
+
"LEGACY_ADMIN_URL_PREFIX": "admin/", # the legacy admin's mount
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
The value must match the prefix you mounted the legacy admin under in
|
|
316
|
+
`urls.py`. When set, the SPA renders a thin notice banner at the top
|
|
317
|
+
of every page linking the matching legacy URL (computed by swapping
|
|
318
|
+
the prefix — both admins honour the same `app_label/model_name/...`
|
|
319
|
+
URL shape). The banner is dismissible per session (`sessionStorage`),
|
|
320
|
+
so each session shows it once and a user who forgot the escape hatch
|
|
321
|
+
exists is reminded the next time they log in.
|
|
322
|
+
|
|
323
|
+
When you remove the setting (or set it to `None`), the banner
|
|
324
|
+
disappears on the next page load — completing the migration.
|
|
325
|
+
|
|
301
326
|
---
|
|
302
327
|
|
|
303
328
|
## Extend without writing React
|
|
@@ -265,6 +265,31 @@ urlpatterns = [
|
|
|
265
265
|
]
|
|
266
266
|
```
|
|
267
267
|
|
|
268
|
+
#### Legacy-admin escape hatch (optional)
|
|
269
|
+
|
|
270
|
+
During the rollout, show an in-SPA banner on every page that links to
|
|
271
|
+
**the same page** in the original admin. End-users with muscle memory
|
|
272
|
+
for `/admin/` (or bookmarks pointing at it) can return to the classic
|
|
273
|
+
surface in one click while you close feature gaps in the SPA:
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
# settings.py
|
|
277
|
+
DJANGO_ADMIN_REACT = {
|
|
278
|
+
"LEGACY_ADMIN_URL_PREFIX": "admin/", # the legacy admin's mount
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
The value must match the prefix you mounted the legacy admin under in
|
|
283
|
+
`urls.py`. When set, the SPA renders a thin notice banner at the top
|
|
284
|
+
of every page linking the matching legacy URL (computed by swapping
|
|
285
|
+
the prefix — both admins honour the same `app_label/model_name/...`
|
|
286
|
+
URL shape). The banner is dismissible per session (`sessionStorage`),
|
|
287
|
+
so each session shows it once and a user who forgot the escape hatch
|
|
288
|
+
exists is reminded the next time they log in.
|
|
289
|
+
|
|
290
|
+
When you remove the setting (or set it to `None`), the banner
|
|
291
|
+
disappears on the next page load — completing the migration.
|
|
292
|
+
|
|
268
293
|
---
|
|
269
294
|
|
|
270
295
|
## Extend without writing React
|
|
@@ -99,6 +99,25 @@ DEFAULTS: dict[str, Any] = {
|
|
|
99
99
|
# `django_admin_react.urls` skips the inline `api/v1/` include so
|
|
100
100
|
# there is no double-mount.
|
|
101
101
|
"API_URL_PREFIX": None,
|
|
102
|
+
# ``LEGACY_ADMIN_URL_PREFIX`` — opt-in escape-hatch banner (#577).
|
|
103
|
+
# When set, every SPA page renders a thin notice banner at the top
|
|
104
|
+
# linking to **the same page** under the legacy Django admin's URL
|
|
105
|
+
# prefix. Useful during a progressive migration: end-users with
|
|
106
|
+
# muscle memory for ``/admin/`` (or wherever the legacy admin is
|
|
107
|
+
# mounted) can return to the classic surface in one click, and the
|
|
108
|
+
# bug list grows from "what they clicked back for." Default
|
|
109
|
+
# ``None`` keeps behaviour unchanged — no banner, no extra
|
|
110
|
+
# requests, no SPA overhead.
|
|
111
|
+
#
|
|
112
|
+
# The value matches the prefix the consumer registered the legacy
|
|
113
|
+
# admin under in ``urls.py`` — e.g. ``"admin/"`` for
|
|
114
|
+
# ``urlpatterns = [path("admin/", legacy_admin.urls), ...]``. The
|
|
115
|
+
# SPA computes the matching legacy URL by swapping its own mount
|
|
116
|
+
# for this value (both admins use the same ``app_label/model_name``
|
|
117
|
+
# URL shape, so it's a straight prefix swap with no per-route
|
|
118
|
+
# mapping). When the matching legacy route doesn't exist, the
|
|
119
|
+
# legacy admin 404s — same outcome as visiting that URL directly.
|
|
120
|
+
"LEGACY_ADMIN_URL_PREFIX": None,
|
|
102
121
|
"PWA_NAME": None,
|
|
103
122
|
"PWA_SHORT_NAME": None,
|
|
104
123
|
"PWA_ICONS": None,
|
|
@@ -122,6 +141,7 @@ class _PackageSettings:
|
|
|
122
141
|
PRIMARY_COLOR: str = DEFAULTS["PRIMARY_COLOR"]
|
|
123
142
|
REACT_LOGIN: bool = DEFAULTS["REACT_LOGIN"]
|
|
124
143
|
API_URL_PREFIX: str | None = DEFAULTS["API_URL_PREFIX"]
|
|
144
|
+
LEGACY_ADMIN_URL_PREFIX: str | None = DEFAULTS["LEGACY_ADMIN_URL_PREFIX"]
|
|
125
145
|
PWA_NAME: str | None = DEFAULTS["PWA_NAME"]
|
|
126
146
|
PWA_SHORT_NAME: str | None = DEFAULTS["PWA_SHORT_NAME"]
|
|
127
147
|
PWA_ICONS: list[dict[str, str]] | None = DEFAULTS["PWA_ICONS"]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"../../packages/details/src/JsonViewer.tsx": {
|
|
3
|
+
"file": "assets/JsonViewer-7Pvk14Q0.js",
|
|
4
|
+
"name": "JsonViewer",
|
|
5
|
+
"src": "../../packages/details/src/JsonViewer.tsx",
|
|
6
|
+
"isDynamicEntry": true,
|
|
7
|
+
"imports": [
|
|
8
|
+
"index.html"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"index.html": {
|
|
12
|
+
"file": "assets/index-BAk9ZaWt.js",
|
|
13
|
+
"name": "index",
|
|
14
|
+
"src": "index.html",
|
|
15
|
+
"isEntry": true,
|
|
16
|
+
"dynamicImports": [
|
|
17
|
+
"../../packages/details/src/JsonViewer.tsx"
|
|
18
|
+
],
|
|
19
|
+
"css": [
|
|
20
|
+
"assets/index-CAPQqmPH.css"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as x,r as l,j as e,C as h}from"./index-BAk9ZaWt.js";const p=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],g=x("chevron-right",p);const y=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],j=x("copy",y);function N({raw:r,parsed:t}){const[s,c]=l.useState(!1);async function a(){try{await navigator.clipboard.writeText(r),c(!0),setTimeout(()=>c(!1),2e3)}catch{}}return e.jsxs("div",{className:"relative w-full overflow-x-auto rounded border border-gray-200 bg-gray-50 p-3 font-mono text-xs leading-relaxed text-gray-800 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200",children:[e.jsx("button",{type:"button",onClick:a,"aria-label":"Copy JSON",title:s?"Copied":"Copy",className:"absolute right-2 top-2 inline-flex h-6 w-6 items-center justify-center rounded border border-gray-300 bg-white text-gray-600 hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700",children:s?e.jsx(h,{className:"h-3.5 w-3.5 text-green-600","aria-hidden":!0}):e.jsx(j,{className:"h-3.5 w-3.5","aria-hidden":!0})}),e.jsx(o,{value:t,depth:0})]})}function o({value:r,depth:t}){return r===null?e.jsx("span",{className:"text-purple-600 dark:text-purple-400",children:"null"}):typeof r=="boolean"?e.jsx("span",{className:"text-purple-600 dark:text-purple-400",children:r?"true":"false"}):typeof r=="number"?e.jsx("span",{className:"text-blue-700",children:String(r)}):typeof r=="string"?e.jsxs("span",{className:"text-green-700 dark:text-green-400",children:['"',r,'"']}):Array.isArray(r)?e.jsx(u,{value:r,depth:t}):typeof r=="object"?e.jsx(m,{value:r,depth:t}):e.jsx("span",{className:"text-gray-500",children:String(r)})}function m({value:r,depth:t}){const s=Object.keys(r),[c,a]=l.useState(t<2);return s.length===0?e.jsx("span",{className:"text-gray-500",children:"{}"}):e.jsx(d,{open:c,onToggle:()=>a(n=>!n),collapsedLabel:`{…} ${s.length} ${s.length===1?"key":"keys"}`,openBracket:"{",closeBracket:"}",depth:t,children:s.map((n,i)=>e.jsxs("div",{className:"pl-4",children:[e.jsxs("span",{className:"text-rose-700 dark:text-rose-400",children:['"',n,'"']}),e.jsx("span",{className:"text-gray-500",children:": "}),e.jsx(o,{value:r[n],depth:t+1}),i<s.length-1?e.jsx("span",{className:"text-gray-500",children:","}):null]},n))})}function u({value:r,depth:t}){const[s,c]=l.useState(t<2);return r.length===0?e.jsx("span",{className:"text-gray-500",children:"[]"}):e.jsx(d,{open:s,onToggle:()=>c(a=>!a),collapsedLabel:`[…] ${r.length} ${r.length===1?"item":"items"}`,openBracket:"[",closeBracket:"]",depth:t,children:r.map((a,n)=>e.jsxs("div",{className:"pl-4",children:[e.jsx(o,{value:a,depth:t+1}),n<r.length-1?e.jsx("span",{className:"text-gray-500",children:","}):null]},n))})}function d({open:r,onToggle:t,collapsedLabel:s,openBracket:c,closeBracket:a,depth:n,children:i}){return e.jsxs("span",{children:[e.jsx("button",{type:"button",onClick:t,"aria-expanded":r,className:"inline-flex items-center align-baseline text-gray-500 hover:text-gray-800 dark:hover:text-gray-200",children:e.jsx(g,{className:`h-3 w-3 shrink-0 transition-transform ${r?"rotate-90":""}`,"aria-hidden":!0})}),e.jsx("span",{className:"text-gray-500",children:c}),r?e.jsxs(e.Fragment,{children:[i,e.jsx("div",{className:n===0?"":"pl-0",children:e.jsx("span",{className:"text-gray-500",children:a})})]}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"px-1 text-gray-500",children:s}),e.jsx("span",{className:"text-gray-500",children:a})]})]})}export{N as default};
|