Skip to content

Commit

Permalink
Merge pull request #343 from Pixilib/editTable
Browse files Browse the repository at this point in the history
Edit table
  • Loading branch information
salimkanoun authored Oct 16, 2024
2 parents 573e1cc + 604b447 commit fbbeea5
Show file tree
Hide file tree
Showing 36 changed files with 672 additions and 307 deletions.
4 changes: 3 additions & 1 deletion src/admin/general/OrthancCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ const OrthancSettingsCard = ({ orthancData }: OrthancCardProps) => {
)}
</Modal.Body>
<Modal.Footer>
<Button color={Colors.primary} onClick={() => setShowModal(false)}>
<Button
color={Colors.primary}
onClick={() => setShowModal(false)}>
Close
</Button>
</Modal.Footer>
Expand Down
47 changes: 47 additions & 0 deletions src/anonymize/AnonQueues.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useSelector } from "react-redux";
import { deleteAnonymizeQueue, getAnonymizeQueue, getExistingAnonymizeQueues } from "../services/queues";
import { useCustomMutation, useCustomQuery } from "../utils";
import { RootState } from "../store";
import { Spinner } from "../ui";
import ProgressQueueBar from "../queue/ProgressQueueBar";
import { Queue } from "../utils/types";

const AnonQueues = () => {
const currentUserId = useSelector((state: RootState) => state.user.currentUserId);

const { data: existingAnonymizeQueues } = useCustomQuery<string[]>(
['queue', 'anon', currentUserId?.toString() || ''],
() => getExistingAnonymizeQueues(currentUserId)
);

const firstQueue = existingAnonymizeQueues?.[0]

const { data, isPending , isLoading} = useCustomQuery<Queue>(
['queue', 'anon', firstQueue],
() => getAnonymizeQueue(firstQueue),
{ refetchInterval: 2000,
enabled : existingAnonymizeQueues?.length > 0 }
);

const { mutate: mutateDeleteQueue } = useCustomMutation(
() => deleteAnonymizeQueue(firstQueue),
[['queue', 'anon']]
);

if (existingAnonymizeQueues?.length > 0 && isPending) return <Spinner />;

return (
<div className="w-full space-y-4">
{existingAnonymizeQueues?.map((uuid) => (
<div
key={uuid}
className="p-4 bg-white border border-gray-100 shadow-inner rounded-xl"
>
<ProgressQueueBar queueData={data} onDelete={mutateDeleteQueue} />
</div>
))}
</div>
);
};

export default AnonQueues;
206 changes: 160 additions & 46 deletions src/anonymize/AnonymizeRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,200 @@
import { useDispatch, useSelector } from "react-redux";
import { Card, CardHeader, CardBody, CardFooter, Button } from "../ui";
import { Colors } from "../utils";
import { Card, CardHeader, CardBody, CardFooter, Button, SelectInput, Input, CheckBox } from "../ui";
import { Colors, useCustomMutation } from "../utils";
import PatientTable from "./PatientTable";
import StudyTable from "./StudyTable";
import { RootState } from "../store";
import { useMemo, useState } from "react";
import { flushAnonymizeList, removeStudyFromAnonymizeList, updateAnonymizePatientValue, updateAnonymizeStudyValue } from "../reducers/AnonymizeSlice";
import { Empty } from "../icons";
import { Patient } from "../utils/types";
import {
flushAnonymizeList,
removeStudyFromAnonymizeList,
updateAnonymizationProfile,
updateAnonymizePatientValue,
updateAnonymizeStudyValue,
} from "../reducers/AnonymizeSlice";
import { Anon, Empty } from "../icons";
import AutoFill from "../icons/AutofIll";
import { AnonItem } from "../utils/types";
import { createAnonymizeQueue } from "../services/queues";
import AnonQueues from "./AnonQueues";
import DropdownButton from "../ui/menu/DropDownButton";

const profileOptions = [
{ value: "Default", label: "Default" },
{ value: "Full", label: "Full" },
];

