0
0
Fork 0
mirror of https://github.com/dani-garcia/vaultwarden synced 2024-12-14 09:33:44 +01:00

Merge branch 'BlackDex-admin-interface' into main

This commit is contained in:
Daniel García 2021-09-16 21:36:31 +02:00
commit 4e8828e41a
No known key found for this signature in database
GPG key ID: FC8A7D14C3CD543A
6 changed files with 759 additions and 1152 deletions

View file

@ -7,6 +7,7 @@ repos:
- id: check-json - id: check-json
- id: check-toml - id: check-toml
- id: end-of-file-fixer - id: end-of-file-fixer
exclude: "(.*js$|.*css$)"
- id: check-case-conflict - id: check-case-conflict
- id: check-merge-conflict - id: check-merge-conflict
- id: detect-private-key - id: detect-private-key

View file

@ -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 * Copyright 2015-2021 © dnp_theme
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) * 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 modalBackdropClass = 'modal-backdrop';
const offcanvasBackdropClass = 'offcanvas-backdrop';
const modalActiveSelector = `.modal.${showClass}`; const modalActiveSelector = `.modal.${showClass}`;
const offcanvasActiveSelector = `.offcanvas.${showClass}`; const offcanvasActiveSelector = `.offcanvas.${showClass}`;
const overlay = document.createElement('div'); const overlay = document.createElement('div');
overlay.setAttribute('class', `${modalBackdropClass}`);
function getCurrentOpen() { function getCurrentOpen() {
return queryElement(`${modalActiveSelector},${offcanvasActiveSelector}`); 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); document.body.appendChild(overlay);
if (hasFade) addClass(overlay, fadeClass); if (hasFade) addClass(overlay, fadeClass);
} }
@ -1499,7 +1506,6 @@
if (!currentOpen) { if (!currentOpen) {
removeClass(overlay, fadeClass); removeClass(overlay, fadeClass);
removeClass(bd, modalOpenClass);
bd.removeChild(overlay); bd.removeChild(overlay);
resetScrollbar(); resetScrollbar();
} }
@ -1518,7 +1524,6 @@
const modalString = 'modal'; const modalString = 'modal';
const modalComponent = 'Modal'; const modalComponent = 'Modal';
const modalSelector = `.${modalString}`; const modalSelector = `.${modalString}`;
// const modalActiveSelector = `.${modalString}.${showClass}`;
const modalToggleSelector = `[${dataBsToggle}="${modalString}"]`; const modalToggleSelector = `[${dataBsToggle}="${modalString}"]`;
const modalDismissSelector = `[${dataBsDismiss}="${modalString}"]`; const modalDismissSelector = `[${dataBsDismiss}="${modalString}"]`;
const modalStaticClass = `${modalString}-static`; const modalStaticClass = `${modalString}-static`;
@ -1567,8 +1572,11 @@
} }
function afterModalHide(self) { function afterModalHide(self) {
const { triggers } = self; const { triggers, options } = self;
removeOverlay(); if (!getCurrentOpen()) {
if (options.backdrop) removeOverlay();
resetScrollbar();
}
self.element.style.paddingRight = ''; self.element.style.paddingRight = '';
self.isAnimating = false; self.isAnimating = false;
@ -1594,9 +1602,8 @@
element.style.display = 'block'; element.style.display = 'block';
setModalScrollbar(self); setModalScrollbar(self);
if (!queryElement(modalActiveSelector)) { if (!getCurrentOpen()) {
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
addClass(document.body, modalOpenClass);
} }
addClass(element, showClass); addClass(element, showClass);
@ -1609,16 +1616,15 @@
function beforeModalHide(self, force) { function beforeModalHide(self, force) {
const { const {
element, relatedTarget, hasFade, element, options, relatedTarget, hasFade,
} = self; } = self;
const currentOpen = getCurrentOpen();
element.style.display = ''; element.style.display = '';
// force can also be the transitionEvent object, we wanna make sure it's not // force can also be the transitionEvent object, we wanna make sure it's not
// call is not forced and overlay is visible // call is not forced and overlay is visible
if (!force && hasFade && hasClass(overlay, showClass) if (options.backdrop && !force && hasFade && hasClass(overlay, showClass)
&& !currentOpen) { // AND no modal is visible && !getCurrentOpen()) { // AND no modal is visible
hideOverlay(); hideOverlay();
emulateTransitionEnd(overlay, () => afterModalHide(self)); emulateTransitionEnd(overlay, () => afterModalHide(self));
} else { } else {
@ -1666,7 +1672,8 @@
if (self.isAnimating) return; if (self.isAnimating) return;
const { isStatic, modalDialog } = self; const { options, isStatic, modalDialog } = self;
const { backdrop } = options;
const { target } = e; const { target } = e;
const selectedText = document.getSelection().toString().length; const selectedText = document.getSelection().toString().length;
const targetInsideDialog = modalDialog.contains(target); const targetInsideDialog = modalDialog.contains(target);
@ -1676,7 +1683,7 @@
addClass(element, modalStaticClass); addClass(element, modalStaticClass);
self.isAnimating = true; self.isAnimating = true;
emulateTransitionEnd(modalDialog, () => staticTransitionEnd(self)); emulateTransitionEnd(modalDialog, () => staticTransitionEnd(self));
} else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog)) { } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog && backdrop)) {
self.relatedTarget = dismiss || null; self.relatedTarget = dismiss || null;
self.hide(); self.hide();
e.preventDefault(); e.preventDefault();
@ -1734,8 +1741,9 @@
show() { show() {
const self = this; const self = this;
const { const {
element, isAnimating, hasFade, relatedTarget, element, options, isAnimating, hasFade, relatedTarget,
} = self; } = self;
const { backdrop } = options;
let overlayDelay = 0; let overlayDelay = 0;
if (hasClass(element, showClass) && !isAnimating) return; if (hasClass(element, showClass) && !isAnimating) return;
@ -1744,8 +1752,6 @@
element.dispatchEvent(showModalEvent); element.dispatchEvent(showModalEvent);
if (showModalEvent.defaultPrevented) return; if (showModalEvent.defaultPrevented) return;
self.isAnimating = true;
// we elegantly hide any opened modal/offcanvas // we elegantly hide any opened modal/offcanvas
const currentOpen = getCurrentOpen(); const currentOpen = getCurrentOpen();
if (currentOpen && currentOpen !== element) { if (currentOpen && currentOpen !== element) {
@ -1755,18 +1761,24 @@
that.hide(); that.hide();
} }
if (!queryElement(`.${modalBackdropClass}`)) { self.isAnimating = true;
appendOverlay(hasFade);
}
overlayDelay = getElementTransitionDuration(overlay);
if (!hasClass(overlay, showClass)) { if (backdrop) {
showOverlay(); 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); setTimeout(() => beforeModalShow(self), overlayDelay);
} else beforeModalShow(self); } else {
beforeModalShow(self);
if (currentOpen && hasClass(overlay, showClass)) {
hideOverlay();
}
}
} }
hide(force) { hide(force) {
@ -1863,7 +1875,6 @@
const { element, options } = self; const { element, options } = self;
if (!options.scroll) { if (!options.scroll) {
addClass(document.body, modalOpenClass);
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
setOffCanvasScrollbar(self); setOffCanvasScrollbar(self);
} }
@ -1909,15 +1920,15 @@
const self = element[offcanvasComponent]; const self = element[offcanvasComponent];
if (!self) return; if (!self) return;
const { options, open, triggers } = self; const { options, triggers } = self;
const { target } = e; const { target } = e;
const trigger = target.closest(offcanvasToggleSelector); const trigger = target.closest(offcanvasToggleSelector);
if (trigger && trigger.tagName === 'A') e.preventDefault(); 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)))) && (!trigger || (trigger && !triggers.includes(trigger))))
|| offCanvasDismiss.contains(target))) { || offCanvasDismiss.contains(target)) {
self.relatedTarget = target === offCanvasDismiss ? offCanvasDismiss : null; self.relatedTarget = target === offCanvasDismiss ? offCanvasDismiss : null;
self.hide(); self.hide();
} }
@ -1965,7 +1976,6 @@
element.removeAttribute(ariaModal); element.removeAttribute(ariaModal);
element.removeAttribute('role'); element.removeAttribute('role');
element.style.visibility = ''; element.style.visibility = '';
self.open = false;
self.isAnimating = false; self.isAnimating = false;
if (triggers.length) { if (triggers.length) {
@ -1979,7 +1989,6 @@
if (options.backdrop) removeOverlay(); if (options.backdrop) removeOverlay();
if (!options.scroll) { if (!options.scroll) {
resetScrollbar(); resetScrollbar();
removeClass(document.body, modalOpenClass);
} }
} }
@ -2005,7 +2014,6 @@
.filter((btn) => getTargetElement(btn) === element); .filter((btn) => getTargetElement(btn) === element);
// additional instance property // additional instance property
self.open = false;
self.isAnimating = false; self.isAnimating = false;
self.scrollbarWidth = measureScrollbar(); self.scrollbarWidth = measureScrollbar();
@ -2017,7 +2025,8 @@
// ======================== // ========================
toggle() { toggle() {
const self = this; const self = this;
return self.open ? self.hide() : self.show(); if (hasClass(self.element, showClass)) self.hide();
else self.show();
} }
show() { show() {
@ -2027,7 +2036,7 @@
} = self; } = self;
let overlayDelay = 0; let overlayDelay = 0;
if (self.open || isAnimating) return; if (hasClass(element, showClass) || isAnimating) return;
showOffcanvasEvent.relatedTarget = relatedTarget || null; showOffcanvasEvent.relatedTarget = relatedTarget || null;
element.dispatchEvent(showOffcanvasEvent); element.dispatchEvent(showOffcanvasEvent);
@ -2043,12 +2052,13 @@
that.hide(); that.hide();
} }
self.open = true;
self.isAnimating = true; self.isAnimating = true;
if (options.backdrop) { if (options.backdrop) {
if (!queryElement(`.${modalBackdropClass}`)) { if (!currentOpen) {
appendOverlay(1); appendOverlay(1);
} else {
toggleOverlayType();
} }
overlayDelay = getElementTransitionDuration(overlay); overlayDelay = getElementTransitionDuration(overlay);
@ -2056,14 +2066,19 @@
if (!hasClass(overlay, showClass)) showOverlay(); if (!hasClass(overlay, showClass)) showOverlay();
setTimeout(() => beforeOffcanvasShow(self), overlayDelay); setTimeout(() => beforeOffcanvasShow(self), overlayDelay);
} else beforeOffcanvasShow(self); } else {
beforeOffcanvasShow(self);
if (currentOpen && hasClass(overlay, showClass)) {
hideOverlay();
}
}
} }
hide(force) { hide(force) {
const self = this; const self = this;
const { element, isAnimating, relatedTarget } = self; const { element, isAnimating, relatedTarget } = self;
if (!self.open || isAnimating) return; if (!hasClass(element, showClass) || isAnimating) return;
hideOffcanvasEvent.relatedTarget = relatedTarget || null; hideOffcanvasEvent.relatedTarget = relatedTarget || null;
element.dispatchEvent(hideOffcanvasEvent); element.dispatchEvent(hideOffcanvasEvent);
@ -3483,7 +3498,7 @@
constructor: Tooltip, constructor: Tooltip,
}; };
var version = "4.0.4"; var version = "4.0.6";
// import { alertInit } from '../components/alert-native.js'; // import { alertInit } from '../components/alert-native.js';
// import { buttonInit } from '../components/button-native.js'; // import { buttonInit } from '../components/button-native.js';

