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