const AnonymizeRoot = () => {
const dispatch = useDispatch();
const anonList = useSelector((state: RootState) => state.anonymize);
const [selectedPatientId, setSelectedPatientId] = useState<string | null>(null)
const [selectedPatientId, setSelectedPatientId] = useState<string | null>(
null
);

const patients = useMemo(() => {
return Object.values(anonList.patients);
}, [anonList]);
const [anonJobId, setAnonJobId] = useState<string | null>(null);

const { mutate: mutateCreateAnonymizeQueue } = useCustomMutation(
({ anonItems }) => createAnonymizeQueue(anonItems),
[['queue', 'anon']],
{
onSuccess: (jobId) => {
setAnonJobId(jobId)
},
}
)

const patients = useMemo(() => Object.values(anonList.patients), [anonList]);

const studies = useMemo(() => {
if (!selectedPatientId) return []
return Object.values(anonList.studies).filter(study => study.originalStudy.parentPatient === selectedPatientId);
if (!selectedPatientId) return [];
return Object.values(anonList.studies).filter(
(study) => study.originalStudy.parentPatient === selectedPatientId
);
}, [anonList, selectedPatientId]);

const handlePatientSelect = (patient: Patient) => {
setSelectedPatientId(patient.id)
}
const handleRemovePatient = (patientId: string) => {
const studiesIds = studies
.filter((study) => study.originalStudy.parentPatient === patientId)
.map((study) => study.originalStudy.id);
for (const studyId of studiesIds) {
dispatch(removeStudyFromAnonymizeList({ studyId }));
}
};
const handleAutoFill = () => {
patients.forEach((patient) => {
dispatch(
updateAnonymizePatientValue({
patientId: patient.originalPatient.id,
newPatientName: `Patient_${patient.originalPatient.id}`,
newPatientId: `ID_${patient.originalPatient.id}`,
})
);
});

const handleRemoveStudy = (studyId: string) => {
dispatch(removeStudyFromAnonymizeList({ studyId }));
studies.forEach((study) => {
dispatch(
updateAnonymizeStudyValue({
studyId: study.originalStudy.id,
newStudyDescription: `Study_${study.originalStudy.id}`,
newAccessionNumber: `Acc_${study.originalStudy.id}`,
})
);
});
};

const handleChangeStudy = (studyId: string, key: string, newStudyDescription: string) => {
console.log(studyId, key, newStudyDescription)
dispatch(updateAnonymizeStudyValue({ newStudyDescription, studyId }));
};
const onChangeStudy = (studyId, key, value) => {
dispatch(
updateAnonymizeStudyValue({ studyId, [key]: value })
)
}

const handleChangePatient = (patientId: string, key: string, value: string) => {
dispatch(updateAnonymizePatientValue({ patientId, [key]: value }));
const onRemoveStudy = (studyId) => {
dispatch(removeStudyFromAnonymizeList({ studyId }))
}

const handleClearList = () => {
dispatch(flushAnonymizeList());
};
const onChangePatient = (patientId, key, value) => {
dispatch(
updateAnonymizePatientValue({ patientId, [key]: value })
)
}

const onRemovePatient = (patientId) => {
studies.filter((study) => study.originalStudy.parentPatient === patientId).
forEach((study) => {
console.log(study.originalStudy.id)
dispatch(
removeStudyFromAnonymizeList({ studyId: study.originalStudy.id })
)
}
)

}

const onChangeProfile = (option) => {
dispatch(updateAnonymizationProfile({ anonymizationProfile: option.value }))
}

const handleAnonymizeStart = () => {
const anonItems: AnonItem[] = Object.values(anonList.studies).map((study) => {
return {
OrthancStudyID: study.originalStudy.id,
Profile: anonList.anonymizationProfile,
NewPatientID: study.newPatientId,
NewPatientName: study.newPatientName,
NewStudyDescription: study.newStudyDescription,
NewAccessionNumber: study.newAccessionNumber
}

})
mutateCreateAnonymizeQueue({ anonItems })
}

return (
<Card>
<CardHeader
color={Colors.primary}
>
<CardHeader color={Colors.primary}>
<div className="flex items-center w-full">
<div className="w-4/5 text-lg font-bold text-center">Anonymize Ressources</div>
<div className="flex justify-end w-1/5 gap-3 p-3">
<div className="w-4/5 text-lg font-bold text-center">
Anonymize resources </div>
<div className="flex justify-end w-1/5 p-3">


<DropdownButton row={null}
options={[]} buttonText="Auto Fill"
className="">
<Input
type="text"
placeholder="Enter value"
className="w-full p-2 border"
/>
<CheckBox bordered={false}
/>
</DropdownButton>

<AutoFill className="text-xl text-primary group-hover:text-white" />
<Button
onClick={() => dispatch(flushAnonymizeList())}
color={Colors.light}
className="rounded-lg hover:bg-secondary group"
>
<Empty className="text-xl text-primary group-hover:text-white" />
</Button>
<Button
onClick={handleClearList}
onClick={handleAutoFill}
color={Colors.light}
className="rounded-lg hover:bg-secondary group">
<Empty
className="text-xl text-bol text-primary group-hover:text-white" />
className="rounded-lg hover:bg-secondary group"
>
<AutoFill className="text-xl text-primary group-hover:text-white" />
</Button>
</div>
</div>
</CardHeader>
<CardBody color={Colors.almond}>
<div className="flex flex-row w-full gap-4">
<div className="flex-1 overflow-auto">
<PatientTable patients={patients} onClickRow={handlePatientSelect} onCellEdit={handleChangePatient} onRemovePatient={handleRemovePatient} />
<div className="flex-1 overflow-auto break-words">
<PatientTable
patients={patients}
onClickRow={setSelectedPatientId}
onChangePatient={onChangePatient}
onRemovePatient={onRemovePatient}
/>
</div>
<div className="flex-1 overflow-auto">
<StudyTable studies={studies} onCellEdit={handleChangeStudy} onRemoveStudy={handleRemoveStudy} />
<StudyTable
studies={studies}
onChangeStudy={onChangeStudy}
onRemoveStudy={onRemoveStudy}
/>
</div>
</div>
</CardBody>
<CardFooter color={Colors.light} className="flex justify-center gap-3">
<CardFooter
color={Colors.light}
className="flex items-center gap-3">
<Button
className="flex items-center gap-2 "
color={Colors.blueCustom} onClick={handleAnonymizeStart}>
<Anon />
Anonymise
</Button>
<SelectInput
placeholder="Select an option"
value={anonList.anonymizationProfile}
options={profileOptions}
onChange={onChangeProfile}
/>
<AnonQueues />
</CardFooter>
</Card>
);
Expand Down
Loading

0 comments on commit fbbeea5

Please sign in to comment.