diff --git a/babybuddy/settings/base.py b/babybuddy/settings/base.py index 285a1abf..65c9005b 100644 --- a/babybuddy/settings/base.py +++ b/babybuddy/settings/base.py @@ -79,7 +79,7 @@ ROOT_URLCONF = "babybuddy.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": ["babybuddy/templates/error"], + "DIRS": ["babybuddy/templates", "babybuddy/templates/error"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ diff --git a/babybuddy/templates/babybuddy/site_settings_form.html b/babybuddy/templates/dbsettings/site_settings.html similarity index 100% rename from babybuddy/templates/babybuddy/site_settings_form.html rename to babybuddy/templates/dbsettings/site_settings.html diff --git a/requirements.txt b/requirements.txt index 62957456..f4681843 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,13 @@ -i https://pypi.python.org/simple asgiref==3.6.0 ; python_version >= '3.7' -boto3==1.26.114 -botocore==1.29.114 ; python_version >= '3.7' +boto3==1.26.123 +botocore==1.29.123 ; python_version >= '3.7' defusedxml==0.7.1 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' diff-match-patch==20200713 ; python_version >= '2.7' -dj-database-url==1.3.0 +dj-database-url==2.0.0 django==4.2 django-appconf==1.0.5 ; python_version >= '3.1' -django-axes==5.41.0 +django-axes==5.41.1 django-dbsettings==1.3.0 django-filter==23.1 django-imagekit==4.1.0 @@ -19,7 +19,7 @@ django-taggit==3.1.0 django-widget-tweaks==1.4.12 djangorestframework==3.14.0 et-xmlfile==1.1.0 ; python_version >= '3.6' -faker==18.4.0 +faker==18.6.0 gunicorn==20.1.0 jmespath==1.0.1 ; python_version >= '3.7' markuppy==1.14 @@ -37,9 +37,9 @@ pytz==2023.3 pyyaml==6.0 s3transfer==0.6.0 ; python_version >= '3.7' segno==1.5.2 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -setuptools==67.6.1 ; python_version >= '3.7' +setuptools==67.7.2 ; python_version >= '3.7' six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -sqlparse==0.4.3 ; python_version >= '3.5' +sqlparse==0.4.4 ; python_version >= '3.5' tablib[html,ods,xls,xlsx,yaml]==3.4.0 ; python_version >= '3.7' tenacity==8.2.2 ; python_version >= '3.6' typing-extensions==4.5.0 ; python_version >= '3.7' diff --git a/static/admin/css/base.01580fff1759.css.gz b/static/admin/css/base.01580fff1759.css.gz deleted file mode 100644 index 4853b919..00000000 Binary files a/static/admin/css/base.01580fff1759.css.gz and /dev/null differ diff --git a/static/admin/css/base.01580fff1759.css b/static/admin/css/base.64976e0f7339.css similarity index 87% rename from static/admin/css/base.01580fff1759.css rename to static/admin/css/base.64976e0f7339.css index 81e4b8d1..456af38a 100644 --- a/static/admin/css/base.01580fff1759.css +++ b/static/admin/css/base.64976e0f7339.css @@ -2,59 +2,90 @@ DJANGO Admin styles */ -@import url("fonts.168bab448fee.css"); - /* VARIABLE DEFINITIONS */ +html[data-theme="light"], :root { - --primary: #79aec8; - --secondary: #417690; - --accent: #f5dd5d; - --primary-fg: #fff; + --primary: #79aec8; + --secondary: #417690; + --accent: #f5dd5d; + --primary-fg: #fff; - --body-fg: #333; - --body-bg: #fff; - --body-quiet-color: #666; - --body-loud-color: #000; + --body-fg: #333; + --body-bg: #fff; + --body-quiet-color: #666; + --body-loud-color: #000; - --header-color: #ffc; - --header-branding-color: var(--accent); - --header-bg: var(--secondary); - --header-link-color: var(--primary-fg); + --header-color: #ffc; + --header-branding-color: var(--accent); + --header-bg: var(--secondary); + --header-link-color: var(--primary-fg); - --breadcrumbs-fg: #c4dce8; - --breadcrumbs-link-fg: var(--body-bg); - --breadcrumbs-bg: var(--primary); + --breadcrumbs-fg: #c4dce8; + --breadcrumbs-link-fg: var(--body-bg); + --breadcrumbs-bg: var(--primary); - --link-fg: #447e9b; - --link-hover-color: #036; - --link-selected-fg: #5b80b2; + --link-fg: #417893; + --link-hover-color: #036; + --link-selected-fg: #5b80b2; - --hairline-color: #e8e8e8; - --border-color: #ccc; + --hairline-color: #e8e8e8; + --border-color: #ccc; - --error-fg: #ba2121; + --error-fg: #ba2121; - --message-success-bg: #dfd; - --message-warning-bg: #ffc; - --message-error-bg: #ffefef; + --message-success-bg: #dfd; + --message-warning-bg: #ffc; + --message-error-bg: #ffefef; - --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ - --selected-bg: #e4e4e4; /* E.g. selected table cells */ - --selected-row: #ffc; + --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ + --selected-bg: #e4e4e4; /* E.g. selected table cells */ + --selected-row: #ffc; - --button-fg: #fff; - --button-bg: var(--primary); - --button-hover-bg: #609ab6; - --default-button-bg: var(--secondary); - --default-button-hover-bg: #205067; - --close-button-bg: #888; /* Previously #bbb, contrast 1.92 */ - --close-button-hover-bg: #747474; - --delete-button-bg: #ba2121; - --delete-button-hover-bg: #a41515; + --button-fg: #fff; + --button-bg: var(--primary); + --button-hover-bg: #609ab6; + --default-button-bg: var(--secondary); + --default-button-hover-bg: #205067; + --close-button-bg: #747474; + --close-button-hover-bg: #333; + --delete-button-bg: #ba2121; + --delete-button-hover-bg: #a41515; - --object-tools-fg: var(--button-fg); - --object-tools-bg: var(--close-button-bg); - --object-tools-hover-bg: var(--close-button-hover-bg); + --object-tools-fg: var(--button-fg); + --object-tools-bg: var(--close-button-bg); + --object-tools-hover-bg: var(--close-button-hover-bg); + + --font-family-primary: + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + system-ui, + Roboto, + "Helvetica Neue", + Arial, + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; + --font-family-monospace: + ui-monospace, + Menlo, + Monaco, + "Cascadia Mono", + "Segoe UI Mono", + "Roboto Mono", + "Oxygen Mono", + "Ubuntu Monospace", + "Source Code Pro", + "Fira Mono", + "Droid Sans Mono", + "Courier New", + monospace, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; } html, body { @@ -65,7 +96,7 @@ body { margin: 0; padding: 0; font-size: 0.875rem; - font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; + font-family: var(--font-family-primary); color: var(--body-fg); background: var(--body-bg); } @@ -163,7 +194,7 @@ li ul { li, dt, dd { font-size: 0.8125rem; - line-height: 20px; + line-height: 1.25rem; } dt { @@ -197,7 +228,7 @@ blockquote { } code, pre { - font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; + font-family: var(--font-family-monospace); color: var(--body-quiet-color); font-size: 0.75rem; overflow-x: auto; @@ -277,7 +308,7 @@ table { td, th { font-size: 0.8125rem; - line-height: 16px; + line-height: 1rem; border-bottom: 1px solid var(--hairline-color); vertical-align: top; padding: 8px; @@ -441,7 +472,7 @@ input, textarea, select, .form-row p, form .button { margin: 2px 0; padding: 2px 3px; vertical-align: middle; - font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif; + font-family: var(--font-family-primary); font-weight: normal; font-size: 0.8125rem; } @@ -470,7 +501,7 @@ textarea:focus, select:focus, .vTextField:focus { } select { - height: 30px; + height: 1.875rem; } select[multiple] { @@ -506,7 +537,6 @@ a.button { } .button.default, input[type=submit].default, .submit-row input.default { - float: right; border: none; font-weight: 400; background: var(--default-button-bg); @@ -731,7 +761,7 @@ a.deletelink:focus, a.deletelink:hover { display: block; float: left; margin-left: 5px; - height: 16px; + height: 1rem; } .object-tools a { @@ -815,6 +845,20 @@ a.deletelink:focus, a.deletelink:hover { max-width: 100%; } +.skip-to-content-link { + position: absolute; + top: -999px; + margin: 5px; + padding: 5px; + background: var(--body-bg); + z-index: 1; +} + +.skip-to-content-link:focus { + left: 0px; + top: 0px; +} + #content { padding: 20px 40px; } @@ -887,12 +931,13 @@ a.deletelink:focus, a.deletelink:hover { } #branding { - float: left; + display: flex; } #branding h1 { padding: 0; - margin: 0 20px 0 0; + margin: 0; + margin-inline-end: 20px; font-weight: 300; font-size: 1.5rem; color: var(--header-branding-color); @@ -922,7 +967,7 @@ a.deletelink:focus, a.deletelink:hover { background: none; border: 0; cursor: pointer; - font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; + font-family: var(--font-family-primary); } #user-tools { @@ -1014,8 +1059,8 @@ a.deletelink:focus, a.deletelink:hover { .delete-confirmation form .cancel-link { display: inline-block; vertical-align: middle; - height: 15px; - line-height: 15px; + height: 0.9375rem; + line-height: 0.9375rem; border-radius: 4px; padding: 10px 15px; color: var(--button-fg); @@ -1087,3 +1132,7 @@ a.deletelink:focus, a.deletelink:hover { color: white; background: var(--link-hover-color); } + +.base-svgs { + display: none; +} diff --git a/static/admin/css/base.64976e0f7339.css.gz b/static/admin/css/base.64976e0f7339.css.gz new file mode 100644 index 00000000..e8dc2686 Binary files /dev/null and b/static/admin/css/base.64976e0f7339.css.gz differ diff --git a/static/admin/css/base.css b/static/admin/css/base.css index 1ff93e24..72f4ae16 100644 --- a/static/admin/css/base.css +++ b/static/admin/css/base.css @@ -2,59 +2,90 @@ DJANGO Admin styles */ -@import url(fonts.css); - /* VARIABLE DEFINITIONS */ +html[data-theme="light"], :root { - --primary: #79aec8; - --secondary: #417690; - --accent: #f5dd5d; - --primary-fg: #fff; + --primary: #79aec8; + --secondary: #417690; + --accent: #f5dd5d; + --primary-fg: #fff; - --body-fg: #333; - --body-bg: #fff; - --body-quiet-color: #666; - --body-loud-color: #000; + --body-fg: #333; + --body-bg: #fff; + --body-quiet-color: #666; + --body-loud-color: #000; - --header-color: #ffc; - --header-branding-color: var(--accent); - --header-bg: var(--secondary); - --header-link-color: var(--primary-fg); + --header-color: #ffc; + --header-branding-color: var(--accent); + --header-bg: var(--secondary); + --header-link-color: var(--primary-fg); - --breadcrumbs-fg: #c4dce8; - --breadcrumbs-link-fg: var(--body-bg); - --breadcrumbs-bg: var(--primary); + --breadcrumbs-fg: #c4dce8; + --breadcrumbs-link-fg: var(--body-bg); + --breadcrumbs-bg: var(--primary); - --link-fg: #447e9b; - --link-hover-color: #036; - --link-selected-fg: #5b80b2; + --link-fg: #417893; + --link-hover-color: #036; + --link-selected-fg: #5b80b2; - --hairline-color: #e8e8e8; - --border-color: #ccc; + --hairline-color: #e8e8e8; + --border-color: #ccc; - --error-fg: #ba2121; + --error-fg: #ba2121; - --message-success-bg: #dfd; - --message-warning-bg: #ffc; - --message-error-bg: #ffefef; + --message-success-bg: #dfd; + --message-warning-bg: #ffc; + --message-error-bg: #ffefef; - --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ - --selected-bg: #e4e4e4; /* E.g. selected table cells */ - --selected-row: #ffc; + --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ + --selected-bg: #e4e4e4; /* E.g. selected table cells */ + --selected-row: #ffc; - --button-fg: #fff; - --button-bg: var(--primary); - --button-hover-bg: #609ab6; - --default-button-bg: var(--secondary); - --default-button-hover-bg: #205067; - --close-button-bg: #888; /* Previously #bbb, contrast 1.92 */ - --close-button-hover-bg: #747474; - --delete-button-bg: #ba2121; - --delete-button-hover-bg: #a41515; + --button-fg: #fff; + --button-bg: var(--primary); + --button-hover-bg: #609ab6; + --default-button-bg: var(--secondary); + --default-button-hover-bg: #205067; + --close-button-bg: #747474; + --close-button-hover-bg: #333; + --delete-button-bg: #ba2121; + --delete-button-hover-bg: #a41515; - --object-tools-fg: var(--button-fg); - --object-tools-bg: var(--close-button-bg); - --object-tools-hover-bg: var(--close-button-hover-bg); + --object-tools-fg: var(--button-fg); + --object-tools-bg: var(--close-button-bg); + --object-tools-hover-bg: var(--close-button-hover-bg); + + --font-family-primary: + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + system-ui, + Roboto, + "Helvetica Neue", + Arial, + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; + --font-family-monospace: + ui-monospace, + Menlo, + Monaco, + "Cascadia Mono", + "Segoe UI Mono", + "Roboto Mono", + "Oxygen Mono", + "Ubuntu Monospace", + "Source Code Pro", + "Fira Mono", + "Droid Sans Mono", + "Courier New", + monospace, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; } html, body { @@ -65,7 +96,7 @@ body { margin: 0; padding: 0; font-size: 0.875rem; - font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; + font-family: var(--font-family-primary); color: var(--body-fg); background: var(--body-bg); } @@ -163,7 +194,7 @@ li ul { li, dt, dd { font-size: 0.8125rem; - line-height: 20px; + line-height: 1.25rem; } dt { @@ -197,7 +228,7 @@ blockquote { } code, pre { - font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; + font-family: var(--font-family-monospace); color: var(--body-quiet-color); font-size: 0.75rem; overflow-x: auto; @@ -277,7 +308,7 @@ table { td, th { font-size: 0.8125rem; - line-height: 16px; + line-height: 1rem; border-bottom: 1px solid var(--hairline-color); vertical-align: top; padding: 8px; @@ -441,7 +472,7 @@ input, textarea, select, .form-row p, form .button { margin: 2px 0; padding: 2px 3px; vertical-align: middle; - font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif; + font-family: var(--font-family-primary); font-weight: normal; font-size: 0.8125rem; } @@ -470,7 +501,7 @@ textarea:focus, select:focus, .vTextField:focus { } select { - height: 30px; + height: 1.875rem; } select[multiple] { @@ -506,7 +537,6 @@ a.button { } .button.default, input[type=submit].default, .submit-row input.default { - float: right; border: none; font-weight: 400; background: var(--default-button-bg); @@ -731,7 +761,7 @@ a.deletelink:focus, a.deletelink:hover { display: block; float: left; margin-left: 5px; - height: 16px; + height: 1rem; } .object-tools a { @@ -815,6 +845,20 @@ a.deletelink:focus, a.deletelink:hover { max-width: 100%; } +.skip-to-content-link { + position: absolute; + top: -999px; + margin: 5px; + padding: 5px; + background: var(--body-bg); + z-index: 1; +} + +.skip-to-content-link:focus { + left: 0px; + top: 0px; +} + #content { padding: 20px 40px; } @@ -887,12 +931,13 @@ a.deletelink:focus, a.deletelink:hover { } #branding { - float: left; + display: flex; } #branding h1 { padding: 0; - margin: 0 20px 0 0; + margin: 0; + margin-inline-end: 20px; font-weight: 300; font-size: 1.5rem; color: var(--header-branding-color); @@ -922,7 +967,7 @@ a.deletelink:focus, a.deletelink:hover { background: none; border: 0; cursor: pointer; - font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; + font-family: var(--font-family-primary); } #user-tools { @@ -1014,8 +1059,8 @@ a.deletelink:focus, a.deletelink:hover { .delete-confirmation form .cancel-link { display: inline-block; vertical-align: middle; - height: 15px; - line-height: 15px; + height: 0.9375rem; + line-height: 0.9375rem; border-radius: 4px; padding: 10px 15px; color: var(--button-fg); @@ -1087,3 +1132,7 @@ a.deletelink:focus, a.deletelink:hover { color: white; background: var(--link-hover-color); } + +.base-svgs { + display: none; +} diff --git a/static/admin/css/base.css.gz b/static/admin/css/base.css.gz index 77fe9a81..fa107378 100644 Binary files a/static/admin/css/base.css.gz and b/static/admin/css/base.css.gz differ diff --git a/static/admin/css/changelists.ae46354f4e80.css.gz b/static/admin/css/changelists.ae46354f4e80.css.gz deleted file mode 100644 index ba2f6bad..00000000 Binary files a/static/admin/css/changelists.ae46354f4e80.css.gz and /dev/null differ diff --git a/static/admin/css/changelists.css b/static/admin/css/changelists.css index 68ba5578..641dccd7 100644 --- a/static/admin/css/changelists.css +++ b/static/admin/css/changelists.css @@ -90,7 +90,7 @@ } #toolbar #searchbar { - height: 19px; + height: 1.1875rem; border: 1px solid var(--border-color); padding: 2px 5px; margin: 0; @@ -223,27 +223,24 @@ /* DATE DRILLDOWN */ -.change-list ul.toplinks { - display: block; - float: left; - padding: 0; - margin: 0; - width: 100%; -} - -.change-list ul.toplinks li { - padding: 3px 6px; +.change-list .toplinks { + display: flex; + padding-bottom: 5px; + flex-wrap: wrap; + gap: 3px 17px; font-weight: bold; - list-style-type: none; - display: inline-block; } -.change-list ul.toplinks .date-back a { +.change-list .toplinks a { + font-size: 0.8125rem; +} + +.change-list .toplinks .date-back { color: var(--body-quiet-color); } -.change-list ul.toplinks .date-back a:focus, -.change-list ul.toplinks .date-back a:hover { +.change-list .toplinks .date-back:focus, +.change-list .toplinks .date-back:hover { color: var(--link-hover-color); } @@ -258,16 +255,22 @@ vertical-align: baseline; } +/* Once the :has() pseudo-class is supported by all browsers, the tr.selected + selector and the JS adding the class can be removed. */ #changelist table tbody tr.selected { background-color: var(--selected-row); } +#changelist table tbody tr:has(input[type=checkbox]:checked) { + background-color: var(--selected-row); +} + #changelist .actions { padding: 10px; background: var(--body-bg); border-top: none; border-bottom: none; - line-height: 24px; + line-height: 1.5rem; color: var(--body-quiet-color); width: 100%; } @@ -286,7 +289,7 @@ #changelist .actions select { vertical-align: top; - height: 24px; + height: 1.5rem; color: var(--body-fg); border: 1px solid var(--border-color); border-radius: 4px; @@ -313,7 +316,7 @@ background: var(--body-bg); box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; cursor: pointer; - height: 24px; + height: 1.5rem; line-height: 1; padding: 4px 8px; margin: 0; diff --git a/static/admin/css/changelists.css.gz b/static/admin/css/changelists.css.gz index ba2f6bad..f90753ce 100644 Binary files a/static/admin/css/changelists.css.gz and b/static/admin/css/changelists.css.gz differ diff --git a/static/admin/css/changelists.ae46354f4e80.css b/static/admin/css/changelists.f4631a29abad.css similarity index 90% rename from static/admin/css/changelists.ae46354f4e80.css rename to static/admin/css/changelists.f4631a29abad.css index 68ba5578..641dccd7 100644 --- a/static/admin/css/changelists.ae46354f4e80.css +++ b/static/admin/css/changelists.f4631a29abad.css @@ -90,7 +90,7 @@ } #toolbar #searchbar { - height: 19px; + height: 1.1875rem; border: 1px solid var(--border-color); padding: 2px 5px; margin: 0; @@ -223,27 +223,24 @@ /* DATE DRILLDOWN */ -.change-list ul.toplinks { - display: block; - float: left; - padding: 0; - margin: 0; - width: 100%; -} - -.change-list ul.toplinks li { - padding: 3px 6px; +.change-list .toplinks { + display: flex; + padding-bottom: 5px; + flex-wrap: wrap; + gap: 3px 17px; font-weight: bold; - list-style-type: none; - display: inline-block; } -.change-list ul.toplinks .date-back a { +.change-list .toplinks a { + font-size: 0.8125rem; +} + +.change-list .toplinks .date-back { color: var(--body-quiet-color); } -.change-list ul.toplinks .date-back a:focus, -.change-list ul.toplinks .date-back a:hover { +.change-list .toplinks .date-back:focus, +.change-list .toplinks .date-back:hover { color: var(--link-hover-color); } @@ -258,16 +255,22 @@ vertical-align: baseline; } +/* Once the :has() pseudo-class is supported by all browsers, the tr.selected + selector and the JS adding the class can be removed. */ #changelist table tbody tr.selected { background-color: var(--selected-row); } +#changelist table tbody tr:has(input[type=checkbox]:checked) { + background-color: var(--selected-row); +} + #changelist .actions { padding: 10px; background: var(--body-bg); border-top: none; border-bottom: none; - line-height: 24px; + line-height: 1.5rem; color: var(--body-quiet-color); width: 100%; } @@ -286,7 +289,7 @@ #changelist .actions select { vertical-align: top; - height: 24px; + height: 1.5rem; color: var(--body-fg); border: 1px solid var(--border-color); border-radius: 4px; @@ -313,7 +316,7 @@ background: var(--body-bg); box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; cursor: pointer; - height: 24px; + height: 1.5rem; line-height: 1; padding: 4px 8px; margin: 0; diff --git a/static/admin/css/changelists.f4631a29abad.css.gz b/static/admin/css/changelists.f4631a29abad.css.gz new file mode 100644 index 00000000..f90753ce Binary files /dev/null and b/static/admin/css/changelists.f4631a29abad.css.gz differ diff --git a/static/admin/css/dark_mode.4e3d1504ca81.css b/static/admin/css/dark_mode.4e3d1504ca81.css deleted file mode 100644 index 547717cc..00000000 --- a/static/admin/css/dark_mode.4e3d1504ca81.css +++ /dev/null @@ -1,33 +0,0 @@ -@media (prefers-color-scheme: dark) { - :root { - --primary: #264b5d; - --primary-fg: #f7f7f7; - - --body-fg: #eeeeee; - --body-bg: #121212; - --body-quiet-color: #e0e0e0; - --body-loud-color: #ffffff; - - --breadcrumbs-link-fg: #e0e0e0; - --breadcrumbs-bg: var(--primary); - - --link-fg: #81d4fa; - --link-hover-color: #4ac1f7; - --link-selected-fg: #6f94c6; - - --hairline-color: #272727; - --border-color: #353535; - - --error-fg: #e35f5f; - --message-success-bg: #006b1b; - --message-warning-bg: #583305; - --message-error-bg: #570808; - - --darkened-bg: #212121; - --selected-bg: #1b1b1b; - --selected-row: #00363a; - - --close-button-bg: #333333; - --close-button-hover-bg: #666666; - } - } diff --git a/static/admin/css/dark_mode.4e3d1504ca81.css.gz b/static/admin/css/dark_mode.4e3d1504ca81.css.gz deleted file mode 100644 index 25f338e5..00000000 Binary files a/static/admin/css/dark_mode.4e3d1504ca81.css.gz and /dev/null differ diff --git a/static/admin/css/dark_mode.css b/static/admin/css/dark_mode.css index 547717cc..6d08233a 100644 --- a/static/admin/css/dark_mode.css +++ b/static/admin/css/dark_mode.css @@ -31,3 +31,107 @@ --close-button-hover-bg: #666666; } } + + +html[data-theme="dark"] { + --primary: #264b5d; + --primary-fg: #f7f7f7; + + --body-fg: #eeeeee; + --body-bg: #121212; + --body-quiet-color: #e0e0e0; + --body-loud-color: #ffffff; + + --breadcrumbs-link-fg: #e0e0e0; + --breadcrumbs-bg: var(--primary); + + --link-fg: #81d4fa; + --link-hover-color: #4ac1f7; + --link-selected-fg: #6f94c6; + + --hairline-color: #272727; + --border-color: #353535; + + --error-fg: #e35f5f; + --message-success-bg: #006b1b; + --message-warning-bg: #583305; + --message-error-bg: #570808; + + --darkened-bg: #212121; + --selected-bg: #1b1b1b; + --selected-row: #00363a; + + --close-button-bg: #333333; + --close-button-hover-bg: #666666; +} + +/* THEME SWITCH */ +.theme-toggle { + cursor: pointer; + border: none; + padding: 0; + background: transparent; + vertical-align: middle; + margin-inline-start: 5px; + margin-top: -1px; +} + +.theme-toggle svg { + vertical-align: middle; + height: 1rem; + width: 1rem; + display: none; +} + +/* +Fully hide screen reader text so we only show the one matching the current +theme. +*/ +.theme-toggle .visually-hidden { + display: none; +} + +html[data-theme="auto"] .theme-toggle .theme-label-when-auto { + display: block; +} + +html[data-theme="dark"] .theme-toggle .theme-label-when-dark { + display: block; +} + +html[data-theme="light"] .theme-toggle .theme-label-when-light { + display: block; +} + +/* ICONS */ +.theme-toggle svg.theme-icon-when-auto, +.theme-toggle svg.theme-icon-when-dark, +.theme-toggle svg.theme-icon-when-light { + fill: var(--header-link-color); + color: var(--header-bg); +} + +html[data-theme="auto"] .theme-toggle svg.theme-icon-when-auto { + display: block; +} + +html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark { + display: block; +} + +html[data-theme="light"] .theme-toggle svg.theme-icon-when-light { + display: block; +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0,0,0,0); + white-space: nowrap; + border: 0; + color: var(--body-fg); + background-color: var(--body-bg); +} diff --git a/static/admin/css/dark_mode.css.gz b/static/admin/css/dark_mode.css.gz index 25f338e5..faebccea 100644 Binary files a/static/admin/css/dark_mode.css.gz and b/static/admin/css/dark_mode.css.gz differ diff --git a/static/admin/css/dark_mode.ef27a31af300.css b/static/admin/css/dark_mode.ef27a31af300.css new file mode 100644 index 00000000..6d08233a --- /dev/null +++ b/static/admin/css/dark_mode.ef27a31af300.css @@ -0,0 +1,137 @@ +@media (prefers-color-scheme: dark) { + :root { + --primary: #264b5d; + --primary-fg: #f7f7f7; + + --body-fg: #eeeeee; + --body-bg: #121212; + --body-quiet-color: #e0e0e0; + --body-loud-color: #ffffff; + + --breadcrumbs-link-fg: #e0e0e0; + --breadcrumbs-bg: var(--primary); + + --link-fg: #81d4fa; + --link-hover-color: #4ac1f7; + --link-selected-fg: #6f94c6; + + --hairline-color: #272727; + --border-color: #353535; + + --error-fg: #e35f5f; + --message-success-bg: #006b1b; + --message-warning-bg: #583305; + --message-error-bg: #570808; + + --darkened-bg: #212121; + --selected-bg: #1b1b1b; + --selected-row: #00363a; + + --close-button-bg: #333333; + --close-button-hover-bg: #666666; + } + } + + +html[data-theme="dark"] { + --primary: #264b5d; + --primary-fg: #f7f7f7; + + --body-fg: #eeeeee; + --body-bg: #121212; + --body-quiet-color: #e0e0e0; + --body-loud-color: #ffffff; + + --breadcrumbs-link-fg: #e0e0e0; + --breadcrumbs-bg: var(--primary); + + --link-fg: #81d4fa; + --link-hover-color: #4ac1f7; + --link-selected-fg: #6f94c6; + + --hairline-color: #272727; + --border-color: #353535; + + --error-fg: #e35f5f; + --message-success-bg: #006b1b; + --message-warning-bg: #583305; + --message-error-bg: #570808; + + --darkened-bg: #212121; + --selected-bg: #1b1b1b; + --selected-row: #00363a; + + --close-button-bg: #333333; + --close-button-hover-bg: #666666; +} + +/* THEME SWITCH */ +.theme-toggle { + cursor: pointer; + border: none; + padding: 0; + background: transparent; + vertical-align: middle; + margin-inline-start: 5px; + margin-top: -1px; +} + +.theme-toggle svg { + vertical-align: middle; + height: 1rem; + width: 1rem; + display: none; +} + +/* +Fully hide screen reader text so we only show the one matching the current +theme. +*/ +.theme-toggle .visually-hidden { + display: none; +} + +html[data-theme="auto"] .theme-toggle .theme-label-when-auto { + display: block; +} + +html[data-theme="dark"] .theme-toggle .theme-label-when-dark { + display: block; +} + +html[data-theme="light"] .theme-toggle .theme-label-when-light { + display: block; +} + +/* ICONS */ +.theme-toggle svg.theme-icon-when-auto, +.theme-toggle svg.theme-icon-when-dark, +.theme-toggle svg.theme-icon-when-light { + fill: var(--header-link-color); + color: var(--header-bg); +} + +html[data-theme="auto"] .theme-toggle svg.theme-icon-when-auto { + display: block; +} + +html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark { + display: block; +} + +html[data-theme="light"] .theme-toggle svg.theme-icon-when-light { + display: block; +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0,0,0,0); + white-space: nowrap; + border: 0; + color: var(--body-fg); + background-color: var(--body-bg); +} diff --git a/static/admin/css/dark_mode.ef27a31af300.css.gz b/static/admin/css/dark_mode.ef27a31af300.css.gz new file mode 100644 index 00000000..faebccea Binary files /dev/null and b/static/admin/css/dark_mode.ef27a31af300.css.gz differ diff --git a/static/admin/css/dashboard.be83f13e4369.css.gz b/static/admin/css/dashboard.be83f13e4369.css.gz deleted file mode 100644 index 372fe7e7..00000000 Binary files a/static/admin/css/dashboard.be83f13e4369.css.gz and /dev/null differ diff --git a/static/admin/css/dashboard.css b/static/admin/css/dashboard.css index 91d6efde..242b81a4 100644 --- a/static/admin/css/dashboard.css +++ b/static/admin/css/dashboard.css @@ -1,4 +1,7 @@ /* DASHBOARD */ +.dashboard td, .dashboard th { + word-break: break-word; +} .dashboard .module table th { width: 100%; diff --git a/static/admin/css/dashboard.css.gz b/static/admin/css/dashboard.css.gz index 372fe7e7..06db5fd5 100644 Binary files a/static/admin/css/dashboard.css.gz and b/static/admin/css/dashboard.css.gz differ diff --git a/static/admin/css/dashboard.be83f13e4369.css b/static/admin/css/dashboard.e90f2068217b.css similarity index 86% rename from static/admin/css/dashboard.be83f13e4369.css rename to static/admin/css/dashboard.e90f2068217b.css index 91d6efde..242b81a4 100644 --- a/static/admin/css/dashboard.be83f13e4369.css +++ b/static/admin/css/dashboard.e90f2068217b.css @@ -1,4 +1,7 @@ /* DASHBOARD */ +.dashboard td, .dashboard th { + word-break: break-word; +} .dashboard .module table th { width: 100%; diff --git a/static/admin/css/dashboard.e90f2068217b.css.gz b/static/admin/css/dashboard.e90f2068217b.css.gz new file mode 100644 index 00000000..06db5fd5 Binary files /dev/null and b/static/admin/css/dashboard.e90f2068217b.css.gz differ diff --git a/static/admin/css/fonts.168bab448fee.css b/static/admin/css/fonts.168bab448fee.css deleted file mode 100644 index 83551350..00000000 --- a/static/admin/css/fonts.168bab448fee.css +++ /dev/null @@ -1,20 +0,0 @@ -@font-face { - font-family: 'Roboto'; - src: url("../fonts/Roboto-Bold-webfont.50d75e48e0a3.woff"); - font-weight: 700; - font-style: normal; -} - -@font-face { - font-family: 'Roboto'; - src: url("../fonts/Roboto-Regular-webfont.35b07eb2f871.woff"); - font-weight: 400; - font-style: normal; -} - -@font-face { - font-family: 'Roboto'; - src: url("../fonts/Roboto-Light-webfont.c73eb1ceba33.woff"); - font-weight: 300; - font-style: normal; -} diff --git a/static/admin/css/fonts.168bab448fee.css.gz b/static/admin/css/fonts.168bab448fee.css.gz deleted file mode 100644 index 1cb6be85..00000000 Binary files a/static/admin/css/fonts.168bab448fee.css.gz and /dev/null differ diff --git a/static/admin/css/fonts.css b/static/admin/css/fonts.css deleted file mode 100644 index c837e017..00000000 --- a/static/admin/css/fonts.css +++ /dev/null @@ -1,20 +0,0 @@ -@font-face { - font-family: 'Roboto'; - src: url('../fonts/Roboto-Bold-webfont.woff'); - font-weight: 700; - font-style: normal; -} - -@font-face { - font-family: 'Roboto'; - src: url('../fonts/Roboto-Regular-webfont.woff'); - font-weight: 400; - font-style: normal; -} - -@font-face { - font-family: 'Roboto'; - src: url('../fonts/Roboto-Light-webfont.woff'); - font-weight: 300; - font-style: normal; -} diff --git a/static/admin/css/fonts.css.gz b/static/admin/css/fonts.css.gz deleted file mode 100644 index 834a4582..00000000 Binary files a/static/admin/css/fonts.css.gz and /dev/null differ diff --git a/static/admin/css/forms.c192d1ec6902.css b/static/admin/css/forms.1dd11ef16031.css similarity index 90% rename from static/admin/css/forms.c192d1ec6902.css rename to static/admin/css/forms.1dd11ef16031.css index 67b1747b..f9622fde 100644 --- a/static/admin/css/forms.c192d1ec6902.css +++ b/static/admin/css/forms.1dd11ef16031.css @@ -1,4 +1,4 @@ -@import url("widgets.00318bc424d3.css"); +@import url("widgets.801bda05bd0d.css"); /* FORM ROWS */ @@ -22,6 +22,15 @@ form .form-row p { padding-left: 0; } +.flex-container { + display: flex; + flex-wrap: wrap; +} + +.form-multiline > div { + padding-bottom: 10px; +} + /* FORM LABELS */ label { @@ -69,7 +78,6 @@ form ul.inline li { .aligned label { display: block; padding: 4px 10px 0 0; - float: left; width: 160px; word-wrap: break-word; line-height: 1; @@ -79,14 +87,14 @@ form ul.inline li { content: ''; display: inline-block; vertical-align: middle; - height: 26px; + height: 1.625rem; } -.aligned label + p, .aligned label + div.help, .aligned label + div.readonly { +.aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly { padding: 6px 0; margin-top: 0; margin-bottom: 0; - margin-left: 170px; + margin-left: 0; overflow-wrap: break-word; } @@ -117,16 +125,15 @@ form .aligned div.radiolist { form .aligned p.help, form .aligned div.help { - clear: left; margin-top: 0; margin-left: 160px; padding-left: 10px; } -form .aligned label + p.help, -form .aligned label + div.help { +form .aligned p.datetime div.help.timezonewarning { margin-left: 0; padding-left: 0; + font-weight: normal; } form .aligned p.help:last-child, @@ -171,14 +178,7 @@ form .aligned table p { width: 610px; } -.checkbox-row p.help, -.checkbox-row div.help { - margin-left: 0; - padding-left: 0; -} - fieldset .fieldBox { - float: left; margin-right: 20px; } @@ -189,6 +189,7 @@ fieldset .fieldBox { } form .wide p, +form .wide ul.errorlist, form .wide input + p.help, form .wide input + div.help { margin-left: 200px; @@ -196,7 +197,7 @@ form .wide input + div.help { form .wide p.help, form .wide div.help { - padding-left: 38px; + padding-left: 50px; } form div.help ul { @@ -242,19 +243,21 @@ fieldset.collapsed .collapse-toggle { /* MONOSPACE TEXTAREAS */ fieldset.monospace textarea { - font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; + font-family: var(--font-family-monospace); } /* SUBMIT ROW */ .submit-row { - padding: 12px 14px 7px; + padding: 12px 14px 12px; margin: 0 0 20px; background: var(--darkened-bg); border: 1px solid var(--hairline-color); border-radius: 4px; - text-align: right; overflow: hidden; + display: flex; + gap: 10px; + flex-wrap: wrap; } body.popup .submit-row { @@ -262,33 +265,29 @@ body.popup .submit-row { } .submit-row input { - height: 35px; - line-height: 15px; - margin: 0 0 5px 5px; + height: 2.1875rem; + line-height: 0.9375rem; +} + +.submit-row input, .submit-row a { + margin: 0; } .submit-row input.default { - margin: 0 0 5px 8px; text-transform: uppercase; } -.submit-row p { - margin: 0.3em; -} - -.submit-row p.deletelink-box { - float: left; - margin: 0; +.submit-row a.deletelink { + margin-left: auto; } .submit-row a.deletelink { display: block; background: var(--delete-button-bg); border-radius: 4px; - padding: 10px 15px; - height: 15px; - line-height: 15px; - margin-bottom: 5px; + padding: 0.625rem 0.9375rem; + height: 0.9375rem; + line-height: 0.9375rem; color: var(--button-fg); } @@ -297,9 +296,8 @@ body.popup .submit-row { background: var(--close-button-bg); border-radius: 4px; padding: 10px 15px; - height: 15px; - line-height: 15px; - margin: 0 0 0 5px; + height: 0.9375rem; + line-height: 0.9375rem; color: var(--button-fg); } @@ -307,12 +305,14 @@ body.popup .submit-row { .submit-row a.deletelink:hover, .submit-row a.deletelink:active { background: var(--delete-button-hover-bg); + text-decoration: none; } .submit-row a.closelink:focus, .submit-row a.closelink:hover, .submit-row a.closelink:active { background: var(--close-button-hover-bg); + text-decoration: none; } /* CUSTOM FORM FIELDS */ @@ -512,8 +512,8 @@ body.popup .submit-row { } .related-lookup { - width: 16px; - height: 16px; + width: 1rem; + height: 1rem; background-image: url("../img/search.7cf54ff789c6.svg"); } diff --git a/static/admin/css/forms.1dd11ef16031.css.gz b/static/admin/css/forms.1dd11ef16031.css.gz new file mode 100644 index 00000000..0c646efe Binary files /dev/null and b/static/admin/css/forms.1dd11ef16031.css.gz differ diff --git a/static/admin/css/forms.c192d1ec6902.css.gz b/static/admin/css/forms.c192d1ec6902.css.gz deleted file mode 100644 index d97ef72f..00000000 Binary files a/static/admin/css/forms.c192d1ec6902.css.gz and /dev/null differ diff --git a/static/admin/css/forms.css b/static/admin/css/forms.css index e1873b33..52f956e2 100644 --- a/static/admin/css/forms.css +++ b/static/admin/css/forms.css @@ -22,6 +22,15 @@ form .form-row p { padding-left: 0; } +.flex-container { + display: flex; + flex-wrap: wrap; +} + +.form-multiline > div { + padding-bottom: 10px; +} + /* FORM LABELS */ label { @@ -69,7 +78,6 @@ form ul.inline li { .aligned label { display: block; padding: 4px 10px 0 0; - float: left; width: 160px; word-wrap: break-word; line-height: 1; @@ -79,14 +87,14 @@ form ul.inline li { content: ''; display: inline-block; vertical-align: middle; - height: 26px; + height: 1.625rem; } -.aligned label + p, .aligned label + div.help, .aligned label + div.readonly { +.aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly { padding: 6px 0; margin-top: 0; margin-bottom: 0; - margin-left: 170px; + margin-left: 0; overflow-wrap: break-word; } @@ -117,16 +125,15 @@ form .aligned div.radiolist { form .aligned p.help, form .aligned div.help { - clear: left; margin-top: 0; margin-left: 160px; padding-left: 10px; } -form .aligned label + p.help, -form .aligned label + div.help { +form .aligned p.datetime div.help.timezonewarning { margin-left: 0; padding-left: 0; + font-weight: normal; } form .aligned p.help:last-child, @@ -171,14 +178,7 @@ form .aligned table p { width: 610px; } -.checkbox-row p.help, -.checkbox-row div.help { - margin-left: 0; - padding-left: 0; -} - fieldset .fieldBox { - float: left; margin-right: 20px; } @@ -189,6 +189,7 @@ fieldset .fieldBox { } form .wide p, +form .wide ul.errorlist, form .wide input + p.help, form .wide input + div.help { margin-left: 200px; @@ -196,7 +197,7 @@ form .wide input + div.help { form .wide p.help, form .wide div.help { - padding-left: 38px; + padding-left: 50px; } form div.help ul { @@ -242,19 +243,21 @@ fieldset.collapsed .collapse-toggle { /* MONOSPACE TEXTAREAS */ fieldset.monospace textarea { - font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; + font-family: var(--font-family-monospace); } /* SUBMIT ROW */ .submit-row { - padding: 12px 14px 7px; + padding: 12px 14px 12px; margin: 0 0 20px; background: var(--darkened-bg); border: 1px solid var(--hairline-color); border-radius: 4px; - text-align: right; overflow: hidden; + display: flex; + gap: 10px; + flex-wrap: wrap; } body.popup .submit-row { @@ -262,33 +265,29 @@ body.popup .submit-row { } .submit-row input { - height: 35px; - line-height: 15px; - margin: 0 0 5px 5px; + height: 2.1875rem; + line-height: 0.9375rem; +} + +.submit-row input, .submit-row a { + margin: 0; } .submit-row input.default { - margin: 0 0 5px 8px; text-transform: uppercase; } -.submit-row p { - margin: 0.3em; -} - -.submit-row p.deletelink-box { - float: left; - margin: 0; +.submit-row a.deletelink { + margin-left: auto; } .submit-row a.deletelink { display: block; background: var(--delete-button-bg); border-radius: 4px; - padding: 10px 15px; - height: 15px; - line-height: 15px; - margin-bottom: 5px; + padding: 0.625rem 0.9375rem; + height: 0.9375rem; + line-height: 0.9375rem; color: var(--button-fg); } @@ -297,9 +296,8 @@ body.popup .submit-row { background: var(--close-button-bg); border-radius: 4px; padding: 10px 15px; - height: 15px; - line-height: 15px; - margin: 0 0 0 5px; + height: 0.9375rem; + line-height: 0.9375rem; color: var(--button-fg); } @@ -307,12 +305,14 @@ body.popup .submit-row { .submit-row a.deletelink:hover, .submit-row a.deletelink:active { background: var(--delete-button-hover-bg); + text-decoration: none; } .submit-row a.closelink:focus, .submit-row a.closelink:hover, .submit-row a.closelink:active { background: var(--close-button-hover-bg); + text-decoration: none; } /* CUSTOM FORM FIELDS */ @@ -512,8 +512,8 @@ body.popup .submit-row { } .related-lookup { - width: 16px; - height: 16px; + width: 1rem; + height: 1rem; background-image: url(../img/search.svg); } diff --git a/static/admin/css/forms.css.gz b/static/admin/css/forms.css.gz index ce5b06de..72464f19 100644 Binary files a/static/admin/css/forms.css.gz and b/static/admin/css/forms.css.gz differ diff --git a/static/admin/css/nav_sidebar.30423191f399.css b/static/admin/css/nav_sidebar.269a1bd44627.css similarity index 97% rename from static/admin/css/nav_sidebar.30423191f399.css rename to static/admin/css/nav_sidebar.269a1bd44627.css index 5fd2ff0b..f76e6ce4 100644 --- a/static/admin/css/nav_sidebar.30423191f399.css +++ b/static/admin/css/nav_sidebar.269a1bd44627.css @@ -59,8 +59,13 @@ content: '\00AB'; } +.main > #nav-sidebar { + visibility: hidden; +} + .main.shifted > #nav-sidebar { margin-left: 0; + visibility: visible; } [dir="rtl"] .main.shifted > #nav-sidebar { diff --git a/static/admin/css/nav_sidebar.269a1bd44627.css.gz b/static/admin/css/nav_sidebar.269a1bd44627.css.gz new file mode 100644 index 00000000..7398c4df Binary files /dev/null and b/static/admin/css/nav_sidebar.269a1bd44627.css.gz differ diff --git a/static/admin/css/nav_sidebar.30423191f399.css.gz b/static/admin/css/nav_sidebar.30423191f399.css.gz deleted file mode 100644 index 4f404a61..00000000 Binary files a/static/admin/css/nav_sidebar.30423191f399.css.gz and /dev/null differ diff --git a/static/admin/css/nav_sidebar.css b/static/admin/css/nav_sidebar.css index 5fd2ff0b..f76e6ce4 100644 --- a/static/admin/css/nav_sidebar.css +++ b/static/admin/css/nav_sidebar.css @@ -59,8 +59,13 @@ content: '\00AB'; } +.main > #nav-sidebar { + visibility: hidden; +} + .main.shifted > #nav-sidebar { margin-left: 0; + visibility: visible; } [dir="rtl"] .main.shifted > #nav-sidebar { diff --git a/static/admin/css/nav_sidebar.css.gz b/static/admin/css/nav_sidebar.css.gz index 4f404a61..7398c4df 100644 Binary files a/static/admin/css/nav_sidebar.css.gz and b/static/admin/css/nav_sidebar.css.gz differ diff --git a/static/admin/css/responsive.02281633b5f1.css.gz b/static/admin/css/responsive.02281633b5f1.css.gz deleted file mode 100644 index d51e1923..00000000 Binary files a/static/admin/css/responsive.02281633b5f1.css.gz and /dev/null differ diff --git a/static/admin/css/responsive.02281633b5f1.css b/static/admin/css/responsive.76d4b69c4c82.css similarity index 96% rename from static/admin/css/responsive.02281633b5f1.css rename to static/admin/css/responsive.76d4b69c4c82.css index 9a4615d0..55f67f06 100644 --- a/static/admin/css/responsive.02281633b5f1.css +++ b/static/admin/css/responsive.76d4b69c4c82.css @@ -104,13 +104,13 @@ input[type="submit"], button { } #changelist-search label { - line-height: 22px; + line-height: 1.375rem; } #toolbar form #searchbar { flex: 1 0 auto; width: 0; - height: 22px; + height: 1.375rem; margin: 0 10px 0 6px; } @@ -186,12 +186,12 @@ input[type="submit"], button { box-sizing: border-box; margin: 0; padding: 6px 8px; - min-height: 36px; + min-height: 2.25rem; font-size: 0.875rem; } .form-row select { - height: 36px; + height: 2.25rem; } .form-row select[multiple] { @@ -199,12 +199,6 @@ input[type="submit"], button { min-height: 0; } - fieldset .fieldBox { - float: none; - margin: 0 -10px; - padding: 0 10px; - } - fieldset .fieldBox + .fieldBox { margin-top: 10px; padding-top: 10px; @@ -232,17 +226,13 @@ input[type="submit"], button { } .submit-row { - padding: 8px 8px 3px 8px; + padding: 8px; } .submit-row a.deletelink { padding: 10px 7px; } - .submit-row input.default { - margin: 0 0 5px 5px; - } - .button, input[type=submit], input[type=button], .submit-row input, a.button { padding: 7px; } @@ -394,10 +384,6 @@ input[type="submit"], button { display: none; } - form .form-row p.datetime { - width: 100%; - } - .datetime input { width: 50%; max-width: 120px; @@ -568,8 +554,6 @@ input[type="submit"], button { .aligned .form-row, .aligned .form-row > div { - display: flex; - flex-wrap: wrap; max-width: 100vw; } @@ -577,6 +561,10 @@ input[type="submit"], button { width: calc(100vw - 30px); } + .flex-container { + flex-flow: column; + } + textarea { max-width: none; } @@ -656,7 +644,8 @@ input[type="submit"], button { padding: 0; } - form .aligned ul { + form .aligned ul, + form .aligned ul.errorlist { margin-left: 0; padding-left: 0; } @@ -823,28 +812,23 @@ input[type="submit"], button { /* Submit row */ .submit-row { - padding: 10px 10px 5px; + padding: 10px; margin: 0 0 15px; - display: flex; flex-direction: column; + gap: 8px; } - .submit-row > * { - width: 100%; - } - - .submit-row input, .submit-row input.default, .submit-row a, .submit-row a.closelink { - float: none; - margin: 0 0 10px; + .submit-row input, .submit-row input.default, .submit-row a { text-align: center; } .submit-row a.closelink { padding: 10px 0; + text-align: center; } - .submit-row p.deletelink-box { - order: 4; + .submit-row a.deletelink { + margin: 0; } /* Messages */ @@ -966,7 +950,7 @@ input[type="submit"], button { .calendar-shortcuts { padding: 10px 0; font-size: 0.75rem; - line-height: 12px; + line-height: 0.75rem; } .calendar-shortcuts a { diff --git a/static/admin/css/responsive.76d4b69c4c82.css.gz b/static/admin/css/responsive.76d4b69c4c82.css.gz new file mode 100644 index 00000000..2358e41a Binary files /dev/null and b/static/admin/css/responsive.76d4b69c4c82.css.gz differ diff --git a/static/admin/css/responsive.css b/static/admin/css/responsive.css index 9a4615d0..55f67f06 100644 --- a/static/admin/css/responsive.css +++ b/static/admin/css/responsive.css @@ -104,13 +104,13 @@ input[type="submit"], button { } #changelist-search label { - line-height: 22px; + line-height: 1.375rem; } #toolbar form #searchbar { flex: 1 0 auto; width: 0; - height: 22px; + height: 1.375rem; margin: 0 10px 0 6px; } @@ -186,12 +186,12 @@ input[type="submit"], button { box-sizing: border-box; margin: 0; padding: 6px 8px; - min-height: 36px; + min-height: 2.25rem; font-size: 0.875rem; } .form-row select { - height: 36px; + height: 2.25rem; } .form-row select[multiple] { @@ -199,12 +199,6 @@ input[type="submit"], button { min-height: 0; } - fieldset .fieldBox { - float: none; - margin: 0 -10px; - padding: 0 10px; - } - fieldset .fieldBox + .fieldBox { margin-top: 10px; padding-top: 10px; @@ -232,17 +226,13 @@ input[type="submit"], button { } .submit-row { - padding: 8px 8px 3px 8px; + padding: 8px; } .submit-row a.deletelink { padding: 10px 7px; } - .submit-row input.default { - margin: 0 0 5px 5px; - } - .button, input[type=submit], input[type=button], .submit-row input, a.button { padding: 7px; } @@ -394,10 +384,6 @@ input[type="submit"], button { display: none; } - form .form-row p.datetime { - width: 100%; - } - .datetime input { width: 50%; max-width: 120px; @@ -568,8 +554,6 @@ input[type="submit"], button { .aligned .form-row, .aligned .form-row > div { - display: flex; - flex-wrap: wrap; max-width: 100vw; } @@ -577,6 +561,10 @@ input[type="submit"], button { width: calc(100vw - 30px); } + .flex-container { + flex-flow: column; + } + textarea { max-width: none; } @@ -656,7 +644,8 @@ input[type="submit"], button { padding: 0; } - form .aligned ul { + form .aligned ul, + form .aligned ul.errorlist { margin-left: 0; padding-left: 0; } @@ -823,28 +812,23 @@ input[type="submit"], button { /* Submit row */ .submit-row { - padding: 10px 10px 5px; + padding: 10px; margin: 0 0 15px; - display: flex; flex-direction: column; + gap: 8px; } - .submit-row > * { - width: 100%; - } - - .submit-row input, .submit-row input.default, .submit-row a, .submit-row a.closelink { - float: none; - margin: 0 0 10px; + .submit-row input, .submit-row input.default, .submit-row a { text-align: center; } .submit-row a.closelink { padding: 10px 0; + text-align: center; } - .submit-row p.deletelink-box { - order: 4; + .submit-row a.deletelink { + margin: 0; } /* Messages */ @@ -966,7 +950,7 @@ input[type="submit"], button { .calendar-shortcuts { padding: 10px 0; font-size: 0.75rem; - line-height: 12px; + line-height: 0.75rem; } .calendar-shortcuts a { diff --git a/static/admin/css/responsive.css.gz b/static/admin/css/responsive.css.gz index d51e1923..2358e41a 100644 Binary files a/static/admin/css/responsive.css.gz and b/static/admin/css/responsive.css.gz differ diff --git a/static/admin/css/responsive_rtl.e13ae754cceb.css b/static/admin/css/responsive_rtl.97b066429fd8.css similarity index 95% rename from static/admin/css/responsive_rtl.e13ae754cceb.css rename to static/admin/css/responsive_rtl.97b066429fd8.css index 66d3c2f9..639e20b2 100644 --- a/static/admin/css/responsive_rtl.e13ae754cceb.css +++ b/static/admin/css/responsive_rtl.97b066429fd8.css @@ -69,7 +69,8 @@ margin-right: 15px; } - [dir="rtl"] .aligned ul { + [dir="rtl"] .aligned ul, + [dir="rtl"] form .aligned ul.errorlist { margin-right: 0; } diff --git a/static/admin/css/responsive_rtl.97b066429fd8.css.gz b/static/admin/css/responsive_rtl.97b066429fd8.css.gz new file mode 100644 index 00000000..92a5f17f Binary files /dev/null and b/static/admin/css/responsive_rtl.97b066429fd8.css.gz differ diff --git a/static/admin/css/responsive_rtl.css b/static/admin/css/responsive_rtl.css index 66d3c2f9..639e20b2 100644 --- a/static/admin/css/responsive_rtl.css +++ b/static/admin/css/responsive_rtl.css @@ -69,7 +69,8 @@ margin-right: 15px; } - [dir="rtl"] .aligned ul { + [dir="rtl"] .aligned ul, + [dir="rtl"] form .aligned ul.errorlist { margin-right: 0; } diff --git a/static/admin/css/responsive_rtl.css.gz b/static/admin/css/responsive_rtl.css.gz index 79b16071..92a5f17f 100644 Binary files a/static/admin/css/responsive_rtl.css.gz and b/static/admin/css/responsive_rtl.css.gz differ diff --git a/static/admin/css/responsive_rtl.e13ae754cceb.css.gz b/static/admin/css/responsive_rtl.e13ae754cceb.css.gz deleted file mode 100644 index 79b16071..00000000 Binary files a/static/admin/css/responsive_rtl.e13ae754cceb.css.gz and /dev/null differ diff --git a/static/admin/css/rtl.8473f45bd49b.css.gz b/static/admin/css/rtl.8473f45bd49b.css.gz deleted file mode 100644 index 9f2932f2..00000000 Binary files a/static/admin/css/rtl.8473f45bd49b.css.gz and /dev/null differ diff --git a/static/admin/css/rtl.8473f45bd49b.css b/static/admin/css/rtl.ac25b2aecb6e.css similarity index 70% rename from static/admin/css/rtl.8473f45bd49b.css rename to static/admin/css/rtl.ac25b2aecb6e.css index 3a4b37fb..3cfff06d 100644 --- a/static/admin/css/rtl.8473f45bd49b.css +++ b/static/admin/css/rtl.ac25b2aecb6e.css @@ -111,19 +111,11 @@ thead th.sorted .text { .aligned label { padding: 0 0 3px 1em; - float: right; } -.submit-row { - text-align: left -} - -.submit-row p.deletelink-box { - float: right; -} - -.submit-row input.default { +.submit-row a.deletelink { margin-left: 0; + margin-right: auto; } .vDateField, .vTimeField { @@ -134,13 +126,11 @@ thead th.sorted .text { margin-left: 5px; } -form .aligned p.help, form .aligned div.help { - clear: right; -} - form .aligned ul { margin-right: 163px; + padding-right: 10px; margin-left: 0; + padding-left: 0; } form ul.inline li { @@ -149,12 +139,37 @@ form ul.inline li { padding-left: 7px; } -input[type=submit].default, .submit-row input.default { - float: left; +form .aligned p.help, +form .aligned div.help { + margin-right: 160px; + padding-right: 10px; +} + +form div.help ul, +form .aligned .checkbox-row + .help, +form .aligned p.datetime div.help.timezonewarning { + margin-right: 0; + padding-right: 0; +} + +form .wide p.help, form .wide div.help { + padding-left: 0; + padding-right: 50px; +} + +form .wide p, +form .wide ul.errorlist, +form .wide input + p.help, +form .wide input + div.help { + margin-right: 200px; + margin-left: 0px; +} + +.submit-row { + text-align: right; } fieldset .fieldBox { - float: right; margin-left: 20px; margin-right: 0; } @@ -207,6 +222,38 @@ fieldset .fieldBox { text-align: right; } +.selector-add { + background: url("../img/selector-icons.b4555096cea2.svg") 0 -64px no-repeat; +} + +.active.selector-add:focus, .active.selector-add:hover { + background-position: 0 -80px; +} + +.selector-remove { + background: url("../img/selector-icons.b4555096cea2.svg") 0 -96px no-repeat; +} + +.active.selector-remove:focus, .active.selector-remove:hover { + background-position: 0 -112px; +} + +a.selector-chooseall { + background: url("../img/selector-icons.b4555096cea2.svg") right -128px no-repeat; +} + +a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { + background-position: 100% -144px; +} + +a.selector-clearall { + background: url("../img/selector-icons.b4555096cea2.svg") 0 -160px no-repeat; +} + +a.active.selector-clearall:focus, a.active.selector-clearall:hover { + background-position: 0 -176px; +} + .inline-deletelink { float: left; } diff --git a/static/admin/css/rtl.ac25b2aecb6e.css.gz b/static/admin/css/rtl.ac25b2aecb6e.css.gz new file mode 100644 index 00000000..2cd2be06 Binary files /dev/null and b/static/admin/css/rtl.ac25b2aecb6e.css.gz differ diff --git a/static/admin/css/rtl.css b/static/admin/css/rtl.css index e0fadcef..800f943e 100644 --- a/static/admin/css/rtl.css +++ b/static/admin/css/rtl.css @@ -111,19 +111,11 @@ thead th.sorted .text { .aligned label { padding: 0 0 3px 1em; - float: right; } -.submit-row { - text-align: left -} - -.submit-row p.deletelink-box { - float: right; -} - -.submit-row input.default { +.submit-row a.deletelink { margin-left: 0; + margin-right: auto; } .vDateField, .vTimeField { @@ -134,13 +126,11 @@ thead th.sorted .text { margin-left: 5px; } -form .aligned p.help, form .aligned div.help { - clear: right; -} - form .aligned ul { margin-right: 163px; + padding-right: 10px; margin-left: 0; + padding-left: 0; } form ul.inline li { @@ -149,12 +139,37 @@ form ul.inline li { padding-left: 7px; } -input[type=submit].default, .submit-row input.default { - float: left; +form .aligned p.help, +form .aligned div.help { + margin-right: 160px; + padding-right: 10px; +} + +form div.help ul, +form .aligned .checkbox-row + .help, +form .aligned p.datetime div.help.timezonewarning { + margin-right: 0; + padding-right: 0; +} + +form .wide p.help, form .wide div.help { + padding-left: 0; + padding-right: 50px; +} + +form .wide p, +form .wide ul.errorlist, +form .wide input + p.help, +form .wide input + div.help { + margin-right: 200px; + margin-left: 0px; +} + +.submit-row { + text-align: right; } fieldset .fieldBox { - float: right; margin-left: 20px; margin-right: 0; } @@ -207,6 +222,38 @@ fieldset .fieldBox { text-align: right; } +.selector-add { + background: url(../img/selector-icons.svg) 0 -64px no-repeat; +} + +.active.selector-add:focus, .active.selector-add:hover { + background-position: 0 -80px; +} + +.selector-remove { + background: url(../img/selector-icons.svg) 0 -96px no-repeat; +} + +.active.selector-remove:focus, .active.selector-remove:hover { + background-position: 0 -112px; +} + +a.selector-chooseall { + background: url(../img/selector-icons.svg) right -128px no-repeat; +} + +a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { + background-position: 100% -144px; +} + +a.selector-clearall { + background: url(../img/selector-icons.svg) 0 -160px no-repeat; +} + +a.active.selector-clearall:focus, a.active.selector-clearall:hover { + background-position: 0 -176px; +} + .inline-deletelink { float: left; } diff --git a/static/admin/css/rtl.css.gz b/static/admin/css/rtl.css.gz index 282f7241..8f2db5b2 100644 Binary files a/static/admin/css/rtl.css.gz and b/static/admin/css/rtl.css.gz differ diff --git a/static/admin/css/widgets.00318bc424d3.css.gz b/static/admin/css/widgets.00318bc424d3.css.gz deleted file mode 100644 index b9a389be..00000000 Binary files a/static/admin/css/widgets.00318bc424d3.css.gz and /dev/null differ diff --git a/static/admin/css/widgets.00318bc424d3.css b/static/admin/css/widgets.801bda05bd0d.css similarity index 93% rename from static/admin/css/widgets.00318bc424d3.css rename to static/admin/css/widgets.801bda05bd0d.css index 52806d7e..39151e16 100644 --- a/static/admin/css/widgets.00318bc424d3.css +++ b/static/admin/css/widgets.801bda05bd0d.css @@ -20,15 +20,26 @@ flex-direction: column; } -.selector-chosen select { - border-top: none; -} - .selector-available h2, .selector-chosen h2 { border: 1px solid var(--border-color); border-radius: 4px 4px 0 0; } +.selector-chosen .list-footer-display { + border: 1px solid var(--border-color); + border-top: none; + border-radius: 0 0 4px 4px; + margin: 0 0 10px; + padding: 8px; + text-align: center; + background: var(--primary); + color: var(--header-link-color); + cursor: pointer; +} +.selector-chosen .list-footer-display__clear { + color: var(--breadcrumbs-fg); +} + .selector-chosen h2 { background: var(--primary); color: var(--header-link-color); @@ -60,7 +71,8 @@ line-height: 1; } -.selector .selector-available input { +.selector .selector-available input, +.selector .selector-chosen input { width: 320px; margin-left: 8px; } @@ -86,6 +98,15 @@ margin: 0 0 10px; border-radius: 0 0 4px 4px; } +.selector .selector-chosen--with-filtered select { + margin: 0; + border-radius: 0; + height: 14em; +} + +.selector .selector-chosen:not(.selector-chosen--with-filtered) .list-footer-display { + display: none; +} .selector-add, .selector-remove { width: 16px; @@ -256,8 +277,8 @@ a.active.selector-clearall:focus, a.active.selector-clearall:hover { .selector .search-label-icon { background: url("../img/search.7cf54ff789c6.svg") 0 0 no-repeat; display: inline-block; - height: 18px; - width: 18px; + height: 1.125rem; + width: 1.125rem; } /* DATE AND TIME */ @@ -477,7 +498,7 @@ span.clearable-file-input label { background: var(--body-bg); color: var(--body-quiet-color); font-size: 0.6875rem; - line-height: 11px; + line-height: 0.6875rem; border-top: 1px solid var(--hairline-color); padding: 8px 0; } @@ -578,3 +599,9 @@ select + .related-widget-wrapper-link, .related-widget-wrapper-link + .related-widget-wrapper-link { margin-left: 7px; } + +/* GIS MAPS */ +.dj_map { + width: 600px; + height: 400px; +} diff --git a/static/admin/css/widgets.801bda05bd0d.css.gz b/static/admin/css/widgets.801bda05bd0d.css.gz new file mode 100644 index 00000000..ee008eef Binary files /dev/null and b/static/admin/css/widgets.801bda05bd0d.css.gz differ diff --git a/static/admin/css/widgets.css b/static/admin/css/widgets.css index cd1d6b41..572dc0a5 100644 --- a/static/admin/css/widgets.css +++ b/static/admin/css/widgets.css @@ -20,15 +20,26 @@ flex-direction: column; } -.selector-chosen select { - border-top: none; -} - .selector-available h2, .selector-chosen h2 { border: 1px solid var(--border-color); border-radius: 4px 4px 0 0; } +.selector-chosen .list-footer-display { + border: 1px solid var(--border-color); + border-top: none; + border-radius: 0 0 4px 4px; + margin: 0 0 10px; + padding: 8px; + text-align: center; + background: var(--primary); + color: var(--header-link-color); + cursor: pointer; +} +.selector-chosen .list-footer-display__clear { + color: var(--breadcrumbs-fg); +} + .selector-chosen h2 { background: var(--primary); color: var(--header-link-color); @@ -60,7 +71,8 @@ line-height: 1; } -.selector .selector-available input { +.selector .selector-available input, +.selector .selector-chosen input { width: 320px; margin-left: 8px; } @@ -86,6 +98,15 @@ margin: 0 0 10px; border-radius: 0 0 4px 4px; } +.selector .selector-chosen--with-filtered select { + margin: 0; + border-radius: 0; + height: 14em; +} + +.selector .selector-chosen:not(.selector-chosen--with-filtered) .list-footer-display { + display: none; +} .selector-add, .selector-remove { width: 16px; @@ -256,8 +277,8 @@ a.active.selector-clearall:focus, a.active.selector-clearall:hover { .selector .search-label-icon { background: url(../img/search.svg) 0 0 no-repeat; display: inline-block; - height: 18px; - width: 18px; + height: 1.125rem; + width: 1.125rem; } /* DATE AND TIME */ @@ -477,7 +498,7 @@ span.clearable-file-input label { background: var(--body-bg); color: var(--body-quiet-color); font-size: 0.6875rem; - line-height: 11px; + line-height: 0.6875rem; border-top: 1px solid var(--hairline-color); padding: 8px 0; } @@ -578,3 +599,9 @@ select + .related-widget-wrapper-link, .related-widget-wrapper-link + .related-widget-wrapper-link { margin-left: 7px; } + +/* GIS MAPS */ +.dj_map { + width: 600px; + height: 400px; +} diff --git a/static/admin/css/widgets.css.gz b/static/admin/css/widgets.css.gz index 6d9e0f0a..4cb91008 100644 Binary files a/static/admin/css/widgets.css.gz and b/static/admin/css/widgets.css.gz differ diff --git a/static/admin/fonts/LICENSE.d273d63619c9.txt b/static/admin/fonts/LICENSE.d273d63619c9.txt deleted file mode 100644 index d6456956..00000000 --- a/static/admin/fonts/LICENSE.d273d63619c9.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/static/admin/fonts/LICENSE.d273d63619c9.txt.gz b/static/admin/fonts/LICENSE.d273d63619c9.txt.gz deleted file mode 100644 index d3fd5926..00000000 Binary files a/static/admin/fonts/LICENSE.d273d63619c9.txt.gz and /dev/null differ diff --git a/static/admin/fonts/LICENSE.txt b/static/admin/fonts/LICENSE.txt deleted file mode 100644 index d6456956..00000000 --- a/static/admin/fonts/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/static/admin/fonts/LICENSE.txt.gz b/static/admin/fonts/LICENSE.txt.gz deleted file mode 100644 index d3fd5926..00000000 Binary files a/static/admin/fonts/LICENSE.txt.gz and /dev/null differ diff --git a/static/admin/fonts/README.ab99e6b541ea.txt b/static/admin/fonts/README.ab99e6b541ea.txt deleted file mode 100644 index b247bef3..00000000 --- a/static/admin/fonts/README.ab99e6b541ea.txt +++ /dev/null @@ -1,3 +0,0 @@ -Roboto webfont source: https://www.google.com/fonts/specimen/Roboto -WOFF files extracted using https://github.com/majodev/google-webfonts-helper -Weights used in this project: Light (300), Regular (400), Bold (700) diff --git a/static/admin/fonts/README.ab99e6b541ea.txt.gz b/static/admin/fonts/README.ab99e6b541ea.txt.gz deleted file mode 100644 index 5c802db4..00000000 Binary files a/static/admin/fonts/README.ab99e6b541ea.txt.gz and /dev/null differ diff --git a/static/admin/fonts/README.txt b/static/admin/fonts/README.txt deleted file mode 100644 index b247bef3..00000000 --- a/static/admin/fonts/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Roboto webfont source: https://www.google.com/fonts/specimen/Roboto -WOFF files extracted using https://github.com/majodev/google-webfonts-helper -Weights used in this project: Light (300), Regular (400), Bold (700) diff --git a/static/admin/fonts/README.txt.gz b/static/admin/fonts/README.txt.gz deleted file mode 100644 index 5c802db4..00000000 Binary files a/static/admin/fonts/README.txt.gz and /dev/null differ diff --git a/static/admin/fonts/Roboto-Bold-webfont.50d75e48e0a3.woff b/static/admin/fonts/Roboto-Bold-webfont.50d75e48e0a3.woff deleted file mode 100644 index 6e0f5626..00000000 Binary files a/static/admin/fonts/Roboto-Bold-webfont.50d75e48e0a3.woff and /dev/null differ diff --git a/static/admin/fonts/Roboto-Bold-webfont.woff b/static/admin/fonts/Roboto-Bold-webfont.woff deleted file mode 100644 index 6e0f5626..00000000 Binary files a/static/admin/fonts/Roboto-Bold-webfont.woff and /dev/null differ diff --git a/static/admin/fonts/Roboto-Light-webfont.c73eb1ceba33.woff b/static/admin/fonts/Roboto-Light-webfont.c73eb1ceba33.woff deleted file mode 100644 index b9e99185..00000000 Binary files a/static/admin/fonts/Roboto-Light-webfont.c73eb1ceba33.woff and /dev/null differ diff --git a/static/admin/fonts/Roboto-Light-webfont.woff b/static/admin/fonts/Roboto-Light-webfont.woff deleted file mode 100644 index b9e99185..00000000 Binary files a/static/admin/fonts/Roboto-Light-webfont.woff and /dev/null differ diff --git a/static/admin/fonts/Roboto-Regular-webfont.35b07eb2f871.woff b/static/admin/fonts/Roboto-Regular-webfont.35b07eb2f871.woff deleted file mode 100644 index 96c1986f..00000000 Binary files a/static/admin/fonts/Roboto-Regular-webfont.35b07eb2f871.woff and /dev/null differ diff --git a/static/admin/fonts/Roboto-Regular-webfont.woff b/static/admin/fonts/Roboto-Regular-webfont.woff deleted file mode 100644 index 96c1986f..00000000 Binary files a/static/admin/fonts/Roboto-Regular-webfont.woff and /dev/null differ diff --git a/static/admin/js/SelectBox.8161741c7647.js b/static/admin/js/SelectBox.7d3ce5a98007.js similarity index 96% rename from static/admin/js/SelectBox.8161741c7647.js rename to static/admin/js/SelectBox.7d3ce5a98007.js index ace6d9df..3db4ec7f 100644 --- a/static/admin/js/SelectBox.8161741c7647.js +++ b/static/admin/js/SelectBox.7d3ce5a98007.js @@ -41,6 +41,10 @@ } SelectBox.redisplay(id); }, + get_hidden_node_count(id) { + const cache = SelectBox.cache[id] || []; + return cache.filter(node => node.displayed === 0).length; + }, delete_from_cache: function(id, value) { let delete_index = null; const cache = SelectBox.cache[id]; diff --git a/static/admin/js/SelectBox.7d3ce5a98007.js.gz b/static/admin/js/SelectBox.7d3ce5a98007.js.gz new file mode 100644 index 00000000..8ee916c3 Binary files /dev/null and b/static/admin/js/SelectBox.7d3ce5a98007.js.gz differ diff --git a/static/admin/js/SelectBox.8161741c7647.js.gz b/static/admin/js/SelectBox.8161741c7647.js.gz deleted file mode 100644 index 5a25140a..00000000 Binary files a/static/admin/js/SelectBox.8161741c7647.js.gz and /dev/null differ diff --git a/static/admin/js/SelectBox.js b/static/admin/js/SelectBox.js index ace6d9df..3db4ec7f 100644 --- a/static/admin/js/SelectBox.js +++ b/static/admin/js/SelectBox.js @@ -41,6 +41,10 @@ } SelectBox.redisplay(id); }, + get_hidden_node_count(id) { + const cache = SelectBox.cache[id] || []; + return cache.filter(node => node.displayed === 0).length; + }, delete_from_cache: function(id, value) { let delete_index = null; const cache = SelectBox.cache[id]; diff --git a/static/admin/js/SelectBox.js.gz b/static/admin/js/SelectBox.js.gz index 5a25140a..8ee916c3 100644 Binary files a/static/admin/js/SelectBox.js.gz and b/static/admin/js/SelectBox.js.gz differ diff --git a/static/admin/js/SelectFilter2.3f53e33c88d6.js.gz b/static/admin/js/SelectFilter2.3f53e33c88d6.js.gz deleted file mode 100644 index 522f6676..00000000 Binary files a/static/admin/js/SelectFilter2.3f53e33c88d6.js.gz and /dev/null differ diff --git a/static/admin/js/SelectFilter2.3f53e33c88d6.js b/static/admin/js/SelectFilter2.bdb8d0cc579e.js similarity index 65% rename from static/admin/js/SelectFilter2.3f53e33c88d6.js rename to static/admin/js/SelectFilter2.bdb8d0cc579e.js index 194c2db2..9a4e0a3a 100644 --- a/static/admin/js/SelectFilter2.3f53e33c88d6.js +++ b/static/admin/js/SelectFilter2.bdb8d0cc579e.js @@ -78,7 +78,7 @@ Requires core.js and SelectBox.js. remove_link.className = 'selector-remove'; //
- const selector_chosen = quickElement('div', selector_div); + const selector_chosen = quickElement('div', selector_div, '', 'id', field_id + '_selector_chosen'); selector_chosen.className = 'selector-chosen'; const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); quickElement( @@ -93,9 +93,30 @@ Requires core.js and SelectBox.js. [field_name] ) ); + + const filter_selected_p = quickElement('p', selector_chosen, '', 'id', field_id + '_filter_selected'); + filter_selected_p.className = 'selector-filter'; + + const search_filter_selected_label = quickElement('label', filter_selected_p, '', 'for', field_id + '_selected_input'); + + quickElement( + 'span', search_filter_selected_label, '', + 'class', 'help-tooltip search-label-icon', + 'title', interpolate(gettext("Type into this box to filter down the list of selected %s."), [field_name]) + ); + + filter_selected_p.appendChild(document.createTextNode(' ')); + + const filter_selected_input = quickElement('input', filter_selected_p, '', 'type', 'text', 'placeholder', gettext("Filter")); + filter_selected_input.id = field_id + '_selected_input'; const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name); to_box.className = 'filtered'; + + const warning_footer = quickElement('div', selector_chosen, '', 'class', 'list-footer-display'); + quickElement('span', warning_footer, '', 'id', field_id + '_list-footer-display-text'); + quickElement('span', warning_footer, ' (click to clear)', 'class', 'list-footer-display__clear'); + const clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link'); clear_all.className = 'selector-clearall'; @@ -106,6 +127,8 @@ Requires core.js and SelectBox.js. if (elem.classList.contains('active')) { move_func(from, to); SelectFilter.refresh_icons(field_id); + SelectFilter.refresh_filtered_selects(field_id); + SelectFilter.refresh_filtered_warning(field_id); } e.preventDefault(); }; @@ -121,14 +144,29 @@ Requires core.js and SelectBox.js. clear_all.addEventListener('click', function(e) { move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from'); }); + warning_footer.addEventListener('click', function(e) { + filter_selected_input.value = ''; + SelectBox.filter(field_id + '_to', ''); + SelectFilter.refresh_filtered_warning(field_id); + SelectFilter.refresh_icons(field_id); + }); filter_input.addEventListener('keypress', function(e) { - SelectFilter.filter_key_press(e, field_id); + SelectFilter.filter_key_press(e, field_id, '_from', '_to'); }); filter_input.addEventListener('keyup', function(e) { - SelectFilter.filter_key_up(e, field_id); + SelectFilter.filter_key_up(e, field_id, '_from'); }); filter_input.addEventListener('keydown', function(e) { - SelectFilter.filter_key_down(e, field_id); + SelectFilter.filter_key_down(e, field_id, '_from', '_to'); + }); + filter_selected_input.addEventListener('keypress', function(e) { + SelectFilter.filter_key_press(e, field_id, '_to', '_from'); + }); + filter_selected_input.addEventListener('keyup', function(e) { + SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input'); + }); + filter_selected_input.addEventListener('keydown', function(e) { + SelectFilter.filter_key_down(e, field_id, '_to', '_from'); }); selector_div.addEventListener('change', function(e) { if (e.target.tagName === 'SELECT') { @@ -146,6 +184,7 @@ Requires core.js and SelectBox.js. } }); from_box.closest('form').addEventListener('submit', function() { + SelectBox.filter(field_id + '_to', ''); SelectBox.select_all(field_id + '_to'); }); SelectBox.init(field_id + '_from'); @@ -163,6 +202,24 @@ Requires core.js and SelectBox.js. field.required = false; return any_selected; }, + refresh_filtered_warning: function(field_id) { + const count = SelectBox.get_hidden_node_count(field_id + '_to'); + const selector = document.getElementById(field_id + '_selector_chosen'); + const warning = document.getElementById(field_id + '_list-footer-display-text'); + selector.className = selector.className.replace('selector-chosen--with-filtered', ''); + warning.textContent = interpolate(ngettext( + '%s selected option not visible', + '%s selected options not visible', + count + ), [count]); + if(count > 0) { + selector.className += ' selector-chosen--with-filtered'; + } + }, + refresh_filtered_selects: function(field_id) { + SelectBox.filter(field_id + '_from', document.getElementById(field_id + "_input").value); + SelectBox.filter(field_id + '_to', document.getElementById(field_id + "_selected_input").value); + }, refresh_icons: function(field_id) { const from = document.getElementById(field_id + '_from'); const to = document.getElementById(field_id + '_to'); @@ -172,39 +229,47 @@ Requires core.js and SelectBox.js. // Active if the corresponding box isn't empty document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option')); document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option')); + SelectFilter.refresh_filtered_warning(field_id); }, - filter_key_press: function(event, field_id) { - const from = document.getElementById(field_id + '_from'); + filter_key_press: function(event, field_id, source, target) { + const source_box = document.getElementById(field_id + source); // don't submit form if user pressed Enter if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) { - from.selectedIndex = 0; - SelectBox.move(field_id + '_from', field_id + '_to'); - from.selectedIndex = 0; + source_box.selectedIndex = 0; + SelectBox.move(field_id + source, field_id + target); + source_box.selectedIndex = 0; event.preventDefault(); } }, - filter_key_up: function(event, field_id) { - const from = document.getElementById(field_id + '_from'); - const temp = from.selectedIndex; - SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); - from.selectedIndex = temp; + filter_key_up: function(event, field_id, source, filter_input) { + const input = filter_input || '_input'; + const source_box = document.getElementById(field_id + source); + const temp = source_box.selectedIndex; + SelectBox.filter(field_id + source, document.getElementById(field_id + input).value); + source_box.selectedIndex = temp; + SelectFilter.refresh_filtered_warning(field_id); + SelectFilter.refresh_icons(field_id); }, - filter_key_down: function(event, field_id) { - const from = document.getElementById(field_id + '_from'); + filter_key_down: function(event, field_id, source, target) { + const source_box = document.getElementById(field_id + source); + // right key (39) or left key (37) + const direction = source === '_from' ? 39 : 37; // right arrow -- move across - if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) { - const old_index = from.selectedIndex; - SelectBox.move(field_id + '_from', field_id + '_to'); - from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index; + if ((event.which && event.which === direction) || (event.keyCode && event.keyCode === direction)) { + const old_index = source_box.selectedIndex; + SelectBox.move(field_id + source, field_id + target); + SelectFilter.refresh_filtered_selects(field_id); + SelectFilter.refresh_filtered_warning(field_id); + source_box.selectedIndex = (old_index === source_box.length) ? source_box.length - 1 : old_index; return; } // down arrow -- wrap around if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) { - from.selectedIndex = (from.length === from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; + source_box.selectedIndex = (source_box.length === source_box.selectedIndex + 1) ? 0 : source_box.selectedIndex + 1; } // up arrow -- wrap around if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) { - from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1; + source_box.selectedIndex = (source_box.selectedIndex === 0) ? source_box.length - 1 : source_box.selectedIndex - 1; } } }; diff --git a/static/admin/js/SelectFilter2.bdb8d0cc579e.js.gz b/static/admin/js/SelectFilter2.bdb8d0cc579e.js.gz new file mode 100644 index 00000000..67e33860 Binary files /dev/null and b/static/admin/js/SelectFilter2.bdb8d0cc579e.js.gz differ diff --git a/static/admin/js/SelectFilter2.js b/static/admin/js/SelectFilter2.js index 194c2db2..9a4e0a3a 100644 --- a/static/admin/js/SelectFilter2.js +++ b/static/admin/js/SelectFilter2.js @@ -78,7 +78,7 @@ Requires core.js and SelectBox.js. remove_link.className = 'selector-remove'; //
- const selector_chosen = quickElement('div', selector_div); + const selector_chosen = quickElement('div', selector_div, '', 'id', field_id + '_selector_chosen'); selector_chosen.className = 'selector-chosen'; const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); quickElement( @@ -93,9 +93,30 @@ Requires core.js and SelectBox.js. [field_name] ) ); + + const filter_selected_p = quickElement('p', selector_chosen, '', 'id', field_id + '_filter_selected'); + filter_selected_p.className = 'selector-filter'; + + const search_filter_selected_label = quickElement('label', filter_selected_p, '', 'for', field_id + '_selected_input'); + + quickElement( + 'span', search_filter_selected_label, '', + 'class', 'help-tooltip search-label-icon', + 'title', interpolate(gettext("Type into this box to filter down the list of selected %s."), [field_name]) + ); + + filter_selected_p.appendChild(document.createTextNode(' ')); + + const filter_selected_input = quickElement('input', filter_selected_p, '', 'type', 'text', 'placeholder', gettext("Filter")); + filter_selected_input.id = field_id + '_selected_input'; const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name); to_box.className = 'filtered'; + + const warning_footer = quickElement('div', selector_chosen, '', 'class', 'list-footer-display'); + quickElement('span', warning_footer, '', 'id', field_id + '_list-footer-display-text'); + quickElement('span', warning_footer, ' (click to clear)', 'class', 'list-footer-display__clear'); + const clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link'); clear_all.className = 'selector-clearall'; @@ -106,6 +127,8 @@ Requires core.js and SelectBox.js. if (elem.classList.contains('active')) { move_func(from, to); SelectFilter.refresh_icons(field_id); + SelectFilter.refresh_filtered_selects(field_id); + SelectFilter.refresh_filtered_warning(field_id); } e.preventDefault(); }; @@ -121,14 +144,29 @@ Requires core.js and SelectBox.js. clear_all.addEventListener('click', function(e) { move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from'); }); + warning_footer.addEventListener('click', function(e) { + filter_selected_input.value = ''; + SelectBox.filter(field_id + '_to', ''); + SelectFilter.refresh_filtered_warning(field_id); + SelectFilter.refresh_icons(field_id); + }); filter_input.addEventListener('keypress', function(e) { - SelectFilter.filter_key_press(e, field_id); + SelectFilter.filter_key_press(e, field_id, '_from', '_to'); }); filter_input.addEventListener('keyup', function(e) { - SelectFilter.filter_key_up(e, field_id); + SelectFilter.filter_key_up(e, field_id, '_from'); }); filter_input.addEventListener('keydown', function(e) { - SelectFilter.filter_key_down(e, field_id); + SelectFilter.filter_key_down(e, field_id, '_from', '_to'); + }); + filter_selected_input.addEventListener('keypress', function(e) { + SelectFilter.filter_key_press(e, field_id, '_to', '_from'); + }); + filter_selected_input.addEventListener('keyup', function(e) { + SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input'); + }); + filter_selected_input.addEventListener('keydown', function(e) { + SelectFilter.filter_key_down(e, field_id, '_to', '_from'); }); selector_div.addEventListener('change', function(e) { if (e.target.tagName === 'SELECT') { @@ -146,6 +184,7 @@ Requires core.js and SelectBox.js. } }); from_box.closest('form').addEventListener('submit', function() { + SelectBox.filter(field_id + '_to', ''); SelectBox.select_all(field_id + '_to'); }); SelectBox.init(field_id + '_from'); @@ -163,6 +202,24 @@ Requires core.js and SelectBox.js. field.required = false; return any_selected; }, + refresh_filtered_warning: function(field_id) { + const count = SelectBox.get_hidden_node_count(field_id + '_to'); + const selector = document.getElementById(field_id + '_selector_chosen'); + const warning = document.getElementById(field_id + '_list-footer-display-text'); + selector.className = selector.className.replace('selector-chosen--with-filtered', ''); + warning.textContent = interpolate(ngettext( + '%s selected option not visible', + '%s selected options not visible', + count + ), [count]); + if(count > 0) { + selector.className += ' selector-chosen--with-filtered'; + } + }, + refresh_filtered_selects: function(field_id) { + SelectBox.filter(field_id + '_from', document.getElementById(field_id + "_input").value); + SelectBox.filter(field_id + '_to', document.getElementById(field_id + "_selected_input").value); + }, refresh_icons: function(field_id) { const from = document.getElementById(field_id + '_from'); const to = document.getElementById(field_id + '_to'); @@ -172,39 +229,47 @@ Requires core.js and SelectBox.js. // Active if the corresponding box isn't empty document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option')); document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option')); + SelectFilter.refresh_filtered_warning(field_id); }, - filter_key_press: function(event, field_id) { - const from = document.getElementById(field_id + '_from'); + filter_key_press: function(event, field_id, source, target) { + const source_box = document.getElementById(field_id + source); // don't submit form if user pressed Enter if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) { - from.selectedIndex = 0; - SelectBox.move(field_id + '_from', field_id + '_to'); - from.selectedIndex = 0; + source_box.selectedIndex = 0; + SelectBox.move(field_id + source, field_id + target); + source_box.selectedIndex = 0; event.preventDefault(); } }, - filter_key_up: function(event, field_id) { - const from = document.getElementById(field_id + '_from'); - const temp = from.selectedIndex; - SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); - from.selectedIndex = temp; + filter_key_up: function(event, field_id, source, filter_input) { + const input = filter_input || '_input'; + const source_box = document.getElementById(field_id + source); + const temp = source_box.selectedIndex; + SelectBox.filter(field_id + source, document.getElementById(field_id + input).value); + source_box.selectedIndex = temp; + SelectFilter.refresh_filtered_warning(field_id); + SelectFilter.refresh_icons(field_id); }, - filter_key_down: function(event, field_id) { - const from = document.getElementById(field_id + '_from'); + filter_key_down: function(event, field_id, source, target) { + const source_box = document.getElementById(field_id + source); + // right key (39) or left key (37) + const direction = source === '_from' ? 39 : 37; // right arrow -- move across - if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) { - const old_index = from.selectedIndex; - SelectBox.move(field_id + '_from', field_id + '_to'); - from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index; + if ((event.which && event.which === direction) || (event.keyCode && event.keyCode === direction)) { + const old_index = source_box.selectedIndex; + SelectBox.move(field_id + source, field_id + target); + SelectFilter.refresh_filtered_selects(field_id); + SelectFilter.refresh_filtered_warning(field_id); + source_box.selectedIndex = (old_index === source_box.length) ? source_box.length - 1 : old_index; return; } // down arrow -- wrap around if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) { - from.selectedIndex = (from.length === from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; + source_box.selectedIndex = (source_box.length === source_box.selectedIndex + 1) ? 0 : source_box.selectedIndex + 1; } // up arrow -- wrap around if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) { - from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1; + source_box.selectedIndex = (source_box.selectedIndex === 0) ? source_box.length - 1 : source_box.selectedIndex - 1; } } }; diff --git a/static/admin/js/SelectFilter2.js.gz b/static/admin/js/SelectFilter2.js.gz index 522f6676..67e33860 100644 Binary files a/static/admin/js/SelectFilter2.js.gz and b/static/admin/js/SelectFilter2.js.gz differ diff --git a/static/admin/js/admin/DateTimeShortcuts.300591891b2b.js.gz b/static/admin/js/admin/DateTimeShortcuts.300591891b2b.js.gz deleted file mode 100644 index 27d1430c..00000000 Binary files a/static/admin/js/admin/DateTimeShortcuts.300591891b2b.js.gz and /dev/null differ diff --git a/static/admin/js/admin/DateTimeShortcuts.300591891b2b.js b/static/admin/js/admin/DateTimeShortcuts.9f6e209cebca.js similarity index 99% rename from static/admin/js/admin/DateTimeShortcuts.300591891b2b.js rename to static/admin/js/admin/DateTimeShortcuts.9f6e209cebca.js index 176b0e3e..aa1cae9e 100644 --- a/static/admin/js/admin/DateTimeShortcuts.300591891b2b.js +++ b/static/admin/js/admin/DateTimeShortcuts.9f6e209cebca.js @@ -90,10 +90,9 @@ } message = interpolate(message, [timezoneOffset]); - const warning = document.createElement('span'); - warning.className = warningClass; + const warning = document.createElement('div'); + warning.classList.add('help', warningClass); warning.textContent = message; - inp.parentNode.appendChild(document.createElement('br')); inp.parentNode.appendChild(warning); }, // Add clock widget to a given field diff --git a/static/admin/js/admin/DateTimeShortcuts.9f6e209cebca.js.gz b/static/admin/js/admin/DateTimeShortcuts.9f6e209cebca.js.gz new file mode 100644 index 00000000..d184bad9 Binary files /dev/null and b/static/admin/js/admin/DateTimeShortcuts.9f6e209cebca.js.gz differ diff --git a/static/admin/js/admin/DateTimeShortcuts.js b/static/admin/js/admin/DateTimeShortcuts.js index 176b0e3e..aa1cae9e 100644 --- a/static/admin/js/admin/DateTimeShortcuts.js +++ b/static/admin/js/admin/DateTimeShortcuts.js @@ -90,10 +90,9 @@ } message = interpolate(message, [timezoneOffset]); - const warning = document.createElement('span'); - warning.className = warningClass; + const warning = document.createElement('div'); + warning.classList.add('help', warningClass); warning.textContent = message; - inp.parentNode.appendChild(document.createElement('br')); inp.parentNode.appendChild(warning); }, // Add clock widget to a given field diff --git a/static/admin/js/admin/DateTimeShortcuts.js.gz b/static/admin/js/admin/DateTimeShortcuts.js.gz index 27d1430c..d184bad9 100644 Binary files a/static/admin/js/admin/DateTimeShortcuts.js.gz and b/static/admin/js/admin/DateTimeShortcuts.js.gz differ diff --git a/static/admin/js/admin/RelatedObjectLookups.de5309ac06dd.js b/static/admin/js/admin/RelatedObjectLookups.8609f99b9ab2.js similarity index 98% rename from static/admin/js/admin/RelatedObjectLookups.de5309ac06dd.js rename to static/admin/js/admin/RelatedObjectLookups.8609f99b9ab2.js index 752dcad7..afb6b66c 100644 --- a/static/admin/js/admin/RelatedObjectLookups.de5309ac06dd.js +++ b/static/admin/js/admin/RelatedObjectLookups.8609f99b9ab2.js @@ -26,13 +26,11 @@ } function addPopupIndex(name) { - name = name + "__" + (popupIndex + 1); - return name; + return name + "__" + (popupIndex + 1); } function removePopupIndex(name) { - name = name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); - return name; + return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); } function showAdminPopup(triggeringLink, name_regexp, add_popup) { diff --git a/static/admin/js/admin/RelatedObjectLookups.8609f99b9ab2.js.gz b/static/admin/js/admin/RelatedObjectLookups.8609f99b9ab2.js.gz new file mode 100644 index 00000000..2c550cc7 Binary files /dev/null and b/static/admin/js/admin/RelatedObjectLookups.8609f99b9ab2.js.gz differ diff --git a/static/admin/js/admin/RelatedObjectLookups.de5309ac06dd.js.gz b/static/admin/js/admin/RelatedObjectLookups.de5309ac06dd.js.gz deleted file mode 100644 index 075adb59..00000000 Binary files a/static/admin/js/admin/RelatedObjectLookups.de5309ac06dd.js.gz and /dev/null differ diff --git a/static/admin/js/admin/RelatedObjectLookups.js b/static/admin/js/admin/RelatedObjectLookups.js index 752dcad7..afb6b66c 100644 --- a/static/admin/js/admin/RelatedObjectLookups.js +++ b/static/admin/js/admin/RelatedObjectLookups.js @@ -26,13 +26,11 @@ } function addPopupIndex(name) { - name = name + "__" + (popupIndex + 1); - return name; + return name + "__" + (popupIndex + 1); } function removePopupIndex(name) { - name = name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); - return name; + return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); } function showAdminPopup(triggeringLink, name_regexp, add_popup) { diff --git a/static/admin/js/admin/RelatedObjectLookups.js.gz b/static/admin/js/admin/RelatedObjectLookups.js.gz index 075adb59..2c550cc7 100644 Binary files a/static/admin/js/admin/RelatedObjectLookups.js.gz and b/static/admin/js/admin/RelatedObjectLookups.js.gz differ diff --git a/static/admin/js/core.5d6b384a08b5.js.gz b/static/admin/js/core.5d6b384a08b5.js.gz deleted file mode 100644 index d7f3fbfa..00000000 Binary files a/static/admin/js/core.5d6b384a08b5.js.gz and /dev/null differ diff --git a/static/admin/js/core.5d6b384a08b5.js b/static/admin/js/core.cf103cd04ebf.js similarity index 97% rename from static/admin/js/core.5d6b384a08b5.js rename to static/admin/js/core.cf103cd04ebf.js index afdae281..0344a13f 100644 --- a/static/admin/js/core.5d6b384a08b5.js +++ b/static/admin/js/core.cf103cd04ebf.js @@ -119,11 +119,11 @@ function findPosY(obj) { let result = '', i = 0; while (i < format.length) { if (format.charAt(i) === '%') { - result = result + fields[format.charAt(i + 1)]; + result += fields[format.charAt(i + 1)]; ++i; } else { - result = result + format.charAt(i); + result += format.charAt(i); } ++i; } diff --git a/static/admin/js/core.cf103cd04ebf.js.gz b/static/admin/js/core.cf103cd04ebf.js.gz new file mode 100644 index 00000000..39bab4a5 Binary files /dev/null and b/static/admin/js/core.cf103cd04ebf.js.gz differ diff --git a/static/admin/js/core.js b/static/admin/js/core.js index afdae281..0344a13f 100644 --- a/static/admin/js/core.js +++ b/static/admin/js/core.js @@ -119,11 +119,11 @@ function findPosY(obj) { let result = '', i = 0; while (i < format.length) { if (format.charAt(i) === '%') { - result = result + fields[format.charAt(i + 1)]; + result += fields[format.charAt(i + 1)]; ++i; } else { - result = result + format.charAt(i); + result += format.charAt(i); } ++i; } diff --git a/static/admin/js/core.js.gz b/static/admin/js/core.js.gz index d7f3fbfa..39bab4a5 100644 Binary files a/static/admin/js/core.js.gz and b/static/admin/js/core.js.gz differ diff --git a/static/admin/js/filters.295a9d3d8b6a.js b/static/admin/js/filters.0e360b7a9f80.js similarity index 96% rename from static/admin/js/filters.295a9d3d8b6a.js rename to static/admin/js/filters.0e360b7a9f80.js index ba691ac8..f5536ebc 100644 --- a/static/admin/js/filters.295a9d3d8b6a.js +++ b/static/admin/js/filters.0e360b7a9f80.js @@ -11,7 +11,7 @@ } Object.entries(filters).forEach(([key, value]) => { - const detailElement = document.querySelector(`[data-filter-title='${key}']`); + const detailElement = document.querySelector(`[data-filter-title='${CSS.escape(key)}']`); // Check if the filter is present, it could be from other view. if (detailElement) { diff --git a/static/admin/js/filters.0e360b7a9f80.js.gz b/static/admin/js/filters.0e360b7a9f80.js.gz new file mode 100644 index 00000000..5bb1833c Binary files /dev/null and b/static/admin/js/filters.0e360b7a9f80.js.gz differ diff --git a/static/admin/js/filters.295a9d3d8b6a.js.gz b/static/admin/js/filters.295a9d3d8b6a.js.gz deleted file mode 100644 index 8a2dbd52..00000000 Binary files a/static/admin/js/filters.295a9d3d8b6a.js.gz and /dev/null differ diff --git a/static/admin/js/filters.js b/static/admin/js/filters.js index ba691ac8..f5536ebc 100644 --- a/static/admin/js/filters.js +++ b/static/admin/js/filters.js @@ -11,7 +11,7 @@ } Object.entries(filters).forEach(([key, value]) => { - const detailElement = document.querySelector(`[data-filter-title='${key}']`); + const detailElement = document.querySelector(`[data-filter-title='${CSS.escape(key)}']`); // Check if the filter is present, it could be from other view. if (detailElement) { diff --git a/static/admin/js/filters.js.gz b/static/admin/js/filters.js.gz index 8a2dbd52..5bb1833c 100644 Binary files a/static/admin/js/filters.js.gz and b/static/admin/js/filters.js.gz differ diff --git a/static/admin/js/nav_sidebar.36a64ecb39ed.js.gz b/static/admin/js/nav_sidebar.36a64ecb39ed.js.gz deleted file mode 100644 index 0b540d97..00000000 Binary files a/static/admin/js/nav_sidebar.36a64ecb39ed.js.gz and /dev/null differ diff --git a/static/admin/js/nav_sidebar.36a64ecb39ed.js b/static/admin/js/nav_sidebar.3b9190d420b1.js similarity index 75% rename from static/admin/js/nav_sidebar.36a64ecb39ed.js rename to static/admin/js/nav_sidebar.3b9190d420b1.js index 261a9d49..7e735db1 100644 --- a/static/admin/js/nav_sidebar.36a64ecb39ed.js +++ b/static/admin/js/nav_sidebar.3b9190d420b1.js @@ -2,47 +2,24 @@ { const toggleNavSidebar = document.getElementById('toggle-nav-sidebar'); if (toggleNavSidebar !== null) { - const navLinks = document.querySelectorAll('#nav-sidebar a'); - function disableNavLinkTabbing() { - for (const navLink of navLinks) { - navLink.tabIndex = -1; - } - } - function enableNavLinkTabbing() { - for (const navLink of navLinks) { - navLink.tabIndex = 0; - } - } - function disableNavFilterTabbing() { - document.getElementById('nav-filter').tabIndex = -1; - } - function enableNavFilterTabbing() { - document.getElementById('nav-filter').tabIndex = 0; - } - + const navSidebar = document.getElementById('nav-sidebar'); const main = document.getElementById('main'); let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); if (navSidebarIsOpen === null) { navSidebarIsOpen = 'true'; } - if (navSidebarIsOpen === 'false') { - disableNavLinkTabbing(); - disableNavFilterTabbing(); - } main.classList.toggle('shifted', navSidebarIsOpen === 'true'); + navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); toggleNavSidebar.addEventListener('click', function() { if (navSidebarIsOpen === 'true') { navSidebarIsOpen = 'false'; - disableNavLinkTabbing(); - disableNavFilterTabbing(); } else { navSidebarIsOpen = 'true'; - enableNavLinkTabbing(); - enableNavFilterTabbing(); } localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); main.classList.toggle('shifted'); + navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); }); } diff --git a/static/admin/js/nav_sidebar.3b9190d420b1.js.gz b/static/admin/js/nav_sidebar.3b9190d420b1.js.gz new file mode 100644 index 00000000..c666ede6 Binary files /dev/null and b/static/admin/js/nav_sidebar.3b9190d420b1.js.gz differ diff --git a/static/admin/js/nav_sidebar.js b/static/admin/js/nav_sidebar.js index 261a9d49..7e735db1 100644 --- a/static/admin/js/nav_sidebar.js +++ b/static/admin/js/nav_sidebar.js @@ -2,47 +2,24 @@ { const toggleNavSidebar = document.getElementById('toggle-nav-sidebar'); if (toggleNavSidebar !== null) { - const navLinks = document.querySelectorAll('#nav-sidebar a'); - function disableNavLinkTabbing() { - for (const navLink of navLinks) { - navLink.tabIndex = -1; - } - } - function enableNavLinkTabbing() { - for (const navLink of navLinks) { - navLink.tabIndex = 0; - } - } - function disableNavFilterTabbing() { - document.getElementById('nav-filter').tabIndex = -1; - } - function enableNavFilterTabbing() { - document.getElementById('nav-filter').tabIndex = 0; - } - + const navSidebar = document.getElementById('nav-sidebar'); const main = document.getElementById('main'); let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); if (navSidebarIsOpen === null) { navSidebarIsOpen = 'true'; } - if (navSidebarIsOpen === 'false') { - disableNavLinkTabbing(); - disableNavFilterTabbing(); - } main.classList.toggle('shifted', navSidebarIsOpen === 'true'); + navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); toggleNavSidebar.addEventListener('click', function() { if (navSidebarIsOpen === 'true') { navSidebarIsOpen = 'false'; - disableNavLinkTabbing(); - disableNavFilterTabbing(); } else { navSidebarIsOpen = 'true'; - enableNavLinkTabbing(); - enableNavFilterTabbing(); } localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); main.classList.toggle('shifted'); + navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); }); } diff --git a/static/admin/js/nav_sidebar.js.gz b/static/admin/js/nav_sidebar.js.gz index 0b540d97..c666ede6 100644 Binary files a/static/admin/js/nav_sidebar.js.gz and b/static/admin/js/nav_sidebar.js.gz differ diff --git a/static/admin/js/theme.ab270f56bb9c.js b/static/admin/js/theme.ab270f56bb9c.js new file mode 100644 index 00000000..794cd15f --- /dev/null +++ b/static/admin/js/theme.ab270f56bb9c.js @@ -0,0 +1,56 @@ +'use strict'; +{ + window.addEventListener('load', function(e) { + + function setTheme(mode) { + if (mode !== "light" && mode !== "dark" && mode !== "auto") { + console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); + mode = "auto"; + } + document.documentElement.dataset.theme = mode; + localStorage.setItem("theme", mode); + } + + function cycleTheme() { + const currentTheme = localStorage.getItem("theme") || "auto"; + const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + + if (prefersDark) { + // Auto (dark) -> Light -> Dark + if (currentTheme === "auto") { + setTheme("light"); + } else if (currentTheme === "light") { + setTheme("dark"); + } else { + setTheme("auto"); + } + } else { + // Auto (light) -> Dark -> Light + if (currentTheme === "auto") { + setTheme("dark"); + } else if (currentTheme === "dark") { + setTheme("light"); + } else { + setTheme("auto"); + } + } + } + + function initTheme() { + // set theme defined in localStorage if there is one, or fallback to auto mode + const currentTheme = localStorage.getItem("theme"); + currentTheme ? setTheme(currentTheme) : setTheme("auto"); + } + + function setupTheme() { + // Attach event handlers for toggling themes + const buttons = document.getElementsByClassName("theme-toggle"); + Array.from(buttons).forEach((btn) => { + btn.addEventListener("click", cycleTheme); + }); + initTheme(); + } + + setupTheme(); + }); +} diff --git a/static/admin/js/theme.ab270f56bb9c.js.gz b/static/admin/js/theme.ab270f56bb9c.js.gz new file mode 100644 index 00000000..1e4a36a7 Binary files /dev/null and b/static/admin/js/theme.ab270f56bb9c.js.gz differ diff --git a/static/admin/js/theme.js b/static/admin/js/theme.js new file mode 100644 index 00000000..794cd15f --- /dev/null +++ b/static/admin/js/theme.js @@ -0,0 +1,56 @@ +'use strict'; +{ + window.addEventListener('load', function(e) { + + function setTheme(mode) { + if (mode !== "light" && mode !== "dark" && mode !== "auto") { + console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); + mode = "auto"; + } + document.documentElement.dataset.theme = mode; + localStorage.setItem("theme", mode); + } + + function cycleTheme() { + const currentTheme = localStorage.getItem("theme") || "auto"; + const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + + if (prefersDark) { + // Auto (dark) -> Light -> Dark + if (currentTheme === "auto") { + setTheme("light"); + } else if (currentTheme === "light") { + setTheme("dark"); + } else { + setTheme("auto"); + } + } else { + // Auto (light) -> Dark -> Light + if (currentTheme === "auto") { + setTheme("dark"); + } else if (currentTheme === "dark") { + setTheme("light"); + } else { + setTheme("auto"); + } + } + } + + function initTheme() { + // set theme defined in localStorage if there is one, or fallback to auto mode + const currentTheme = localStorage.getItem("theme"); + currentTheme ? setTheme(currentTheme) : setTheme("auto"); + } + + function setupTheme() { + // Attach event handlers for toggling themes + const buttons = document.getElementsByClassName("theme-toggle"); + Array.from(buttons).forEach((btn) => { + btn.addEventListener("click", cycleTheme); + }); + initTheme(); + } + + setupTheme(); + }); +} diff --git a/static/admin/js/theme.js.gz b/static/admin/js/theme.js.gz new file mode 100644 index 00000000..1e4a36a7 Binary files /dev/null and b/static/admin/js/theme.js.gz differ diff --git a/static/admin/js/urlify.25cc3eac8123.js.gz b/static/admin/js/urlify.25cc3eac8123.js.gz deleted file mode 100644 index 75663059..00000000 Binary files a/static/admin/js/urlify.25cc3eac8123.js.gz and /dev/null differ diff --git a/static/admin/js/urlify.25cc3eac8123.js b/static/admin/js/urlify.ae970a820212.js similarity index 98% rename from static/admin/js/urlify.25cc3eac8123.js rename to static/admin/js/urlify.ae970a820212.js index 61dedb23..9fc04094 100644 --- a/static/admin/js/urlify.25cc3eac8123.js +++ b/static/admin/js/urlify.ae970a820212.js @@ -163,8 +163,7 @@ s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens s = s.substring(0, num_chars); // trim to first num_chars chars - s = s.replace(/-+$/g, ''); // trim any trailing hyphens - return s; + return s.replace(/-+$/g, ''); // trim any trailing hyphens } window.URLify = URLify; } diff --git a/static/admin/js/urlify.ae970a820212.js.gz b/static/admin/js/urlify.ae970a820212.js.gz new file mode 100644 index 00000000..34e96295 Binary files /dev/null and b/static/admin/js/urlify.ae970a820212.js.gz differ diff --git a/static/admin/js/urlify.js b/static/admin/js/urlify.js index 61dedb23..9fc04094 100644 --- a/static/admin/js/urlify.js +++ b/static/admin/js/urlify.js @@ -163,8 +163,7 @@ s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens s = s.substring(0, num_chars); // trim to first num_chars chars - s = s.replace(/-+$/g, ''); // trim any trailing hyphens - return s; + return s.replace(/-+$/g, ''); // trim any trailing hyphens } window.URLify = URLify; } diff --git a/static/admin/js/urlify.js.gz b/static/admin/js/urlify.js.gz index 75663059..34e96295 100644 Binary files a/static/admin/js/urlify.js.gz and b/static/admin/js/urlify.js.gz differ diff --git a/static/admin/js/vendor/jquery/jquery.2849239b95f5.js b/static/admin/js/vendor/jquery/jquery.0208b96062ba.js similarity index 97% rename from static/admin/js/vendor/jquery/jquery.2849239b95f5.js rename to static/admin/js/vendor/jquery/jquery.0208b96062ba.js index fc6c299b..7f35c11b 100644 --- a/static/admin/js/vendor/jquery/jquery.2849239b95f5.js +++ b/static/admin/js/vendor/jquery/jquery.0208b96062ba.js @@ -1,5 +1,5 @@ /*! - * jQuery JavaScript Library v3.6.0 + * jQuery JavaScript Library v3.6.4 * https://jquery.com/ * * Includes Sizzle.js @@ -9,7 +9,7 @@ * Released under the MIT license * https://jquery.org/license * - * Date: 2021-03-02T17:08Z + * Date: 2023-03-08T15:28Z */ ( function( global, factory ) { @@ -23,7 +23,7 @@ // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. + // See ticket trac-14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { @@ -151,7 +151,7 @@ function toType( obj ) { var - version = "3.6.0", + version = "3.6.4", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -522,14 +522,14 @@ function isArrayLike( obj ) { } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.3.6 + * Sizzle CSS Selector Engine v2.3.10 * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://js.foundation/ * - * Date: 2021-02-16 + * Date: 2023-02-14 */ ( function( window ) { var i, @@ -633,7 +633,7 @@ var i, whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), rdescend = new RegExp( whitespace + "|>" ), @@ -850,7 +850,7 @@ function Sizzle( selector, context, results, seed ) { // as such selectors are not recognized by querySelectorAll. // Thanks to Andrew Dupont for this technique. if ( nodeType === 1 && - ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || @@ -1174,6 +1174,24 @@ setDocument = Sizzle.setDocument = function( node ) { !el.querySelectorAll( ":scope fieldset div" ).length; } ); + // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ + // Make sure the the `:has()` argument is parsed unforgivingly. + // We include `*` in the test to detect buggy implementations that are + // _selectively_ forgiving (specifically when the list includes at least + // one valid selector). + // Note that we treat complete lack of support for `:has()` as if it were + // spec-compliant support, which is fine because use of `:has()` in such + // environments will fail in the qSA path and fall back to jQuery traversal + // anyway. + support.cssHas = assert( function() { + try { + document.querySelector( ":has(*,:jqfake)" ); + return false; + } catch ( e ) { + return true; + } + } ); + /* Attributes ---------------------------------------------------------------------- */ @@ -1440,6 +1458,17 @@ setDocument = Sizzle.setDocument = function( node ) { } ); } + if ( !support.cssHas ) { + + // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ + // Our regular `try-catch` mechanism fails to detect natively-unsupported + // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) + // in browsers that parse the `:has()` argument as a forgiving selector list. + // https://drafts.csswg.org/selectors/#relational now requires the argument + // to be parsed unforgivingly, but browsers have not yet fully adjusted. + rbuggyQSA.push( ":has" ); + } + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); @@ -1452,7 +1481,14 @@ setDocument = Sizzle.setDocument = function( node ) { // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, + + // Support: IE <9 only + // IE doesn't have `contains` on `document` so we need to check for + // `documentElement` presence. + // We need to fall back to `a` when `documentElement` is missing + // as `ownerDocument` of elements within `