Skip to content

Commit

Permalink
resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
sabrine33 committed Jan 30, 2025
2 parents dd7b0ca + 800c858 commit f1a2683
Show file tree
Hide file tree
Showing 15 changed files with 1,163 additions and 471 deletions.
497 changes: 242 additions & 255 deletions cypress/e2e/pages/cytAssist.cy.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions cypress/e2e/pages/sectioningPlanning.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe('Sectioning Planning', () => {
cy.findByText('A1').click();
cy.findByText('Done').click();
});
cy.findByLabelText('Section Thickness').type('5');
cy.findByTestId('section-thickness-A1').type('5');
});

after(() => {
Expand Down Expand Up @@ -266,7 +266,7 @@ function createLabware() {
cy.findByText('A1').click();
cy.findByText('Done').click();
});
cy.findByLabelText('Section Thickness').clear().type('5');
cy.findByTestId('section-thickness-A1').clear().type('5');
cy.findByText('Create Labware').click();
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@types/lodash": "^4.17.13",
"@types/node": "^20.17.6",
"@types/papaparse": "^5.3.14",
"@types/react": "^18.3.12",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3",
Expand Down
43 changes: 39 additions & 4 deletions src/components/labware/Labware.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useImperativeHandle, useMemo } from 'rea
import classNames from 'classnames';
import BarcodeIcon from '../icons/BarcodeIcon';
import { Slot } from './Slot';
import { buildAddresses, GridDirection, isSameArray, Position } from '../../lib/helpers';
import { buildAddresses, GridDirection, isSameArray, LabwareDirection, Position } from '../../lib/helpers';
import _ from 'lodash';
import { LabwareFlaggedFieldsFragment, SlotFieldsFragment } from '../../types/sdk';
import createLabwareMachine from './labware.machine';
Expand Down Expand Up @@ -108,6 +108,12 @@ export interface LabwareProps {

labwareRef?: React.RefObject<LabwareImperativeRef>;

/**
* A callback used to manage references to individual labware elements.
* This is useful for dynamically tracking labware elements in a collection.
*/
labwareRefCallback?: (el: LabwareImperativeRef) => void;

/**
* A callback that will be called for each slot in the labware. Must return a react component that will be placed
* in the labelled slot beside the component
Expand All @@ -123,7 +129,24 @@ export interface LabwareProps {

barcodeInfoPosition?: Position;

/**
* Specifies the grid direction used to determine the positioning of wells inside the labware.
*/
gridDirection?: GridDirection;

/**
* Callback to highlight slots due to an external action
* without requiring direct selection or clicking on the slot.
* This is useful when existing actions are already hooked to
* the `onSelect` and `onClick` events.
* @param addresses The addresses of the slots to highlight.
*/
highlightedSlots?: Set<string>;

/**
* Specifies the orientation of the labware layout. Defaults to vertical.
*/
labwareDirection?: LabwareDirection;
}

