WIP DisplaySetService
This commit is contained in:
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,
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user