From 628e74ecb306a523cfb269b4e9ce794ba557c27f Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 1 Jul 2024 18:55:52 +0200 Subject: [PATCH] wip: add a way to remove data from a layer from a condition --- umap/static/umap/js/modules/global.js | 3 +- umap/static/umap/js/modules/rules.js | 57 +++++++++++++++---------- umap/static/umap/js/umap.tableeditor.js | 36 +++++++++++++++- 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js index c4eebe03..fe2ef751 100644 --- a/umap/static/umap/js/modules/global.js +++ b/umap/static/umap/js/modules/global.js @@ -11,7 +11,7 @@ import Help from './help.js' import Importer from './importer.js' import Orderable from './orderable.js' import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './request.js' -import Rules from './rules.js' +import { Rule, Rules } from './rules.js' import { SCHEMA } from './schema.js' import { SyncEngine } from './sync/engine.js' import Dialog from './ui/dialog.js' @@ -44,6 +44,7 @@ window.U = { Panel, Request, RequestError, + Rule, Rules, SCHEMA, ServerRequest, diff --git a/umap/static/umap/js/modules/rules.js b/umap/static/umap/js/modules/rules.js index 518339c1..ed541b03 100644 --- a/umap/static/umap/js/modules/rules.js +++ b/umap/static/umap/js/modules/rules.js @@ -2,7 +2,7 @@ import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm. import { translate } from './i18n.js' import * as Utils from './utils.js' -class Rule { +export class Rule { get condition() { return this._condition } @@ -12,20 +12,10 @@ class Rule { this.parse() } - get isDirty() { - return this._isDirty - } - - set isDirty(status) { - this._isDirty = status - if (status) this.map.isDirty = status - } - - constructor(map, condition = '', options = {}) { + constructor(condition = '') { // TODO make this public properties when browser coverage is ok // cf https://caniuse.com/?search=public%20class%20field this._condition = null - this._isDirty = false this.OPERATORS = [ ['>', this.gt], ['<', this.lt], @@ -34,16 +24,9 @@ class Rule { ['!=', this.not_equal], ['=', this.equal], ] - this.map = map - this.active = true - this.options = options this.condition = condition } - render(fields) { - this.map.render(fields) - } - equal(other) { return this.expected === other } @@ -85,9 +68,37 @@ class Rule { } match(props) { - if (!this.operator || !this.active) return false + if (!this.operator) return false return this.operator(this.cast(props[this.key])) } +} + +class ConditionalRule extends Rule { + get isDirty() { + return this._isDirty + } + + set isDirty(status) { + this._isDirty = status + if (status) this.map.isDirty = status + } + + match(props) { + if (!this.active) return false + return super.match(props) + } + + constructor(map, condition = '', options = {}) { + super() + this._isDirty = false + this.map = map + this.active = true + this.options = options + } + + render(fields) { + this.map.render(fields) + } getMap() { return this.map @@ -170,7 +181,7 @@ class Rule { } } -export default class Rules { +export class Rules { constructor(map) { this.map = map this.rules = [] @@ -181,7 +192,7 @@ export default class Rules { if (!this.map.options.rules?.length) return for (const { condition, options } of this.map.options.rules) { if (!condition) continue - this.rules.push(new Rule(this.map, condition, options)) + this.rules.push(new ConditionalRule(this.map, condition, options)) } } @@ -218,7 +229,7 @@ export default class Rules { } addRule() { - const rule = new Rule(this.map) + const rule = new ConditionalRule(this.map) rule.isDirty = true this.rules.push(rule) rule.edit(map) diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index 20e1dbcc..509d246d 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -101,6 +101,34 @@ U.TableEditor = L.Class.extend({ }) }, + refine: function () { + const promise = new U.Prompt().open({ + className: 'dark', + title: L._('Deleting rows matching condition'), + }) + promise.then((raw) => { + if (!raw) return + const rule = new U.Rule(raw) + const matched = [] + this.datalayer.eachLayer((feature) => { + if (rule.match(feature.properties)) { + matched.push(feature) + } + }) + if (!matched) { + U.Alert.error(L._('Nothing matched')) + return + } + this.datalayer.hide() + for (const feature of matched) { + feature.del() + } + this.datalayer.isDirty = true + this.datalayer.show() + this.edit() + }) + }, + edit: function () { const id = 'tableeditor:edit' this.compileProperties() @@ -115,10 +143,16 @@ U.TableEditor = L.Class.extend({ const iconElement = L.DomUtil.createIcon(addButton, 'icon-add') addButton.insertBefore(iconElement, addButton.firstChild) L.DomEvent.on(addButton, 'click', this.addProperty, this) + const refineButton = L.DomUtil.createButton('flat', undefined, L._('Delete rows')) + refineButton.insertBefore( + L.DomUtil.createIcon(refineButton, 'icon-add'), + refineButton.firstChild + ) + L.DomEvent.on(refineButton, 'click', this.refine, this) this.datalayer.map.fullPanel.open({ content: this.table, className: 'umap-table-editor', - actions: [addButton], + actions: [addButton, refineButton], }) }, })