Skip to content

Commit

Permalink
dciom create enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
salimkanoun committed Sep 1, 2024
1 parent 9b679fc commit 6101e90
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 229 deletions.
30 changes: 10 additions & 20 deletions src/import/create/CreateDrop.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
import React, { useCallback, useState } from "react";
import React, { useCallback } from "react";
import { BsFillCloudArrowUpFill as CloudIcon, BsCheckCircleFill as CheckIcon } from 'react-icons/bs';
import { ProgressBar } from '../../ui';
import { useDropzone } from "react-dropzone";
import { useCustomToast } from "../../utils";

interface CreateDropProps {
files: File[],
onDrop: (files: File[]) => void;
}

const CreateDrop: React.FC<CreateDropProps> = ({ onDrop }) => {
const CreateDrop: React.FC<CreateDropProps> = ({ files, onDrop }) => {

const {toastError} = useCustomToast()
const [numberOfLoadedFiles, setNumberOfLoadedFiles] = useState(0);
const [numberOfProcessedFiles, setNumberOfProcessedFiles] = useState(0);

const uploadComplete = numberOfLoadedFiles > 0 && numberOfLoadedFiles === numberOfProcessedFiles;
const { toastError } = useCustomToast()

const { getRootProps, open } = useDropzone({
multiple: true,
onDrop: async (files : File[]) => {
onDrop: async (files: File[]) => {
if (files && files.length > 0) {
setNumberOfLoadedFiles(files.length);
setNumberOfProcessedFiles(files.length);
onDrop(files);
}
},
onDropRejected : (_fileRejection :any)=>{
onDropRejected: (_fileRejection: any) => {
toastError("File format rejected (accepts png, jpeg or pdf)")
},
accept: {
'image/png': [],
'image/jpeg': [],
'application/pdf' : []
}
'application/pdf': []
}
});

const handleDragOver = useCallback(
Expand All @@ -48,7 +42,7 @@ const CreateDrop: React.FC<CreateDropProps> = ({ onDrop }) => {
{...getRootProps({ onClick: open })}
onDragOver={handleDragOver}
>
{uploadComplete ? (
{files.length > 0 ? (
<CheckIcon
size={40}
className="text-success" />
Expand All @@ -57,12 +51,8 @@ const CreateDrop: React.FC<CreateDropProps> = ({ onDrop }) => {
size={40}
className={`text-primary`} />
)}
<p className="text-primary">{uploadComplete ? numberOfLoadedFiles + ' files loaded' : 'Drag and drop image files here'}</p>
<p className="text-primary">{files.length > 0 ? files.length + ' files loaded' : 'Drag and drop image files here'}</p>
<input type="file" style={{ display: 'none' }} />
{numberOfLoadedFiles > 0 && (
<ProgressBar
progression={Math.round((numberOfProcessedFiles / numberOfLoadedFiles) * 100)} />
)}
</div>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/import/create/CreateForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Colors } from "../../utils/enums";
interface TagFormProps {
title: string;
className?: string;
onAddTag: (tag: { TagName: string; Value: string }) => void;
onAddTag: (tag: { name: string; value: string }) => void;
}

const CreateForm = ({ title, className, onAddTag }: TagFormProps) => {
Expand All @@ -17,7 +17,7 @@ const CreateForm = ({ title, className, onAddTag }: TagFormProps) => {

const handleAddTag = () => {
if (tag && value) {
onAddTag({ TagName: tag, Value: value });
onAddTag({ name: tag, value: value });
setTag('');
setValue('');
}
Expand Down
98 changes: 39 additions & 59 deletions src/import/create/CreateRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,104 +1,84 @@
import React, { useState, useEffect, useRef } from 'react';
import React, { useState } from 'react';

import { Button } from '../../ui';
import Model from '../../model/Model';
import CreateTableSeries from './CreateTableSeries';
import CreateTableStudy from './CreateTableStudy';
import CreateForm from './CreateForm';
import CreateDrop from './CreateDrop';
import TagTable from './TagTable';
import { Colors } from '../../utils';
import { Colors, useCustomMutation, useCustomToast } from '../../utils';
import { createDicom } from '../../services/instances';

const CreateRoot: React.FC = () => {
const refModel = useRef<Model>(new Model());
const [currentStudyInstanceUID, setCurrentStudyInstanceUID] = useState<string | null>(null);
const [studiesData, setStudiesData] = useState<any[]>([]);
const [seriesData, setSeriesData] = useState<any[]>([]);
const [tags, setTags] = useState<{ TagName: string, Value: string }[]>([]);

const { toastError, toastSuccess } = useCustomToast()
const [tags, setTags] = useState<{ name: string, value: string }[]>([]);
const [files, setFiles] = useState<File[]>([])

const { mutate } = useCustomMutation(
({ content, tags }) => createDicom(content, tags),
[[]],
{
onSuccess: () => {
toastSuccess('Dicom series created')
},
onError: () => {
toastError('Unable to create series')
}
}
)

const handleFilesUploaded = () => setStudiesData(refModel.current.getStudies());

const handleStudyClick = (studyInstanceUID: string) => {
setCurrentStudyInstanceUID(studyInstanceUID);
updateSeriesData(studyInstanceUID);
const handleFilesUploaded = (files: File[]) => {
setFiles(files)
};

const updateSeriesData = (studyInstanceUID: string) => {
setSeriesData(refModel.current.getStudy(studyInstanceUID).getAllseries());
};

useEffect(() => {
if (currentStudyInstanceUID) {
updateSeriesData(currentStudyInstanceUID);
const handleCreateDicoms = async () => {
const content: string[] = []
for (const file of files) {
const dataURI = await readFileAsDataURL(file)
content.push(dataURI)
}
}, [currentStudyInstanceUID]);
const formattedtags = {}
tags.forEach(tag => formattedtags[tag.name] = tag.value);
mutate({ content: content, tags: formattedtags })
}

const handleAddTag = (tag: { TagName: string, Value: string }) => {
const handleAddTag = (tag: { name: string, value: string }) => {
setTags(prevTags => [...prevTags, tag]);
};

const handleTagUpdate = (tagName: string, columnId: string, value: string) => {
setTags(prevTags =>
prevTags.map(tag =>
tag.TagName === tagName ? { ...tag, [columnId]: value } : tag
)
);
};

const handleTagDelete = (tagName: string) => {
setTags(prevTags => prevTags.filter(tag => tag.TagName !== tagName));
const handleTagDelete = (name: string) => {
setTags(prevTags => prevTags.filter(tag => tag.name !== name));
};

const readFileAsDataURL = (file : File) => {
return new Promise((resolve) => {
const readFileAsDataURL = (file: File) => {
return new Promise<string>((resolve) => {
var reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
resolve(reader.result)
resolve(reader.result as string)
}
})
}

return (
<>


<div className="w-full space-y-3 md:flex md:space-x-3 p-6">
<CreateDrop onDrop={handleFilesUploaded} />

<div className="md:w-1/2 md:flex-1">
{studiesData.length > 0 && (
<CreateTableStudy
data={studiesData}
selectedStudyInstanceUID={currentStudyInstanceUID}
onStudyClick={handleStudyClick}
/>
)}
</div>
<div className="md:w-1/2 md:flex-1">
{seriesData.length > 0 && (
<CreateTableSeries data={seriesData} />
)}
</div>
<CreateDrop files={files} onDrop={handleFilesUploaded} />
</div>

<div className="flex flex-col justify-center border-indigo-100 shadow-inner p-3 bg-light">
<TagTable
data={tags}
onDataUpdate={handleTagUpdate}
onDeleteTag={handleTagDelete}
/>
<CreateForm
title="Define DICOM Tags"
onAddTag={handleAddTag}
/>


</div>
<div className="flex bg-white justify-center p-3">
<Button
color={tags.length > 0 ? Colors.primary : Colors.almond}
onClick={handleCreateDicoms}
>
Create Dicoms
</Button>
Expand Down
55 changes: 0 additions & 55 deletions src/import/create/CreateTableSeries.tsx

This file was deleted.

75 changes: 0 additions & 75 deletions src/import/create/CreateTableStudy.tsx

This file was deleted.

Loading

0 comments on commit 6101e90

Please sign in to comment.