WIP DisplaySetService

This commit is contained in:
James A. Petts committed 2020-05-18 17:21:57 +02:00
1 parent 649216fde4
commit 7a8418f64b
29 files changed
+460 -541

No files matched your search

@@ -22,8 +22,16 @@ const getTrackedSeries = displaySets => {
return trackedSeries;
};
const StudyBrowser = ({ tabs, activeTabName, onSetTabActive, onClickStudy, onClickThumbnail }) => {
const [tabActive, setTabActive] = useState(activeTabName || getInitialActiveTab(tabs));
const StudyBrowser = ({
tabs,
activeTabName,
onSetTabActive,
onClickStudy,
onClickThumbnail,
}) => {
const [tabActive, setTabActive] = useState(
activeTabName || getInitialActiveTab(tabs)
);
const [studyActive, setStudyActive] = useState(null);
const [thumbnailActive, setThumbnailActive] = useState(null);
@@ -66,6 +74,7 @@ const StudyBrowser = ({ tabs, activeTabName, onSetTabActive, onClickStudy, onCli
/>
{isActive && displaySets && (
<ThumbnailList
dragData={{ type: 'displayset' }}
thumbnails={displaySets}
thumbnailActive={thumbnailActive}
onThumbnailClick={thumbnailId => {
@@ -110,7 +119,7 @@ const StudyBrowser = ({ tabs, activeTabName, onSetTabActive, onClickStudy, onCli
setStudyActive(null);
if (onSetTabActive) {
onSetTabActive(name)
onSetTabActive(name);
}
}}
>
@@ -141,6 +150,21 @@ StudyBrowser.propTypes = {
numInstances: PropTypes.number,
modalities: PropTypes.string,
description: PropTypes.string,
// These apply to each thumbnail; we should set Thumbnails
// As children and kill the <ThumbnailList> component to
// make it easier to set this prop.
// Do much less nesting so we have a bit more control.
/**
* Data the thumbnail should expose to a receiving drop target. Use a matching
* `dragData.type` to identify which targets can receive this draggable item.
* If this is not set, drag-n-drop will be disabled for this thumbnail.
*
* Ref: https://react-dnd.github.io/react-dnd/docs/api/use-drag#specification-object-members
*/
dragData: PropTypes.shape({
/** Must match the "type" a dropTarget expects */
type: PropTypes.string.isRequired,
}),
displaySets: PropTypes.arrayOf(
PropTypes.shape({
displaySetInstanceUID: PropTypes.string.isRequired,
@@ -3,7 +3,12 @@ import PropTypes from 'prop-types';
import { Thumbnail, ThumbnailNoImage, ThumbnailTracked } from '@ohif/ui';
const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
const ThumbnailList = ({
dragData,
thumbnails,
thumbnailActive,
onThumbnailClick,
}) => {
return (
<div className="bg-black py-3">
{thumbnails.map(
@@ -27,6 +32,7 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
return (
<Thumbnail
key={displaySetInstanceUID}
dragData={dragData}
description={description}
seriesNumber={seriesNumber}
numInstances={numInstances}
@@ -41,6 +47,7 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
return (
<ThumbnailNoImage
key={displaySetInstanceUID}
dragData={dragData}
modality={modality}
seriesDate={seriesDate}
description={description}
@@ -51,6 +58,7 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
return (
<ThumbnailTracked
key={displaySetInstanceUID}
dragData={dragData}
description={description}
seriesNumber={seriesNumber}
numInstances={numInstances}
@@ -72,6 +80,17 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
};
ThumbnailList.propTypes = {
/**
* Data the thumbnail should expose to a receiving drop target. Use a matching
* `dragData.type` to identify which targets can receive this draggable item.
* If this is not set, drag-n-drop will be disabled for this thumbnail.
*
* Ref: https://react-dnd.github.io/react-dnd/docs/api/use-drag#specification-object-members
*/
dragData: PropTypes.shape({
/** Must match the "type" a dropTarget expects */
type: PropTypes.string.isRequired,
}),
thumbnails: PropTypes.arrayOf(
PropTypes.shape({
displaySetInstanceUID: PropTypes.string.isRequired,
@@ -5,7 +5,7 @@ route: components/viewportGrid
---
import { Playground, Props } from 'docz';
import { ViewportGrid } from '@ohif/ui';
import { DragAndDropProvider, ViewportGrid } from '@ohif/ui';
# ViewportGrid
@@ -20,6 +20,7 @@ import { ViewportGrid } from '@ohif/ui';
## Basic usage
<Playground>
<DragAndDropProvider>
<div className="p-4 h-56">
<ViewportGrid numRows={1} numCols={2}>
<div className="flex items-center justify-center h-full text-white">
@@ -30,6 +31,7 @@ import { ViewportGrid } from '@ohif/ui';
</div>
</ViewportGrid>
</div>
</DragAndDropProvider>
</Playground>
## Properties
@@ -6,20 +6,22 @@ import { useDrop } from 'react-dnd';
// NOTE: If we found a way to make `useDrop` conditional,
// Or we provided a HOC of this component, we could provide
// this UI without the DragAndDropContext dependency.
function ViewportPane({ children, className, isActive, onDrop }) {
function ViewportPane({
children,
className,
isActive,
onDrop,
acceptDropsFor,
}) {
const [{ isHovered, isHighlighted }, drop] = useDrop({
accept: 'displayset',
accept: acceptDropsFor,
// TODO: pass in as prop?
drop: (displaySet, monitor) => {
drop: (droppedItem, monitor) => {
const canDrop = monitor.canDrop();
const isOver = monitor.isOver();
if (canDrop && isOver && onDrop) {
const { StudyInstanceUID, displaySetInstanceUID } = displaySet;
onDrop({
//viewportIndex, StudyInstanceUID, displaySetInstanceUID
});
onDrop(droppedItem);
}
},
// Monitor, and collect props; returned as values by `useDrop`
@@ -53,6 +55,8 @@ ViewportPane.propTypes = {
className: PropTypes.string,
/** Bool to show active styling */
isActive: PropTypes.bool.isRequired,
/** Indicates drag items we should accept for drops */
acceptDropsFor: PropTypes.string.isRequired,
/** Function that handles drop events */
onDrop: PropTypes.func.isRequired,
};
+38 -30
View File
@@ -1,43 +1,51 @@
import React from 'react';
import { SidePanel, StudyBrowser } from '@ohif/ui';
import {
SidePanel,
StudyBrowser,
DragAndDropProvider,
ViewportGrid,
ViewportPane,
} from '@ohif/ui';
import Header from './components/Header';
import ViewportToolbar from './components/ViewportToolBar';
const Viewer = () => {
return (
<div>
<Header />
<div
className="flex flex-row flex-no-wrap flex-1 items-stretch overflow-hidden w-full"
style={{ height: 'calc(100vh - 57px' }}
>
<SidePanel
side="left"
iconName="group-layers"
iconLabel="Studies"
componentLabel="Studies"
defaultIsOpen={true}
<DragAndDropProvider>
<div>
<Header />
<div
className="flex flex-row flex-no-wrap flex-1 items-stretch overflow-hidden w-full"
style={{ height: 'calc(100vh - 57px' }}
>
<StudyBrowser />
</SidePanel>
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
<ViewportToolbar />
<div>CONTENT</div>
</div>
<SidePanel
side="right"
iconName="list-bullets"
iconLabel="Measure"
componentLabel="Measurements"
defaultIsOpen={false}
>
<div className="flex justify-center text-white p-2">
panel placeholder
<SidePanel
side="left"
iconName="group-layers"
iconLabel="Studies"
componentLabel="Studies"
defaultIsOpen={true}
>
<StudyBrowser />
</SidePanel>
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
<ViewportToolbar />
<div>CONTENT</div>
</div>
</SidePanel>
<SidePanel
side="right"
iconName="list-bullets"
iconLabel="Measure"
componentLabel="Measurements"
defaultIsOpen={false}
>
<div className="flex justify-center text-white p-2">
panel placeholder
</div>
</SidePanel>
</div>
</div>
</div>
</DragAndDropProvider>
);
};