@@ -209,37 +209,39 @@ export class ComponentsPacksWebviewMain {
209209 return undefined ;
210210 }
211211
212- private async isDirty ( ) : Promise < boolean > {
212+ private async isDirty ( usedItems ?: UsedItems ) : Promise < boolean > {
213213 const actx = this . getActiveContext ( ) ;
214214
215215 if ( this . solutionManager . getCsolution ( ) ?. cbuildPackFile . isModified ( ) ) {
216216 return true ;
217217 }
218218
219- const usedItems = await this . csolutionService . getUsedItems ( { context : actx } ) ;
220- if ( this . usedItems ?. packs . length !== usedItems . packs . length || this . usedItems ?. components . length !== usedItems . components . length ) {
219+ const latestUsedItems = usedItems ?? await this . csolutionService . getUsedItems ( { context : actx } ) ;
220+ if ( this . usedItems ?. packs . length !== latestUsedItems . packs . length || this . usedItems ?. components . length !== latestUsedItems . components . length ) {
221221 return true ;
222222 }
223223
224224 const componentMapper = ( c : ComponentInstance ) => ( { id : c . id , variant : c . resolvedComponent ?. pack } ) ;
225225 const packMapper = ( p : PackReference ) => ( { pack : p . pack , origin : normalizeForCompare ( p . origin ) } ) ;
226226 const localUsedItemsSorted = {
227- components : this . usedItems ?. components . sort ( ( a , b ) => a . id . localeCompare ( b . id ) ) . map ( componentMapper ) ?? [ ] ,
228- packs : this . usedItems ?. packs . sort ( ( a , b ) => a . pack . localeCompare ( b . pack ) ) . map ( packMapper ) ?? [ ] ,
227+ components : [ ... ( this . usedItems ?. components ?? [ ] ) ] . sort ( ( a , b ) => a . id . localeCompare ( b . id ) ) . map ( componentMapper ) ,
228+ packs : [ ... ( this . usedItems ?. packs ?? [ ] ) ] . sort ( ( a , b ) => a . pack . localeCompare ( b . pack ) ) . map ( packMapper ) ,
229229 } ;
230230 const usedItemsSorted = {
231- components : usedItems . components . sort ( ( a , b ) => a . id . localeCompare ( b . id ) ) . map ( componentMapper ) ,
232- packs : usedItems . packs . sort ( ( a , b ) => a . pack . localeCompare ( b . pack ) ) . map ( packMapper ) ,
231+ components : [ ... latestUsedItems . components ] . sort ( ( a , b ) => a . id . localeCompare ( b . id ) ) . map ( componentMapper ) ,
232+ packs : [ ... latestUsedItems . packs ] . sort ( ( a , b ) => a . pack . localeCompare ( b . pack ) ) . map ( packMapper ) ,
233233 } ;
234234 const usedItemsChanged = ! isDeepStrictEqual ( localUsedItemsSorted , usedItemsSorted ) ;
235235 return usedItemsChanged ;
236236 }
237237
238- private async sendDirtyState ( ) : Promise < void > {
238+ private async sendDirtyState ( options ?: { skipApply ?: boolean , usedItems ?: UsedItems } ) : Promise < void > {
239239 const actx = this . getActiveContext ( ) ;
240- await this . csolutionService . apply ( { context : actx } ) ;
240+ if ( ! options ?. skipApply ) {
241+ await this . csolutionService . apply ( { context : actx } ) ;
242+ }
241243
242- const isDirty = await this . isDirty ( ) ;
244+ const isDirty = await this . isDirty ( options ?. usedItems ) ;
243245 await this . webviewManager . sendMessage ( { type : 'IS_DIRTY' , isDirty : isDirty } ) ;
244246 }
245247
@@ -373,7 +375,7 @@ export class ComponentsPacksWebviewMain {
373375 label : `Layer: ${ layerLabel } ` ,
374376 key : layer . absolutePath ,
375377 path : backToForwardSlashes ( layer . absolutePath ) ,
376- relativePath : backToForwardSlashes ( path . relative ( dirname ( this . currentProject ?. solutionPath ?? '' ) , layer . absolutePath ) ) ,
378+ relativePath : this . getRelativePath ( this . getSolutionDir ( ) , layer . absolutePath ) ,
377379 type : 'layer' as const
378380 } ;
379381
@@ -431,7 +433,7 @@ export class ComponentsPacksWebviewMain {
431433 if ( state . success === false ) {
432434 this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage : state . message ?? 'Unspecified error when writing solution information' } ) ;
433435 }
434- await this . sendDirtyState ( ) ;
436+ await this . sendDirtyState ( { skipApply : true , usedItems : this . usedItems } ) ;
435437 }
436438
437439 private async handleOpenFile ( message : Messages . OutgoingMessage ) : Promise < void > {
@@ -452,9 +454,7 @@ export class ComponentsPacksWebviewMain {
452454 ) ;
453455
454456 await this . sendDirtyState ( ) ;
455- const validations = await this . csolutionService . validateComponents ( { context : activeContext } ) ;
456- this . componentTree = this . manageComponentsActions . mapComponentsFromService ( await this . csolutionService . getComponentsTree ( { context : activeContext , all : this . scope === ComponentScope . All } ) ) ;
457- await this . webviewManager ?. sendMessage ( { type : 'SET_COMPONENT_TREE' , tree : this . componentTree , validations : validations . validation } ) ;
457+ await this . refreshComponentTree ( activeContext ) ;
458458 }
459459 }
460460 }
@@ -470,9 +470,7 @@ export class ComponentsPacksWebviewMain {
470470 variant
471471 ) ;
472472 await this . sendDirtyState ( ) ;
473- this . componentTree = this . manageComponentsActions . mapComponentsFromService ( await this . csolutionService . getComponentsTree ( { context : activeContext , all : this . scope === ComponentScope . All } ) ) ;
474- const validations = await this . csolutionService . validateComponents ( { context : activeContext } ) ;
475- await this . webviewManager ?. sendMessage ( { type : 'SET_COMPONENT_TREE' , tree : this . componentTree , validations : validations . validation } ) ;
473+ await this . refreshComponentTree ( activeContext ) ;
476474 }
477475 }
478476 }
@@ -488,10 +486,7 @@ export class ComponentsPacksWebviewMain {
488486 bundle
489487 ) ;
490488 await this . sendDirtyState ( ) ;
491- const requestAll = this . scope === ComponentScope . All ;
492- this . componentTree = this . manageComponentsActions . mapComponentsFromService ( await this . csolutionService . getComponentsTree ( { context : activeContext , all : requestAll } ) ) ;
493- this . validations = await this . csolutionService . validateComponents ( { context : activeContext } ) ;
494- await this . webviewManager . sendMessage ( { type : 'SET_COMPONENT_TREE' , tree : this . componentTree , validations : this . validations . validation ?? [ ] , scope : this . scope } ) ;
489+ await this . refreshComponentTree ( activeContext ) ;
495490 }
496491 }
497492 }
@@ -601,37 +596,40 @@ export class ComponentsPacksWebviewMain {
601596 }
602597 } ;
603598
599+ private async handlePackageSelectionChange (
600+ target : string ,
601+ packId : string ,
602+ stateMessage : string ,
603+ action : ( actx : string , target : string , packId : string ) => Promise < void >
604+ ) : Promise < void > {
605+ try {
606+ await this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage } ) ;
607+ const actx = this . getActiveContext ( ) ;
608+ await action ( actx , target , packId ) ;
609+ const requestAll = this . scope === ComponentScope . All ;
610+ const packs = this . mapPacksFromService ( await this . csolutionService . getPacksInfo ( { context : actx , all : requestAll } ) ) ;
611+ await this . webviewManager . sendMessage ( { type : 'SET_PACKS_INFO' , packs : packs ?. packs || [ ] } ) ;
612+ await this . sendDirtyState ( ) ;
613+ } finally {
614+ await this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage : undefined } ) ;
615+ }
616+ }
617+
604618 private async selectPackage ( message : Messages . OutgoingMessage ) : Promise < void > {
605619 if ( isSelectPackageMessage ( message ) ) {
606- try {
607- await this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage : 'Selecting Pack' } ) ;
608-
609- const actx = this . getActiveContext ( ) ;
610- await this . manageComponentsActions . selectPackage ( actx , message . target , message . packId ) ;
611- const requestAll = this . scope === ComponentScope . All ;
612- const packs = this . mapPacksFromService ( await this . csolutionService ?. getPacksInfo ( { context : actx , all : requestAll } ) ) ;
613- await this . webviewManager ?. sendMessage ( { type : 'SET_PACKS_INFO' , packs : packs ?. packs || [ ] } ) ;
614- await this . sendDirtyState ( ) ;
615- } finally {
616- await this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage : undefined } ) ;
617- }
620+ await this . handlePackageSelectionChange (
621+ message . target , message . packId , 'Selecting Pack' ,
622+ ( actx , target , packId ) => this . manageComponentsActions . selectPackage ( actx , target , packId )
623+ ) ;
618624 }
619625 }
620626
621627 private async unselectPackage ( message : Messages . OutgoingMessage ) : Promise < void > {
622628 if ( isUnselectPackageMessage ( message ) ) {
623- try {
624- await this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage : 'Unselecting Pack' } ) ;
625-
626- const actx = this . getActiveContext ( ) ;
627- await this . manageComponentsActions . unselectPackage ( actx , message . target , message . packId ) ;
628- const requestAll = this . scope === ComponentScope . All ;
629- const packs = this . mapPacksFromService ( await this . csolutionService ?. getPacksInfo ( { context : actx , all : requestAll } ) ) ;
630- await this . webviewManager ?. sendMessage ( { type : 'SET_PACKS_INFO' , packs : packs ?. packs || [ ] } ) ;
631- await this . sendDirtyState ( ) ;
632- } finally {
633- await this . webviewManager . sendMessage ( { type : 'SET_SOLUTION_STATE' , stateMessage : undefined } ) ;
634- }
629+ await this . handlePackageSelectionChange (
630+ message . target , message . packId , 'Unselecting Pack' ,
631+ ( actx , target , packId ) => this . manageComponentsActions . unselectPackage ( actx , target , packId )
632+ ) ;
635633 }
636634 }
637635
@@ -781,6 +779,19 @@ export class ComponentsPacksWebviewMain {
781779 await this . webviewManager . sendMessage ( programMessage ) ;
782780 }
783781
782+ private async refreshComponentTree ( activeContext : string ) : Promise < void > {
783+ this . componentTree = this . manageComponentsActions . mapComponentsFromService (
784+ await this . csolutionService . getComponentsTree ( { context : activeContext , all : this . scope === ComponentScope . All } )
785+ ) ;
786+ this . validations = await this . csolutionService . validateComponents ( { context : activeContext } ) ;
787+ await this . webviewManager . sendMessage ( {
788+ type : 'SET_COMPONENT_TREE' ,
789+ tree : this . componentTree ,
790+ validations : this . validations . validation ?? [ ] ,
791+ scope : this . scope
792+ } ) ;
793+ }
794+
784795 private async openFile ( filePath : string , openExternal ?: boolean , focusOn ?: string ) : Promise < void > {
785796 if ( openExternal ) {
786797 this . openFileExternal . openFile ( filePath ) ;
0 commit comments