Compare commits
No commits in common. "a03d7031b10936a608ff28bcec993772ae1892f2" and "501edda217c0bc8a0c56b726018a6bba5dae8694" have entirely different histories.
a03d7031b1
...
501edda217
@ -86,7 +86,6 @@
|
|||||||
<script src="/js/utils/ui-helpers.js"></script>
|
<script src="/js/utils/ui-helpers.js"></script>
|
||||||
<script src="/js/utils/router.js"></script>
|
<script src="/js/utils/router.js"></script>
|
||||||
<script src="/js/utils/data-loader.js"></script>
|
<script src="/js/utils/data-loader.js"></script>
|
||||||
<script src="/js/utils/dismissible.js"></script>
|
|
||||||
<script src="/js/components/eo-modal.js"></script>
|
<script src="/js/components/eo-modal.js"></script>
|
||||||
<script src="/js/components/dashboard.js"></script>
|
<script src="/js/components/dashboard.js"></script>
|
||||||
<script src="/js/system/system-loader.js"></script>
|
<script src="/js/system/system-loader.js"></script>
|
||||||
|
|||||||
@ -94,7 +94,6 @@ class BackupPage {
|
|||||||
this.applyActiveTabUi(this.currentTab);
|
this.applyActiveTabUi(this.currentTab);
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
await this.refreshAll();
|
await this.refreshAll();
|
||||||
await window.Dismissible?.load();
|
|
||||||
this.render();
|
this.render();
|
||||||
this.updatePageHeader();
|
this.updatePageHeader();
|
||||||
this.updatePrimaryAction();
|
this.updatePrimaryAction();
|
||||||
@ -214,7 +213,7 @@ class BackupPage {
|
|||||||
|
|
||||||
const dismissWarn = e.target.closest('[data-action="dismiss-config-warning"]');
|
const dismissWarn = e.target.closest('[data-action="dismiss-config-warning"]');
|
||||||
if (dismissWarn) {
|
if (dismissWarn) {
|
||||||
window.Dismissible?.dismiss('backup-config-warning');
|
localStorage.setItem('libreportal:backup-config-warning-dismissed', '1');
|
||||||
const banner = dismissWarn.closest('.backup-warning-banner');
|
const banner = dismissWarn.closest('.backup-warning-banner');
|
||||||
const divider = banner?.nextElementSibling;
|
const divider = banner?.nextElementSibling;
|
||||||
if (divider && divider.classList.contains('config-divider')) divider.remove();
|
if (divider && divider.classList.contains('config-divider')) divider.remove();
|
||||||
@ -831,10 +830,10 @@ class BackupPage {
|
|||||||
const body = document.getElementById('backup-configuration-body');
|
const body = document.getElementById('backup-configuration-body');
|
||||||
if (!body) return;
|
if (!body) return;
|
||||||
|
|
||||||
// Dismissed state is persisted server-side via Dismissible
|
// The warning is a dismissible nudge, so its dismissed state lives in
|
||||||
// (data/ui-state.json), so it follows the user across browsers/devices.
|
// localStorage (per-browser) rather than server config. Banner + its
|
||||||
// Banner + its divider are omitted entirely once dismissed.
|
// divider are omitted entirely once dismissed.
|
||||||
const warningDismissed = !!window.Dismissible?.isDismissed('backup-config-warning');
|
const warningDismissed = localStorage.getItem('libreportal:backup-config-warning-dismissed') === '1';
|
||||||
const warningHTML = warningDismissed ? '' : `
|
const warningHTML = warningDismissed ? '' : `
|
||||||
<div class="backup-warning-banner">
|
<div class="backup-warning-banner">
|
||||||
<svg class="backup-warning-banner-icon" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
<svg class="backup-warning-banner-icon" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
// Dismissible — reusable "hide this UI element permanently" store.
|
|
||||||
//
|
|
||||||
// State is persisted server-side in data/ui-state.json via the authenticated
|
|
||||||
// /read-file + /write-file endpoints, so a dismissal follows the user across
|
|
||||||
// browsers and devices. It is a direct file read/write: no task is created
|
|
||||||
// (nothing appears in the task manager) and no system scan runs.
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// await Dismissible.load(); // once, before reading state (e.g. in a page init)
|
|
||||||
// if (!Dismissible.isDismissed('my-id')) { ...render the thing... }
|
|
||||||
// Dismissible.dismiss('my-id'); // on close — persists, fire-and-forget
|
|
||||||
// Dismissible.restore('my-id'); // bring it back
|
|
||||||
window.Dismissible = (() => {
|
|
||||||
const FILE = 'ui-state.json';
|
|
||||||
let dismissed = new Set();
|
|
||||||
let loaded = false;
|
|
||||||
|
|
||||||
async function load() {
|
|
||||||
if (loaded) return;
|
|
||||||
try {
|
|
||||||
const res = await fetch(`/read-file?path=${encodeURIComponent(FILE)}`);
|
|
||||||
if (res.ok) {
|
|
||||||
const data = JSON.parse(await res.text());
|
|
||||||
if (Array.isArray(data?.dismissed)) dismissed = new Set(data.dismissed);
|
|
||||||
}
|
|
||||||
// A 404 just means nothing has been dismissed yet — leave the set empty.
|
|
||||||
} catch (_) {
|
|
||||||
// On any error, fail open: treat nothing as dismissed so notices still show.
|
|
||||||
}
|
|
||||||
loaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDismissed(id) {
|
|
||||||
return dismissed.has(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function dismiss(id) {
|
|
||||||
await load();
|
|
||||||
if (dismissed.has(id)) return;
|
|
||||||
dismissed.add(id);
|
|
||||||
await persist();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function restore(id) {
|
|
||||||
await load();
|
|
||||||
if (!dismissed.has(id)) return;
|
|
||||||
dismissed.delete(id);
|
|
||||||
await persist();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function persist() {
|
|
||||||
try {
|
|
||||||
await fetch('/write-file', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
path: FILE,
|
|
||||||
content: JSON.stringify({ dismissed: [...dismissed] }, null, 2)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('Dismissible: failed to persist state', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { load, isDismissed, dismiss, restore };
|
|
||||||
})();
|
|
||||||
Loading…
x
Reference in New Issue
Block a user