chore: Clean up unused files, imports, and work on getting end-to-end tests and unit tests running (#2272)

This commit is contained in:
Erik Ziegler authored and GitHub committed 2021-03-01 16:52:54 +01:00
1 parent 414ebc6850
commit 0db81b30f3
374 files changed
+14138 -21288

No files matched your search

@@ -1,27 +0,0 @@
import OHIF from '@ohif/core';
import { connect } from 'react-redux';
import OHIFDicomPDFViewport from './OHIFDicomPDFViewport';
const { setViewportActive } = OHIF.redux.actions;
const mapStateToProps = (state, ownProps) => {
const { activeViewportIndex } = state.viewports;
return { activeViewportIndex };
};
const mapDispatchToProps = (dispatch, ownProps) => {
const { viewportIndex } = ownProps;
return {
setViewportActive: () => {
dispatch(setViewportActive(viewportIndex));
},
};
};
const ConnectedOHIFDicomPDFViewer = connect(
mapStateToProps,
mapDispatchToProps
)(OHIFDicomPDFViewport);
export default ConnectedOHIFDicomPDFViewer;
@@ -1,62 +0,0 @@
.DicomPDFViewport {
--header-height: 50px;
}
.DicomPDFViewport #toolbar {
display: flex;
align-items: center;
color: #fff;
padding: 0.5em;
border-bottom: var(--ui-border-thickness) solid var(--ui-border-color);
height: var(--header-height);
}
.DicomPDFViewport #canvas {
height: calc(100% - var(--header-height));
overflow-y: scroll;
}
.DicomPDFViewport #text-layer {
height: 100%;
margin-top: var(--header-height);
}
.DicomPDFViewport #pdf-canvas-container {
position: relative;
}
.DicomPDFViewport canvas, #text-layer {
display: block;
margin: 0 auto;
overflow: hidden;
}
.DicomPDFViewport #toolbar button {
color: currentColor;
background-color: transparent;
font: inherit;
border: var(--ui-border-thickness) solid var(--ui-border-color);
border-radius: 3px;
padding: 0.25em 0.5em;
margin-right: 0.5em;
cursor: pointer;
}
.DicomPDFViewport #text-layer {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
opacity: 0.2;
line-height: 1;
}
.DicomPDFViewport #text-layer>span {
color: transparent;
position: absolute;
white-space: pre;
cursor: text;
transform-origin: 0% 0%;
}
@@ -1,265 +0,0 @@
import React, { Component, createRef } from 'react';
import dicomParser from 'dicom-parser';
import PDFJS from 'pdfjs-dist';
import PropTypes from 'prop-types';
import TypedArrayProp from './TypedArrayProp';
import './DicomPDFViewport.css';
import pdfjsBuild from 'pdfjs-dist/build/pdf';
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
pdfjsBuild.GlobalWorkerOptions.workerSrc = pdfjsWorker;
// TODO: Should probably use dcmjs for this
const SOP_CLASS_UIDS = {
ENCAPSULATED_PDF: '1.2.840.10008.5.1.4.1.1.104.1',
};
class DicomPDFViewport extends Component {
constructor(props) {
super(props);
this.state = {
fileURL: null,
error: null,
currentPageIndex: 1,
pdf: null,
scale: 1,
};
this.canvas = createRef();
this.textLayer = createRef();
}
static propTypes = {
byteArray: TypedArrayProp.uint8,
useNative: PropTypes.bool,
viewportData: PropTypes.object,
activeViewportIndex: PropTypes.number,
setViewportActive: PropTypes.func,
viewportIndex: PropTypes.number,
};
static defaultProps = {
useNative: false,
};
async componentDidMount() {
const dataSet = this.parseByteArray(this.props.byteArray);
const fileURL = this.getPDFFileUrl(dataSet, this.props.byteArray);
this.setState(state => ({ ...state, fileURL }));
if (!this.props.useNative) {
const pdf = await PDFJS.getDocument(fileURL).promise;
this.setState(
state => ({ ...state, pdf }),
() => this.updatePDFCanvas()
);
}
}
updatePDFCanvas = async () => {
const { pdf, scale, currentPageIndex } = this.state;
const context = this.canvas.getContext('2d');
const page = await pdf.getPage(currentPageIndex);
let viewport = page.getViewport({ scale });
this.canvas.height = viewport.height;
this.canvas.width = viewport.width;
const renderContext = {
canvasContext: context,
viewport: viewport,
};
await page.render(renderContext);
const textContent = await page.getTextContent();
this.textLayer.innerHTML = '';
this.textLayer.style.height = viewport.height + 'px';
this.textLayer.style.width = viewport.width + 'px';
PDFJS.renderTextLayer({
textContent,
container: this.textLayer,
viewport,
textDivs: [],
});
};
componentDidUpdate(prevProps, prevState) {
const { currentPageIndex, scale } = this.state;
const newValidScale = prevState.scale !== scale && scale > 0;
const newValidPageNumber =
prevState.currentPageIndex !== currentPageIndex && currentPageIndex > 0;
if (newValidScale || newValidPageNumber) {
this.updatePDFCanvas();
}
}
getPDFFileUrl = (dataSet, byteArray) => {
let pdfByteArray = byteArray;
if (dataSet) {
const SOPClassUID = dataSet.string('x00080016');
if (SOPClassUID !== SOP_CLASS_UIDS.ENCAPSULATED_PDF) {
throw new Error('This is not a DICOM-encapsulated PDF');
}
const fileTag = dataSet.elements.x00420011;
const offset = fileTag.dataOffset;
const remainder = offset + fileTag.length;
pdfByteArray = dataSet.byteArray.slice(offset, remainder);
}
const PDF = new Blob([pdfByteArray], { type: 'application/pdf' });
const fileURL = URL.createObjectURL(PDF);
return fileURL;
};
onPageChange = async event => {
const { currentPageIndex, pdf } = this.state;
let newPageIndex = currentPageIndex;
const action = event.target.getAttribute('data-pager');
if (action === 'prev') {
if (currentPageIndex === 1) {
return;
}
newPageIndex -= 1;
if (currentPageIndex < 0) {
newPageIndex = 0;
}
}
if (action === 'next') {
if (currentPageIndex === pdf.numPages - 1) {
return;
}
newPageIndex += 1;
if (currentPageIndex > pdf.numPages - 1) {
newPageIndex = pdf.numPages - 1;
}
}
this.setState(state => ({ ...state, currentPageIndex: newPageIndex }));
};
onZoomChange = () => {
let newZoomValue = this.state.scale;
const action = event.target.getAttribute('data-pager');
if (action === '+') {
newZoomValue += 0.25;
}
if (action === '-') {
newZoomValue -= 0.25;
}
this.setState(state => ({ ...state, scale: newZoomValue }));
};
parseByteArray = byteArray => {
const options = { untilTag: '' };
let dataSet;
try {
dataSet = dicomParser.parseDicom(byteArray, options);
} catch (error) {
this.setState(state => ({ ...state, error }));
}
return dataSet;
};
setViewportActiveHandler = () => {
const {
setViewportActive,
viewportIndex,
activeViewportIndex,
} = this.props;
if (viewportIndex !== activeViewportIndex) {
setViewportActive(viewportIndex);
}
};
downloadPDFCanvas = () => {
const { fileURL } = this.state;
const a = document.createElement('a');
a.href = fileURL;
a.download = fileURL.substr(fileURL.lastIndexOf('/') + 1);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
render() {
const { fileURL, pdf, error } = this.state;
return (
<div
className={'DicomPDFViewport'}
onClick={this.setViewportActiveHandler}
onScroll={this.setViewportActiveHandler}
style={{ width: '100%', height: '100%' }}
>
{!this.props.useNative ? (
<>
<div id="toolbar">
<div id="pager">
{pdf && pdf.numPages > 1 && (
<>
<button data-pager="prev" onClick={this.onPageChange}>
{`<`}
</button>
<button data-pager="next" onClick={this.onPageChange}>
{`>`}
</button>
</>
)}
<button data-pager="-" onClick={this.onZoomChange}>
{`-`}
</button>
<button data-pager="+" onClick={this.onZoomChange}>
{`+`}
</button>
<button onClick={this.downloadPDFCanvas}>Download</button>
</div>
</div>
<div id="canvas">
<div id="pdf-canvas-container">
<canvas
id="pdf-canvas"
ref={canvas => (this.canvas = canvas)}
/>
<div
id="text-layer"
ref={textLayer => (this.textLayer = textLayer)}
></div>
</div>
</div>
</>
) : (
<object
aria-label="PDF Viewer"
data={fileURL}
type="application/pdf"
width="100%"
height="100%"
/>
)}
{error && <h2>{JSON.stringify(error)}</h2>}
</div>
);
}
}
export default DicomPDFViewport;
@@ -1,15 +0,0 @@
import React from 'react';
import PropTypes from "prop-types";
function OHIFComponentPlugin(props) {
return (<React.Fragment>{props.children}</React.Fragment>);
}
OHIFComponentPlugin.propTypes = {
id: PropTypes.string.isRequired,
init: PropTypes.func.isRequired,
destroy: PropTypes.func.isRequired,
children: PropTypes.node
};
export default OHIFComponentPlugin;
@@ -1,29 +0,0 @@
import { MODULE_TYPES, utils } from '@ohif/core';
// TODO: Should probably use dcmjs for this
const SOP_CLASS_UIDS = {
ENCAPSULATED_PDF: '1.2.840.10008.5.1.4.1.1.104.1',
};
const OHIFDicomPDFSopClassHandler = {
id: 'OHIFDicomPDFSopClassHandlerPlugin',
type: MODULE_TYPES.SOP_CLASS_HANDLER,
sopClassUIDs: [SOP_CLASS_UIDS.ENCAPSULATED_PDF],
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();
return {
plugin: 'pdf',
Modality: 'DOC',
displaySetInstanceUID: utils.guid(),
wadoRoot: study.getData().wadoRoot,
wadoUri: instance.getData().wadouri,
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
authorizationHeaders: authorizationHeaders,
};
},
};
export default OHIFDicomPDFSopClassHandler;
@@ -1,72 +0,0 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import OHIF from '@ohif/core';
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
import DicomPDFViewport from './DicomPDFViewport';
const { DicomLoaderService } = OHIF.utils;
class OHIFDicomPDFViewport extends Component {
static propTypes = {
studies: PropTypes.object,
displaySet: PropTypes.object,
viewportIndex: PropTypes.number,
viewportData: PropTypes.object,
activeViewportIndex: PropTypes.number,
setViewportActive: PropTypes.func,
};
state = {
byteArray: null,
error: null,
};
static id = 'DicomPDFViewportPDF';
static init() {
console.log('DicomPDFViewport init()');
}
static destroy() {
console.log('DicomPDFViewport destroy()');
}
componentDidMount() {
const { displaySet, studies } = this.props.viewportData;
DicomLoaderService.findDicomDataPromise(displaySet, studies).then(
data => this.setState({ byteArray: new Uint8Array(data) }),
error => {
this.setState({ error });
throw new Error(error);
}
);
}
render() {
const {
setViewportActive,
viewportIndex,
activeViewportIndex,
} = this.props;
const { byteArray, error } = this.state;
const { id, init, destroy } = OHIFDicomPDFViewport;
const pluginProps = { id, init, destroy };
return (
<OHIFComponentPlugin {...pluginProps}>
{byteArray && (
<DicomPDFViewport
byteArray={byteArray}
setViewportActive={setViewportActive}
viewportIndex={viewportIndex}
activeViewportIndex={activeViewportIndex}
/>
)}
{error && <h2>{JSON.stringify(error)}</h2>}
</OHIFComponentPlugin>
);
}
}
export default OHIFDicomPDFViewport;
-137
View File
@@ -1,137 +0,0 @@
// https://github.com/facebook/prop-types/issues/69
export const TypedArrayProp = {
any: (props, propName, componentName) => {
let obj = props[propName];
if (!(obj instanceof Float64Array ||
obj instanceof Float32Array ||
obj instanceof Int32Array ||
obj instanceof Int16Array ||
obj instanceof Int8Array ||
obj instanceof Uint32Array ||
obj instanceof Uint16Array ||
obj instanceof Uint8Array ||
obj instanceof Uint8ClampedArray)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a typed array.'
);
}
},
float64: (props, propName, componentName) => {
if (!(props[propName] instanceof Float64Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Float64Array.'
);
}
},
float32: (props, propName, componentName) => {
if (!(props[propName] instanceof Float32Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Float32Array.'
);
}
},
float: (props, propName, componentName) => {
if (!(props[propName] instanceof Float64Array ||
props[propName] instanceof Float32Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Float32Array or Float64Array.'
);
}
},
int32: (props, propName, componentName) => {
if (!(props[propName] instanceof Int32Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected an Int32Array.'
);
}
},
int16: (props, propName, componentName) => {
if (!(props[propName] instanceof Int16Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected an In16Array.'
);
}
},
int8: (props, propName, componentName) => {
if (!(props[propName] instanceof Int8Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected an Int8Array.'
);
}
},
int: (props, propName, componentName) => {
if (!(props[propName] instanceof Int32Array ||
props[propName] instanceof Int16Array ||
props[propName] instanceof Int8Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected an Int32Array, In16Array, or Int8Array.'
);
}
},
uint32: (props, propName, componentName) => {
if (!(props[propName] instanceof Uint32Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Uint32Array.'
);
}
},
uint16: (props, propName, componentName) => {
if (!(props[propName] instanceof Uint16Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Uint16Array.'
);
}
},
uint8: (props, propName, componentName) => {
if (!(props[propName] instanceof Uint8Array)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Uint8Array.'
);
}
},
uint8clamped: (props, propName, componentName) => {
if (!(props[propName] instanceof Uint8ClampedArray)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Uint8ClampedArray.'
);
}
},
uint: (props, propName, componentName) => {
if (!(props[propName] instanceof Uint32Array ||
props[propName] instanceof Uint16Array ||
props[propName] instanceof Uint8Array ||
props[propName] instanceof Uint8ClampedArray)) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Expected a Uint32Array, Uint16Array, Uint8Array, or Uint8ClampedArray.'
);
}
},
};
export { TypedArrayProp as default };
-27
View File
@@ -1,27 +0,0 @@
import React from 'react';
import OHIFDicomPDFSopClassHandler from './OHIFDicomPDFSopClassHandler.js';
const Component = React.lazy(() => {
return import('./ConnectedOHIFDicomPDFViewer');
});
const ConnectedOHIFDicomPDFViewer = props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
export default {
/**
* Only required property. Should be a unique value across all extensions.
*/
id: 'pdf',
getViewportModule() {
return ConnectedOHIFDicomPDFViewer;
},
getSopClassHandlerModule() {
return OHIFDicomPDFSopClassHandler;
},
};