Skip to content
Open
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
45 changes: 32 additions & 13 deletions src/components/DataBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,40 @@ export default defineComponent({
{ immediate: true }
);

watch(
[hasAnonymousImages, patients] as const,
([showAnonymous, patients_]) => {
const showPatients = patients_.length > 0;
if (showAnonymous) {
panels.value.push(ANONYMOUS_DATA_KEY);
}
if (showPatients) {
panels.value.push(...patients_.map((patient) => patient.key));
}
if (showAnonymous || showPatients) {
removeFromArray(panels.value, SAMPLE_DATA_KEY);
}
const openPanel = (key: string) => {
if (!panels.value.includes(key)) {
panels.value.push(key);
}
removeFromArray(panels.value, SAMPLE_DATA_KEY);
};

// Expand the panel of newly loaded data, also when the panel already
// exists but was collapsed.
const anonymousImageIDs = computed(() =>
imageStore.idList.filter((id) => isRegularImage(id))
);
watch(anonymousImageIDs, (ids, oldIds) => {
if (ids.some((id) => !oldIds.includes(id))) {
openPanel(ANONYMOUS_DATA_KEY);
}
});

const patientVolumes = computed(() =>
Object.fromEntries(
Object.entries(dicomStore.patientStudies).map(([patient, studies]) => [
patient,
studies.flatMap((study) => dicomStore.studyVolumes[study] ?? []),
])
)
);
watch(patientVolumes, (volumes, oldVolumes) => {
Object.entries(volumes).forEach(([patient, ids]) => {
const oldIds = oldVolumes[patient] ?? [];
if (ids.some((id) => !oldIds.includes(id))) {
openPanel(patient);
}
});
});

const deletePatient = (key: string) => {
dicomStore.patientStudies[key]
Expand Down
91 changes: 91 additions & 0 deletions src/components/__tests__/DataBrowser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { createPinia, setActivePinia } from 'pinia';
import { nextTick } from 'vue';
import { enableAutoUnmount, shallowMount } from '@vue/test-utils';
import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';

import DataBrowser from '@/src/components/DataBrowser.vue';
import { useDICOMStore } from '@/src/store/datasets-dicom';
import { useImageStore } from '@/src/store/datasets-images';

enableAutoUnmount(afterEach);

const mountPanels = () => {
const wrapper = shallowMount(DataBrowser);
const panels = wrapper.findComponent({ name: 'VExpansionPanels' });
return {
open: () => panels.props('modelValue'),
collapse: async () => {
panels.vm.$emit('update:modelValue', []);
await nextTick();
},
};
};

describe('DataBrowser panels', () => {
beforeEach(() => {
setActivePinia(createPinia());
});

it('reopens Anonymous for a new image, without duplicate keys or reopening on deletion', async () => {
const panels = mountPanels();
const images = useImageStore();
const addImage = (id: string) =>
images.addVTKImageData(id, vtkImageData.newInstance(), { id });

addImage('first');
await nextTick();
expect(panels.open()).toEqual(['anonymousData']);
await panels.collapse();

addImage('second');
await nextTick();
expect(panels.open()).toEqual(['anonymousData']);
addImage('third');
await nextTick();
expect(panels.open()).toEqual(['anonymousData']);

await panels.collapse();
images.deleteData('first');
await nextTick();
expect(panels.open()).toEqual([]);
});

it.each(['new study', 'existing study'])(
'reopens only the patient receiving a volume in a %s',
async (target) => {
const dicom = useDICOMStore();
const panels = mountPanels();
for (const patient of ['patient', 'other']) {
dicom.patientInfo[patient] = {
PatientID: patient,
PatientName: patient,
PatientBirthDate: '',
PatientSex: '',
};
dicom.patientStudies[patient] = [patient];
dicom.studyVolumes[patient] = [`${patient}-volume`];
}
await nextTick();
expect([...panels.open()].sort()).toEqual(['other', 'patient']);
await panels.collapse();

const study = target === 'new study' ? 'study-2' : 'patient';
if (target === 'new study') {
dicom.patientStudies.patient.push(study);
dicom.studyVolumes[study] = [];
}
dicom.studyVolumes[study].push('volume-2');
await nextTick();
expect(panels.open()).toEqual(['patient']);

dicom.studyVolumes[study].push('volume-3');
await nextTick();
expect(panels.open()).toEqual(['patient']);
await panels.collapse();
dicom.studyVolumes[study].pop();
await nextTick();
expect(panels.open()).toEqual([]);
}
);
});
5 changes: 4 additions & 1 deletion tests/specs/pet-ct-sample.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ async function reopenSample(
await browser.saveScreenshot(path.join(TEMP_DIR, 'pet-ct-sample-reload.png'));
await sample.waitForClickable();
await sample.click();
await sample.$('.mdi-check').waitForExist();
await expect(
$('.volume-card[html-title="PET WB Corrected"]')
).toBeDisplayed();
await waitForModuleTransitions();
await volViewPage.waitForViewCounts(1, false);
await volViewPage.renderingModuleTab.click();
await expect($$('h4*=PET WB Corrected')).toBeElementsArrayOfSize(1);
Expand Down
Loading