37 lines
1.4 KiB
JavaScript
37 lines
1.4 KiB
JavaScript
import { confirmAction } from './dialog.js';
|
|
|
|
const scopes = new Map();
|
|
|
|
if (typeof window !== 'undefined') {
|
|
window.addEventListener('beforeunload', event => {
|
|
if (![...scopes.values()].some(scope => scope.dirty)) return;
|
|
event.preventDefault();
|
|
event.returnValue = '';
|
|
});
|
|
}
|
|
|
|
export function createDirtyScope(name, message = 'Есть несохранённые изменения. Покинуть страницу и потерять их?') {
|
|
const scope = { name, message, dirty: false };
|
|
scopes.set(name, scope);
|
|
return {
|
|
mark() { scope.dirty = true; document.dispatchEvent(new CustomEvent('magistr:dirty-change')); },
|
|
clear() { scope.dirty = false; document.dispatchEvent(new CustomEvent('magistr:dirty-change')); },
|
|
isDirty() { return scope.dirty; },
|
|
dispose() { scopes.delete(name); }
|
|
};
|
|
}
|
|
|
|
export async function confirmAbandonDirtyChanges() {
|
|
const dirty = [...scopes.values()].filter(scope => scope.dirty);
|
|
if (!dirty.length) return true;
|
|
const confirmed = await confirmAction({
|
|
title: 'Несохранённые изменения',
|
|
message: dirty[0].message,
|
|
confirmLabel: 'Покинуть без сохранения',
|
|
cancelLabel: 'Остаться',
|
|
danger: true
|
|
});
|
|
if (confirmed) dirty.forEach(scope => { scope.dirty = false; });
|
|
return confirmed;
|
|
}
|