From 66f6e3eade5708c8e03d788ebfbe9429a5ffdd81 Mon Sep 17 00:00:00 2001
From: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
Date: Fri, 28 Apr 2023 16:13:47 -0400
Subject: [PATCH] feat(DICOM Upload): Added new DICOM upload dialogue launched
from the worklist page (#3326)
* feat(DICOM Upload)
OHIF #3297
- DicomWebDataSource.store.dicom now accepts an ArrayBuffer of data sets to store
- DicomWebDataSource.store.dicom now also accepts optional callbacks to track upload and an AbortSignal object to cancel upload
- Added DicomFileUploader class that performs and tracks the upload of a DICOM file
- Added various UI pieces for the upload: DicomUpload, DicomUploadProgress, DicomUploadProgressItem
- ProgressLoadingBar was extracted from LoadingIndicatorProgress so it can be reused
- Modal dialogues can now optionally prevent an outside click from closing the Modal
* Passing an XMLHttpRequest to the dataSource.store.dicom method instead of callbacks and AbortSignal.
Cleanup of various UI pieces to minimize code and increase readability.
* Made the DicomUpload component a customization module exported by the cornerstone extension.
* Exposed a copy of the data source configuration via the IWebApiDataSource interface.
Added dicomUploadEnabled to a data source's configuration.
* Code clean up.
* Upgraded the dicomweb-client version to one that provides the ability to
pass a custom HTTP request. DICOM upload uses that custom HTTP request
to track progress and cancel requests.
* Distinguished between failed and cancelled uploads.
* Allow no selection in the upload dialogue.
Fixed the styling of various progress information so that everything aligns.
* Switched from cornerstone wado image loader to cornerstone dicom image loader for DICOM upload.
* Added special cancelled icon to differentiate from failed.
* Added a bit of spacing between the upload progress bar and percentage.
* Fixed minor issue with upload rejection.
* Performance improvement for cancel all uploads:
- use React memo for each upload item progress (row)
- do not await each request of a cancel all
* Fixed various padding/spacing for the DICOM upload drop zone component.
Changed the border dashing for the DICOM upload drop zone to be a background image gradient.
Added hover and active effects to the 'Cancel All Uploads' text.
---
.../components/DicomUpload/DicomUpload.css | 6 +
.../components/DicomUpload/DicomUpload.tsx | 116 +++++
.../DicomUpload/DicomUploadProgress.tsx | 436 ++++++++++++++++++
.../DicomUpload/DicomUploadProgressItem.tsx | 117 +++++
.../cornerstone/src/getCustomizationModule.ts | 8 +
.../src/utils/DicomFileUploader.ts | 220 +++++++++
extensions/default/package.json | 2 +-
.../default/src/DicomWebDataSource/index.js | 52 ++-
platform/core/package.json | 2 +-
.../core/src/DataSources/IWebApiDataSource.js | 7 +
.../ui/src/assets/icons/icon-alert-small.svg | 8 +
.../ui/src/assets/icons/icon-status-alert.svg | 8 +
.../ui/src/assets/icons/icon-transferring.svg | 6 +
platform/ui/src/assets/icons/icon-upload.svg | 6 +
.../src/assets/icons/icons-alert-outline.svg | 8 +
platform/ui/src/components/Button/Button.tsx | 4 +
platform/ui/src/components/Icon/getIcon.js | 10 +
.../LoadingIndicatorProgress.tsx | 17 +-
platform/ui/src/components/Modal/Modal.tsx | 4 +
.../ProgressLoadingBar.css} | 10 +-
.../ProgressLoadingBar/ProgressLoadingBar.tsx | 34 ++
.../components/ProgressLoadingBar/index.js | 2 +
.../StudyListFilter/StudyListFilter.tsx | 11 +
platform/ui/src/components/index.js | 2 +
.../ui/src/contextProviders/ModalProvider.tsx | 10 +-
platform/ui/src/index.js | 1 +
.../viewer/public/config/local_dcm4chee.js | 5 +
.../viewer/public/config/local_orthanc.js | 5 +
.../viewer/src/routes/DataSourceWrapper.tsx | 7 +-
.../viewer/src/routes/WorkList/WorkList.tsx | 34 +-
platform/viewer/src/routes/index.tsx | 13 +-
yarn.lock | 305 +-----------
32 files changed, 1126 insertions(+), 350 deletions(-)
create mode 100644 extensions/cornerstone/src/components/DicomUpload/DicomUpload.css
create mode 100644 extensions/cornerstone/src/components/DicomUpload/DicomUpload.tsx
create mode 100644 extensions/cornerstone/src/components/DicomUpload/DicomUploadProgress.tsx
create mode 100644 extensions/cornerstone/src/components/DicomUpload/DicomUploadProgressItem.tsx
create mode 100644 extensions/cornerstone/src/utils/DicomFileUploader.ts
create mode 100644 platform/ui/src/assets/icons/icon-alert-small.svg
create mode 100644 platform/ui/src/assets/icons/icon-status-alert.svg
create mode 100644 platform/ui/src/assets/icons/icon-transferring.svg
create mode 100644 platform/ui/src/assets/icons/icon-upload.svg
create mode 100644 platform/ui/src/assets/icons/icons-alert-outline.svg
rename platform/ui/src/components/{LoadingIndicatorProgress/LoadingIndicatorProgress.css => ProgressLoadingBar/ProgressLoadingBar.css} (71%)
create mode 100644 platform/ui/src/components/ProgressLoadingBar/ProgressLoadingBar.tsx
create mode 100644 platform/ui/src/components/ProgressLoadingBar/index.js
diff --git a/extensions/cornerstone/src/components/DicomUpload/DicomUpload.css b/extensions/cornerstone/src/components/DicomUpload/DicomUpload.css
new file mode 100644
index 000000000..55ddf7922
--- /dev/null
+++ b/extensions/cornerstone/src/components/DicomUpload/DicomUpload.css
@@ -0,0 +1,6 @@
+.dicom-upload-drop-area-border-dash {
+ background-image: repeating-linear-gradient(to right, #7BB2CE 0%, #7BB2CE 50%, transparent 50%, transparent 100%), repeating-linear-gradient(to right, #7BB2CE 0%, #7BB2CE 50%, transparent 50%, transparent 100%), repeating-linear-gradient(to bottom, #7BB2CE 0%, #7BB2CE 50%, transparent 50%, transparent 100%), repeating-linear-gradient(to bottom, #7BB2CE 0%, #7BB2CE 50%, transparent 50%, transparent 100%);
+ background-position: left top, left bottom, left top, right top;
+ background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
+ background-size: 20px 3px, 20px 3px, 3px 20px, 3px 20px;
+}
diff --git a/extensions/cornerstone/src/components/DicomUpload/DicomUpload.tsx b/extensions/cornerstone/src/components/DicomUpload/DicomUpload.tsx
new file mode 100644
index 000000000..fa29e65d1
--- /dev/null
+++ b/extensions/cornerstone/src/components/DicomUpload/DicomUpload.tsx
@@ -0,0 +1,116 @@
+import React, { useCallback, useState } from 'react';
+import { ReactElement } from 'react';
+import Dropzone from 'react-dropzone';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import DicomFileUploader from '../../utils/DicomFileUploader';
+import DicomUploadProgress from './DicomUploadProgress';
+import { Button } from '@ohif/ui';
+import './DicomUpload.css';
+
+type DicomUploadProps = {
+ dataSource;
+ onComplete: () => void;
+ onStarted: () => void;
+};
+
+function DicomUpload({
+ dataSource,
+ onComplete,
+ onStarted,
+}: DicomUploadProps): ReactElement {
+ const baseClassNames = 'min-h-[520px] flex flex-col bg-black select-none';
+ const [dicomFileUploaderArr, setDicomFileUploaderArr] = useState([]);
+
+ const onDrop = useCallback(async acceptedFiles => {
+ onStarted();
+ setDicomFileUploaderArr(
+ acceptedFiles.map(file => new DicomFileUploader(file, dataSource))
+ );
+ }, []);
+
+ const getDropZoneComponent = (): ReactElement => {
+ return (
+