File diff suppressed because it is too large Load diff

View file

@ -4,13 +4,94 @@
* *
* To rebuild or modify this file with the latest versions of the included * To rebuild or modify this file with the latest versions of the included
* software please visit: * software please visit:
* https://datatables.net/download/#bs5/dt-1.10.25 * https://datatables.net/download/#bs5/dt-1.11.2
* *
* Included libraries: * Included libraries:
* DataTables 1.10.25 * DataTables 1.11.2
*/ */
@charset "UTF-8"; @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 /*! Bootstrap 5 integration for DataTables
* *
* ©2020 SpryMedia Ltd, all rights reserved. * ©2020 SpryMedia Ltd, all rights reserved.
@ -143,21 +224,21 @@ div.dataTables_scrollHead table.dataTable {
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
div.dataTables_scrollBody table { div.dataTables_scrollBody > table {
border-top: none; border-top: none;
margin-top: 0 !important; margin-top: 0 !important;
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
div.dataTables_scrollBody table thead .sorting:before, div.dataTables_scrollBody > table > thead .sorting:before,
div.dataTables_scrollBody table thead .sorting_asc:before, div.dataTables_scrollBody > table > thead .sorting_asc:before,
div.dataTables_scrollBody table thead .sorting_desc:before, div.dataTables_scrollBody > table > thead .sorting_desc:before,
div.dataTables_scrollBody table thead .sorting:after, div.dataTables_scrollBody > table > thead .sorting:after,
div.dataTables_scrollBody table thead .sorting_asc:after, div.dataTables_scrollBody > table > thead .sorting_asc:after,
div.dataTables_scrollBody table thead .sorting_desc:after { div.dataTables_scrollBody > table > thead .sorting_desc:after {
display: none; display: none;
} }
div.dataTables_scrollBody table tbody tr:first-child th, 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 td {
border-top: none; border-top: none;
} }
@ -235,4 +316,11 @@ div.table-responsive > div.dataTables_wrapper > div.row > div[class^=col-]:last-
padding-right: 0; 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);
}

File diff suppressed because it is too large Load diff

View file

@ -12,9 +12,7 @@
{{#each config}} {{#each config}}
{{#if groupdoc}} {{#if groupdoc}}
<div class="card bg-light mb-3"> <div class="card bg-light mb-3">
<div class="card-header" role="button" data-bs-toggle="collapse" data-bs-target="#g_{{group}}"> <button id="b_{{group}}" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_{{group}}" data-bs-toggle="collapse" data-bs-target="#g_{{group}}">{{groupdoc}}</button>
<button type="button" class="btn btn-link text-decoration-none collapsed" data-bs-toggle="collapse" data-bs-target="#g_{{group}}">{{groupdoc}}</button>
</div>
<div id="g_{{group}}" class="card-body collapse"> <div id="g_{{group}}" class="card-body collapse">
{{#each elements}} {{#each elements}}
{{#if editable}} {{#if editable}}
@ -61,10 +59,8 @@
{{/each}} {{/each}}
<div class="card bg-light mb-3"> <div class="card bg-light mb-3">
<div class="card-header" role="button" data-bs-toggle="collapse" data-bs-target="#g_readonly"> <button id="b_readonly" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_readonly"
<button type="button" class="btn btn-link text-decoration-none collapsed" data-bs-toggle="collapse" data-bs-target="#g_readonly">Read-Only Config</button> data-bs-toggle="collapse" data-bs-target="#g_readonly">Read-Only Config</button>
</div>
<div id="g_readonly" class="card-body collapse"> <div id="g_readonly" class="card-body collapse">
<div class="small mb-3"> <div class="small mb-3">
NOTE: These options can't be modified in the editor because they would require the server NOTE: These options can't be modified in the editor because they would require the server
@ -109,9 +105,8 @@
{{#if can_backup}} {{#if can_backup}}
<div class="card bg-light mb-3"> <div class="card bg-light mb-3">
<div class="card-header" role="button" data-bs-toggle="collapse" data-bs-target="#g_database"> <button id="b_database" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_database"
<button type="button" class="btn btn-link text-decoration-none collapsed" data-bs-toggle="collapse" data-bs-target="#g_database">Backup Database</button> data-bs-toggle="collapse" data-bs-target="#g_database">Backup Database</button>
</div>
<div id="g_database" class="card-body collapse"> <div id="g_database" class="card-body collapse">
<div class="small mb-3"> <div class="small mb-3">
WARNING: This function only creates a backup copy of the SQLite database. WARNING: This function only creates a backup copy of the SQLite database.