Skip to content

Commit 9d464e0

Browse files
committed
refactor: simplify edit count handling and improve LNodeType update logic
1 parent d57db16 commit 9d464e0

1 file changed

Lines changed: 97 additions & 111 deletions

File tree

scl-template-update.ts

Lines changed: 97 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,6 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
127127
@state()
128128
lNodeTypeDescription = '';
129129

130-
private ignoreNextEditCount = false;
131-
132130
updated(changedProperties: Map<string, unknown>) {
133131
super.updated?.(changedProperties);
134132
if (changedProperties.has('doc')) {
@@ -137,35 +135,22 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
137135
}
138136

139137
if (changedProperties.has('editCount') && this.editCount >= 0) {
140-
const shouldRebuildTree = !this.ignoreNextEditCount;
141-
142-
if (this.ignoreNextEditCount) {
143-
this.ignoreNextEditCount = false;
144-
}
145-
146138
this.lNodeTypes = getLNodeTypes(this.doc);
147-
this.refreshSelectedLNodeType(shouldRebuildTree);
139+
this.refreshSelectedLNodeType();
148140
}
149141
}
150142

151-
private refreshSelectedLNodeType(rebuildTree: boolean = true): void {
143+
private refreshSelectedLNodeType(): void {
152144
if (!this.selectedLNodeType) return;
153145

154146
const selectedId = this.selectedLNodeType.getAttribute('id');
155147
const updatedLNodeType = getSelectedLNodeType(this.doc!, selectedId!);
156148

157-
if (!updatedLNodeType) {
158-
// Selected LNodeType no longer exists (was deleted), reset UI
159-
this.resetUI(true);
160-
return;
161-
}
149+
if (!updatedLNodeType) return;
162150

163-
// Update the reference and description to reflect current document state
164151
this.selectedLNodeType = updatedLNodeType;
165152
this.lNodeTypeDescription = updatedLNodeType.getAttribute('desc') ?? '';
166153

167-
if (!rebuildTree) return;
168-
169154
// Rebuild the tree to show the updated structure after undo/redo
170155
const selectedLNodeTypeClass = updatedLNodeType.getAttribute('lnClass');
171156
if (selectedLNodeTypeClass) {
@@ -176,6 +161,7 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
176161
);
177162
if (tree) {
178163
this.lNodeTypeSelection = lNodeTypeToSelection(updatedLNodeType);
164+
this.nsdSelection = this.lNodeTypeSelection;
179165
this.treeUI.tree = tree;
180166
this.treeUI.selection = this.lNodeTypeSelection;
181167
this.treeUI.requestUpdate();
@@ -216,6 +202,22 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
216202
this.choiceDialog?.close();
217203
}
218204

205+
// eslint-disable-next-line class-methods-use-this
206+
private applyDescriptionUpdate(
207+
newLNodeType: Element,
208+
desc: string,
209+
currentLNodeType: Element
210+
): void {
211+
const currentDesc = currentLNodeType.getAttribute('desc') ?? '';
212+
if (desc !== currentDesc) {
213+
if (desc) {
214+
newLNodeType.setAttribute('desc', desc);
215+
} else {
216+
newLNodeType.removeAttribute('desc');
217+
}
218+
}
219+
}
220+
219221
private async saveTemplates() {
220222
if (!this.doc || !this.nsdSelection) return;
221223
const updateSetting =
@@ -241,6 +243,7 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
241243
if (this.selectedLNodeType && descChanged) {
242244
this.updateLNodeTypeDescription(desc);
243245
this.lNodeTypes = getLNodeTypes(this.doc);
246+
this.showSuccessFeedback(lnID);
244247
}
245248
return;
246249
}
@@ -252,76 +255,13 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
252255
});
253256

