Skip to content

Commit 28afda5

Browse files
arneschmidedriouk
andauthored
Fix/initial open view missing layer path (#62)
* Fix project loading logic and reorder component tree updates in ComponentsPacksWebviewMain * Remove redundant 'activated' property from solution load state factories * Refactor dirty state handling and improve component tree refresh logic and reduce RPC calls to getUsedItems * Fix project file update logic by using a deep clone of used items --------- Co-authored-by: Evgueni Driouk <edriouk@arm.com>
1 parent 9c4ddab commit 28afda5

1 file changed

Lines changed: 70 additions & 53 deletions

File tree

src/views/manage-components-packs/components-packs-webview-main.ts

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { BuildContext, Project, TargetSetData } from './components-data';
3131
import { ComponentsPacksActions, CurrentProject, normalizeForCompare } from './components-packs-actions';
3232
import { ComponentRowDataType, ComponentScope } from './data/component-tools';
3333
import { componentTreeWalker } from './data/component-tree-walker';
34-
import { uniqWith } from 'lodash';
34+
import { uniqWith, cloneDeep } from 'lodash';
3535
import { parsePackId } from './data/pack-parse';
3636
import { lineOf, readTextFile } from '../../utils/fs-utils';
3737
import { stripTwoExtensions } from '../../utils/string-utils';
@@ -131,6 +131,12 @@ export class ComponentsPacksWebviewMain {
131131
return; // nothing to show
132132
}
133133

134+
const reload = this.projectFromPath(this.currentProject?.project.projectId) !== this.projectFromPath(cprojectPath);
135+
const csolution = this.solutionManager.getCsolution();
136+
if (csolution) {
137+
this.currentProject = { solutionPath: csolution.solutionPath, project: createProject(cprojectPath) };
138+
}
139+
134140
if (clayerPath) {
135141
const selectedTarget = this.findTargetSetFromPath(clayerPath);
136142
if (selectedTarget) {
@@ -141,7 +147,6 @@ export class ComponentsPacksWebviewMain {
141147
}
142148
this.webviewManager.createOrShowPanel();
143149

144-
const reload = this.projectFromPath(this.currentProject?.project.projectId) !== this.projectFromPath(cprojectPath);
145150
await this.debounce_load(cprojectPath, reload);
146151
await this.sendDirtyState();
147152
}
@@ -204,37 +209,39 @@ export class ComponentsPacksWebviewMain {
204209
return undefined;
205210
}
206211

207-
private async isDirty(): Promise<boolean> {
212+
private async isDirty(usedItems?: UsedItems): Promise<boolean> {
208213
const actx = this.getActiveContext();
209214

210215
if (this.solutionManager.getCsolution()?.cbuildPackFile.isModified()) {
211216
return true;
212217
}
213218

214-
const usedItems = await this.csolutionService.getUsedItems({ context: actx });
215-
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) {
216221
return true;
217222
}
218223

219224
const componentMapper = (c: ComponentInstance) => ({ id: c.id, variant: c.resolvedComponent?.pack });
220225
const packMapper = (p: PackReference) => ({ pack: p.pack, origin: normalizeForCompare(p.origin) });
221226
const localUsedItemsSorted = {
222-
components: this.usedItems?.components.sort((a, b) => a.id.localeCompare(b.id)).map(componentMapper) ?? [],
223-
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),
224229
};
225230
const usedItemsSorted = {
226-
components: usedItems.components.sort((a, b) => a.id.localeCompare(b.id)).map(componentMapper),
227-
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),
228233
};
229234
const usedItemsChanged = !isDeepStrictEqual(localUsedItemsSorted, usedItemsSorted);
230235
return usedItemsChanged;
231236
}
232237

