From 1de1963fd32c761daabfe7726f4683c34ffbb162 Mon Sep 17 00:00:00 2001 From: Salim Kanoun Date: Tue, 10 Dec 2024 13:36:15 +0000 Subject: [PATCH] update --- src/autorouting/AutoRoutingRoot.tsx | 274 +++++++++++++++++----------- src/autorouting/types.ts | 101 ++++++++++ src/ui/SelectInput.tsx | 49 +++-- 3 files changed, 302 insertions(+), 122 deletions(-) create mode 100644 src/autorouting/types.ts diff --git a/src/autorouting/AutoRoutingRoot.tsx b/src/autorouting/AutoRoutingRoot.tsx index 350172b..fec0456 100644 --- a/src/autorouting/AutoRoutingRoot.tsx +++ b/src/autorouting/AutoRoutingRoot.tsx @@ -1,118 +1,184 @@ -import React, { useState, ChangeEvent } from 'react'; -import { Input, SelectInput } from "../ui"; +import React, { useState, ChangeEvent } from "react"; +import { Input, SelectInput, Label } from "../ui"; +import { AutoroutingEventType, AutoRoutingRule, Destination, RuleCondition } from "./types"; const AutoRoutingRoot = () => { - const [name, setName] = useState(''); - const [eventType, setEventType] = useState([]); - const [isActivated, setIsActivated] = useState(false); - const [condition, setCondition] = useState('AND'); - const [rule, setRule] = useState('value1'); - const [destination, setDestination] = useState('value1'); + const [name, setName] = useState(""); + const [eventType, setEventType] = useState(null); + const [isActivated, setIsActivated] = useState(false); + const [condition, setCondition] = useState(RuleCondition.AND); + const [rules, setRules] = useState("value1"); + const [destinations, setDestinations] = useState("value1"); - const eventTypeOptions = [ - { label: 'NewInstance', value: 'NewInstance' }, - { label: 'NewSerie', value: 'NewSerie' }, - { label: 'NewStudies', value: 'NewStudies' }, - { label: 'NewPatient', value: 'NewPatient' } - ]; + const eventTypeOptions = [ + { label: "New Instance", value: AutoroutingEventType.NEW_INSTANCE }, + { label: "New Series", value: AutoroutingEventType.NEW_SERIES }, + { label: "New Study", value: AutoroutingEventType.NEW_STUDY }, + { label: "New Patient", value: AutoroutingEventType.NEW_PATIENT }, + { label: "Stable Series", value: AutoroutingEventType.STABLE_SERIES }, + { label: "Stable Study", value: AutoroutingEventType.STABLE_STUDY }, + { label: "Stable Patient", value: AutoroutingEventType.STABLE_PATIENT } + ]; - const handleInputChange = (event: ChangeEvent) => { - setName(event.target.value); - }; + const handleInputChange = (event: ChangeEvent) => { + setName(event.target.value); + }; - const handleEventTypeChange = (selectedOptions: any) => { - setEventType(selectedOptions); - }; + const handleEventTypeChange = (selectedOptions: any) => { + setEventType(selectedOptions); + }; - const handleSwitchChange = () => { - setIsActivated(!isActivated); - }; + const handleSwitchChange = () => { + setIsActivated(!isActivated); + }; - const handleConditionChange = (event: ChangeEvent) => { - setCondition(event.target.value); - }; + const handleConditionChange = (event: ChangeEvent) => { + setCondition(event.target.value); + }; - const handleRuleChange = (event: ChangeEvent) => { - setRule(event.target.value); - }; + const handleRuleChange = (event: ChangeEvent) => { + setRules(event.target.value); + }; - const handleDestinationChange = (event: ChangeEvent) => { - setDestination(event.target.value); - }; + const handleDestinationChange = (event: ChangeEvent) => { + setDestinations(event.target.value); + }; - const handleAddClick = () => { - const selectedLabels = eventType.map(option => option.label).join(', '); - alert(`Name: ${name}, Event Type: ${selectedLabels}, Activated: ${isActivated}, Condition: ${condition}, Rule: ${rule}, Destination: ${destination}`); - }; - - return ( -
- - - - - - - - - - - - - -

- Hello, {name || 'world'}! Selected event type: {eventType.map(option => option.label).join(', ')}. Activated: {isActivated ? 'Yes' : 'No'}. Condition: {condition}. Rule: {rule}. Destination: {destination}. -

-
+ const handleAddClick = () => { + const selectedLabels = eventType.map((option) => option.label).join(", "); + alert( + `Name: ${name}, Event Type: ${selectedLabels}, Activated: ${isActivated}, Condition: ${condition}, Rule: ${rule}, Destination: ${destination}` ); + }; + + return ( +
+ +
+ ); }; export default AutoRoutingRoot; diff --git a/src/autorouting/types.ts b/src/autorouting/types.ts new file mode 100644 index 0000000..bac6e27 --- /dev/null +++ b/src/autorouting/types.ts @@ -0,0 +1,101 @@ +export enum AutoroutingEventType { + NEW_INSTANCE = 'NewInstance', + NEW_SERIES = 'NewSeries', + NEW_STUDY = 'NewStudy', + NEW_PATIENT = 'NewPatient', + STABLE_SERIES = 'StableSeries', + STABLE_STUDY = 'StableStudy', + STABLE_PATIENT = 'StablePatient', + } + + export enum RuleCondition { + AND = 'AND', + OR = 'OR', + } + + export enum Condition { + EQUALS = 'EQUALS', + DIFFERENT = 'DIFFERENT', + IN = 'IN', // in array + NOT_IN = 'NOT_IN', // not in array + LESS_THAN = 'LESS_THAN', + GREATER_THAN = 'GREATER_THAN', + } + + export enum DestinationType { + AET = 'AET', + TMTVJOB = 'TMTVJob', + PEER = 'Peer', + } + + export enum ValueRepresentation { + STRING = 'string', + NUMBER = 'number', + DATE = 'date', + } + + export enum DicomTag { + PATIENT_NAME = 'PatientName', + PATIENT_ID = 'PatientID', + PATIENT_BIRTHDATE = 'PatientBirthDate', + PATIENT_SEX = 'PatientSex', + OTHER_PATIENT_IDS = 'OtherPatientIDs', + + STUDY_DATE = 'StudyDate', + STUDY_TIME = 'StudyTime', + STUDY_ID = 'StudyID', + STUDY_DESCRIPTION = 'StudyDescription', + ACCESSION_NUMBER = 'AccessionNumber', + STUDY_INSTANCE_UID = 'StudyInstanceUID', + REQUESTED_PROCEDURE_DESCRIPTION = 'RequestedProcedureDescription', + INSTITUTION_NAME = 'InstitutionName', + REQUESTING_PHYSICIAN = 'RequestingPhysician', + REFERRING_PHYSICIAN_NAME = 'ReferringPhysicianName', + + SERIES_DATE = 'SeriesDate', + SERIES_TIME = 'SeriesTime', + MODALITY = 'Modality', + MANUFACTURER = 'Manufacturer', + STATION_NAME = 'StationName', + SERIES_DESCRIPTION = 'SeriesDescription', + BODY_PART_EXAMINED = 'BodyPartExamined', + SEQUENCE_NAME = 'SequenceName', + PROTOCOL_NAME = 'ProtocolName', + SERIES_NUMBER = 'SeriesNumber', + CARDIAC_NUMBER_OF_IMAGES = 'CardiacNumberOfImages', + IMAGES_IN_ACQUISITION = 'ImagesInAcquisition', + NUMBER_OF_TEMPORAL_POSITIONS = 'NumberOfTemporalPositions', + NUMBER_OF_SLICES = 'NumberOfSlices', + NUMBER_OF_TIME_SLICES = 'NumberOfTimeSlices', + SERIES_INSTANCE_UID = 'SeriesInstanceUID', + IMAGE_ORIENTATION_PATIENT = 'ImageOrientationPatient', + SERIES_TYPE = 'SeriesType', + OPERATORS_NAME = 'OperatorsName', + PERFORMED_PROCEDURE_STEP_DESCRIPTION = 'PerformedProcedureStepDescription', + ACQUISITION_DEVICE_PROCESSING_DESCRIPTION = 'AcquisitionDeviceProcessingDescription', + CONTRAST_BOLUS_AGENT = 'ContrastBolusAgent', + + INSTANCE_CREATION_DATE = 'InstanceCreationDate', + INSTANCE_CREATION_TIME = 'InstanceCreationTime', + ACQUISITION_NUMBER = 'AcquisitionNumber', + IMAGE_INDEX = 'ImageIndex', + INSTANCE_NUMBER = 'InstanceNumber', + NUMBER_OF_FRAMES = 'NumberOfFrames', + TEMPORAL_POSITION_IDENTIFIER = 'TemporalPositionIdentifier', + SOP_INSTANCE_UID = 'SOPInstanceUID', + IMAGE_POSITION_PATIENT = 'ImagePositionPatient', + IMAGE_COMMENTS = 'ImageComments', + } + + export type AutoRoutingRule = { + DicomTag: DicomTag; + ValueRepresentation: ValueRepresentation; + Value: string | number; + Condition: Condition; + } + + + export type Destination { + Destination: DestinationType; + Name: string; + } \ No newline at end of file diff --git a/src/ui/SelectInput.tsx b/src/ui/SelectInput.tsx index 5a5742e..9c8257e 100644 --- a/src/ui/SelectInput.tsx +++ b/src/ui/SelectInput.tsx @@ -1,4 +1,4 @@ -import Select, { ActionMeta, StylesConfig } from 'react-select'; +import Select, { ActionMeta, StylesConfig } from "react-select"; interface OptionType { value: string; @@ -7,67 +7,80 @@ interface OptionType { interface SelectInputProps { isMulti?: boolean; + name?: string; value: string | string[] | null; options: OptionType[]; - onChange: (selectedOption: OptionType | OptionType[] | null, meta: ActionMeta) => void; + onChange: ( + selectedOption: OptionType | OptionType[] | null, + meta: ActionMeta + ) => void; placeholder?: string; rounded?: boolean; isClearable?: boolean; closeMenuOnSelect?: boolean; menuPosition?: "fixed" | undefined; formatOptionLabel?: (option: OptionType) => JSX.Element; - formatGroupLabel?: (group: { label: string; options: OptionType[] }) => JSX.Element; + formatGroupLabel?: (group: { + label: string; + options: OptionType[]; + }) => JSX.Element; } // Styles personnalisés pour React-Select const customStyles: StylesConfig = { placeholder: (base) => ({ ...base, - color: 'white', // Placeholder en blanc + color: "white", // Placeholder en blanc }), input: (base) => ({ ...base, - color: 'white', // Texte saisi en blanc + color: "white", // Texte saisi en blanc }), singleValue: (base) => ({ ...base, - color: 'white', // Valeur sélectionnée en blanc + color: "white", // Valeur sélectionnée en blanc }), }; const customClass: ClassNamesConfig = { control: (state) => { - const borderRadius = state.selectProps.rounded ? 'rounded-3xl' : 'rounded-xl'; + const borderRadius = state.selectProps.rounded + ? "rounded-3xl" + : "rounded-xl"; return `border border-gray-300 min-h-[40px] bg-gray-50 dark:bg-neutral-800 ${borderRadius} focus:border-active hover:border-primary-active px-2`; }, - menu: () => 'rounded-3xl p-1 bg-white dark:bg-neutral-800', + menu: () => "rounded-3xl p-1 bg-white dark:bg-neutral-800", option: (state) => { - return `rounded-xl p-2 ${state.isSelected ? 'bg-primary-active text-white' : 'bg-white dark:bg-neutral-800 text-gray-800 dark:text-white'} hover:bg-primary hover:text-white px-2`; + return `rounded-xl p-2 ${state.isSelected ? "bg-primary-active text-white" : "bg-white dark:bg-neutral-800 text-gray-800 dark:text-white"} hover:bg-primary hover:text-white px-2`; }, - multiValue: () => 'bg-gray-200 dark:bg-neutral-800 rounded-3xl px-2 py-0.5', - multiValueLabel: () => 'text-gray-800', - multiValueRemove: () => 'text-red-500 hover:bg-red-200 rounded-full p-0.5', + multiValue: () => "bg-gray-200 dark:bg-neutral-800 rounded-3xl px-2 py-0.5", + multiValueLabel: () => "text-gray-800", + multiValueRemove: () => "text-red-500 hover:bg-red-200 rounded-full p-0.5", }; const SelectInput = ({ value, + name, isMulti = false, options, onChange, - placeholder = 'Select...', + placeholder = "Select...", rounded = true, isClearable = false, closeMenuOnSelect = true, menuPosition = undefined, formatOptionLabel, - formatGroupLabel + formatGroupLabel, }: SelectInputProps) => { - const selectedValue = isMulti - ? (value as string[]).map(val => options.find(option => option.value === val)).filter(Boolean) - : options.find(option => option.value === value) || null; + const selectedValue = isMulti + ? (value as string[]) + .map((val) => options.find((option) => option.value === val)) + .filter(Boolean) + : options.find((option) => option.value === value) || null; return (