Skip to content

Commit 7fd9b95

Browse files
committed
wip: add fields management on the Umap object
1 parent 47b6c0a commit 7fd9b95

File tree

8 files changed

+524
-161
lines changed

8 files changed

+524
-161
lines changed

umap/static/umap/js/modules/data/features.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ class Feature {
256256
`<button type="button"><i class="icon icon-16 icon-add"></i>${translate('Add a new field')}</button>`
257257
)
258258
button.addEventListener('click', () => {
259-
this.datalayer.addField().then(() => this.edit({ force: true }))
259+
this.datalayer.fields.editField().then(() => this.edit({ force: true }))
260260
})
261261
form.appendChild(button)
262262
this.appendEditFieldsets(container)

umap/static/umap/js/modules/data/layer.js

Lines changed: 14 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import TableEditor from '../tableeditor.js'
2121
import * as Utils from '../utils.js'
2222
import { LineString, Point, Polygon } from './features.js'
2323
import Rules from '../rules.js'
24-
import Orderable from '../orderable.js'
2524
import { FeatureManager, FieldManager } from '../managers.js'
2625

2726
export const LAYER_TYPES = [
@@ -96,7 +95,7 @@ export class DataLayer {
9695
{ key: 'description', type: 'Text' },
9796
]
9897
}
99-
this.fields = new FieldManager(this)
98+
this.fields = new FieldManager(this, this._umap.dialog)
10099

101100
// Only layers that are displayed on load must be hidden/shown
102101
// Automatically, others will be shown manually, and thus will
@@ -464,107 +463,34 @@ export class DataLayer {
464463
if (this._umap.fields.has(key)) continue
465464
// retrocompat: guess type from facets if any
466465
// otherwise it will fallback to default in facets
467-
const type = this._umap.facets.get(key)?.dataType
466+
let type = this._umap.facets.get(key)?.dataType
467+
if (!type && key === 'description') type = 'Text'
468468
this.fields.add({ key, type })
469469
}
470470
}
471471
this.fields.push()
472472
}
473473

474-
async confirmDeleteField(name) {
475-
return this._umap.dialog
476-
.confirm(
477-
translate('Are you sure you want to delete this field on all the features?')
478-
)
479-
.then(() => {
480-
this.deleteField(name)
481-
})
482-
}
483-
484-
async editField(name) {
485-
const FIELD_TYPES = ['String', 'Text', 'Number', 'Date', 'Datetime', 'Enum']
486-
const field = this.fields.get(name)
487-
const metadatas = [
488-
['key', { handler: 'BlurInput' }],
489-
[
490-
'type',
491-
{ handler: 'Select', selectOptions: FIELD_TYPES, label: translate('Type') },
492-
],
493-
]
494-
const form = new Form(field, metadatas, { umap: this.umap })
495-
496-
return this._umap.dialog.open({ template: form.build() }).then(() => {
497-
if (!this.validateName(field.key)) {
498-
this.fields.pull()
499-
return
500-
}
501-
this.push()
502-
if (name !== field.key) {
503-
this.renameField(name, field.key)
504-
}
505-
})
506-
}
507-
508-
async askForRenameField(property) {
509-
return this._umap.dialog
510-
.prompt(translate('Please enter the new name of this field'))
511-
.then(({ prompt }) => {
512-
if (!prompt || !this.validateName(prompt)) return
513-
this.renameField(property, prompt)
514-
})
515-
}
516-
517474
renameField(oldName, newName) {
518-
const field = this.fields.get(oldName)
519-
if (field) {
520-
this.sync.startBatch()
521-
const oldFields = Utils.CopyJSON(this.properties.fields)
522-
field.key = newName
523-
this.fields.push()
524-
this.sync.update('properties.fields', this.properties.fields, oldFields)
525-
this.features.forEach((feature) => {
526-
feature.renameField(oldName, newName)
527-
})
528-
this.sync.commitBatch()
529-
}
475+
this.renameFeaturesField(oldName, newName)
530476
}
531477