233-
private async sendDirtyState(): Promise<void> {
238+
private async sendDirtyState(options?: { skipApply?: boolean, usedItems?: UsedItems }): Promise<void> {
234239
const actx = this.getActiveContext();
235-
await this.csolutionService.apply({ context: actx });
240+
if (!options?.skipApply) {
241+
await this.csolutionService.apply({ context: actx });
242+
}
236243

237-
const isDirty = await this.isDirty();
244+
const isDirty = await this.isDirty(options?.usedItems);
238245
await this.webviewManager.sendMessage({ type: 'IS_DIRTY', isDirty: isDirty });
239246
}
240247

@@ -368,7 +375,7 @@ export class ComponentsPacksWebviewMain {
368375
label: `Layer: ${layerLabel}`,
369376
key: layer.absolutePath,
370377
path: backToForwardSlashes(layer.absolutePath),
371-
relativePath: backToForwardSlashes(path.relative(dirname(this.currentProject?.solutionPath ?? ''), layer.absolutePath)),
378+
relativePath: this.getRelativePath(this.getSolutionDir(), layer.absolutePath),
372379
type: 'layer' as const
373380
};
374381

@@ -413,11 +420,12 @@ export class ComponentsPacksWebviewMain {
413420
const activeContext = this.getActiveContext();
414421
const state = await this.csolutionService.apply({ context: activeContext });
415422
this.usedItems = await this.csolutionService.getUsedItems({ context: activeContext });
423+
const usedItemsForProjectFileUpdate = cloneDeep(this.usedItems);
416424
const projectFileName = this.currentProject?.project.projectId ?? '';
417425
const requestAll = this.scope === ComponentScope.All;
418426
this.componentTree = this.manageComponentsActions.mapComponentsFromService(await this.csolutionService.getComponentsTree({ context: activeContext, all: requestAll }));
419427
this.validations = await this.csolutionService.validateComponents({ context: activeContext });
420-
await this.projectFileUpdater.updateUsedItems(activeContext, projectFileName, this.usedItems);
428+
await this.projectFileUpdater.updateUsedItems(activeContext, projectFileName, usedItemsForProjectFileUpdate);
421429

422430
await Promise.all([
423431
this.webviewManager.sendMessage({ type: 'SET_ERROR_MESSAGES', messages: [] }),
@@ -426,7 +434,7 @@ export class ComponentsPacksWebviewMain {
426434
if (state.success === false) {
427435
this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: state.message ?? 'Unspecified error when writing solution information' });
428436
}
429-
await this.sendDirtyState();
437+
await this.sendDirtyState({ skipApply: true, usedItems: usedItemsForProjectFileUpdate });
430438
}
431439

432440
private async handleOpenFile(message: Messages.OutgoingMessage): Promise<void> {
@@ -447,9 +455,7 @@ export class ComponentsPacksWebviewMain {
447455
);
448456

449457
await this.sendDirtyState();
450-
const validations = await this.csolutionService.validateComponents({ context: activeContext });
451-
this.componentTree = this.manageComponentsActions.mapComponentsFromService(await this.csolutionService.getComponentsTree({ context: activeContext, all: this.scope === ComponentScope.All }));
452-
await this.webviewManager?.sendMessage({ type: 'SET_COMPONENT_TREE', tree: this.componentTree, validations: validations.validation });
458+
await this.refreshComponentTree(activeContext);
453459
}
454460
}
455461
}
@@ -465,9 +471,7 @@ export class ComponentsPacksWebviewMain {
465471
variant
466472
);
467473
await this.sendDirtyState();
468-
this.componentTree = this.manageComponentsActions.mapComponentsFromService(await this.csolutionService.getComponentsTree({ context: activeContext, all: this.scope === ComponentScope.All }));
469-
const validations = await this.csolutionService.validateComponents({ context: activeContext });
470-
await this.webviewManager?.sendMessage({ type: 'SET_COMPONENT_TREE', tree: this.componentTree, validations: validations.validation });
474+
await this.refreshComponentTree(activeContext);
471475
}
472476
}
473477
}
@@ -483,10 +487,7 @@ export class ComponentsPacksWebviewMain {
483487
bundle
484488
);
485489
await this.sendDirtyState();
486-
const requestAll = this.scope === ComponentScope.All;
487-
this.componentTree = this.manageComponentsActions.mapComponentsFromService(await this.csolutionService.getComponentsTree({ context: activeContext, all: requestAll }));
488-
this.validations = await this.csolutionService.validateComponents({ context: activeContext });
489-
await this.webviewManager.sendMessage({ type: 'SET_COMPONENT_TREE', tree: this.componentTree, validations: this.validations.validation ?? [], scope: this.scope });
490+
await this.refreshComponentTree(activeContext);
490491
}
491492
}
492493
}
@@ -596,37 +597,40 @@ export class ComponentsPacksWebviewMain {
596597
}
597598
};
598599

