diff --git a/src/store/tools/__tests__/placementOrder.spec.ts b/src/store/tools/__tests__/placementOrder.spec.ts new file mode 100644 index 000000000..6a2d849e6 --- /dev/null +++ b/src/store/tools/__tests__/placementOrder.spec.ts @@ -0,0 +1,44 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { setActivePinia, createPinia } from 'pinia'; +import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData'; + +import { useImageCacheStore } from '@/src/store/image-cache'; +import { useRulerStore } from '@/src/store/tools/rulers'; +import { useRectangleStore } from '@/src/store/tools/rectangles'; +import { usePolygonStore } from '@/src/store/tools/polygons'; +import { useViewStore } from '@/src/store/views'; + +const IMAGE_ID = 'img-1'; + +describe.each([ + ['ruler', useRulerStore], + ['rectangle', useRectangleStore], + ['polygon', usePolygonStore], +] as const)('%s placement order', (_name, useStore) => { + beforeEach(() => { + setActivePinia(createPinia()); + useImageCacheStore().addVTKImageData(vtkImageData.newInstance(), 'CT', { + id: IMAGE_ID, + }); + useViewStore().setDataForAllViews(IMAGE_ID); + }); + + it('lists and saves finished tools in placement order, excluding unfinished tools', () => { + const store = useStore(); + const existing = store.addTool({ imageID: IMAGE_ID }); + // each view creates its placing tool up front + const lowerLeft = store.addTool({ imageID: IMAGE_ID, placing: true }); + const upperLeft = store.addTool({ imageID: IMAGE_ID, placing: true }); + + store.addTool({ imageID: IMAGE_ID, placing: true }); + + store.placeTool(upperLeft); + store.placeTool(lowerLeft); + + const expected = [existing, upperLeft, lowerLeft]; + expect(store.finishedTools.map((tool) => tool.id)).toEqual(expected); + expect(store.serializeTools().tools.map((tool) => tool.id)).toEqual( + expected + ); + }); +}); diff --git a/src/store/tools/useAnnotationTool.ts b/src/store/tools/useAnnotationTool.ts index 0ee6b50b4..ed31f040d 100644 --- a/src/store/tools/useAnnotationTool.ts +++ b/src/store/tools/useAnnotationTool.ts @@ -145,6 +145,12 @@ export const useAnnotationTool = < function placeTool(id: ToolID) { resolveToolSegment(id); updateTool(id, { placing: false } as ToolPatch); + // Placing tools are created ahead of time per view, so their IDs are not in + // the order they get placed. Move the placed tool last so lists follow it. + if (id in toolByID.value) { + removeFromArray(toolIDs.value, id); + toolIDs.value.push(id); + } } // Delete-base cleanup: a removed image's tools