diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9dfcbf4..b26d8445 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,7 @@ repos: - id: check-json - id: check-toml - id: end-of-file-fixer + exclude: "(.*js$|.*css$)" - id: check-case-conflict - id: check-merge-conflict - id: detect-private-key diff --git a/src/static/scripts/bootstrap-native.js b/src/static/scripts/bootstrap-native.js index 82e63f27..2159b3db 100644 --- a/src/static/scripts/bootstrap-native.js +++ b/src/static/scripts/bootstrap-native.js @@ -1,5 +1,5 @@ /*! - * Native JavaScript for Bootstrap v4.0.4 (https://thednp.github.io/bootstrap.native/) + * Native JavaScript for Bootstrap v4.0.6 (https://thednp.github.io/bootstrap.native/) * Copyright 2015-2021 © dnp_theme * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) */ @@ -1467,19 +1467,26 @@ } } - const modalOpenClass = 'modal-open'; const modalBackdropClass = 'modal-backdrop'; + const offcanvasBackdropClass = 'offcanvas-backdrop'; const modalActiveSelector = `.modal.${showClass}`; const offcanvasActiveSelector = `.offcanvas.${showClass}`; - const overlay = document.createElement('div'); - overlay.setAttribute('class', `${modalBackdropClass}`); function getCurrentOpen() { return queryElement(`${modalActiveSelector},${offcanvasActiveSelector}`); } - function appendOverlay(hasFade) { + function toggleOverlayType(isModal) { + const targetClass = isModal ? modalBackdropClass : offcanvasBackdropClass; + [modalBackdropClass, offcanvasBackdropClass].forEach((c) => { + removeClass(overlay, c); + }); + addClass(overlay, targetClass); + } + + function appendOverlay(hasFade, isModal) { + toggleOverlayType(isModal); document.body.appendChild(overlay); if (hasFade) addClass(overlay, fadeClass); } @@ -1499,7 +1506,6 @@ if (!currentOpen) { removeClass(overlay, fadeClass); - removeClass(bd, modalOpenClass); bd.removeChild(overlay); resetScrollbar(); } @@ -1518,7 +1524,6 @@ const modalString = 'modal'; const modalComponent = 'Modal'; const modalSelector = `.${modalString}`; - // const modalActiveSelector = `.${modalString}.${showClass}`; const modalToggleSelector = `[${dataBsToggle}="${modalString}"]`; const modalDismissSelector = `[${dataBsDismiss}="${modalString}"]`; const modalStaticClass = `${modalString}-static`; @@ -1567,8 +1572,11 @@ } function afterModalHide(self) { - const { triggers } = self; - removeOverlay(); + const { triggers, options } = self; + if (!getCurrentOpen()) { + if (options.backdrop) removeOverlay(); + resetScrollbar(); + } self.element.style.paddingRight = ''; self.isAnimating = false; @@ -1594,9 +1602,8 @@ element.style.display = 'block'; setModalScrollbar(self); - if (!queryElement(modalActiveSelector)) { + if (!getCurrentOpen()) { document.body.style.overflow = 'hidden'; - addClass(document.body, modalOpenClass); } addClass(element, showClass); @@ -1609,16 +1616,15 @@ function beforeModalHide(self, force) { const { - element, relatedTarget, hasFade, + element, options, relatedTarget, hasFade, } = self; - const currentOpen = getCurrentOpen(); element.style.display = ''; // force can also be the transitionEvent object, we wanna make sure it's not // call is not forced and overlay is visible - if (!force && hasFade && hasClass(overlay, showClass) - && !currentOpen) { // AND no modal is visible + if (options.backdrop && !force && hasFade && hasClass(overlay, showClass) + && !getCurrentOpen()) { // AND no modal is visible hideOverlay(); emulateTransitionEnd(overlay, () => afterModalHide(self)); } else { @@ -1666,7 +1672,8 @@ if (self.isAnimating) return; - const { isStatic, modalDialog } = self; + const { options, isStatic, modalDialog } = self; + const { backdrop } = options; const { target } = e; const selectedText = document.getSelection().toString().length; const targetInsideDialog = modalDialog.contains(target); @@ -1676,7 +1683,7 @@ addClass(element, modalStaticClass); self.isAnimating = true; emulateTransitionEnd(modalDialog, () => staticTransitionEnd(self)); - } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog)) { + } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog && backdrop)) { self.relatedTarget = dismiss || null; self.hide(); e.preventDefault(); @@ -1734,8 +1741,9 @@ show() { const self = this; const { - element, isAnimating, hasFade, relatedTarget, + element, options, isAnimating, hasFade, relatedTarget, } = self; + const { backdrop } = options; let overlayDelay = 0; if (hasClass(element, showClass) && !isAnimating) return; @@ -1744,8 +1752,6 @@ element.dispatchEvent(showModalEvent); if (showModalEvent.defaultPrevented) return; - self.isAnimating = true; - // we elegantly hide any opened modal/offcanvas const currentOpen = getCurrentOpen(); if (currentOpen && currentOpen !== element) { @@ -1755,18 +1761,24 @@ that.hide(); } - if (!queryElement(`.${modalBackdropClass}`)) { - appendOverlay(hasFade); - } - overlayDelay = getElementTransitionDuration(overlay); + self.isAnimating = true; - if (!hasClass(overlay, showClass)) { - showOverlay(); - } + if (backdrop) { + if (!currentOpen && !hasClass(overlay, showClass)) { + appendOverlay(hasFade, 1); + } else { + toggleOverlayType(1); + } + overlayDelay = getElementTransitionDuration(overlay); - if (!currentOpen) { + if (!hasClass(overlay, showClass)) showOverlay(); setTimeout(() => beforeModalShow(self), overlayDelay); - } else beforeModalShow(self); + } else { + beforeModalShow(self); + if (currentOpen && hasClass(overlay, showClass)) { + hideOverlay(); + } + } } hide(force) { @@ -1863,7 +1875,6 @@ const { element, options } = self; if (!options.scroll) { - addClass(document.body, modalOpenClass); document.body.style.overflow = 'hidden'; setOffCanvasScrollbar(self); } @@ -1909,15 +1920,15 @@ const self = element[offcanvasComponent]; if (!self) return; - const { options, open, triggers } = self; + const { options, triggers } = self; const { target } = e; const trigger = target.closest(offcanvasToggleSelector); if (trigger && trigger.tagName === 'A') e.preventDefault(); - if (open && ((!element.contains(target) && options.backdrop + if ((!element.contains(target) && options.backdrop && (!trigger || (trigger && !triggers.includes(trigger)))) - || offCanvasDismiss.contains(target))) { + || offCanvasDismiss.contains(target)) { self.relatedTarget = target === offCanvasDismiss ? offCanvasDismiss : null; self.hide(); } @@ -1965,7 +1976,6 @@ element.removeAttribute(ariaModal); element.removeAttribute('role'); element.style.visibility = ''; - self.open = false; self.isAnimating = false; if (triggers.length) { @@ -1979,7 +1989,6 @@ if (options.backdrop) removeOverlay(); if (!options.scroll) { resetScrollbar(); - removeClass(document.body, modalOpenClass); } } @@ -2005,7 +2014,6 @@ .filter((btn) => getTargetElement(btn) === element); // additional instance property - self.open = false; self.isAnimating = false; self.scrollbarWidth = measureScrollbar(); @@ -2017,7 +2025,8 @@ // ======================== toggle() { const self = this; - return self.open ? self.hide() : self.show(); + if (hasClass(self.element, showClass)) self.hide(); + else self.show(); } show() { @@ -2027,7 +2036,7 @@ } = self; let overlayDelay = 0; - if (self.open || isAnimating) return; + if (hasClass(element, showClass) || isAnimating) return; showOffcanvasEvent.relatedTarget = relatedTarget || null; element.dispatchEvent(showOffcanvasEvent); @@ -2043,12 +2052,13 @@ that.hide(); } - self.open = true; self.isAnimating = true; if (options.backdrop) { - if (!queryElement(`.${modalBackdropClass}`)) { + if (!currentOpen) { appendOverlay(1); + } else { + toggleOverlayType(); } overlayDelay = getElementTransitionDuration(overlay); @@ -2056,14 +2066,19 @@ if (!hasClass(overlay, showClass)) showOverlay(); setTimeout(() => beforeOffcanvasShow(self), overlayDelay); - } else beforeOffcanvasShow(self); + } else { + beforeOffcanvasShow(self); + if (currentOpen && hasClass(overlay, showClass)) { + hideOverlay(); + } + } } hide(force) { const self = this; const { element, isAnimating, relatedTarget } = self; - if (!self.open || isAnimating) return; + if (!hasClass(element, showClass) || isAnimating) return; hideOffcanvasEvent.relatedTarget = relatedTarget || null; element.dispatchEvent(hideOffcanvasEvent); @@ -3483,7 +3498,7 @@ constructor: Tooltip, }; - var version = "4.0.4"; + var version = "4.0.6"; // import { alertInit } from '../components/alert-native.js'; // import { buttonInit } from '../components/button-native.js'; diff --git a/src/static/scripts/bootstrap.css b/src/static/scripts/bootstrap.css index da83b00f..892302a6 100644 --- a/src/static/scripts/bootstrap.css +++ b/src/static/scripts/bootstrap.css @@ -1,6 +1,6 @@ @charset "UTF-8"; /*! - * Bootstrap v5.1.0 (https://getbootstrap.com/) + * Bootstrap v5.0.2 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) @@ -19,15 +19,6 @@ --bs-white: #fff; --bs-gray: #6c757d; --bs-gray-dark: #343a40; - --bs-gray-100: #f8f9fa; - --bs-gray-200: #e9ecef; - --bs-gray-300: #dee2e6; - --bs-gray-400: #ced4da; - --bs-gray-500: #adb5bd; - --bs-gray-600: #6c757d; - --bs-gray-700: #495057; - --bs-gray-800: #343a40; - --bs-gray-900: #212529; --bs-primary: #0d6efd; --bs-secondary: #6c757d; --bs-success: #198754; @@ -36,26 +27,9 @@ --bs-danger: #dc3545; --bs-light: #f8f9fa; --bs-dark: #212529; - --bs-primary-rgb: 13, 110, 253; - --bs-secondary-rgb: 108, 117, 125; - --bs-success-rgb: 25, 135, 84; - --bs-info-rgb: 13, 202, 240; - --bs-warning-rgb: 255, 193, 7; - --bs-danger-rgb: 220, 53, 69; - --bs-light-rgb: 248, 249, 250; - --bs-dark-rgb: 33, 37, 41; - --bs-white-rgb: 255, 255, 255; - --bs-black-rgb: 0, 0, 0; - --bs-body-rgb: 33, 37, 41; --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); - --bs-body-font-family: var(--bs-font-sans-serif); - --bs-body-font-size: 1rem; - --bs-body-font-weight: 400; - --bs-body-line-height: 1.5; - --bs-body-color: #212529; - --bs-body-bg: #fff; } *, @@ -72,13 +46,12 @@ body { margin: 0; - font-family: var(--bs-body-font-family); - font-size: var(--bs-body-font-size); - font-weight: var(--bs-body-font-weight); - line-height: var(--bs-body-line-height); - color: var(--bs-body-color); - text-align: var(--bs-body-text-align); - background-color: var(--bs-body-bg); + font-family: var(--bs-font-sans-serif); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } @@ -712,6 +685,206 @@ progress { width: 16.6666666667%; } +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } +} .col-auto { flex: 0 0 auto; width: auto; @@ -882,45 +1055,6 @@ progress { } @media (min-width: 576px) { - .col-sm { - flex: 1 0 0%; - } - - .row-cols-sm-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-sm-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-sm-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-sm-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-sm-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-sm-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-sm-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-sm-auto { flex: 0 0 auto; width: auto; @@ -1095,45 +1229,6 @@ progress { } } @media (min-width: 768px) { - .col-md { - flex: 1 0 0%; - } - - .row-cols-md-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-md-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-md-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-md-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-md-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-md-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-md-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-md-auto { flex: 0 0 auto; width: auto; @@ -1308,45 +1403,6 @@ progress { } } @media (min-width: 992px) { - .col-lg { - flex: 1 0 0%; - } - - .row-cols-lg-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-lg-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-lg-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-lg-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-lg-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-lg-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-lg-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-lg-auto { flex: 0 0 auto; width: auto; @@ -1521,45 +1577,6 @@ progress { } } @media (min-width: 1200px) { - .col-xl { - flex: 1 0 0%; - } - - .row-cols-xl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-xl-auto { flex: 0 0 auto; width: auto; @@ -1734,45 +1751,6 @@ progress { } } @media (min-width: 1400px) { - .col-xxl { - flex: 1 0 0%; - } - - .row-cols-xxl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xxl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xxl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xxl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xxl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xxl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xxl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - .col-xxl-auto { flex: 0 0 auto; width: auto; @@ -2288,7 +2266,7 @@ progress { } .form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); + min-height: calc(1.5em + (0.5rem + 2px)); padding: 0.25rem 0.5rem; font-size: 0.875rem; border-radius: 0.2rem; @@ -2307,7 +2285,7 @@ progress { } .form-control-lg { - min-height: calc(1.5em + 1rem + 2px); + min-height: calc(1.5em + (1rem + 2px)); padding: 0.5rem 1rem; font-size: 1.25rem; border-radius: 0.3rem; @@ -2326,17 +2304,17 @@ progress { } textarea.form-control { - min-height: calc(1.5em + 0.75rem + 2px); + min-height: calc(1.5em + (0.75rem + 2px)); } textarea.form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); + min-height: calc(1.5em + (0.5rem + 2px)); } textarea.form-control-lg { - min-height: calc(1.5em + 1rem + 2px); + min-height: calc(1.5em + (1rem + 2px)); } .form-control-color { - width: 3rem; + max-width: 3rem; height: auto; padding: 0.375rem; } @@ -3452,16 +3430,6 @@ textarea.form-control-lg { transition: none; } } -.collapsing.collapse-horizontal { - width: 0; - height: auto; - transition: width 0.35s ease; -} -@media (prefers-reduced-motion: reduce) { - .collapsing.collapse-horizontal { - transition: none; - } -} .dropup, .dropend, @@ -4079,33 +4047,6 @@ textarea.form-control-lg { .navbar-expand-sm .navbar-toggler { display: none; } - .navbar-expand-sm .offcanvas-header { - display: none; - } - .navbar-expand-sm .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-sm .offcanvas-top, -.navbar-expand-sm .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-sm .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 768px) { .navbar-expand-md { @@ -4132,33 +4073,6 @@ textarea.form-control-lg { .navbar-expand-md .navbar-toggler { display: none; } - .navbar-expand-md .offcanvas-header { - display: none; - } - .navbar-expand-md .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-md .offcanvas-top, -.navbar-expand-md .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-md .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 992px) { .navbar-expand-lg { @@ -4185,33 +4099,6 @@ textarea.form-control-lg { .navbar-expand-lg .navbar-toggler { display: none; } - .navbar-expand-lg .offcanvas-header { - display: none; - } - .navbar-expand-lg .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-lg .offcanvas-top, -.navbar-expand-lg .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-lg .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 1200px) { .navbar-expand-xl { @@ -4238,33 +4125,6 @@ textarea.form-control-lg { .navbar-expand-xl .navbar-toggler { display: none; } - .navbar-expand-xl .offcanvas-header { - display: none; - } - .navbar-expand-xl .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-xl .offcanvas-top, -.navbar-expand-xl .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-xl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } @media (min-width: 1400px) { .navbar-expand-xxl { @@ -4291,33 +4151,6 @@ textarea.form-control-lg { .navbar-expand-xxl .navbar-toggler { display: none; } - .navbar-expand-xxl .offcanvas-header { - display: none; - } - .navbar-expand-xxl .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; - } - .navbar-expand-xxl .offcanvas-top, -.navbar-expand-xxl .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; - } - .navbar-expand-xxl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - } } .navbar-expand { flex-wrap: nowrap; @@ -4343,33 +4176,6 @@ textarea.form-control-lg { .navbar-expand .navbar-toggler { display: none; } -.navbar-expand .offcanvas-header { - display: none; -} -.navbar-expand .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; -} -.navbar-expand .offcanvas-top, -.navbar-expand .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; -} -.navbar-expand .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; -} .navbar-light .navbar-brand { color: rgba(0, 0, 0, 0.9); @@ -4493,6 +4299,9 @@ textarea.form-control-lg { margin-bottom: 0; } +.card-link:hover { + text-decoration: none; +} .card-link + .card-link { margin-left: 1rem; } @@ -5368,10 +5177,10 @@ textarea.form-control-lg { box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); border-radius: 0.25rem; } -.toast.showing { +.toast:not(.showing):not(.show) { opacity: 0; } -.toast:not(.show) { +.toast.hide { display: none; } @@ -5411,7 +5220,7 @@ textarea.form-control-lg { position: fixed; top: 0; left: 0; - z-index: 1055; + z-index: 1060; display: none; width: 100%; height: 100%; @@ -5476,7 +5285,7 @@ textarea.form-control-lg { position: fixed; top: 0; left: 0; - z-index: 1050; + z-index: 1040; width: 100vw; height: 100vh; background-color: #000; @@ -6201,7 +6010,7 @@ textarea.form-control-lg { .offcanvas { position: fixed; bottom: 0; - z-index: 1045; + z-index: 1050; display: flex; flex-direction: column; max-width: 100%; @@ -6217,22 +6026,6 @@ textarea.form-control-lg { } } -.offcanvas-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1040; - width: 100vw; - height: 100vh; - background-color: #000; -} -.offcanvas-backdrop.fade { - opacity: 0; -} -.offcanvas-backdrop.show { - opacity: 0.5; -} - .offcanvas-header { display: flex; align-items: center; @@ -6296,69 +6089,6 @@ textarea.form-control-lg { transform: none; } -.placeholder { - display: inline-block; - min-height: 1em; - vertical-align: middle; - cursor: wait; - background-color: currentColor; - opacity: 0.5; -} -.placeholder.btn::before { - display: inline-block; - content: ""; -} - -.placeholder-xs { - min-height: 0.6em; -} - -.placeholder-sm { - min-height: 0.8em; -} - -.placeholder-lg { - min-height: 1.2em; -} - -.placeholder-glow .placeholder { - -webkit-animation: placeholder-glow 2s ease-in-out infinite; - animation: placeholder-glow 2s ease-in-out infinite; -} - -@-webkit-keyframes placeholder-glow { - 50% { - opacity: 0.2; - } -} - -@keyframes placeholder-glow { - 50% { - opacity: 0.2; - } -} -.placeholder-wave { - -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); - mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); - -webkit-mask-size: 200% 100%; - mask-size: 200% 100%; - -webkit-animation: placeholder-wave 2s linear infinite; - animation: placeholder-wave 2s linear infinite; -} - -@-webkit-keyframes placeholder-wave { - 100% { - -webkit-mask-position: -200% 0%; - mask-position: -200% 0%; - } -} - -@keyframes placeholder-wave { - 100% { - -webkit-mask-position: -200% 0%; - mask-position: -200% 0%; - } -} .clearfix::after { display: block; clear: both; @@ -6517,20 +6247,6 @@ textarea.form-control-lg { z-index: 1020; } } -.hstack { - display: flex; - flex-direction: row; - align-items: center; - align-self: stretch; -} - -.vstack { - display: flex; - flex: 1 1 auto; - flex-direction: column; - align-self: stretch; -} - .visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { position: absolute !important; @@ -6560,15 +6276,6 @@ textarea.form-control-lg { white-space: nowrap; } -.vr { - display: inline-block; - align-self: stretch; - width: 1px; - min-height: 1em; - background-color: currentColor; - opacity: 0.25; -} - .align-baseline { vertical-align: baseline !important; } @@ -6605,26 +6312,6 @@ textarea.form-control-lg { float: none !important; } -.opacity-0 { - opacity: 0 !important; -} - -.opacity-25 { - opacity: 0.25 !important; -} - -.opacity-50 { - opacity: 0.5 !important; -} - -.opacity-75 { - opacity: 0.75 !important; -} - -.opacity-100 { - opacity: 1 !important; -} - .overflow-auto { overflow: auto !important; } @@ -7648,176 +7335,105 @@ textarea.form-control-lg { /* rtl:end:remove */ .text-primary { - --bs-text-opacity: 1; - color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important; + color: #0d6efd !important; } .text-secondary { - --bs-text-opacity: 1; - color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important; + color: #6c757d !important; } .text-success { - --bs-text-opacity: 1; - color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important; + color: #198754 !important; } .text-info { - --bs-text-opacity: 1; - color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important; + color: #0dcaf0 !important; } .text-warning { - --bs-text-opacity: 1; - color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important; + color: #ffc107 !important; } .text-danger { - --bs-text-opacity: 1; - color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important; + color: #dc3545 !important; } .text-light { - --bs-text-opacity: 1; - color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important; + color: #f8f9fa !important; } .text-dark { - --bs-text-opacity: 1; - color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important; -} - -.text-black { - --bs-text-opacity: 1; - color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important; + color: #212529 !important; } .text-white { - --bs-text-opacity: 1; - color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important; + color: #fff !important; } .text-body { - --bs-text-opacity: 1; - color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important; + color: #212529 !important; } .text-muted { - --bs-text-opacity: 1; color: #6c757d !important; } .text-black-50 { - --bs-text-opacity: 1; color: rgba(0, 0, 0, 0.5) !important; } .text-white-50 { - --bs-text-opacity: 1; color: rgba(255, 255, 255, 0.5) !important; } .text-reset { - --bs-text-opacity: 1; color: inherit !important; } -.text-opacity-25 { - --bs-text-opacity: 0.25; -} - -.text-opacity-50 { - --bs-text-opacity: 0.5; -} - -.text-opacity-75 { - --bs-text-opacity: 0.75; -} - -.text-opacity-100 { - --bs-text-opacity: 1; -} - .bg-primary { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; + background-color: #0d6efd !important; } .bg-secondary { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important; + background-color: #6c757d !important; } .bg-success { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important; + background-color: #198754 !important; } .bg-info { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important; + background-color: #0dcaf0 !important; } .bg-warning { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important; + background-color: #ffc107 !important; } .bg-danger { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important; + background-color: #dc3545 !important; } .bg-light { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important; + background-color: #f8f9fa !important; } .bg-dark { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important; -} - -.bg-black { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; -} - -.bg-white { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important; + background-color: #212529 !important; } .bg-body { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important; + background-color: #fff !important; +} + +.bg-white { + background-color: #fff !important; } .bg-transparent { - --bs-bg-opacity: 1; background-color: transparent !important; } -.bg-opacity-10 { - --bs-bg-opacity: 0.1; -} - -.bg-opacity-25 { - --bs-bg-opacity: 0.25; -} - -.bg-opacity-50 { - --bs-bg-opacity: 0.5; -} - -.bg-opacity-75 { - --bs-bg-opacity: 0.75; -} - -.bg-opacity-100 { - --bs-bg-opacity: 1; -} - .bg-gradient { background-image: var(--bs-gradient) !important; } @@ -11218,4 +10834,4 @@ textarea.form-control-lg { } } -/*# sourceMappingURL=bootstrap.css.map */ +/*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file diff --git a/src/static/scripts/datatables.css b/src/static/scripts/datatables.css index db60b110..585f9390 100644 --- a/src/static/scripts/datatables.css +++ b/src/static/scripts/datatables.css @@ -4,13 +4,94 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#bs5/dt-1.10.25 + * https://datatables.net/download/#bs5/dt-1.11.2 * * Included libraries: - * DataTables 1.10.25 + * DataTables 1.11.2 */ @charset "UTF-8"; +td.dt-control { + background: url("https://www.datatables.net/examples/resources/details_open.png") no-repeat center center; + cursor: pointer; +} + +tr.dt-hasChild td.dt-control { + background: url("https://www.datatables.net/examples/resources/details_close.png") no-repeat center center; +} + +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center, +table.dataTable td.dataTables_empty { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + /*! Bootstrap 5 integration for DataTables * * ©2020 SpryMedia Ltd, all rights reserved. @@ -143,21 +224,21 @@ div.dataTables_scrollHead table.dataTable { margin-bottom: 0 !important; } -div.dataTables_scrollBody table { +div.dataTables_scrollBody > table { border-top: none; margin-top: 0 !important; margin-bottom: 0 !important; } -div.dataTables_scrollBody table thead .sorting:before, -div.dataTables_scrollBody table thead .sorting_asc:before, -div.dataTables_scrollBody table thead .sorting_desc:before, -div.dataTables_scrollBody table thead .sorting:after, -div.dataTables_scrollBody table thead .sorting_asc:after, -div.dataTables_scrollBody table thead .sorting_desc:after { +div.dataTables_scrollBody > table > thead .sorting:before, +div.dataTables_scrollBody > table > thead .sorting_asc:before, +div.dataTables_scrollBody > table > thead .sorting_desc:before, +div.dataTables_scrollBody > table > thead .sorting:after, +div.dataTables_scrollBody > table > thead .sorting_asc:after, +div.dataTables_scrollBody > table > thead .sorting_desc:after { display: none; } -div.dataTables_scrollBody table tbody tr:first-child th, -div.dataTables_scrollBody table tbody tr:first-child td { +div.dataTables_scrollBody > table > tbody tr:first-child th, +div.dataTables_scrollBody > table > tbody tr:first-child td { border-top: none; } @@ -235,4 +316,11 @@ div.table-responsive > div.dataTables_wrapper > div.row > div[class^=col-]:last- padding-right: 0; } +table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) { + --bs-table-accent-bg: transparent; +} +table.dataTable.table-striped > tbody > tr.odd { + --bs-table-accent-bg: var(--bs-table-striped-bg); +} + diff --git a/src/static/scripts/datatables.js b/src/static/scripts/datatables.js index f8f1f3d2..93bbe80b 100644 --- a/src/static/scripts/datatables.js +++ b/src/static/scripts/datatables.js @@ -4,20 +4,20 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#bs5/dt-1.10.25 + * https://datatables.net/download/#bs5/dt-1.11.2 * * Included libraries: - * DataTables 1.10.25 + * DataTables 1.11.2 */ -/*! DataTables 1.10.25 +/*! DataTables 1.11.2 * ©2008-2021 SpryMedia Ltd - datatables.net/license */ /** * @summary DataTables * @description Paginate, search and order HTML tables - * @version 1.10.25 + * @version 1.11.2 * @file jquery.dataTables.js * @author SpryMedia Ltd * @contact www.datatables.net @@ -65,7 +65,7 @@ } else { // Browser - factory( jQuery, window, document ); + window.DataTable = factory( jQuery, window, document ); } } (function( $, window, document, undefined ) { @@ -103,8 +103,17 @@ * } ); * } ); */ - var DataTable = function ( options ) + var DataTable = function ( selector, options ) { + // When creating with `new`, create a new DataTable, returning the API instance + if (this instanceof DataTable) { + return $(selector).DataTable(options); + } + else { + // Argument switching + options = selector; + } + /** * Perform a jQuery selector action on the table's TR elements (from the tbody) and * return the resulting jQuery object. @@ -1097,8 +1106,8 @@ dataType: 'json', url: oLanguage.sUrl, success: function ( json ) { - _fnLanguageCompat( json ); _fnCamelToHungarian( defaults.oLanguage, json ); + _fnLanguageCompat( json ); $.extend( true, oLanguage, json ); _fnCallbackFire( oSettings, null, 'i18n', [oSettings]); @@ -1313,10 +1322,11 @@ }; /* Must be done after everything which can be overridden by the state saving! */ + _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); + if ( oInit.bStateSave ) { features.bStateSave = true; - _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); _fnLoadState( oSettings, oInit, loadedInit ); } else { @@ -1687,6 +1697,227 @@ */ escapeRegex: function ( val ) { return val.replace( _re_escape_regex, '\\$1' ); + }, + + /** + * Create a function that will write to a nested object or array + * @param {*} source JSON notation string + * @returns Write function + */ + set: function ( source ) { + if ( $.isPlainObject( source ) ) { + /* Unlike get, only the underscore (global) option is used for for + * setting data since we don't know the type here. This is why an object + * option is not documented for `mData` (which is read/write), but it is + * for `mRender` which is read only. + */ + return DataTable.util.set( source._ ); + } + else if ( source === null ) { + // Nothing to do when the data source is null + return function () {}; + } + else if ( typeof source === 'function' ) { + return function (data, val, meta) { + source( data, 'set', val, meta ); + }; + } + else if ( typeof source === 'string' && (source.indexOf('.') !== -1 || + source.indexOf('[') !== -1 || source.indexOf('(') !== -1) ) + { + // Like the get, we need to get data from a nested object + var setData = function (data, val, src) { + var a = _fnSplitObjNotation( src ), b; + var aLast = a[a.length-1]; + var arrayNotation, funcNotation, o, innerSrc; + + for ( var i=0, iLen=a.length-1 ; i