600+
private async handlePackageSelectionChange(
601+
target: string,
602+
packId: string,
603+
stateMessage: string,
604+
action: (actx: string, target: string, packId: string) => Promise<void>
605+
): Promise<void> {
606+
try {
607+
await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage });
608+
const actx = this.getActiveContext();
609+
await action(actx, target, packId);
610+
const requestAll = this.scope === ComponentScope.All;
611+
const packs = this.mapPacksFromService(await this.csolutionService.getPacksInfo({ context: actx, all: requestAll }));
612+
await this.webviewManager.sendMessage({ type: 'SET_PACKS_INFO', packs: packs?.packs || [] });
613+
await this.sendDirtyState();
614+
} finally {
615+
await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: undefined });
616+
}
617+
}
618+
599619
private async selectPackage(message: Messages.OutgoingMessage): Promise<void> {
600620
if (isSelectPackageMessage(message)) {
601-
try {
602-
await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: 'Selecting Pack' });
603-
604-
const actx = this.getActiveContext();
605-
await this.manageComponentsActions.selectPackage(actx, message.target, message.packId);
606-
const requestAll = this.scope === ComponentScope.All;
607-
const packs = this.mapPacksFromService(await this.csolutionService?.getPacksInfo({ context: actx, all: requestAll }));
608-
await this.webviewManager?.sendMessage({ type: 'SET_PACKS_INFO', packs: packs?.packs || [] });
609-
await this.sendDirtyState();
610-
} finally {
611-
await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: undefined });
612-
}
621+
await this.handlePackageSelectionChange(
622+
message.target, message.packId, 'Selecting Pack',
623+
(actx, target, packId) => this.manageComponentsActions.selectPackage(actx, target, packId)
624+
);
613625
}
614626
}
615627

616628
private async unselectPackage(message: Messages.OutgoingMessage): Promise<void> {
617629
if (isUnselectPackageMessage(message)) {
618-
try {
619-
await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: 'Unselecting Pack' });
620-
621-
const actx = this.getActiveContext();
622-
await this.manageComponentsActions.unselectPackage(actx, message.target, message.packId);
623-
const requestAll = this.scope === ComponentScope.All;
624-
const packs = this.mapPacksFromService(await this.csolutionService?.getPacksInfo({ context: actx, all: requestAll }));
625-
await this.webviewManager?.sendMessage({ type: 'SET_PACKS_INFO', packs: packs?.packs || [] });
626-
await this.sendDirtyState();
627-
} finally {
628-
await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: undefined });
629-
}
630+
await this.handlePackageSelectionChange(
631+
message.target, message.packId, 'Unselecting Pack',
632+
(actx, target, packId) => this.manageComponentsActions.unselectPackage(actx, target, packId)
633+
);
630634
}
631635
}
632636

@@ -658,14 +662,14 @@ export class ComponentsPacksWebviewMain {
658662
const activeContext = this.getActiveContext();
659663
const requestAll = this.scope === ComponentScope.All;
660664

661-
this.componentTree = this.manageComponentsActions.mapComponentsFromService(await this.csolutionService.getComponentsTree({ context: activeContext, all: requestAll }));
662-
this.validations = await this.csolutionService.validateComponents({ context: activeContext });
663-
const packsInfo = this.mapPacksFromService(await this.csolutionService.getPacksInfo({ context: activeContext, all: requestAll }));
664-
665665
if (!this.availablePacksCache || Object.keys(this.availablePacksCache).length === 0) {
666666
this.availablePacksCache = await this.filterAvailablePacks(activeContext);
667667
}
668668

669+
this.componentTree = this.manageComponentsActions.mapComponentsFromService(await this.csolutionService.getComponentsTree({ context: activeContext, all: requestAll }));
670+
this.validations = await this.csolutionService.validateComponents({ context: activeContext });
671+
const packsInfo = this.mapPacksFromService(await this.csolutionService.getPacksInfo({ context: activeContext, all: requestAll }));
672+
669673
componentTreeWalker(this.componentTree, (node, type) => {
670674
if (type === 'aggregate' && (node as CtAggregate).options?.layer) {
671675
(node as CtAggregate).options!.layer = (node as CtAggregate).options!.layer || '';
@@ -776,6 +780,19 @@ export class ComponentsPacksWebviewMain {
776780
await this.webviewManager.sendMessage(programMessage);
777781
}
778782

783+
private async refreshComponentTree(activeContext: string): Promise<void> {
784+
this.componentTree = this.manageComponentsActions.mapComponentsFromService(
785+
await this.csolutionService.getComponentsTree({ context: activeContext, all: this.scope === ComponentScope.All })
786+
);
787+
this.validations = await this.csolutionService.validateComponents({ context: activeContext });
788+
await this.webviewManager.sendMessage({
789+
type: 'SET_COMPONENT_TREE',
790+
tree: this.componentTree,
791+
validations: this.validations.validation ?? [],
792+
scope: this.scope
793+
});
794+
}
795+
779796
private async openFile(filePath: string, openExternal?: boolean, focusOn?: string): Promise<void> {
780797
if (openExternal) {
781798
this.openFileExternal.openFile(filePath);

0 commit comments

Comments
 (0)