wip: add a way to remove data from a layer from a condition

This commit is contained in:
Yohan Boniface 2024-07-01 18:55:52 +02:00
parent 186025e0f0
commit 55dbe7b9a5
3 changed files with 71 additions and 25 deletions

View file

@ -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, Prompt } from './ui/dialog.js'
@ -45,6 +45,7 @@ window.U = {
Prompt,
Request,
RequestError,
Rule,
Rules,
SCHEMA,
ServerRequest,

View file

@ -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)

View file

@ -102,6 +102,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()
@ -116,10 +144,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],
})
},
})