Skip to content

Commit 8e1758a

Browse files
authored
Merge pull request #1128 from mathuo/fix/vue-header-actions-props-lost-on-update
fix(dockview-vue): preserve full params in header actions after react…
2 parents 54eefb3 + 17684d9 commit 8e1758a

File tree

2 files changed

+57
-28
lines changed

2 files changed

+57
-28
lines changed

packages/dockview-vue/src/__tests__/utils.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,4 +456,42 @@ describe('VueHeaderActionsRenderer', () => {
456456

457457
renderer.dispose();
458458
});
459+
460+
test('should preserve full params including api after reactive updates', () => {
461+
// Regression test for https://github.com/mathuo/dockview/issues/1127
462+
// Partial updates (e.g. isGroupActive) must not discard api and other fields
463+
const renderer = new VueHeaderActionsRenderer(
464+
mockComponent,
465+
mockParent,
466+
groupPanel
467+
);
468+
469+
const mockContainerApi = {} as any;
470+
471+
renderer.init({
472+
api: groupPanel.api,
473+
containerApi: mockContainerApi,
474+
group: groupPanel as any,
475+
});
476+
477+
(cloneVNode as jest.Mock).mockClear();
478+
479+
isGroupActive = false;
480+
onDidActiveChange.fire(undefined);
481+
482+
expect(cloneVNode as jest.Mock).toHaveBeenCalledTimes(1);
483+
const updatedProps = (cloneVNode as jest.Mock).mock.calls[0][1];
484+
expect(updatedProps.params).toEqual(
485+
expect.objectContaining({
486+
api: groupPanel.api,
487+
containerApi: mockContainerApi,
488+
panels: panels,
489+
activePanel: activePanel,
490+
isGroupActive: false,
491+
group: groupPanel,
492+
})
493+
);
494+
495+
renderer.dispose();
496+
});
459497
});

packages/dockview-vue/src/utils.ts

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ export class VueHeaderActionsRenderer
210210
| { update: (props: any) => void; dispose: () => void }
211211
| undefined;
212212
private readonly _mutableDisposable = new DockviewMutableDisposable();
213+
private _baseProps: IGroupHeaderProps | undefined;
213214

214215
get element(): HTMLElement {
215216
return this._element;
@@ -224,35 +225,28 @@ export class VueHeaderActionsRenderer
224225
}
225226

226227
init(props: IGroupHeaderProps): void {
228+
this._baseProps = props;
229+
227230
this._mutableDisposable.value = new DockviewCompositeDisposable(
228231
this.group.model.onDidAddPanel(() => {
229-
this.updatePanels();
232+
this.updateProps();
230233
}),
231234
this.group.model.onDidRemovePanel(() => {
232-
this.updatePanels();
235+
this.updateProps();
233236
}),
234237
this.group.model.onDidActivePanelChange(() => {
235-
this.updateActivePanel();
238+
this.updateProps();
236239
}),
237240
props.api.onDidActiveChange(() => {
238-
this.updateGroupActive();
241+
this.updateProps();
239242
})
240243
);
241244

242-
const enrichedProps: IDockviewHeaderActionsProps = {
243-
...props,
244-
panels: this.group.model.panels,
245-
activePanel: this.group.model.activePanel,
246-
isGroupActive: this.group.api.isActive,
247-
group: this.group,
248-
headerPosition: this.group.model.headerPosition,
249-
};
250-
251245
this._renderDisposable?.dispose();
252246
this._renderDisposable = mountVueComponent(
253247
this.component,
254248
this.parent,
255-
{ params: enrichedProps },
249+
{ params: this.buildEnrichedProps() },
256250
this.element
257251
);
258252
}
@@ -262,22 +256,19 @@ export class VueHeaderActionsRenderer
262256
this._renderDisposable?.dispose();
263257
}
264258

265-
private updatePanels(): void {
266-
this._renderDisposable?.update({
267-
params: { panels: this.group.model.panels },
268-
});
269-
}
270-
271-
private updateActivePanel(): void {
272-
this._renderDisposable?.update({
273-
params: { activePanel: this.group.model.activePanel },
274-
});
259+
private buildEnrichedProps(): IDockviewHeaderActionsProps {
260+
return {
261+
...this._baseProps!,
262+
panels: this.group.model.panels,
263+
activePanel: this.group.model.activePanel,
264+
isGroupActive: this.group.api.isActive,
265+
group: this.group,
266+
headerPosition: this.group.model.headerPosition,
267+
};
275268
}
276269

277-
private updateGroupActive(): void {
278-
this._renderDisposable?.update({
279-
params: { isGroupActive: this.group.api.isActive },
280-
});
270+
private updateProps(): void {
271+
this._renderDisposable?.update({ params: this.buildEnrichedProps() });
281272
}
282273
}
283274

0 commit comments

Comments
 (0)