From 4c222fde0a39db525067411e763d7a70908b4a6a Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Fri, 9 Dec 2022 19:01:17 +0100 Subject: [PATCH] make sure editing multi selection doesn't corrupt tags because the common tag vs. left/right tag situation can be different for different entities in the multiselection, the approach to merge/split/update the tags needs to be made on a per entity basis this introduces a new way to specify tag changes: a callback function which is called for each to be modified entity --- modules/ui/entity_editor.js | 21 +++++++----- modules/ui/fields/directional_combo.js | 46 ++++++++++---------------- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/modules/ui/entity_editor.js b/modules/ui/entity_editor.js index 435d2b37d..ba2956ab3 100644 --- a/modules/ui/entity_editor.js +++ b/modules/ui/entity_editor.js @@ -163,14 +163,19 @@ export function uiEntityEditor(context) { var tags = Object.assign({}, entity.tags); // shallow copy - for (var k in changed) { - if (!k) continue; - var v = changed[k]; - if (typeof v === 'object') { - // a "key only" tag change - tags[k] = tags[v.oldKey]; - } else if (v !== undefined || tags.hasOwnProperty(k)) { - tags[k] = v; + if (typeof changed === 'function') { + // a complex callback tag change + tags = changed(tags); + } else { + for (var k in changed) { + if (!k) continue; + var v = changed[k]; + if (typeof v === 'object') { + // a "key only" tag change + tags[k] = tags[v.oldKey]; + } else if (v !== undefined || tags.hasOwnProperty(k)) { + tags[k] = v; + } } } diff --git a/modules/ui/fields/directional_combo.js b/modules/ui/fields/directional_combo.js index 6ecf26853..c64d432d3 100644 --- a/modules/ui/fields/directional_combo.js +++ b/modules/ui/fields/directional_combo.js @@ -79,35 +79,23 @@ export function uiFieldDirectionalCombo(field, context) { function change(key, newValue) { const commonKey = field.keys[0]; - - // don't override multiple values with blank string - if (!newValue && (Array.isArray(_tags[commonKey]) || Array.isArray(_tags[key]))) return; - - if (newValue === 'none' || newValue === '') { newValue = undefined; } - const otherKey = key === field.keys[1] ? field.keys[2] : field.keys[1]; - let otherValue = typeof _tags[commonKey] === 'string' ? _tags[commonKey] : _tags[otherKey]; - if (otherValue && Array.isArray(otherValue)) { - // we must always have an explicit value for comparison - otherValue = otherValue[0]; - } - if (otherValue === 'none' || otherValue === '') { otherValue = undefined; } - var tag = {}; - - // If the left and right tags match, use the common tag to tag both sides the same way - if (newValue === otherValue) { - tag[commonKey] = newValue; - tag[key] = undefined; - tag[otherKey] = undefined; - } else { - // Always set both left and right as changing one can affect the other - tag[commonKey] = undefined; - tag[key] = newValue; - tag[otherKey] = otherValue; - } - - dispatch.call('change', this, tag); + dispatch.call('change', this, tags => { + const otherValue = tags[otherKey] || tags[commonKey]; + if (newValue === otherValue) { + // both tags match, use the common tag to tag both sides the same way + tags[commonKey] = newValue; + delete tags[key]; + delete tags[otherKey]; + } else { + // Always set both left and right as changing one can affect the other + tags[key] = newValue; + delete tags[commonKey]; + tags[otherKey] = otherValue; + } + return tags; + }); } @@ -117,8 +105,8 @@ export function uiFieldDirectionalCombo(field, context) { const commonKey = field.keys[0]; for (let key in _combos) { const uniqueValues = [... new Set([] - .concat(tags[commonKey]) - .concat(tags[key]) + .concat(_tags[commonKey]) + .concat(_tags[key]) .filter(Boolean))]; _combos[key].tags({ [key]: uniqueValues.length > 1 ? uniqueValues : uniqueValues[0] }); }