Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions client/src/BaseAnnotationStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,7 @@ export default abstract class BaseAnnotationStore<T extends Track | Group> {

clearAll() {
this.annotationMap.clear();
this.intervalTree.items.forEach((item) => {
this.intervalTree.remove(item.key);
});
this.intervalTree.clear();
this.annotationIds.value = [];
}
}
14 changes: 14 additions & 0 deletions client/src/TrackStore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,17 @@ describe('TrackStore', () => {
called = false;
});
});

describe('TrackStore pipeline reload', () => {
it('clears every indexed detection before loading replacement results', () => {
const store = new TrackStore({ markChangesPending: () => null, cameraName: 'left' });
store.add(4, 'fish', undefined, 7);
store.add(4, 'fish', undefined, 8);
store.add(9, 'fish', undefined, 9);
store.clearAll();
expect(store.intervalTree.search([0, 20])).toEqual([]);
store.add(4, 'fish', undefined, 7);
expect(store.intervalTree.search([4, 4])).toEqual(['7']);
expect(store.intervalTree.search([9, 9])).toEqual([]);
});
});
49 changes: 43 additions & 6 deletions client/src/components/LayerManager.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable max-classes-per-file -- lightweight layer doubles */
import {
defineComponent, h, ref,
import Vue, {
defineComponent, h, ref, nextTick,
} from 'vue';
import type { Ref } from 'vue';
import { shallowMount } from '@vue/test-utils';
import Track, { Feature } from '../track';
import CameraStore from '../CameraStore';
Expand All @@ -12,6 +13,7 @@

const layerMocks = vi.hoisted(() => {
const rectangleChangeData = vi.fn();
const mountWidget = vi.fn();

class MockLayer {
bus = { $on: vi.fn() };
Expand Down Expand Up @@ -44,7 +46,7 @@

update = vi.fn();

addDOMWidget = vi.fn();
addDOMWidget = mountWidget;

setToolTipWidget = vi.fn();

Expand All @@ -55,7 +57,9 @@
changeData = rectangleChangeData;
}

return { MockLayer, MockRectangleLayer, rectangleChangeData };
return {
MockLayer, MockRectangleLayer, rectangleChangeData, mountWidget,
};
});

const provided = vi.hoisted(() => ({
Expand Down Expand Up @@ -135,7 +139,7 @@
* semantics for its own children.
*/
function mountLayerManager(props: Record<string, unknown> = {}) {
const Host = defineComponent({

Check warning on line 142 in client/src/components/LayerManager.spec.ts

View workflow job for this annotation

GitHub Actions / Client Tests (web)

There is more than one component in this file
setup: () => () => h(LayerManager, { props }),
});
return shallowMount(Host, { stubs: { LayerManager: false } });
Expand Down Expand Up @@ -316,9 +320,11 @@
pendingSaveCount: ref(0),
};
layerMocks.rectangleChangeData.mockClear();
mountLayerManager({ camera });
const wrapper = mountLayerManager({ camera });
const { calls } = layerMocks.rectangleChangeData.mock;
return calls[calls.length - 1][0] as { styleType: [string, number] }[];
const frameData = calls[calls.length - 1][0] as { styleType: [string, number] }[];
wrapper.destroy();
return frameData;
}

describe('LayerManager multicamera hierarchy selection', () => {
Expand Down Expand Up @@ -352,3 +358,34 @@
expect(renderCamera(cameraStore, trackFilters, 'right')).toHaveLength(0);
});
});

describe('LayerManager pipeline reload lifecycle', () => {
it('stops redraw watchers when the old viewer unmounts, including after mounting a tooltip', async () => {
// GeoJS tooltips mount their own Vue root. Exercise that real Vue lifecycle:
// mounting it during setup detaches subsequent watches from LayerManager.
const widgets: Vue[] = [];
layerMocks.mountWidget.mockImplementation(() => {
const Tooltip = defineComponent({ setup: () => () => h('span') });

Check warning on line 368 in client/src/components/LayerManager.spec.ts

View workflow job for this annotation

GitHub Actions / Client Tests (web)

There is more than one component in this file
widgets.push(new Vue({ render: (createElement) => createElement(Tooltip) }).$mount());
});
const { cameraStore, trackFilters } = makeMultiCamFixture([['fish', 1]], [['fish', 1]], {});
try {
renderCamera(cameraStore, trackFilters, 'left'); // mounts and destroys the old manager
const selectedKey = provided.values?.selectedKey as Ref<string>;
layerMocks.rectangleChangeData.mockClear();
selectedKey.value = '1';
await nextTick();
expect(layerMocks.rectangleChangeData).not.toHaveBeenCalled();

const replacement = mountLayerManager({ camera: 'left' });
layerMocks.rectangleChangeData.mockClear();
selectedKey.value = '';
await nextTick();
expect(layerMocks.rectangleChangeData).toHaveBeenCalledTimes(1);
replacement.destroy();
} finally {
widgets.forEach((widget) => widget.$destroy());
layerMocks.mountWidget.mockReset();
}
});
});
9 changes: 7 additions & 2 deletions client/src/components/LayerManager.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import {
defineComponent, watch, PropType, Ref, ref, computed, toRef,
defineComponent, watch, PropType, Ref, ref, computed, toRef, onMounted,
} from 'vue';

import { clientSettings } from 'dive-common/store/settings';
Expand Down Expand Up @@ -319,7 +319,12 @@ export default defineComponent({
selected: selectedTrackIdRef,
stateStyling: trackStyleManager.stateStyles,
};
uiLayer.addDOMWidget('customToolTip', ToolTipWidget, toolTipWidgetProps, { x: 10, y: 10 });
// Mounting the tooltip's separate Vue root during setup clears Vue's
// current component scope. Later watches then survive a dataset reload
// and redraw the old, destroyed map. Finish setup before mounting it.
onMounted(() => {
uiLayer.addDOMWidget('customToolTip', ToolTipWidget, toolTipWidgetProps, { x: 10, y: 10 });
});

useSegmentationPointsLayer({
camera: props.camera,
Expand Down
Loading