diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js index 8affffb1..55064251 100644 --- a/umap/static/umap/js/modules/global.js +++ b/umap/static/umap/js/modules/global.js @@ -31,7 +31,7 @@ import { DataLayer, LAYER_TYPES } from './data/layer.js' import { DataLayerPermissions, MapPermissions } from './permissions.js' import { Point, LineString, Polygon } from './data/features.js' import { LeafletMarker, LeafletPolyline, LeafletPolygon } from './rendering/ui.js' -import { SAVEMANAGER } from './saving.js' +import * as SAVEMANAGER from './saving.js' // Import modules and export them to the global scope. // For the not yet module-compatible JS out there. @@ -49,7 +49,6 @@ window.U = { DataLayer, DataLayerPermissions, Dialog, - SAVEMANAGER, EditPanel, Facets, Formatter, @@ -72,6 +71,7 @@ window.U = { Request, RequestError, Rules, + SAVEMANAGER, SCHEMA, ServerRequest, Share, diff --git a/umap/static/umap/js/modules/saving.js b/umap/static/umap/js/modules/saving.js index e74f377d..2b8b748a 100644 --- a/umap/static/umap/js/modules/saving.js +++ b/umap/static/umap/js/modules/saving.js @@ -1,53 +1,47 @@ -export class SaveManager { - constructor() { - this._queue = new Set() - } +const _queue = new Set() - get isDirty() { - return Boolean(this._queue.size) - } +export let isDirty = false - async save() { - for (const obj of this._queue) { - const ok = await obj.save() - if (!ok) break - this.delete(obj) - } - } - - add(obj) { - this._queue.add(obj) - this.updateDOM() - } - - delete(obj) { - this._queue.delete(obj) - this.updateDOM() - } - - has(obj) { - return this._queue.has(obj) - } - - updateDOM() { - document.body.classList.toggle('umap-is-dirty', this._queue.size) +export async function save() { + for (const obj of _queue) { + const ok = await obj.save() + if (!ok) break + remove(obj) } } -export const SAVEMANAGER = new SaveManager() +export function add(obj) { + _queue.add(obj) + _onUpdate() +} + +export function remove(obj) { + _queue.delete(obj) + _onUpdate() +} + +export function has(obj) { + return _queue.has(obj) +} + +function _onUpdate() { + console.log(_queue) + isDirty = Boolean(_queue.size) + document.body.classList.toggle('umap-is-dirty', isDirty) +} export class ServerStored { set isDirty(status) { if (status) { - SAVEMANAGER.add(this) + add(this) } else { - SAVEMANAGER.delete(this) + remove(this) } this.onDirty(status) } get isDirty() { - return SAVEMANAGER.has(this) + return has(this) } onDirty(status) {} diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 36748023..893de510 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -158,8 +158,12 @@ U.Map = L.Map.extend({ try { Object.defineProperty(this, 'isDirty', { get: () => U.SAVEMANAGER.has(this), - set: function (status) { - U.SAVEMANAGER.add(this) + set: (status) => { + if (status) { + U.SAVEMANAGER.add(this) + } else { + U.SAVEMANAGER.remove(this) + } }, }) } catch (e) { diff --git a/umap/tests/integration/test_save.py b/umap/tests/integration/test_save.py new file mode 100644 index 00000000..b1366bd9 --- /dev/null +++ b/umap/tests/integration/test_save.py @@ -0,0 +1,35 @@ +import re + + +def test_reseting_map_would_remove_from_save_queue( + live_server, openmap, page, datalayer +): + page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit") + page.get_by_role("link", name="Edit map name and caption").click() + requests = [] + + def register_request(request): + if request.url.endswith(".png"): + return + requests.append((request.method, request.url)) + + page.on("request", register_request) + page.locator('input[name="name"]').click() + page.locator('input[name="name"]').fill("new name") + page.get_by_role("button", name="Cancel edits").click() + page.get_by_role("button", name="OK").click() + page.wait_for_timeout(500) + page.get_by_role("button", name="Edit").click() + page.get_by_role("link", name="Manage layers").click() + page.get_by_role("button", name="Edit", exact=True).click() + page.locator('input[name="name"]').click() + page.locator('input[name="name"]').fill("new datalayer name") + with page.expect_response(re.compile(".*/datalayer/update/.*")): + page.get_by_role("button", name="Save").click() + assert len(requests) == 1 + assert requests == [ + ( + "POST", + f"{live_server.url}/en/map/{openmap.pk}/datalayer/update/{datalayer.pk}/", + ), + ]