532-
deleteField(name) {
533-
this.sync.startBatch()
534-
const oldFields = Utils.CopyJSON(this.properties.fields)
535-
this.fields.delete(name)
536-
this.sync.update('properties.fields', this.properties.fields, oldFields)
478+
renameFeaturesField(oldName, newName) {
537479
this.features.forEach((feature) => {
538-
feature.deleteField(name)
480+
feature.renameField(oldName, newName)
539481
})
540-
this.sync.commitBatch()
541482
}
542483

543-
addField() {
544-
let resolve = undefined
545-
const promise = new Promise((r) => {
546-
resolve = r
547-
})
548-
this._umap.dialog
549-
.prompt(translate('Please enter the name of the field'))
550-
.then(({ prompt }) => {
551-
if (!prompt || !this.validateName(prompt)) return
552-
this.fields.add({ key: prompt })
553-
resolve()
554-
})
555-
return promise
484+
deleteField(name) {
485+
this.deleteFeaturesField(name)
556486
}
557487

558-
validateName(name) {
559-
if (name.includes('.')) {
560-
Alert.error(translate('Name “{name}” should not contain a dot.', { name }))
561-
return false
562-
}
563-
if (this.fields.has(name)) {
564-
Alert.error(translate('This name already exists: “{name}”', { name }))
565-
return false
488+
deleteFeaturesField(name) {
489+
if (!this._umap.fields.has(name) && !this.fields.has(name)) {
490+
this.features.forEach((feature) => {
491+
feature.deleteField(name)
492+
})
566493
}
567-
return true
568494
}
569495

570496
sortedValues(property) {
@@ -927,64 +853,6 @@ export class DataLayer {
927853
fieldset.appendChild(builder.build())
928854
}
929855

930-
_editFields(container) {
931-
const template = `
932-
<details id="fields">
933-
<summary>${translate('Manage Fields')}</summary>
934-
<fieldset>
935-
<ul data-ref=ul></ul>
936-
<button type="button" data-ref=add><i class="icon icon-16 icon-add"></i>${translate('Add a new field')}</button>
937-
</fieldset>
938-
</details>
939-
`
940-
const [fieldset, { ul, add }] = Utils.loadTemplateWithRefs(template)
941-
add.addEventListener('click', () => {
942-
this.addField().then(() => {
943-
this.edit().then((panel) => {
944-
panel.scrollTo('details#fields')
945-
})
946-
})
947-
})
948-
container.appendChild(fieldset)
949-
for (const field of this.fields.all()) {
950-
const [row, { edit, del }] = Utils.loadTemplateWithRefs(
951-
`<li class="orderable" data-key="${field.key}">
952-
<button class="icon icon-16 icon-edit" title="${translate('Edit this field')}" data-ref=edit></button>
953-
<button class="icon icon-16 icon-delete" title="${translate('Delete this field')}" data-ref=del></button>
954-
<i class="icon icon-16 icon-drag" title="${translate('Drag to reorder')}"></i>
955-
${field.key}
956-
</li>`
957-
)
958-
ul.appendChild(row)
959-
edit.addEventListener('click', () => {
960-
this.editField(field.key).then(() => {
961-
this.edit().then((panel) => {
962-
panel.scrollTo('details#fields')
963-
})
964-
})
965-
})
966-
del.addEventListener('click', () => {
967-
this.confirmDeleteField(field.key).then(() => {
968-
this.edit().then((panel) => {
969-
panel.scrollTo('details#fields')
970-
})
971-
})
972-
})
973-
}
974-
const onReorder = (src, dst, initialIndex, finalIndex) => {
975-
const orderedKeys = Array.from(ul.querySelectorAll('li')).map(
976-
(el) => el.dataset.key
977-
)
978-
const oldFields = Utils.CopyJSON(this.properties.fields)
979-
this.properties.fields.sort(
980-
(fieldA, fieldB) =>
981-
orderedKeys.indexOf(fieldA.key) > orderedKeys.indexOf(fieldB.key)
982-
)
983-
this.sync.update('properties.fields', this.properties.fields, oldFields)
984-
}
985-
const orderable = new Orderable(ul, onReorder)
986-
}
987-
988856
_editRemoteDataProperties(container) {
989857
// XXX I'm not sure **why** this is needed (as it's set during `this.initialize`)
990858
// but apparently it's needed.
@@ -1096,7 +964,7 @@ export class DataLayer {
1096964
this._editTextPathProperties(container)
1097965
this._editRemoteDataProperties(container)
1098966
if (!this.isRemoteLayer()) {
1099-
this._editFields(container)
967+
this.fields.edit(container)
1100968
}
1101969
this.rules.edit(container)
1102970

0 commit comments

Comments
 (0)