254257
if (updateSetting === UpdateSetting.Update) {
255-
const lNodeTypeInsertIndex = inserts.findIndex(
256-
insert => (insert.node as Element).tagName === 'LNodeType'
258+
const allEdits = this.buildUpdateEdits(
259+
inserts,
260+
currentLNodeType,
261+
lnID,
262+
desc
257263
);
258264

259-
let newLNodeType: Element | undefined;
260-
let allEdits: Edit[];
261-
262-
if (lNodeTypeInsertIndex >= 0) {
263-
// We have a new LNodeType from insertSelectedLNodeType
264-
const originalInsert = inserts[lNodeTypeInsertIndex];
265-
newLNodeType = (originalInsert.node as Element).cloneNode(
266-
true
267-
) as Element;
268-
newLNodeType.setAttribute('id', lnID);
269-
270-
const currentDescription = currentLNodeType.getAttribute('desc') ?? '';
271-
if (desc !== currentDescription) {
272-
if (desc) {
273-
newLNodeType.setAttribute('desc', desc);
274-
} else {
275-
newLNodeType.removeAttribute('desc');
276-
}
277-
}
278-
279-
// Get supporting types (everything except the LNodeType insert)
280-
const supportingTypes = inserts.filter(
281-
(_, index) => index !== lNodeTypeInsertIndex
282-
);
283-
284-
// Remove the old LNodeType
285-
const removeOld = removeDataType(
286-
{ node: currentLNodeType },
287-
{ force: true }
288-
);
289-
290-
// Create new insert with the modified element
291-
const newInsert = {
292-
parent: originalInsert.parent,
293-
node: newLNodeType,
294-
reference: originalInsert.reference,
295-
};
296-
297-
// Combine: supporting types first, then INSERT new, then remove old
298-
// This ensures the reference element exists when we do the insert
299-
allEdits = [...supportingTypes, newInsert, ...removeOld];
300-
} else if (inserts.length === 0) {
301-
// Only removals - clone existing and remove DOs
302-
newLNodeType = removeDOsNotInSelection(
303-
this.selectedLNodeType!,
304-
this.nsdSelection!
305-
);
306-
307-
newLNodeType.setAttribute('id', lnID);
308-
309-
const currentDescription = currentLNodeType.getAttribute('desc') ?? '';
310-
if (desc !== currentDescription) {
311-
if (desc) {
312-
newLNodeType.setAttribute('desc', desc);
313-
} else {
314-
newLNodeType.removeAttribute('desc');
315-
}
316-
}
317-
318-
const updateEdits = updateLNodeType(newLNodeType, this.doc);
319-
allEdits = updateEdits;
320-
} else {
321-
// Only supporting types, no LNodeType changes
322-
allEdits = inserts;
323-
}
324-
325265
if (allEdits.length > 0) {
326266
this.dispatchEvent(
327267
newEditEvent(allEdits, {
@@ -330,25 +270,16 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
330270
);
331271
}
332272

333-
// Update the reference to point to the updated element in the document
334-
this.selectedLNodeType = getSelectedLNodeType(this.doc, lnID);
335-
336-
// Update nsdSelection to reflect the actual current state after the edit
337-
if (this.selectedLNodeType) {
338-
this.nsdSelection = lNodeTypeToSelection(this.selectedLNodeType);
339-
}
340-
341-
this.fabLabel = `${lnID} updated!`;
273+
this.showSuccessFeedback(lnID, 'update');
342274
} else {
343-
this.ignoreNextEditCount = true;
275+
// Swap mode: Insert new, then remove old with squash
344276
this.dispatchEvent(newEditEvent(inserts));
345277
await this.updateComplete;
346278

347279
const remove = removeDataType(
348280
{ node: this.selectedLNodeType! },
349281
{ force: true }
350282
);
351-
this.ignoreNextEditCount = true;
352283
this.dispatchEvent(
353284
newEditEvent(remove, { squash: true, title: `Update ${lnID}` })
354285
);
@@ -357,29 +288,87 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
357288
insert => (insert.node as Element).tagName === 'LNodeType'
358289
)?.node as Element;
359290

360-
if (updatedLNodeType) {
361-
const updatedLNodeTypeID = updatedLNodeType.getAttribute('id');
362-
this.selectedLNodeType = updatedLNodeType;
363-
await this.updateComplete;
364-
365-
if (this.lNodeTypeUI && updatedLNodeType) {
366-
this.lNodeTypeUI.value = updatedLNodeType.getAttribute('id') ?? '';
367-
}
368-
369-
this.fabLabel = `${updatedLNodeTypeID} swapped!`;
291+
if (updatedLNodeType && this.lNodeTypeUI) {
292+
this.lNodeTypeUI.value = updatedLNodeType.getAttribute('id') ?? '';
370293
}
294+
295+
const updatedID = updatedLNodeType?.getAttribute('id') ?? lnID;
296+
this.showSuccessFeedback(updatedID, 'swap');
371297
}
372298

373299
await this.updateComplete;
374300
this.lNodeTypes = getLNodeTypes(this.doc);
301+
}
375302

303+
private showSuccessFeedback(
304+
lnID: string,
305+
mode: 'update' | 'swap' = 'update'
306+
): void {
307+
this.fabLabel = mode === 'swap' ? `${lnID} swapped!` : `${lnID} updated!`;
376308
setTimeout(() => {
377309
this.fabLabel = 'Update Logical Node Type';
378310
}, 5000);
379311
}
380312

313+
private buildUpdateEdits(
314+
inserts: Edit[],
315+
currentLNodeType: Element,
316+
lnID: string,
317+
desc: string
318+
): Edit[] {
319+
const lNodeTypeInsert = inserts.find(
320+
insert =>
321+
'node' in insert && (insert.node as Element).tagName === 'LNodeType'
322+
);
323+
324+
if (
325+
lNodeTypeInsert &&
326+
'node' in lNodeTypeInsert &&
327+
'parent' in lNodeTypeInsert &&
328+
'reference' in lNodeTypeInsert
329+
) {
330+
const newLNodeType = (lNodeTypeInsert.node as Element).cloneNode(
331+
true
332+
) as Element;
333+
334+
newLNodeType.setAttribute('id', lnID);
335+
this.applyDescriptionUpdate(newLNodeType, desc, currentLNodeType);
336+
337+
const supportingTypes = inserts.filter(
338+
insert => insert !== lNodeTypeInsert
339+
);
340+
const removeOld = removeDataType(
341+
{ node: currentLNodeType },
342+
{ force: true }
343+
);
344+
345+
return [
346+
...supportingTypes,
347+
{
348+
parent: lNodeTypeInsert.parent,
349+
node: newLNodeType,
350+
reference: lNodeTypeInsert.reference,
351+
},
352+
...removeOld,
353+
];
354+
}
355+
356+
if (inserts.length === 0) {
357+
const newLNodeType = removeDOsNotInSelection(
358+
currentLNodeType,
359+
this.nsdSelection!
360+
);
361+
362+
newLNodeType.setAttribute('id', lnID);
363+
this.applyDescriptionUpdate(newLNodeType, desc, currentLNodeType);
364+
365+
return updateLNodeType(newLNodeType, this.doc!);
366+
}
367+
368+
return inserts;
369+
}
370+
381371
private updateLNodeTypeDescription(desc: string): void {
382-
this.ignoreNextEditCount = true;
383372
this.lNodeTypeDescription = desc;
384373
this.dispatchEvent(
385374
newEditEvent([
@@ -406,7 +395,6 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
406395
{ force: true }
407396
);
408397

409-
this.ignoreNextEditCount = true;
410398
this.dispatchEvent(newEditEvent(remove, { title: `Delete ${lnID}` }));
411399

412400
this.resetUI(true);
@@ -421,8 +409,6 @@ export default class NsdTemplateUpdated extends ScopedElementsMixin(
421409
this.treeUI.selection
422410
);
423411

424-
// Only update nsdSelection if the user's selection has actually changed
425-
// This prevents overwriting the document-synced selection from a previous update
426412
if (JSON.stringify(newNsdSelection) !== JSON.stringify(this.nsdSelection)) {
427413
this.nsdSelection = newNsdSelection;
428414
}

0 commit comments

Comments
 (0)