From 2f04a6032a2e4159df31a07b5bdb133d1dedc702 Mon Sep 17 00:00:00 2001 From: Nafiz Islam Date: Mon, 19 Aug 2024 17:06:40 -0400 Subject: [PATCH] Fix placement ordering (#829) --- .../PlacementSamplesTable.tsx | 21 ++++++++----------- frontend/src/utils/functions.ts | 20 ++++++++++-------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/placementVisuals/PlacementSamplesTable.tsx b/frontend/src/components/placementVisuals/PlacementSamplesTable.tsx index 7193d19cf..1cb31a301 100644 --- a/frontend/src/components/placementVisuals/PlacementSamplesTable.tsx +++ b/frontend/src/components/placementVisuals/PlacementSamplesTable.tsx @@ -21,9 +21,8 @@ interface PlacementSample { selected: boolean name: string projectName: string - parentContainerName: string | null + parentContainerName: string coordinates: string | undefined - placed: boolean } //component used to display and select samples in a table format for plate visualization placement @@ -43,12 +42,14 @@ const PlacementSamplesTable = ({ container: containerName, showContainerColumn } const samples = container ? container.cells.reduce( (samples, cell) => { - if (!cell) return samples + // don't show cells that are not loaded or already placed + if (!cell || cell.placedAt) return samples let sample = cell.sample let project = cell.projectName let originalContainer = cell.parentContainerName + // if the cell is a destination, show the source sample if (isDestination && cell.placedFrom) { const otherCell = selectCell(store.getState())(cell.placedFrom) if (!otherCell) { @@ -60,8 +61,10 @@ const PlacementSamplesTable = ({ container: containerName, showContainerColumn } originalContainer = otherCell.parentContainerName } + // if the cell has no sample, don't show it if (!sample) return samples + // if the sample is not loaded, fetch it and later show it if (!samplesByID[sample]) { missingSamples.push(sample) return samples @@ -73,9 +76,8 @@ const PlacementSamplesTable = ({ container: containerName, showContainerColumn } selected: cell.selected, name, projectName: project, - parentContainerName: originalContainer, + parentContainerName: originalContainer ?? 'Tubes without parent', coordinates: cell.coordinates, - placed: cell.placedAt !== null }) return samples }, []) @@ -122,6 +124,7 @@ const PlacementSamplesTable = ({ container: containerName, showContainerColumn } onChange, onSelect, getCheckboxProps: (sample) => ({ + // disable checkbox if the sample is already placed in the destination container disabled: isDestination && sample.parentContainerName === containerName }) }), [selectedRowKeys, onChange, onSelect, isDestination, containerName]) @@ -175,13 +178,7 @@ const PlacementSamplesTable = ({ container: containerName, showContainerColumn } return ( - dataSource={samples.filter(sample => !sample.placed).map( - (sample) => - ({ - ...sample, - parentContainerName: sample.parentContainerName ?? 'Tubes without parent' - }) - )} + dataSource={samples} columns={columns} rowKey={obj => obj.id} rowSelection={selectionProps} diff --git a/frontend/src/utils/functions.ts b/frontend/src/utils/functions.ts index a2ae69e62..89b2ab2db 100644 --- a/frontend/src/utils/functions.ts +++ b/frontend/src/utils/functions.ts @@ -50,38 +50,40 @@ export function offsetsToCoordinates(offsets: readonly number[], spec: Coordinat } export function compareArray(a: readonly number[], b: readonly number[]): number { - if (a.length > b.length) return 1 - if (a.length < b.length) return -1 - for (let i = 0; i < a.length; i++) { + for (let i = 0; i < a.length && i < b.length; i++) { if (a[i] < b[i]) return -1 if (a[i] > b[i]) return 1 } + if (a.length < b.length) return -1 + if (a.length > b.length) return 1 return 0 } -export function comparePlacementSamples>(a: S, b: S, spec?: CoordinateSpec): number { +export function comparePlacementSamples< + S extends Pick +>(a: S, b: S, spec?: CoordinateSpec): number { const MAX = 128 let orderA = MAX let orderB = MAX if (a.selected) orderA -= MAX/2 - else if (b.selected) orderB -= MAX/2 + if (b.selected) orderB -= MAX/2 if (spec && a.coordinates && b.coordinates) { // if both have coordinates, both have a parent container const aOffsets = coordinatesToOffsets(spec, a.coordinates) const bOffsets = coordinatesToOffsets(spec, b.coordinates) const arrayComparison = compareArray(aOffsets.reverse(), bOffsets.reverse()) + if (arrayComparison < 0) orderA -= MAX/4 if (arrayComparison > 0) orderB -= MAX/4 - else if (arrayComparison < 0) orderA -= MAX/4 } + if (a.name < b.name) orderA -= MAX/8 if (a.name > b.name) orderB -= MAX/8 - else if (a.name < b.name) orderA -= MAX/8 - if (a.projectName > b.projectName) orderB -= MAX/32 - else if (a.projectName < b.projectName) orderA -= MAX/32 + if (a.projectName < b.projectName) orderA -= MAX/16 + if (a.projectName > b.projectName) orderB -= MAX/16 return orderA - orderB