Skip to content

Commit

Permalink
Merge pull request #811 from salimkanoun/Salim
Browse files Browse the repository at this point in the history
Add download as nifti
  • Loading branch information
salimkanoun authored May 25, 2023
2 parents 898fe49 + 80b74c9 commit 1a11013
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ services:
networks:
- internal
environment:
NEURO_PLUGIN_ENABLED : "true"
ORTHANC__NAME: "OrthancToolsJS"
ORTHANC__DICOM_SERVER_ENABLED: "true"
ORTHANC__DICOM_MODALITIES_IN_DATABASE: "true"
Expand Down
63 changes: 5 additions & 58 deletions FrontEnd/src/components/AutoQuery/MyRobot/MyRobotRoot.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import React, { useEffect, useMemo, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useSelector } from 'react-redux'

import { CircularProgressbar, CircularProgressbarWithChildren, buildStyles } from 'react-circular-progressbar'
import { Container, Row } from 'react-bootstrap'

import { addStudiesToAnonList } from '../../../actions/AnonList'
import { addStudiesToExportList } from '../../../actions/ExportList'
import { addStudiesToDeleteList } from '../../../actions/DeleteList'

import apis from '../../../services/apis'
import ExportDeleteSendButton from '../../CommonComponents/RessourcesDisplay/ExportDeleteSendButton'
import Study from '../../../model/Study'
import MyRobotTableStudies from './MyRobotTableStudies'
import MyRobotTableSeries from './MyRobotTableSeries'

Expand All @@ -35,10 +29,6 @@ export default () => {
}
})

const dispatch = useDispatch()

const [selectedRowIds, setSelectedRowIds] = useState([])

const [id, setId] = useState(null)
const [projectName, setProjectName] = useState(null)
const [creator, setCreator] = useState(null)
Expand Down Expand Up @@ -99,43 +89,6 @@ export default () => {
setPercentageFailure(newPercentageFailure)
}

const getSelectedItemsStudiesDetails = async () => {
let studyDataRetrieved = []
//Loop each item to retrieve study level
for (let orthancId of selectedRowIds) {
await apis.content.getStudiesDetails(orthancId).then((studyDetails) => {
let study = new Study()
study.fillFromOrthanc(studyDetails.ID, studyDetails.MainDicomTags, studyDetails.Series)
study.fillParentPatient(studyDetails.ParentPatient, studyDetails.PatientMainDicomTags)
studyDataRetrieved.push(study.serialize())
}).catch((error) => {
console.error(error)
})
}

return studyDataRetrieved

}

const selectRowHandler = (selectedRowIds) => {
setSelectedRowIds(selectedRowIds)
}

const sendToAnon = async () => {
let studyArray = await getSelectedItemsStudiesDetails()
dispatch(addStudiesToAnonList(studyArray))
}

const sendToExport = async () => {
let studyArray = await getSelectedItemsStudiesDetails()
dispatch(addStudiesToExportList(studyArray))
}

const sendToDelete = async () => {
let studyArray = await getSelectedItemsStudiesDetails()
dispatch(addStudiesToDeleteList(studyArray))
}

//SK ICI CHECKER LE ITEMID dans le backend (eviter position et remplacer par un ID (actuelement aswerId mais mauvaise idee car existe qu'une fois executee))
const retryQueryHandler = async (itemId) => {
try {
Expand All @@ -155,11 +108,11 @@ export default () => {

const seriesRows = useMemo(() => {
return rows.filter(row => row.Level === LEVEL_SERIES)
}, [rows.length])
}, [rows])

const studiesRows = useMemo(() => {
return rows.filter(row => row.Level === LEVEL_STUDY)
}, [rows.length])
}, [rows])

