From 754c7ce0ed839de8224020997163c6891fd864d2 Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Tue, 17 Mar 2026 11:59:40 +0100 Subject: [PATCH 1/8] Refactor ComponentsPacksWebviewMain to improve project handling and enhance dispose logic; update ComponentPackManager layout for better responsiveness; adjust ComponentsView variant column for improved display. --- .../components-packs-webview-main.ts | 75 ++++++++++++--- .../components/component-pack-manager.tsx | 92 ++++++++++--------- .../view/components/components-view.tsx | 2 +- 3 files changed, 109 insertions(+), 60 deletions(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index 63399d6f8..79560ee48 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -57,8 +57,7 @@ export class ComponentsPacksWebviewMain { public static readonly WEBVIEW_COMMAND_ID = `${manifest.PACKAGE_NAME}.manageComponentsPacks`; - private currentProject: CurrentProject; - + private project: CurrentProject; private componentTree!: CtRoot; private validations!: Results; private selectedContext: TargetSetData | undefined; @@ -88,7 +87,6 @@ export class ComponentsPacksWebviewMain { new WebviewManager(context, MANAGE_COMPONENTS_WEBVIEW_OPTIONS, commandsProvider); this.manageComponentsActions.setCsolutionService(this.csolutionService); this.manageComponentsActions.setMessageProvider(this.messageProvider); - this.manageComponentsActions.setCurrentProject(this.currentProject); this.projectFileUpdater = new ProjectFileUpdaterImpl(this.solutionManager); } @@ -103,11 +101,58 @@ export class ComponentsPacksWebviewMain { await this.webviewManager.activate(context); } - private dispose(): void { - this.currentProject = undefined; - this.componentTree = { success: false, classes: [] }; - this.validations = { success: false, result: 'UNDEFINED', validation: [] }; - this.manageComponentsActions.setCurrentProject(this.currentProject); + private async dispose(): Promise { + const discardView = () => { + this.currentProject = undefined; + this.componentTree = { success: false, classes: [] }; + this.validations = { success: false, result: 'UNDEFINED', validation: [] }; + this.usedItems = { components: [], packs: [], success: false }; + this.cachedTargetSetData = undefined; + this.availablePacksCache = {}; + this.unlinkRequests.clear(); + this.isLoading = false; + this.scope = ComponentScope.Solution; + }; + + if (await this.isDirty()) { + const buttonOptions = [ + { title: 'Save' }, + { title: 'Discard', isCloseAffordance: true }, + { title: 'Reopen' }, + ]; + const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Do you want to save changes before closing?' }; + + const pick = (await vscode.window.showWarningMessage( + 'Unsaved changes will be lost.', + messageOptions, + ...buttonOptions, + )) || { title: 'Cancel' }; + + switch (pick.title) { + case 'Save': + await this.handleApplyComponentSet(); + discardView(); + break; + case 'Reopen': + this.webviewManager.createOrShowPanel(); + break; + case 'Discard': + default: + discardView(); + break; + } + } else { + discardView(); + } + } + + get currentProject(): CurrentProject | undefined { + return this.project; + } + + set currentProject(project: CurrentProject | undefined) { + this.project = project; + this.manageComponentsActions.setCurrentProject(project); } private async handleWebviewCommand(treeNode: COutlineItem | undefined) { @@ -265,7 +310,6 @@ export class ComponentsPacksWebviewMain { if (csolution) { this.clearTargetSetCache(); this.currentProject = { solutionPath: csolution.solutionPath, project: createProject(projectId) }; - this.manageComponentsActions.setCurrentProject(this.currentProject); const actx = this.getActiveContext(); const activeTs = csolution.getActiveTargetSetName() ?? ''; @@ -294,11 +338,12 @@ export class ComponentsPacksWebviewMain { throw new Error(`Failed loading solution: ${solutionPath} due to previous errors`); } - await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: 'Fetching Packs Info...' }); + await this.webviewManager.sendMessage({ type: 'SET_SOLUTION_STATE', stateMessage: 'Retrieving assigned items...' }); + this.usedItems = await this.csolutionService.getUsedItems({ context: activeContext }); } - this.usedItems = await this.csolutionService.getUsedItems({ context: activeContext }); await this.webviewManager.sendMessage({ type: 'SET_UNLINKREQUESTS_STACK', unlinkRequests: Array.from(this.unlinkRequests) }); await this.sendSolutionData(); + await this.sendDirtyState(); } catch (error) { const messages = await this.csolutionService.getLogMessages(); @@ -394,10 +439,12 @@ export class ComponentsPacksWebviewMain { }; private async handleRequestInitialData(): Promise { - const projectId = this.getValidProjectId(); + const cprojectPath = this.getValidProjectId(); this.scope = ComponentScope.Solution; - if (projectId) { - await this.debounce_load(projectId, true); + if (cprojectPath) { + const reload = this.projectFromPath(this.currentProject?.project.projectId) !== this.projectFromPath(cprojectPath); + + await this.debounce_load(cprojectPath, reload); } } diff --git a/src/views/manage-components-packs/view/components/component-pack-manager.tsx b/src/views/manage-components-packs/view/components/component-pack-manager.tsx index 160d06a49..bf65f5355 100644 --- a/src/views/manage-components-packs/view/components/component-pack-manager.tsx +++ b/src/views/manage-components-packs/view/components/component-pack-manager.tsx @@ -110,51 +110,53 @@ export const ComponentPackManager = (props: ComponentProps) => { }, token: { fontSize: 13, sizeStep: 4, borderRadius: 3 } }}> - - - - - - - - - - - - - {activeView === 'components' && - - } - {activeView === 'packs' && - - } +
+ + + + + + + + + + + + + {activeView === 'components' && + + } + {activeView === 'packs' && + + } +
diff --git a/src/views/manage-components-packs/view/components/components-view.tsx b/src/views/manage-components-packs/view/components/components-view.tsx index 566b1734d..cdc9358f6 100644 --- a/src/views/manage-components-packs/view/components/components-view.tsx +++ b/src/views/manage-components-packs/view/components/components-view.tsx @@ -113,7 +113,7 @@ export const ComponentsView: React.FC = ({ { title: '', width: 40, render: (record: ComponentRowDataType) => renderWarningCell(record, state) }, Table.SELECTION_COLUMN, { title: '', width: 40, render: (record: ComponentRowDataType) => renderEditField(record, setSelectedComponent, state) }, - { title: 'Variant', dataIndex: ['parsed', 'variant'], key: 'variant', minWidth: 60, render: (value: string, record: ComponentRowDataType, index: number) => renderVariantCell(value, record, index, onChangeBundle, onChangeComponentVariant), ellipsis: false }, + { title: 'Variant', dataIndex: ['parsed', 'variant'], key: 'variant', minWidth: 60, maxWidth: 90, ellipsis: true, render: (value: string, record: ComponentRowDataType, index: number) => renderVariantCell(value, record, index, onChangeBundle, onChangeComponentVariant) }, { title: 'Version', dataIndex: ['parsed', 'version'], key: 'version', minWidth: 60, ellipsis: false }, { title: 'Vendor', dataIndex: ['parsed', 'vendor'], key: 'vendor', minWidth: 60, ellipsis: false }, { title: 'Description', dataIndex: ['data', 'description'], key: 'data.description', width: 'calc(fit-content - 50px)', ellipsis: true, render: (value: string, record: ComponentRowDataType) => renderDescriptionCell(value, record, state, openDocFile) }, From a35cc3305d09941d3b74321035625efded97de36 Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Tue, 17 Mar 2026 13:10:56 +0100 Subject: [PATCH 2/8] Improve unsaved changes warning in ComponentsPacksWebviewMain; update button labels and message detail for clarity. --- .../components-packs-webview-main.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index 79560ee48..5dcdd1cc7 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -117,13 +117,13 @@ export class ComponentsPacksWebviewMain { if (await this.isDirty()) { const buttonOptions = [ { title: 'Save' }, - { title: 'Discard', isCloseAffordance: true }, - { title: 'Reopen' }, + { title: 'Don\'t Save', isCloseAffordance: true }, + { title: 'Cancel' }, ]; - const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Do you want to save changes before closing?' }; + const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Your changes will be lost if you don\'t save them.' }; const pick = (await vscode.window.showWarningMessage( - 'Unsaved changes will be lost.', + 'Do you want to save the changes you made to the Solution?', messageOptions, ...buttonOptions, )) || { title: 'Cancel' }; @@ -133,10 +133,10 @@ export class ComponentsPacksWebviewMain { await this.handleApplyComponentSet(); discardView(); break; - case 'Reopen': + case 'Cancel': this.webviewManager.createOrShowPanel(); break; - case 'Discard': + case 'Don\'t Save': default: discardView(); break; From 5809937c40f4f1ddeafcac0e6cb0fee32f369d58 Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Tue, 17 Mar 2026 13:40:56 +0100 Subject: [PATCH 3/8] Fix button order in unsaved changes prompt for clarity --- .../manage-components-packs/components-packs-webview-main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index 5dcdd1cc7..52cac1caf 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -117,8 +117,8 @@ export class ComponentsPacksWebviewMain { if (await this.isDirty()) { const buttonOptions = [ { title: 'Save' }, - { title: 'Don\'t Save', isCloseAffordance: true }, - { title: 'Cancel' }, + { title: 'Don\'t Save' }, + { title: 'Cancel', isCloseAffordance: true }, ]; const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Your changes will be lost if you don\'t save them.' }; From 5c66c2cbdd88c45d959d94b4fc14d6971beca7bc Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Tue, 17 Mar 2026 13:54:26 +0100 Subject: [PATCH 4/8] Enhance dispose logic in ComponentsPacksWebviewMain to handle unsaved changes; implement save, discard, and cancel options for user prompts. --- .../components-packs-webview-main.test.ts | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.test.ts b/src/views/manage-components-packs/components-packs-webview-main.test.ts index 1e6b89f0f..1f5b1c34b 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.test.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.test.ts @@ -324,14 +324,15 @@ describe('ComponentsPacksWebviewMain', () => { jest.restoreAllMocks(); }); - it('calls debounce_load with project id and reload=true when a valid project exists', async () => { + it('calls debounce_load with project id and reload=false when selected project is unchanged', async () => { const debounceSpy = jest.spyOn(componentsPacksWebviewMain as any, 'debounce_load').mockResolvedValue(undefined); jest.spyOn(componentsPacksWebviewMain as any, 'getValidProjectId').mockReturnValue('projValid'); + jest.spyOn(componentsPacksWebviewMain as any, 'projectFromPath').mockReturnValue('sameProject'); await (componentsPacksWebviewMain as any).handleMessage({ type: 'REQUEST_INITIAL_DATA' }); expect(debounceSpy).toHaveBeenCalledTimes(1); - expect(debounceSpy).toHaveBeenCalledWith('projValid', true); + expect(debounceSpy).toHaveBeenCalledWith('projValid', false); }); it('does not call debounce_load when no valid project id exists', async () => { @@ -572,7 +573,7 @@ describe('ComponentsPacksWebviewMain', () => { 'Connecting to rpc daemon', 'Loading Packs...', 'Loading Solution...', - 'Fetching Packs Info...' + 'Retrieving assigned items...' ]) ); expect(stateMessages.indexOf('Connecting to rpc daemon')).toBeLessThan(stateMessages.indexOf('Loading Packs...')); @@ -598,6 +599,7 @@ describe('ComponentsPacksWebviewMain', () => { it('skips heavy reload steps when reload=false', async () => { const svc = setupCsolutionServiceMocks(); + (componentsPacksWebviewMain as any).usedItems = usedItemsReturn; await (componentsPacksWebviewMain as any).loadSolution('solPath', 'activeTs', 'activeCtx', false); // Heavy operations not called @@ -613,8 +615,8 @@ describe('ComponentsPacksWebviewMain', () => { const compTreeMsg = webviewManager.sendMessage.mock.calls.map(c => c[0]).find(m => m.type === 'SOLUTION_LOADED'); expect(compTreeMsg?.componentTree).toBe(componentTreeReturn); - // usedItems is set - expect((componentsPacksWebviewMain as any).usedItems).toBeDefined(); + // usedItems is not refreshed in reload=false path + expect((componentsPacksWebviewMain as any).usedItems).toBe(usedItemsReturn); }); it('handles errors and sends error messages', async () => { @@ -892,17 +894,68 @@ describe('ComponentsPacksWebviewMain', () => { expect(spy).toHaveBeenCalledWith({ newState: { solutionPath: 'sol' }, previousState: { solutionPath: '' } }); }); - it('resets cached state when panel disposes', () => { + it('resets cached state when panel disposes without unsaved changes', async () => { + jest.spyOn(componentsPacksWebviewMain as any, 'isDirty').mockResolvedValue(false); + const warningSpy = jest.spyOn(vscode.window, 'showWarningMessage'); (componentsPacksWebviewMain as any).currentProject = { solutionPath: 'sol', project: { projectId: 'proj', projectName: 'proj' } }; (componentsPacksWebviewMain as any).componentTree = { success: true, classes: [{}] }; (componentsPacksWebviewMain as any).validations = { success: true, result: 'OK', validation: [{ id: 'val' }] }; webviewManager.didDisposeEmitter.fire(); + await waitTimeout(); + expect(warningSpy).not.toHaveBeenCalled(); expect((componentsPacksWebviewMain as any).currentProject).toBeUndefined(); expect((componentsPacksWebviewMain as any).componentTree).toEqual({ success: false, classes: [] }); expect((componentsPacksWebviewMain as any).validations).toEqual({ success: false, result: 'UNDEFINED', validation: [] }); }); + + it('saves and then disposes when user picks Save on unsaved changes', async () => { + jest.spyOn(componentsPacksWebviewMain as any, 'isDirty').mockResolvedValue(true); + const applySpy = jest.spyOn(componentsPacksWebviewMain as any, 'handleApplyComponentSet').mockResolvedValue(undefined); + jest.spyOn(vscode.window, 'showWarningMessage').mockResolvedValue({ title: 'Save' } as any); + + (componentsPacksWebviewMain as any).currentProject = { solutionPath: 'sol', project: { projectId: 'proj', projectName: 'proj' } }; + + webviewManager.didDisposeEmitter.fire(); + await waitTimeout(); + + expect(applySpy).toHaveBeenCalledTimes(1); + expect((componentsPacksWebviewMain as any).currentProject).toBeUndefined(); + }); + + it('disposes without saving when user picks Don\'t Save on unsaved changes', async () => { + jest.spyOn(componentsPacksWebviewMain as any, 'isDirty').mockResolvedValue(true); + const applySpy = jest.spyOn(componentsPacksWebviewMain as any, 'handleApplyComponentSet').mockResolvedValue(undefined); + jest.spyOn(vscode.window, 'showWarningMessage').mockResolvedValue({ title: "Don't Save" } as any); + + (componentsPacksWebviewMain as any).currentProject = { solutionPath: 'sol', project: { projectId: 'proj', projectName: 'proj' } }; + + webviewManager.didDisposeEmitter.fire(); + await waitTimeout(); + + expect(applySpy).not.toHaveBeenCalled(); + expect((componentsPacksWebviewMain as any).currentProject).toBeUndefined(); + }); + + it('reopens panel and keeps state when user picks Cancel on unsaved changes', async () => { + jest.spyOn(componentsPacksWebviewMain as any, 'isDirty').mockResolvedValue(true); + const applySpy = jest.spyOn(componentsPacksWebviewMain as any, 'handleApplyComponentSet').mockResolvedValue(undefined); + const reopenSpy = jest.spyOn((componentsPacksWebviewMain as any).webviewManager, 'createOrShowPanel'); + jest.spyOn(vscode.window, 'showWarningMessage').mockResolvedValue({ title: 'Cancel' } as any); + + (componentsPacksWebviewMain as any).currentProject = { solutionPath: 'sol', project: { projectId: 'proj', projectName: 'proj' } }; + + webviewManager.didDisposeEmitter.fire(); + await waitTimeout(); + + expect(applySpy).not.toHaveBeenCalled(); + expect(reopenSpy).toHaveBeenCalledTimes(1); + expect((componentsPacksWebviewMain as any).currentProject).toEqual({ + solutionPath: 'sol', + project: { projectId: 'proj', projectName: 'proj' } + }); + }); }); describe('openWebview context selection', () => { From 626b8f1e3c44c1df055e30c2f8cd4abdacdf8ca1 Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Thu, 19 Mar 2026 09:42:32 +0100 Subject: [PATCH 5/8] Refactor dispose method to handle errors and separate internal logic --- .../components-packs-webview-main.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index c59254245..6ba9bcd2b 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -101,7 +101,14 @@ export class ComponentsPacksWebviewMain { await this.webviewManager.activate(context); } - private async dispose(): Promise { + private dispose(): void { + this.disposeInternal().catch((error) => { + // Ensure any errors during dispose do not become unhandled promise rejections. + console.error('Error during ComponentsPacksWebviewMain.dispose:', error); + }); + } + + private async disposeInternal(): Promise { const discardView = () => { this.currentProject = undefined; this.componentTree = { success: false, classes: [] }; @@ -114,7 +121,9 @@ export class ComponentsPacksWebviewMain { this.scope = ComponentScope.Solution; }; - if (await this.isDirty()) { + const hasBaseline = this.usedItems !== undefined; + + if (hasBaseline && await this.isDirty()) { const buttonOptions = [ { title: 'Save' }, { title: 'Don\'t Save' }, @@ -343,7 +352,11 @@ export class ComponentsPacksWebviewMain { } await this.webviewManager.sendMessage({ type: 'SET_UNLINKREQUESTS_STACK', unlinkRequests: Array.from(this.unlinkRequests) }); await this.sendSolutionData(); - await this.sendDirtyState(); + if (reload) { + await this.sendDirtyState(); + } else { + await this.sendDirtyState({ skipApply: true }); + } } catch (error) { const messages = await this.csolutionService.getLogMessages(); From adb0f0a0e51ce363511c8f17ec3df36df2db2629 Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Wed, 15 Apr 2026 08:37:47 +0200 Subject: [PATCH 6/8] Refactor project handling in ComponentsPacksWebviewMain to use currentProject instead of project --- .../components-packs-webview-main.ts | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index ee583c1a1..4d015ac7b 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -142,7 +142,7 @@ export class ComponentsPacksWebviewMain { private async disposeInternal(): Promise { const discardView = () => { - this.project = undefined; + this.currentProject = undefined; this.componentTree = { success: false, classes: [] }; this.validations = { success: false, result: 'UNDEFINED', validation: [] }; this.usedItems = { components: [], packs: [], success: false }; @@ -192,6 +192,10 @@ export class ComponentsPacksWebviewMain { this.manageComponentsActions.setCurrentProject(project); } + get currentProject(): CurrentProject | undefined { + return this.project; + } + private resolveProjectPathFromContext(context: string): string | undefined { const descriptors = this.solutionManager.getCsolution()?.getContextDescriptors(); return descriptors?.find(descriptor => descriptor.displayName === context)?.projectPath; @@ -238,11 +242,11 @@ export class ComponentsPacksWebviewMain { return; // nothing to show } - const reload = this.project === undefined || - this.projectFromPath(this.project.project.projectId) !== this.projectFromPath(cprojectPath); + const reload = this.currentProject === undefined || + this.projectFromPath(this.currentProject.project.projectId) !== this.projectFromPath(cprojectPath); const csolution = this.solutionManager.getCsolution(); if (csolution) { - this.project = { solutionPath: csolution.solutionPath, project: createProject(cprojectPath) }; + this.currentProject = { solutionPath: csolution.solutionPath, project: createProject(cprojectPath) }; } if (clayerPath) { @@ -272,19 +276,19 @@ export class ComponentsPacksWebviewMain { if (csolution && e.newState.solutionPath) { // in case of switching a solution we need to track the correct or first project from the solution to keep this.currentProject active if (e.newState.solutionPath !== this.project?.solutionPath) { - this.project = undefined; + this.currentProject = undefined; } const validProjectId = this.getValidProjectId(); if (!validProjectId) { - this.project = undefined; + this.currentProject = undefined; } - if (validProjectId && validProjectId !== this.project?.project.projectId) { - this.project = { solutionPath: csolution.solutionPath, project: createProject(validProjectId) }; + if (validProjectId && validProjectId !== this.currentProject?.project.projectId) { + this.currentProject = { solutionPath: csolution.solutionPath, project: createProject(validProjectId) }; } - if (this.project) { - await this.debounce_load(this.project.project.projectId, true); + if (this.currentProject) { + await this.debounce_load(this.currentProject.project.projectId, true); } else { await this.clearComponents(); await this.webviewManager.sendMessage({ @@ -306,8 +310,8 @@ export class ComponentsPacksWebviewMain { private getValidProjectId(): string | undefined { const csolution = this.solutionManager.getCsolution(); if (csolution) { - if (this.project?.project.projectId && csolution.getCproject(this.project.project.projectId)) { - return this.project.project.projectId; + if (this.currentProject?.project.projectId && csolution.getCproject(this.currentProject.project.projectId)) { + return this.currentProject.project.projectId; } const firstProjectPath = csolution?.getContextDescriptors() .find(ctx => ctx.targetType === csolution.getActiveTargetSetName()) @@ -372,7 +376,7 @@ export class ComponentsPacksWebviewMain { const csolution = this.solutionManager.getCsolution(); if (csolution) { this.clearTargetSetCache(); - this.project = { solutionPath: csolution.solutionPath, project: createProject(projectId) }; + this.currentProject = { solutionPath: csolution.solutionPath, project: createProject(projectId) }; const actx = this.getActiveContext(); const activeTs = csolution.getActiveTargetSetName() ?? ''; @@ -435,7 +439,7 @@ export class ComponentsPacksWebviewMain { private getSelectedTargetSetData(): TargetSetData | undefined { if (!this.selectedContext) { - const normalizedProjectId = normalizeForCompare(this.project?.project.projectId || ''); + const normalizedProjectId = normalizeForCompare(this.currentProject?.project.projectId || ''); this.selectedContext = this.getTargetSetData().find(ts => normalizeForCompare(ts.path) === normalizedProjectId); if (!this.selectedContext) { this.selectedContext = this.getTargetSetData()?.at(0); @@ -509,7 +513,7 @@ export class ComponentsPacksWebviewMain { const cprojectPath = this.getValidProjectId(); this.scope = ComponentScope.Solution; if (cprojectPath) { - const reload = this.projectFromPath(this.project?.project.projectId) !== this.projectFromPath(cprojectPath); + const reload = this.projectFromPath(this.currentProject?.project.projectId) !== this.projectFromPath(cprojectPath); await this.debounce_load(cprojectPath, reload); } From 0634766a80d4f3cefe0e0c33675f25eadd9c1a4c Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Wed, 15 Apr 2026 08:40:31 +0200 Subject: [PATCH 7/8] Update warning message to clarify cancel action in ComponentsPacksWebviewMain --- .../manage-components-packs/components-packs-webview-main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index 4d015ac7b..35ad8a4ee 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -161,7 +161,7 @@ export class ComponentsPacksWebviewMain { { title: 'Don\'t Save' }, { title: 'Cancel', isCloseAffordance: true }, ]; - const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Your changes will be lost if you don\'t save them.' }; + const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Your changes will be lost if you don\'t save them. Press cancel to continue editing.' }; const pick = (await vscode.window.showWarningMessage( 'Do you want to save the changes you made to the Solution?', From 18563fadbe772959d351085a7bc4c5ee0a66c32e Mon Sep 17 00:00:00 2001 From: Arne Schmid Date: Wed, 15 Apr 2026 08:41:55 +0200 Subject: [PATCH 8/8] Add newline to dialog details --- .../manage-components-packs/components-packs-webview-main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/manage-components-packs/components-packs-webview-main.ts b/src/views/manage-components-packs/components-packs-webview-main.ts index 35ad8a4ee..562f85707 100644 --- a/src/views/manage-components-packs/components-packs-webview-main.ts +++ b/src/views/manage-components-packs/components-packs-webview-main.ts @@ -161,7 +161,7 @@ export class ComponentsPacksWebviewMain { { title: 'Don\'t Save' }, { title: 'Cancel', isCloseAffordance: true }, ]; - const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Your changes will be lost if you don\'t save them. Press cancel to continue editing.' }; + const messageOptions: vscode.MessageOptions = { modal: true, detail: 'Your changes will be lost if you don\'t save them.\nPress cancel to continue editing.' }; const pick = (await vscode.window.showWarningMessage( 'Do you want to save the changes you made to the Solution?',