export type LabwareImperativeRef = {
Expand Down Expand Up @@ -156,7 +179,10 @@ const Labware = ({
slotBuilder,
cleanedOutAddresses,
barcodeInfoPosition,
gridDirection
gridDirection,
highlightedSlots,
labwareDirection,
labwareRefCallback
}: React.PropsWithChildren<LabwareProps>) => {
const labwareMachine = React.useMemo(() => {
return createLabwareMachine();
Expand Down Expand Up @@ -186,6 +212,9 @@ const Labware = ({
useImperativeHandle(labwareRef, () => ({
deselectAll: () => send({ type: 'RESET_SELECTED' })
}));
useImperativeHandle(labwareRefCallback, () => ({
deselectAll: () => send({ type: 'RESET_SELECTED' })
}));

useEffect(() => {
send({
Expand Down Expand Up @@ -215,13 +244,19 @@ const Labware = ({
const labwareClasses =
'inline-block border border-sdb py-2 bg-blue-100 rounded-lg transition duration-300 ease-in-out';

const grid =
labwareDirection && labwareDirection === LabwareDirection.Horizontal
? `grid grid-cols-${numRows} grid-rows-${numColumns}`
: `grid grid-rows-${numRows} grid-cols-${numColumns}`;

const gridClasses = classNames(
{
'px-12 gap-4': numColumns <= 3,
'px-10 gap-3': numColumns <= 5,
'px-6 gap-2': numColumns > 6
},
`grid grid-rows-${numRows} grid-cols-${numColumns} py-4 select-none`

`${grid} py-4 select-none`
);

// Give slots some default styles if some haven't been passed in
Expand Down Expand Up @@ -342,7 +377,7 @@ const Labware = ({
text={slotText}
secondaryText={slotSecondaryText}
color={_slotColor}
selected={selectedAddresses?.has(address)}
selected={selectedAddresses?.has(address) || (highlightedSlots?.has(address) ?? false)}
isCleanedOut={cleanedOutAddresses?.includes(address)}
/>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export default function BlockProcessing({ processingInfo }: BlockProcessingParam
/** Display created Labware plans**/
const buildPlanLayouts = React.useCallback(
(
plans: Map<string, NewFlaggedLabwareLayout>,
plans: Map<string, { labware: NewFlaggedLabwareLayout; sectionThickness?: number }>,
sourceLabware: LabwareFlaggedFieldsFragment[],
sampleColors: Map<number, string>,
deleteAction: (cid: string) => void,
Expand All @@ -135,7 +135,7 @@ export default function BlockProcessing({ processingInfo }: BlockProcessingParam
const planWithKeys: PlanWithId[] = Array.from(plans.keys()).map((k) => {
return {
cid: k,
plan: plans.get(k)
plan: plans.get(k)?.labware
};
});
const layoutPlanGroupedByType: Dictionary<PlanWithId[]> = groupBy(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export default function PotProcessing({ processingInfo }: PotProcessingParams) {
*/
const buildPlanLayouts = React.useCallback(
(
plans: Map<string, NewFlaggedLabwareLayout>,
plans: Map<string, { labware: NewFlaggedLabwareLayout }>,
sourceLabware: LabwareFlaggedFieldsFragment[],
sampleColors: Map<number, string>,
deleteAction: (cid: string) => void,
Expand All @@ -112,7 +112,7 @@ export default function PotProcessing({ processingInfo }: PotProcessingParams) {
const planWithKeys: PlanWithId[] = Array.from(plans.keys()).map((k) => {
return {
cid: k,
plan: plans.get(k)
plan: plans.get(k)?.labware
};
});
const layoutPlanGroupedByType: Dictionary<PlanWithId[]> = groupBy(
Expand Down
77 changes: 56 additions & 21 deletions src/components/planning/LabwarePlan.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import labwareScanTableColumns from '../dataTableColumns/labwareColumns';
import PinkButton from '../buttons/PinkButton';
import { useMachine } from '@xstate/react';
Expand All @@ -19,7 +19,6 @@ import {
LabwareFieldsFragment,
LabwareFlaggedFieldsFragment,
LabwareType,
LabwareTypeFieldsFragment,
PlanMutation,
SlideCosting
} from '../../types/sdk';
Expand All @@ -34,6 +33,7 @@ import ScanInput from '../scanInput/ScanInput';
import FormikSelect from '../forms/Select';
import { objectKeys, Position } from '../../lib/helpers';
import { FormikErrorMessage } from '../forms';
import Table, { TableBody, TableHead, TableHeader } from '../Table';

type LabwarePlanProps = {
/**
Expand Down Expand Up @@ -121,6 +121,8 @@ const LabwarePlan = React.forwardRef<HTMLDivElement, LabwarePlanProps>(

const columns = [labwareScanTableColumns.barcode(), printColumn];

const [highlightedSlots, setHighlightedSlots] = useState(new Set<string>());

const isLabwareWithCosting =
outputLabware.labwareType.name === LabwareTypeName.VISIUM_TO ||
outputLabware.labwareType.name === LabwareTypeName.VISIUM_ADH ||
Expand All @@ -135,7 +137,7 @@ const LabwarePlan = React.forwardRef<HTMLDivElement, LabwarePlanProps>(
className="relative p-3 shadow"
>
<Formik<FormValues>
initialValues={buildInitialValues(operationType, outputLabware.labwareType, sectionThickness)}
initialValues={buildInitialValues(operationType, outputLabware, sectionThickness)}
validationSchema={buildValidationSchema(outputLabware.labwareType)}
onSubmit={async (values) => {
const newValues = {
Expand All @@ -161,6 +163,7 @@ const LabwarePlan = React.forwardRef<HTMLDivElement, LabwarePlanProps>(
slotSecondaryText={(address) => buildSlotSecondaryText(layoutPlan, address)}
slotColor={(address) => buildSlotColor(layoutPlan, address)}
barcodeInfoPosition={Position.TopRight}
highlightedSlots={highlightedSlots}
/>

{current.matches('prep') && (
Expand Down Expand Up @@ -192,16 +195,6 @@ const LabwarePlan = React.forwardRef<HTMLDivElement, LabwarePlanProps>(
/>
)}

{outputLabware.labwareType.name !== LabwareTypeName.FETAL_WASTE_CONTAINER && (
<FormikInput
disabled={current.matches('printing') || current.matches('done')}
label={'Section Thickness'}
name={'sectionThickness'}
type={'number'}
min={0.5}
step={0.5}
/>
)}
{(outputLabware.labwareType.name === LabwareTypeName.VISIUM_LP ||
outputLabware.labwareType.name === LabwareTypeName.VISIUM_TO ||
outputLabware.labwareType.name === LabwareTypeName.VISIUM_ADH ||
Expand All @@ -228,6 +221,42 @@ const LabwarePlan = React.forwardRef<HTMLDivElement, LabwarePlanProps>(
</FormikSelect>
</>
)}

{outputLabware.labwareType.name !== LabwareTypeName.FETAL_WASTE_CONTAINER && (
<Table>
<TableHead>
<tr>
<TableHeader>Slot</TableHeader>
<TableHeader>Section Thickness</TableHeader>
</tr>
</TableHead>
<TableBody>
{outputLabware.slots.map((slot, index) => (
<tr key={index}>
<td className="text-center">{slot.address}</td>
<td>
<FormikInput
className="text-center focus:ring-sdb-100 focus:border-sdb-100 block border-gray-300 rounded-md disabled:opacity-75 disabled:cursor-not-allowed"
label={''}
disabled={current.matches('printing') || current.matches('done')}
name={`sectionThickness[${slot.address}]`}
data-testid={`section-thickness-${slot.address}`}
type="number"
min={0.5}
step={0.5}
onFocus={() => {
setHighlightedSlots(new Set([slot.address]));
}}
onBlur={() => {
setHighlightedSlots(new Set());
}}
/>
</td>
</tr>
))}
</TableBody>
</Table>
)}
</div>

{plannedLabware.length > 0 && (
Expand Down Expand Up @@ -320,7 +349,7 @@ type FormValues = {
/**
* The thickness of the sections being taken, in micrometres
*/
sectionThickness?: number;
sectionThickness?: { [slotAddress: string]: number };

/**
* The Slide lot number (only for Visium slides)
Expand All @@ -337,14 +366,13 @@ type FormValues = {
*/
function buildInitialValues(
operationType: string,
labwareType: LabwareTypeFieldsFragment,
labwareLayout: NewFlaggedLabwareLayout,
sectionThickness: number
): FormValues {
let formValues: FormValues = {
operationType,
sectionThickness
operationType
};

const labwareType = labwareLayout.labwareType;
if (labwareType.name === LabwareTypeName.VISIUM_LP) {
formValues.barcode = '';
}
Expand All @@ -356,7 +384,10 @@ function buildInitialValues(
formValues.costing = undefined;
formValues.lotNumber = '';
}

formValues.sectionThickness = {};
labwareLayout.slots.forEach((slot) => {
formValues.sectionThickness![slot.address] = sectionThickness;
});
return formValues;
}

Expand All @@ -366,7 +397,7 @@ function buildInitialValues(
*/
function buildValidationSchema(labwareType: LabwareType): Yup.AnyObjectSchema {
type FormShape = {
sectionThickness?: Yup.NumberSchema;
sectionThickness?: Yup.ObjectSchema<any>;
barcode?: Yup.StringSchema;
lotNumber?: Yup.StringSchema;
costing?: Yup.StringSchema;
Expand All @@ -381,7 +412,11 @@ function buildValidationSchema(labwareType: LabwareType): Yup.AnyObjectSchema {
.matches(/^\d{7}$/, 'Xenium barcode should be a 7-digit number');
}
if (labwareType.name !== LabwareTypeName.FETAL_WASTE_CONTAINER) {
formShape.sectionThickness = Yup.number().required().min(0.5);
formShape.sectionThickness = Yup.object().test(
'has-at-least-one-key',
'Section thickness must have at least one entry',
(value) => value && Object.keys(value).length > 0
);
}
if (
labwareType.name === LabwareTypeName.VISIUM_LP ||
Expand Down
Loading

0 comments on commit f1a2683

Please sign in to comment.