return (
<Container fluid>
Expand Down Expand Up @@ -187,25 +140,19 @@ export default () => {
{
studiesRows.length > 0 ?
<Row className='mt-5'>
<MyRobotTableStudies selectedRowsIds={selectedRowIds} onSelectRow={selectRowHandler} robotId={id} rows={studiesRows} />
<MyRobotTableStudies robotId={id} rows={studiesRows} />
</Row>
:
null
}
{
seriesRows.length > 0 ?
<Row className='mt-5'>
<MyRobotTableSeries selectedRowsIds={selectedRowIds} onSelectRow={selectRowHandler} robotId={id} rows={seriesRows} />
<MyRobotTableSeries robotId={id} rows={seriesRows} />
</Row>
:
null
}
<Row>
<ExportDeleteSendButton
onAnonClick={sendToAnon} onExportClick={sendToExport}
onDeleteClick={sendToDelete}
/>
</Row>
</Container>
)
}
10 changes: 6 additions & 4 deletions FrontEnd/src/components/AutoQuery/MyRobot/MyRobotTableSeries.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'
import { Button, Dropdown } from 'react-bootstrap';

import CommonTableV8 from '../../CommonComponents/RessourcesDisplay/ReactTableV8/CommonTableV8';
Expand All @@ -11,7 +11,9 @@ import { ReactComponent as PendingSVG } from '../../../assets/images/pending.svg
import { ReactComponent as RepeatSVG } from '../../../assets/images/arrow-repeat.svg'
import { ITEM_SUCCESS } from './MyRobotRoot';

