django-bootstrap6-admin 0.1.2__tar.gz → 0.2.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_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/CHANGELOG.md +17 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/PKG-INFO +8 -2
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/README.md +7 -1
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/__init__.py +1 -1
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/css/admin.css +45 -1
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/js/admin.js +98 -6
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin.egg-info/PKG-INFO +8 -2
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/test_admin_ui.py +11 -1
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/test_package.py +16 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/CONTRIBUTING.md +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/LICENSE +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/MANIFEST.in +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/NOTICE +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/pyproject.toml +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/setup.cfg +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/apps.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/css/widgets-overrides.css +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/js/theme.js +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/vendor/bootstrap/LICENSE +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/vendor/bootstrap/css/bootstrap.min.css +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/vendor/bootstrap/js/bootstrap.bundle.min.js +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/404.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/500.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/actions.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/app_index.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/app_list.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/auth/user/add_form.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/auth/user/change_password.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/base.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/base_site.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/change_form.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/change_form_object_tools.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/change_list.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/change_list_object_tools.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/change_list_results.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/color_theme_toggle.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/date_hierarchy.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/delete_confirmation.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/delete_selected_confirmation.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/edit_inline/stacked.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/edit_inline/tabular.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/filter.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/includes/fieldset.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/includes/object_delete_summary.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/index.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/login.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/nav_sidebar.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/object_history.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/pagination.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/search_form.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/submit_line.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/widgets/foreign_key_raw_id.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/admin/widgets/related_widget_wrapper.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/registration/logged_out.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/registration/password_change_done.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templates/registration/password_change_form.html +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templatetags/__init__.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/templatetags/bootstrap6_admin.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin.egg-info/SOURCES.txt +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin.egg-info/dependency_links.txt +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin.egg-info/requires.txt +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin.egg-info/top_level.txt +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/__init__.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/js/theme_toggle.test.js +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/settings.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/smoke_wheel.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/test_templatetags.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/testapp/__init__.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/testapp/admin.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/testapp/apps.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/testapp/models.py +0 -0
- {django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/urls.py +0 -0
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-11-15
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- The desktop filter panel can now be collapsed and expanded, and the
|
|
15
|
+
collapsed state is remembered between changelist pages.
|
|
16
|
+
- The "Show counts" / "Hide counts" choice is remembered across changelist
|
|
17
|
+
pages instead of resetting on navigation.
|
|
18
|
+
- Subtle vertical rules separate columns in changelists, inline tables and the
|
|
19
|
+
object history table.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Removed the duplicate native dropdown arrow on the bulk-action select.
|
|
24
|
+
- Improved dark-theme text contrast for secondary labels, table headers,
|
|
25
|
+
filter links, help text and links.
|
|
26
|
+
|
|
10
27
|
## [0.1.2] - 2026-11-15
|
|
11
28
|
|
|
12
29
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-bootstrap6-admin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A modern Bootstrap 6 skin for the Django admin.
|
|
5
5
|
Author-email: Aliberk Sandıkçı <git@asandikci.com>
|
|
6
6
|
Maintainer-email: Aliberk Sandıkçı <git@asandikci.com>
|
|
@@ -57,12 +57,18 @@ permissions and JavaScript remain in charge.
|
|
|
57
57
|
with a backdrop (mobile).
|
|
58
58
|
- Dashboard with application cards, model shortcuts and recent activity.
|
|
59
59
|
- Changelist with search, date hierarchy, collapsible filters, sortable
|
|
60
|
-
headers, bulk actions and Bootstrap pagination.
|
|
60
|
+
headers, bulk actions and Bootstrap pagination. The desktop filter panel can
|
|
61
|
+
be collapsed, and both its state and the "Show counts" choice are remembered
|
|
62
|
+
between pages.
|
|
63
|
+
- Subtle vertical rules separate columns in changelists, inline tables and the
|
|
64
|
+
object history.
|
|
61
65
|
- Change form with card-based fieldsets, collapsible sections, a clear save
|
|
62
66
|
bar, tabular/stacked inlines and related-object popups.
|
|
63
67
|
- Modern login, logout and password change pages.
|
|
64
68
|
- Light, dark and system themes. The existing Django `theme` localStorage
|
|
65
69
|
preference is synchronised with Bootstrap's `data-bs-theme` attribute.
|
|
70
|
+
- Dark-theme secondary text, table headers, filter links and help text use
|
|
71
|
+
higher-contrast tokens for better readability.
|
|
66
72
|
- Soft fade-in/fade-out transition when switching themes, skipped
|
|
67
73
|
automatically for users who prefer reduced motion.
|
|
68
74
|
- Every click changes the visible theme: if `auto` would resolve to the theme
|
|
@@ -20,12 +20,18 @@ permissions and JavaScript remain in charge.
|
|
|
20
20
|
with a backdrop (mobile).
|
|
21
21
|
- Dashboard with application cards, model shortcuts and recent activity.
|
|
22
22
|
- Changelist with search, date hierarchy, collapsible filters, sortable
|
|
23
|
-
headers, bulk actions and Bootstrap pagination.
|
|
23
|
+
headers, bulk actions and Bootstrap pagination. The desktop filter panel can
|
|
24
|
+
be collapsed, and both its state and the "Show counts" choice are remembered
|
|
25
|
+
between pages.
|
|
26
|
+
- Subtle vertical rules separate columns in changelists, inline tables and the
|
|
27
|
+
object history.
|
|
24
28
|
- Change form with card-based fieldsets, collapsible sections, a clear save
|
|
25
29
|
bar, tabular/stacked inlines and related-object popups.
|
|
26
30
|
- Modern login, logout and password change pages.
|
|
27
31
|
- Light, dark and system themes. The existing Django `theme` localStorage
|
|
28
32
|
preference is synchronised with Bootstrap's `data-bs-theme` attribute.
|
|
33
|
+
- Dark-theme secondary text, table headers, filter links and help text use
|
|
34
|
+
higher-contrast tokens for better readability.
|
|
29
35
|
- Soft fade-in/fade-out transition when switching themes, skipped
|
|
30
36
|
automatically for users who prefer reduced motion.
|
|
31
37
|
- Every click changes the visible theme: if `auto` would resolve to the theme
|
|
@@ -111,6 +111,23 @@
|
|
|
111
111
|
2. Base
|
|
112
112
|
-------------------------------------------------------------------------- */
|
|
113
113
|
|
|
114
|
+
/*
|
|
115
|
+
* Bootstrap's dark gray-500/600 secondary text is too dim on the deep navy
|
|
116
|
+
* admin surfaces, especially at the small sizes used by filters, table
|
|
117
|
+
* headers and action help. Lift those tokens for the effective dark theme.
|
|
118
|
+
*/
|
|
119
|
+
[data-bs-theme="dark"],
|
|
120
|
+
[data-effective-theme="dark"] {
|
|
121
|
+
--bs-fg-1: #f1f5f9;
|
|
122
|
+
--bs-fg-2: #d7e0ea;
|
|
123
|
+
--bs-fg-3: #b9c7d6;
|
|
124
|
+
--bs-fg-4: #9fb1c4;
|
|
125
|
+
--ba-text-muted: #c9d4e0;
|
|
126
|
+
--bs-link-color: #8dbcf7;
|
|
127
|
+
--bs-link-hover-color: #b7d4ff;
|
|
128
|
+
--bs-border-muted: #34465a;
|
|
129
|
+
}
|
|
130
|
+
|
|
114
131
|
html {
|
|
115
132
|
min-height: 100%;
|
|
116
133
|
}
|
|
@@ -1365,7 +1382,7 @@ a.ba-timeline-object:focus {
|
|
|
1365
1382
|
}
|
|
1366
1383
|
|
|
1367
1384
|
.ba-filters-toggle-row {
|
|
1368
|
-
display:
|
|
1385
|
+
display: flex;
|
|
1369
1386
|
}
|
|
1370
1387
|
|
|
1371
1388
|
.ba-filters-toggle {
|
|
@@ -1551,6 +1568,20 @@ a.ba-date-chip:focus {
|
|
|
1551
1568
|
border-block-end: 0;
|
|
1552
1569
|
}
|
|
1553
1570
|
|
|
1571
|
+
/* Very light column rules keep dense admin tables readable without making
|
|
1572
|
+
* every cell look boxed in. */
|
|
1573
|
+
#result_list thead th:not(:last-child),
|
|
1574
|
+
#result_list tbody th:not(:last-child),
|
|
1575
|
+
#result_list tbody td:not(:last-child),
|
|
1576
|
+
.ba-inline-table thead th:not(:last-child),
|
|
1577
|
+
.ba-inline-table tbody th:not(:last-child),
|
|
1578
|
+
.ba-inline-table tbody td:not(:last-child),
|
|
1579
|
+
.ba-history-table thead th:not(:last-child),
|
|
1580
|
+
.ba-history-table tbody th:not(:last-child),
|
|
1581
|
+
.ba-history-table tbody td:not(:last-child) {
|
|
1582
|
+
border-inline-end: 1px solid var(--bs-border-muted);
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1554
1585
|
#result_list tbody tr.selected > * {
|
|
1555
1586
|
background: var(--bs-primary-bg-subtle) !important;
|
|
1556
1587
|
}
|
|
@@ -1597,6 +1628,7 @@ a.ba-date-chip:focus {
|
|
|
1597
1628
|
|
|
1598
1629
|
#result_list select {
|
|
1599
1630
|
padding-inline-end: 1.6rem;
|
|
1631
|
+
appearance: none;
|
|
1600
1632
|
background-image: var(--ba-select-arrow);
|
|
1601
1633
|
background-position: right 0.45rem center;
|
|
1602
1634
|
background-repeat: no-repeat;
|
|
@@ -2177,6 +2209,7 @@ label.required::after {
|
|
|
2177
2209
|
.ba-form-group select,
|
|
2178
2210
|
.ba-actions select {
|
|
2179
2211
|
padding-inline-end: 2rem;
|
|
2212
|
+
appearance: none;
|
|
2180
2213
|
background-image: var(--ba-select-arrow);
|
|
2181
2214
|
background-position: right 0.7rem center;
|
|
2182
2215
|
background-repeat: no-repeat;
|
|
@@ -2551,6 +2584,7 @@ div.help ul {
|
|
|
2551
2584
|
|
|
2552
2585
|
.ba-inline-table select {
|
|
2553
2586
|
padding-inline-end: 1.6rem;
|
|
2587
|
+
appearance: none;
|
|
2554
2588
|
background-image: var(--ba-select-arrow);
|
|
2555
2589
|
background-position: right 0.45rem center;
|
|
2556
2590
|
background-repeat: no-repeat;
|
|
@@ -3202,6 +3236,16 @@ body.popup .ba-submit-row {
|
|
|
3202
3236
|
13. Responsive
|
|
3203
3237
|
-------------------------------------------------------------------------- */
|
|
3204
3238
|
|
|
3239
|
+
@media (min-width: 1200px) {
|
|
3240
|
+
#changelist.ba-filters-collapsed .ba-changelist-layout {
|
|
3241
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
#changelist.ba-filters-collapsed .ba-filters {
|
|
3245
|
+
display: none;
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3205
3249
|
@media (max-width: 1199.98px) {
|
|
3206
3250
|
.ba-dashboard {
|
|
3207
3251
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
*/
|
|
11
11
|
(() => {
|
|
12
12
|
const MOBILE = window.matchMedia("(max-width: 1023.98px)");
|
|
13
|
+
const DESKTOP = window.matchMedia("(min-width: 1200px)");
|
|
13
14
|
const STORAGE_KEY = "django.admin.navSidebarIsOpen";
|
|
15
|
+
const FILTERS_KEY = "django.admin.filtersCollapsed";
|
|
16
|
+
const FACETS_KEY = "django.admin.showFacets";
|
|
14
17
|
|
|
15
18
|
function initSidebar() {
|
|
16
19
|
const main = document.getElementById("main");
|
|
@@ -228,16 +231,50 @@
|
|
|
228
231
|
return;
|
|
229
232
|
}
|
|
230
233
|
|
|
234
|
+
const isCollapsed = () =>
|
|
235
|
+
changelist.classList.contains("ba-filters-collapsed");
|
|
236
|
+
|
|
231
237
|
const sync = () => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
changelist.classList.contains("ba-filters-open")
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
+
const expanded = DESKTOP.matches
|
|
239
|
+
? !isCollapsed()
|
|
240
|
+
: changelist.classList.contains("ba-filters-open");
|
|
241
|
+
toggle.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
242
|
+
if (panel) {
|
|
243
|
+
panel.toggleAttribute(
|
|
244
|
+
"inert",
|
|
245
|
+
DESKTOP.matches && isCollapsed(),
|
|
246
|
+
);
|
|
247
|
+
}
|
|
238
248
|
};
|
|
239
249
|
|
|
250
|
+
const setCollapsed = (collapsed) => {
|
|
251
|
+
changelist.classList.toggle("ba-filters-collapsed", collapsed);
|
|
252
|
+
if (DESKTOP.matches) {
|
|
253
|
+
localStorage.setItem(
|
|
254
|
+
FILTERS_KEY,
|
|
255
|
+
collapsed ? "true" : "false",
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
sync();
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// Restore the desktop preference. On mobile the panel is a drawer and
|
|
262
|
+
// the collapsed class has no visual effect.
|
|
263
|
+
if (DESKTOP.matches && localStorage.getItem(FILTERS_KEY) === "true") {
|
|
264
|
+
changelist.classList.add("ba-filters-collapsed");
|
|
265
|
+
}
|
|
266
|
+
|
|
240
267
|
toggle.addEventListener("click", () => {
|
|
268
|
+
if (DESKTOP.matches) {
|
|
269
|
+
const collapsed = !isCollapsed();
|
|
270
|
+
setCollapsed(collapsed);
|
|
271
|
+
if (!collapsed) {
|
|
272
|
+
const target = panel?.querySelector("summary, a, button");
|
|
273
|
+
window.requestAnimationFrame(() => target?.focus());
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
241
278
|
changelist.classList.toggle("ba-filters-open");
|
|
242
279
|
sync();
|
|
243
280
|
if (changelist.classList.contains("ba-filters-open")) {
|
|
@@ -249,15 +286,69 @@
|
|
|
249
286
|
|
|
250
287
|
if (close) {
|
|
251
288
|
close.addEventListener("click", () => {
|
|
289
|
+
setCollapsed(true);
|
|
252
290
|
changelist.classList.remove("ba-filters-open");
|
|
253
291
|
sync();
|
|
254
292
|
toggle.focus();
|
|
255
293
|
});
|
|
256
294
|
}
|
|
257
295
|
|
|
296
|
+
if (DESKTOP.addEventListener) {
|
|
297
|
+
DESKTOP.addEventListener("change", () => {
|
|
298
|
+
if (DESKTOP.matches) {
|
|
299
|
+
changelist.classList.toggle(
|
|
300
|
+
"ba-filters-collapsed",
|
|
301
|
+
localStorage.getItem(FILTERS_KEY) === "true",
|
|
302
|
+
);
|
|
303
|
+
changelist.classList.remove("ba-filters-open");
|
|
304
|
+
}
|
|
305
|
+
sync();
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
258
309
|
sync();
|
|
259
310
|
}
|
|
260
311
|
|
|
312
|
+
function initFacetPreference() {
|
|
313
|
+
const panel = document.getElementById("changelist-filter");
|
|
314
|
+
if (!panel) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const links = document.querySelectorAll(
|
|
319
|
+
".ba-filters-actions .hidelink, .ba-filters-actions .viewlink",
|
|
320
|
+
);
|
|
321
|
+
if (!links.length) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
links.forEach((link) => {
|
|
326
|
+
link.addEventListener("click", () => {
|
|
327
|
+
const show = link.classList.contains("viewlink");
|
|
328
|
+
localStorage.setItem(FACETS_KEY, show ? "true" : "false");
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const stored = localStorage.getItem(FACETS_KEY);
|
|
333
|
+
if (stored !== "true" && stored !== "false") {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const url = new URL(window.location.href);
|
|
338
|
+
const hasFacets = url.searchParams.has("_facets");
|
|
339
|
+
const showFacets = stored === "true";
|
|
340
|
+
if (hasFacets === showFacets) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (showFacets) {
|
|
345
|
+
url.searchParams.set("_facets", "1");
|
|
346
|
+
} else {
|
|
347
|
+
url.searchParams.delete("_facets");
|
|
348
|
+
}
|
|
349
|
+
window.location.replace(url.toString());
|
|
350
|
+
}
|
|
351
|
+
|
|
261
352
|
function initDirtyGuard() {
|
|
262
353
|
const form =
|
|
263
354
|
document.querySelector(".ba-change-form form") ||
|
|
@@ -327,6 +418,7 @@
|
|
|
327
418
|
function initAll() {
|
|
328
419
|
initSidebar();
|
|
329
420
|
initFilterDisclosure();
|
|
421
|
+
initFacetPreference();
|
|
330
422
|
initDirtyGuard();
|
|
331
423
|
initErrorFocus();
|
|
332
424
|
initAccessibility();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-bootstrap6-admin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A modern Bootstrap 6 skin for the Django admin.
|
|
5
5
|
Author-email: Aliberk Sandıkçı <git@asandikci.com>
|
|
6
6
|
Maintainer-email: Aliberk Sandıkçı <git@asandikci.com>
|
|
@@ -57,12 +57,18 @@ permissions and JavaScript remain in charge.
|
|
|
57
57
|
with a backdrop (mobile).
|
|
58
58
|
- Dashboard with application cards, model shortcuts and recent activity.
|
|
59
59
|
- Changelist with search, date hierarchy, collapsible filters, sortable
|
|
60
|
-
headers, bulk actions and Bootstrap pagination.
|
|
60
|
+
headers, bulk actions and Bootstrap pagination. The desktop filter panel can
|
|
61
|
+
be collapsed, and both its state and the "Show counts" choice are remembered
|
|
62
|
+
between pages.
|
|
63
|
+
- Subtle vertical rules separate columns in changelists, inline tables and the
|
|
64
|
+
object history.
|
|
61
65
|
- Change form with card-based fieldsets, collapsible sections, a clear save
|
|
62
66
|
bar, tabular/stacked inlines and related-object popups.
|
|
63
67
|
- Modern login, logout and password change pages.
|
|
64
68
|
- Light, dark and system themes. The existing Django `theme` localStorage
|
|
65
69
|
preference is synchronised with Bootstrap's `data-bs-theme` attribute.
|
|
70
|
+
- Dark-theme secondary text, table headers, filter links and help text use
|
|
71
|
+
higher-contrast tokens for better readability.
|
|
66
72
|
- Soft fade-in/fade-out transition when switching themes, skipped
|
|
67
73
|
automatically for users who prefer reduced motion.
|
|
68
74
|
- Every click changes the visible theme: if `auto` would resolve to the theme
|
|
@@ -76,6 +76,8 @@ class AdminUiTests(TestCase):
|
|
|
76
76
|
'id="changelist-search"',
|
|
77
77
|
'id="searchbar"',
|
|
78
78
|
'id="changelist-filter"',
|
|
79
|
+
'id="ba-filters-toggle"',
|
|
80
|
+
'id="ba-filters-close"',
|
|
79
81
|
'id="action-toggle"',
|
|
80
82
|
'id="date-hierarchy-label"',
|
|
81
83
|
'class="actions ba-actions"',
|
|
@@ -119,7 +121,6 @@ class AdminUiTests(TestCase):
|
|
|
119
121
|
def test_changelist_search_and_pagination(self):
|
|
120
122
|
response = self.client.get(reverse("admin:testapp_book_changelist"), {"q": "Django"})
|
|
121
123
|
self.assertContains(response, "Django for Everyone")
|
|
122
|
-
|
|
123
124
|
for index in range(105):
|
|
124
125
|
Book.objects.create(
|
|
125
126
|
title=f"Extra book {index:03d}",
|
|
@@ -134,6 +135,15 @@ class AdminUiTests(TestCase):
|
|
|
134
135
|
self.assertContains(response, "?p=1")
|
|
135
136
|
self.assertContains(response, 'aria-current="page">2')
|
|
136
137
|
|
|
138
|
+
def test_facet_count_toggle_links(self):
|
|
139
|
+
url = reverse("admin:testapp_book_changelist")
|
|
140
|
+
|
|
141
|
+
response = self.client.get(url)
|
|
142
|
+
self.assertContains(response, "Show counts")
|
|
143
|
+
|
|
144
|
+
response = self.client.get(url, {"_facets": "1"})
|
|
145
|
+
self.assertContains(response, "Hide counts")
|
|
146
|
+
|
|
137
147
|
def test_change_form_keeps_widgets_and_submit_contract(self):
|
|
138
148
|
response = self.client.get(reverse("admin:testapp_book_change", args=[self.book.pk]))
|
|
139
149
|
|
|
@@ -46,3 +46,19 @@ class PackageAssetsTests(SimpleTestCase):
|
|
|
46
46
|
self.assertIn(".ba-theme-fade", admin_css)
|
|
47
47
|
self.assertIn(".ba-theme-fade.is-active", admin_css)
|
|
48
48
|
self.assertIn("transition: opacity 200ms ease", admin_css)
|
|
49
|
+
|
|
50
|
+
def test_changelist_ux_assets(self):
|
|
51
|
+
static_dir = Path(django_bootstrap6_admin.__file__).parent / "static"
|
|
52
|
+
admin_js = (static_dir / "django_bootstrap6_admin" / "js" / "admin.js").read_text(
|
|
53
|
+
encoding="utf-8"
|
|
54
|
+
)
|
|
55
|
+
admin_css = (static_dir / "django_bootstrap6_admin" / "css" / "admin.css").read_text(
|
|
56
|
+
encoding="utf-8"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
self.assertIn("django.admin.showFacets", admin_js)
|
|
60
|
+
self.assertIn("django.admin.filtersCollapsed", admin_js)
|
|
61
|
+
self.assertIn("ba-filters-collapsed", admin_css)
|
|
62
|
+
self.assertIn("border-inline-end: 1px solid var(--bs-border-muted)", admin_css)
|
|
63
|
+
self.assertIn("appearance: none", admin_css)
|
|
64
|
+
self.assertIn("--bs-fg-4: #9fb1c4", admin_css)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/src/django_bootstrap6_admin/apps.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bootstrap6_admin-0.1.2 → django_bootstrap6_admin-0.2.0}/tests/js/theme_toggle.test.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|