OHIF with Cornerstone3D 2.0 (#4347)

This commit is contained in:
Alireza authored and GitHub committed 2024-11-06 07:15:27 -05:00
1 parent 8981a61b8c
commit 7ce7127d7c
803 files changed
+32760 -15893

No files matched your search

@@ -69,7 +69,9 @@ const ProgressItemDetail = ({ option }: { option: ProgressDropdownOption }): Rea
)}
{!info && iconContent}
<div className="grow text-base leading-6">{label}</div>
<div className="grow overflow-hidden text-ellipsis whitespace-nowrap text-base leading-6">
{label}
</div>
</>
);
};
@@ -161,7 +161,7 @@ const SegmentationConfig = ({
/>
)}
</div>
<div className="h-[6px] bg-black "></div>
<div className="h-[6px] bg-black"></div>
</div>
);
};
@@ -98,7 +98,7 @@ function SegmentationDropDownRow({
],
]}
>
<div className="hover:bg-secondary-dark grid h-[28px] w-[28px] cursor-pointer place-items-center rounded-[4px]">
<div className="hover:bg-secondary-dark grid h-[28px] w-[28px] cursor-pointer place-items-center rounded-[4px]">
<Icon name="icon-more-menu"></Icon>
</div>
</Dropdown>
@@ -138,7 +138,7 @@ function SegmentationDropDownRow({
/>
</Tooltip>
<div
className="hover:bg-secondary-dark mr-1 grid h-[28px] w-[28px] cursor-pointer place-items-center rounded-[4px]"
className="hover:bg-secondary-dark mr-1 grid h-[28px] w-[28px] cursor-pointer place-items-center rounded-[4px]"
onClick={() => onToggleSegmentationVisibility(activeSegmentation.id)}
>
{activeSegmentation.isVisible ? (
@@ -94,7 +94,7 @@ const SegmentationGroupTable = ({
segmentationConfig={segmentationConfig}
/>
)}
<div className="bg-primary-dark ">
<div className="bg-primary-dark">
{segmentations?.length === 0 ? (
<div className="select-none bg-black py-[3px]">
{showAddSegmentation && !disableEditing && (
@@ -49,7 +49,7 @@ const StudyItem = ({
<div className="flex-2 flex">
<div
className={classnames(
'bg-secondary-main mt-2 flex flex-row py-1 pl-2 pr-4 text-base text-white ',
'bg-secondary-main mt-2 flex flex-row py-1 pl-2 pr-4 text-base text-white',
isActive
? 'border-secondary-light flex-1 justify-center border-t'
: 'mx-4 mb-4 rounded-sm'
@@ -1,7 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
const StudySummary = ({ date, modality, description }) => {
interface StudySummaryProps {
date: string;
modality: string;
description?: string;
}
const StudySummary: React.FC<StudySummaryProps> = ({ date, modality, description }) => {
return (
<div className="p-2">
<div className="leading-none">
@@ -17,10 +22,4 @@ const StudySummary = ({ date, modality, description }) => {
);
};
StudySummary.propTypes = {
date: PropTypes.string.isRequired,
modality: PropTypes.string.isRequired,
description: PropTypes.string,
};
export default StudySummary;
@@ -64,7 +64,7 @@ function ViewportPane({
onScroll={onInteractionHandler}
onWheel={onInteractionHandler}
className={classnames(
'group h-full w-full overflow-hidden rounded-md transition duration-300',
'group/pane h-full w-full overflow-hidden rounded-md transition duration-300',
{
'border-primary-light border-2': isActive,
'border-2 border-transparent': !isActive,
@@ -80,7 +80,7 @@ function ViewportPane({
'h-full w-full overflow-hidden rounded-md',
{
'border border-transparent': isActive,
'border-secondary-light group-hover:border-primary-light/70 border': !isActive,
'border-secondary-light group-hover/pane:border-primary-light/70 border': !isActive,
},
className
)}
@@ -143,11 +143,12 @@ const WindowLevel = ({
inputClassName="grow"
maxValue={1}
minValue={0}
step={0.1}
step={0.05}
value={opacity}
showLabel={true}
allowNumberEdit={true}
onChange={handleOpacityChange}
showAdjustmentArrows={false}
/>
</div>
)}
@@ -93,6 +93,9 @@ export default function CineProvider({ children, service }) {
setIsCineEnabled: isCineEnabled => service.setIsCineEnabled(isCineEnabled),
playClip: (element, playClipOptions) => service.playClip(element, playClipOptions),
stopClip: (element, stopClipOptions) => service.stopClip(element, stopClipOptions),
setViewportCineClosed: viewportId => service.setViewportCineClosed(viewportId),
clearViewportCineClosed: viewportId => service.clearViewportCineClosed(viewportId),
isViewportCineClosed: viewportId => service.isViewportCineClosed(viewportId),
};
return <CineContext.Provider value={[state, api]}>{children}</CineContext.Provider>;
@@ -1,4 +1,12 @@
import React, { useState, createContext, useContext, useCallback, useEffect, useRef } from 'react';
import React, {
useState,
createContext,
useContext,
useCallback,
useEffect,
useRef,
useMemo,
} from 'react';
import PropTypes from 'prop-types';
import Draggable from 'react-draggable';
@@ -268,8 +276,13 @@ const DialogProvider = ({ children, service = null }) => {
const validCallback = callback => callback && typeof callback === 'function';
const contextValue = useMemo(
() => ({ create, dismiss, dismissAll, isEmpty }),
[create, dismiss, dismissAll, isEmpty]
);
return (
<DialogContext.Provider value={{ create, dismiss, dismissAll, isEmpty }}>
<DialogContext.Provider value={contextValue}>
{!isEmpty() && (
<div
className="absolute h-full w-full"
@@ -2,7 +2,6 @@ export function toolboxReducer(state, action) {
let newState = { ...state };
const { payload } = action;
const { stateSyncService, buttonSectionId } = payload || {};
switch (action.type) {
case 'SET_ACTIVE_TOOL':
@@ -49,18 +48,5 @@ export function toolboxReducer(state, action) {
break;
}
// store the state in the stateSyncService
if (payload?.stateSyncService) {
const prevState = stateSyncService.getState()?.['uiStateStore']?.[buttonSectionId];
stateSyncService.store({
uiStateStore: {
...stateSyncService.getState()?.['uiStateStore'],
[buttonSectionId]: {
...prevState,
...newState,
},
},
});
}
return newState;
}
@@ -1,38 +1,18 @@
import React, { createContext, useCallback, useContext, useEffect, useReducer } from 'react';
import React, {
createContext,
useCallback,
useContext,
useEffect,
useReducer,
ReactNode,
} from 'react';
import merge from 'lodash.merge';
import PropTypes from 'prop-types';
import { ViewportGridService, utils } from '@ohif/core';
import viewportLabels from '../utils/viewportLabels';
interface Viewport {
viewportId: string;
displaySetInstanceUIDs: string[];
viewportOptions: any;
displaySetSelectors: any[];
displaySetOptions: any[];
x: number;
y: number;
width: number;
height: number;
viewportLabel: any;
isReady: boolean;
}
interface Layout {
numRows: number;
numCols: number;
layoutType: string;
}
interface DefaultState {
activeViewportId: string | null;
layout: Layout;
isHangingProtocolLayout: boolean;
viewports: Map<string, Viewport>;
}
const DEFAULT_STATE: DefaultState = {
const DEFAULT_STATE: AppTypes.ViewportGrid.State = {
activeViewportId: null,
layout: {
numRows: 0,
@@ -78,7 +58,10 @@ const getViewportLabel = (viewports, viewportId) => {
return viewportLabels[viewportIds.indexOf(viewportId)];
};
const determineActiveViewportId = (state: DefaultState, newViewports: Map) => {
const determineActiveViewportId = (
state: AppTypes.ViewportGrid.State,
newViewports: Map<string, AppTypes.ViewportGrid.Viewport>
) => {
const { activeViewportId } = state;
const currentActiveViewport = state.viewports.get(activeViewportId);
@@ -132,10 +115,37 @@ const determineActiveViewportId = (state: DefaultState, newViewports: Map) => {
return sortedViewports[0].viewportId;
};
export const ViewportGridContext = createContext(DEFAULT_STATE);
// Define the API interface
interface ViewportGridApi {
getState: () => AppTypes.ViewportGrid.State;
setActiveViewportId: (index: string) => void;
setDisplaySetsForViewport: (props: any) => void;
setDisplaySetsForViewports: (props: any[]) => void;
setLayout: (layout: AppTypes.ViewportGrid.Layout) => void;
reset: () => void;
set: (gridLayoutState: Partial<AppTypes.ViewportGrid.State>) => void;
getNumViewportPanes: () => number;
setViewportIsReady: (viewportId: string, isReady: boolean) => void;
getGridViewportsReady: () => boolean;
getActiveViewportOptionByKey: (key: string) => any;
setViewportGridSizeChanged: (props: any) => void;
publishViewportsReady: () => void;
}
export function ViewportGridProvider({ children, service }) {
const viewportGridReducer = (state: DefaultState, action) => {
// Update the context type
export const ViewportGridContext = createContext<[AppTypes.ViewportGrid.State, ViewportGridApi]>([
DEFAULT_STATE,
{} as ViewportGridApi,
]);
// Update the provider props type
interface ViewportGridProviderProps {
children: ReactNode;
service: ViewportGridService;
}
export function ViewportGridProvider({ children, service }: ViewportGridProviderProps) {
const viewportGridReducer = (state: AppTypes.ViewportGrid.State, action) => {
switch (action.type) {
case 'SET_ACTIVE_VIEWPORT_ID': {
return { ...state, ...{ activeViewportId: action.payload } };
@@ -207,10 +217,10 @@ export function ViewportGridProvider({ children, service }) {
// viewportLabel: getViewportLabel(viewports, viewportId),
};
viewportOptions.presentationIds = ViewportGridService.getPresentationIds(
newViewport,
viewports
);
viewportOptions.presentationIds = service.getPresentationIds({
viewport: newViewport,
viewports,
});
viewports.set(viewportId, {
...viewports.get(viewportId),
@@ -233,7 +243,7 @@ export function ViewportGridProvider({ children, service }) {
// If empty viewportOptions, we use numRow and numCols to calculate number of viewports
const hasOptions = layoutOptions?.length;
const viewports = new Map<string, Viewport>();
const viewports = new Map<string, AppTypes.ViewportGrid.Viewport>();
// Options is a temporary state store which can be used by the
// findOrCreate to store state about already found viewports. Typically,
// it will be used to store the display set UID's which are already
@@ -298,10 +308,11 @@ export function ViewportGridProvider({ children, service }) {
viewport.isReady = false;
if (!viewport.viewportOptions.presentationIds) {
viewport.viewportOptions.presentationIds = ViewportGridService.getPresentationIds(
const presentationIds = service.getPresentationIds({
viewport,
viewports
);
viewports,
});
viewport.viewportOptions.presentationIds = presentationIds;
}
}
}
@@ -513,4 +524,6 @@ ViewportGridProvider.propTypes = {
service: PropTypes.instanceOf(ViewportGridService).isRequired,
};
export const useViewportGrid = () => useContext(ViewportGridContext);
// Update the useViewportGrid hook
export const useViewportGrid = (): [AppTypes.ViewportGrid.State, ViewportGridApi] =>
useContext(ViewportGridContext);
+77
View File
@@ -5,6 +5,10 @@
@tailwind components;
@tailwind utilities;
* {
min-height: 0 !important;
}
@layer base {
html {
font-family: 'Inter', sans-serif;
@@ -28,3 +32,76 @@
user-select: none;
opacity: 0.5;
}
@layer base {
:root {
--highlight: 191 74% 63%;
--background: 236 62% 5%;
--foreground: 0 0% 98%;
--card: 236 62% 5%;
--card-foreground: 0 0% 98%;
--popover: 219 90% 15%;
--popover-foreground: 0 0% 98%;
--primary: 214 98% 60%;
--primary-foreground: 0 0% 98%;
--secondary: 214 66% 48%;
--secondary-foreground: 200 50% 84%;
--muted: 234 64% 10%;
--muted-foreground: 200 46% 65%;
--accent: 217 79% 24%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 236 45% 21%;
--ring: 214 98% 60%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
--radius: 0.5rem;
--success-bg: hsl(143, 85%, 96%);
--success-border: hsl(145, 92%, 91%);
--success-text: hsl(140, 100%, 27%);
--info-bg: hsl(208, 100%, 97%);
--info-border: hsl(221, 91%, 91%);
--info-text: hsl(210, 92%, 45%);
--warning-bg: hsl(49, 100%, 97%);
--warning-border: hsl(49, 91%, 91%);
--warning-text: hsl(31, 92%, 45%);
--error-bg: hsl(359, 100%, 97%);
--error-border: hsl(359, 100%, 94%);
--error-text: hsl(360, 100%, 45%);
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 214 98% 60%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 236 45% 21%;
--ring: 214 98% 60%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}
+12
View File
@@ -253,6 +253,18 @@ module.exports = {
fill: {
current: 'currentColor',
},
fontSize: {
xxs: '0.6875rem', // 11px
xs: '0.75rem', // 12px
sm: '0.8125rem', // 13px
base: '0.875rem', // 14px
lg: '1rem', // 16px
xl: '1.125rem', // 18px
'2xl': '1.25rem', // 20px
'3xl': '1.375rem', // 22px
'4xl': '1.5rem', // 24px
'5xl': '1.875rem', // 30px
},
flex: {
1: '1 1 0%',
0.3: '0.3 0.3 0%',