export default ({ rows = [], selectedRowsIds, onSelectRow, onRetryItem, onDeleteItem }) => {
export default ({ rows = [], onSelectRow, onRetryItem, onDeleteItem }) => {

const [selectedRowsIds, setSelectedRowsIds] = useState([])

const columns = [{
accessorKey: 'id',
Expand Down Expand Up @@ -120,7 +122,7 @@ export default ({ rows = [], selectedRowsIds, onSelectRow, onRetryItem, onDelete
retrievedOrthancIds.push(row.RetrievedOrthancId)
}
}
onSelectRow(retrievedOrthancIds)
setSelectedRowsIds(retrievedOrthancIds)
}


Expand All @@ -131,7 +133,7 @@ export default ({ rows = [], selectedRowsIds, onSelectRow, onRetryItem, onDelete

return (
<>
<CommonTableV8 id={'id'} canSelect={false} selectedRowsIds={selectedRowKey} columns={columns} data={rows} onSelectRow={onSelectRowHandler} paginated />
<CommonTableV8 id={'id'} canSelect={false} canSort selectedRowsIds={selectedRowKey} columns={columns} data={rows} onSelectRow={onSelectRowHandler} paginated />
</>
)
}
52 changes: 47 additions & 5 deletions FrontEnd/src/components/AutoQuery/MyRobot/MyRobotTableStudies.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'
import { Button, Dropdown } from 'react-bootstrap';

import CommonTableV8 from '../../CommonComponents/RessourcesDisplay/ReactTableV8/CommonTableV8';
Expand All @@ -11,8 +11,11 @@ import { ReactComponent as PendingSVG } from '../../../assets/images/pending.svg
import { ReactComponent as RepeatSVG } from '../../../assets/images/arrow-repeat.svg'
import { ITEM_SUCCESS } from './MyRobotRoot';

export default ({ rows = [], selectedRowsIds, onSelectRow, onRetryItem, onDeleteItem }) => {
export default ({ rows = [], onRetryItem, onDeleteItem }) => {

const dispatch = useDispatch()

const [selectedRowIds, setSelectedRowIds] = useState([])

const columns = [{
accessorKey: 'id',
Expand Down Expand Up @@ -114,6 +117,39 @@ export default ({ rows = [], selectedRowsIds, onSelectRow, onRetryItem, onDelete
enableHiding: true
}];

const sendToAnon = async () => {
let studyArray = await getSelectedItemsStudiesDetails()
dispatch(addStudiesToAnonList(studyArray))
}

const sendToExport = async () => {
let studyArray = await getSelectedItemsStudiesDetails()
dispatch(addStudiesToExportList(studyArray))
}

const sendToDelete = async () => {
let studyArray = await getSelectedItemsStudiesDetails()
dispatch(addStudiesToDeleteList(studyArray))
}

const getSelectedItemsStudiesDetails = async () => {
let studyDataRetrieved = []
//Loop each item to retrieve study level
for (let orthancId of selectedRowIds) {
await apis.content.getStudiesDetails(orthancId).then((studyDetails) => {
let study = new Study()
study.fillFromOrthanc(studyDetails.ID, studyDetails.MainDicomTags, studyDetails.Series)
study.fillParentPatient(studyDetails.ParentPatient, studyDetails.PatientMainDicomTags)
studyDataRetrieved.push(study.serialize())
}).catch((error) => {
console.error(error)
})
}

return studyDataRetrieved

}

const onSelectRowHandler = (rowIds) => {
let selectedRows = rows.filter(row => rowIds.includes(row.id))
let retrievedOrthancIds = []
Expand All @@ -122,18 +158,24 @@ export default ({ rows = [], selectedRowsIds, onSelectRow, onRetryItem, onDelete
retrievedOrthancIds.push(row.RetrievedOrthancId)
}
}
onSelectRow(retrievedOrthancIds)
setSelectedRowIds(retrievedOrthancIds)
}


const selectedRowKey = useMemo(() => {
let selectedRows = rows.filter((row) => selectedRowsIds.includes(row.RetrievedOrthancId))
return selectedRows.map(selectedRow => selectedRow.id)
}, [selectedRowsIds.length])
}, [selectedRowIds.length])

return (
<>
<CommonTableV8 id={'id'} canSelect selectedRowsIds={selectedRowKey} columns={columns} data={rows} onSelectRow={onSelectRowHandler} paginated />
<CommonTableV8 id={'id'} canSelect canSort selectedRowsIds={selectedRowKey} columns={columns} data={rows} onSelectRow={onSelectRowHandler} paginated />
<div>
<ExportDeleteSendButton
onAnonClick={sendToAnon} onExportClick={sendToExport}
onDeleteClick={sendToDelete}
/>
</div>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,31 @@ import { Button, Dropdown } from 'react-bootstrap'
export default ({
onDelete,
onShowMetadata,
onShowModify
onShowModify,
onDownloadNifti
}) => {
const handleClick = (e) => {
e.stopPropagation()
}


return (
<Dropdown onClick={handleClick} drop='left' className="text-center">
<Dropdown.Toggle variant="button-dropdown-green" id="dropdown-basic" className="button-dropdown button-dropdown-green">
<Dropdown drop='left' className="text-center">
<Dropdown.Toggle variant="button-dropdown-green" className="button-dropdown button-dropdown-green">
Action
</Dropdown.Toggle>

<Dropdown.Menu className="mt-2 border border-dark border-2">
<Button className='dropdown-item bg-green' onClick={() => onShowMetadata()}>
View Metadata
</Button>
<Button className='dropdown-item bg-green' onClick={() => onDownloadNifti(false)}>
Download nii
</Button>
<Button className='dropdown-item bg-green' onClick={() => onDownloadNifti(true)}>
Download nii.gz
</Button>
<Button className='dropdown-item bg-orange' onClick={() => onShowModify()}>
Modify
</Button>

<Button className='dropdown-item bg-red'
onClick={onDelete}>Delete
</Button>
Expand Down
16 changes: 12 additions & 4 deletions FrontEnd/src/components/Content/ContentTableSeries.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Metadata from "../Metadata/Metadata";
import ActionButtonSeries from "./ActionButtons/ActionButtonSeries"
import Modify from '../Modify/Modify'
import ConstantLevel from "../Modify/ConstantLevel";
import apis from "../../services/apis";
import { errorMessage } from "../../tools/toastify";

export default ({
series = [],
Expand All @@ -14,19 +16,25 @@ export default ({
const [metadataOrthancID, setMetadataOrthancID] = useState(null);
const [modifyOrthancID, setModifyOrthancID] = useState({ orthancID: null, level: null })

const handleDownloadNifti = (seriesOrthancId, compressed) => {
apis.exportDicom.exportToNifti(seriesOrthancId, compressed).catch(() => errorMessage('Uncreatable Nifti'))
}

const additionalColumns = [
{
id: 'Action',
accessorKey: 'Action',
header: 'Action',
cell: ({ row }) => {
const SeriesOrthancID = row.original.SeriesOrthancID
return (
<ActionButtonSeries
orthancID={row.original.SeriesOrthancID}
onDelete={() => onDelete(row.original.SeriesOrthancID)}
orthancID={SeriesOrthancID}
onDelete={() => onDelete(SeriesOrthancID)}
dataDetails={row.original}
onShowMetadata={() => setMetadataOrthancID(row.original.SeriesOrthancID)}
onShowModify={() => setModifyOrthancID({ orthancID: row.original.SeriesOrthancID, level: ConstantLevel.SERIES })}
onShowMetadata={() => setMetadataOrthancID(SeriesOrthancID)}
onShowModify={() => setModifyOrthancID({ orthancID: SeriesOrthancID, level: ConstantLevel.SERIES })}
onDownloadNifti={(compressed) => handleDownloadNifti(SeriesOrthancID, compressed)}
/>)
}
}]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,26 @@ import { Button, Dropdown } from 'react-bootstrap'

export default ({
onShowMetadata,
onDownloadNifti
}) => {
const handleClick = (e) => {
e.stopPropagation()
}

return (
<Dropdown onClick={handleClick} drop='left' className="text-center">
<Dropdown.Toggle variant="button-dropdown-green" id="dropdown-basic" className="button-dropdown button-dropdown-green">
<Dropdown drop='left' className="text-center">
<Dropdown.Toggle variant="button-dropdown-green" className="button-dropdown button-dropdown-green">
Action
</Dropdown.Toggle>

<Dropdown.Menu className="mt-2 border border-dark border-2">
<Button className='dropdown-item bg-green' onClick={() => onShowMetadata()}>
View Metadata
</Button>

<Button className='dropdown-item bg-green' onClick={() => onDownloadNifti(false)}>
Download nii
</Button>
<Button className='dropdown-item bg-green' onClick={() => onDownloadNifti(true)}>
Download nii.gz
</Button>
</Dropdown.Menu>
</Dropdown>
)
Expand Down
12 changes: 10 additions & 2 deletions FrontEnd/src/components/MyDicom/MyDicomSeriesTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,32 @@ import { Modal } from 'react-bootstrap'
import TableSeries from '../CommonComponents/RessourcesDisplay/ReactTableV8/TableSeries'
import ActionButtonSeries from './ActionButtons/ActionButtonSeries'
import Metadata from '../Metadata/Metadata'
import apis from '../../services/apis'
import { errorMessage } from '../../tools/toastify'

export default ({ series = [] }) => {

const [metadataOrthancID, setMetadataOrthancID] = useState(null)

const handleDownloadNifti = (seriesOrthancId, compressed) => {
apis.exportDicom.exportToNifti(seriesOrthancId, compressed).catch(() => errorMessage('Uncreatable Nifti'))
}

const additionalColumns = [
{
id: 'Action',
accessorKey: 'Action',
header: 'Action',
cell: ({ row }) => {
const seriesOrthancID = row.original.SeriesOrthancID
return (
<ActionButtonSeries
orthancID={row.original.SeriesOrthancID}
orthancID={seriesOrthancID}
onDelete={() => { }}
dataDetails={row.original}
onShowMetadata={() => setMetadataOrthancID(row.original.SeriesOrthancID)}
onShowMetadata={() => setMetadataOrthancID(seriesOrthancID)}
onShowModify={() => { }}
onDownloadNifti={(compressed)=> handleDownloadNifti(seriesOrthancID, compressed)}
/>)
}
}]
Expand Down
Loading

0 comments on commit 1a11013

Please sign in to comment.