feat(thumbnail highlight): Thumbnails of hydrated series are now highlighted (#3594)

This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2023-08-16 12:51:26 -04:00
1 parent 3fe676638b
commit 0f9b36906f
11 files changed
+121 -29

No files matched your search

@@ -1,17 +1,8 @@
import { ExtensionManager } from '../../extensions';
import { InstanceMetadata } from '../../types';
import { DisplaySet, InstanceMetadata } from '../../types';
import { PubSubService } from '../_shared/pubSubServiceInterface';
import EVENTS from './EVENTS';
export type DisplaySet = {
displaySetInstanceUID: string;
instances: InstanceMetadata[];
StudyInstanceUID: string;
SeriesInstanceUID?: string;
numImages?: number;
unsupported?: boolean;
};
const displaySetCache = new Map<string, DisplaySet>();
/**
@@ -154,7 +145,10 @@ export default class DisplaySetService extends PubSubService {
return displaySet;
}
public setDisplaySetMetadataInvalidated(displaySetInstanceUID: string): void {
public setDisplaySetMetadataInvalidated(
displaySetInstanceUID: string,
invalidateData = true
): void {
const displaySet = this.getDisplaySetByUID(displaySetInstanceUID);
if (!displaySet) {
@@ -162,10 +156,10 @@ export default class DisplaySetService extends PubSubService {
}
// broadcast event to update listeners with the new displaySets
this._broadcastEvent(
EVENTS.DISPLAY_SET_SERIES_METADATA_INVALIDATED,
displaySetInstanceUID
);
this._broadcastEvent(EVENTS.DISPLAY_SET_SERIES_METADATA_INVALIDATED, {
displaySetInstanceUID,
invalidateData,
});
}
public deleteDisplaySet(displaySetInstanceUID) {
+15
View File
@@ -0,0 +1,15 @@
import { InstanceMetadata } from './StudyMetadata';
export type DisplaySet = {
displaySetInstanceUID: string;
instances: InstanceMetadata[];
StudyInstanceUID: string;
SeriesInstanceUID?: string;
numImages?: number;
unsupported?: boolean;
};
export type DisplaySetSeriesMetadataInvalidatedEvent = {
displaySetInstanceUID: string;
invalidateData: boolean;
};
+2 -9
View File
@@ -2,7 +2,6 @@ import * as Extensions from '../extensions/ExtensionManager';
import * as HangingProtocol from './HangingProtocol';
import Services from './Services';
import Hotkey from '../classes/Hotkey';
import { DisplaySet } from '../services/DisplaySetService/DisplaySetService';
import { DataSourceDefinition } from './DataSource';
export * from '../services/CustomizationService/types';
@@ -10,6 +9,7 @@ export * from '../services/CustomizationService/types';
export * from './AppConfig';
export * from './Consumer';
export * from './Command';
export * from './DisplaySet';
export * from './StudyMetadata';
export * from './PanelModule';
export * from './IPubSub';
@@ -19,11 +19,4 @@ export * from './Color';
* Export the types used within the various services and managers, but
* not the services/managers themselves, which are exported at the top level.
*/
export {
Extensions,
HangingProtocol,
Services,
Hotkey,
DisplaySet,
DataSourceDefinition,
};
export { Extensions, HangingProtocol, Services, Hotkey, DataSourceDefinition };
@@ -160,6 +160,13 @@ The following properties can be added to the `configuration` property of each da
##### `dicomUploadEnabled`
A boolean indicating if the DICOM upload to the data source is permitted/accepted or not. A value of true provides a link on the OHIF work list page that allows for DICOM files from the local file system to be uploaded to the data source
:::tip
The [OHIF plugin for Orthanc](https://book.orthanc-server.com/plugins/ohif.html) by default utilizes the DICOM JSON data
source and it has been discovered that only those studies uploaded to Orthanc AFTER the plugin has been installed are
available as DICOM JSON. As such, if the OHIF plugin for Orthanc is desired for studies uploaded prior to installing the plugin,
then consider switching to using [DICOMweb instead](https://book.orthanc-server.com/plugins/ohif.html#using-dicomweb).
:::
![toolbarModule-layout](../../assets/img/uploader.gif)
#### `singlepart`
@@ -33,6 +33,7 @@ There are three events that get broadcasted in `DisplaySetService`:
| DISPLAY_SETS_ADDED | Fires a displayset is added to the displaysets cache |
| DISPLAY_SETS_CHANGED | Fires when a displayset is changed |
| DISPLAY_SETS_REMOVED | Fires when a displayset is removed |
| DISPLAY_SET_SERIES_METADATA_INVALIDATED | Fires when a displayset's series metadata has been altered. An object payload for the event is sent with properties: `displaySetInstanceUID` - the UID of the display set affected; `invalidateData` - boolean indicating if data should be invalidated
## API
@@ -60,3 +61,5 @@ Let's find out about the public API for `DisplaySetService`.
- `deleteDisplaySet`: Deletes the displaySets from the displaySets cache
- `addActiveDisplaySets`: Adds a new display set independently of the make operation.
- `setDisplaySetMetadataInvalidated`: Fires the `DISPLAY_SET_SERIES_METADATA_INVALIDATED` event.
@@ -36,6 +36,7 @@ const ThumbnailList = ({
imageSrc,
messages,
imageAltText,
isHydratedForDerivedDisplaySet,
}) => {
const isActive = activeDisplaySetInstanceUIDs.includes(
displaySetInstanceUID
@@ -104,6 +105,9 @@ const ThumbnailList = ({
onThumbnailDoubleClick(displaySetInstanceUID)
}
viewportIdentificator={viewportIdentificator}
isHydratedForDerivedDisplaySet={
isHydratedForDerivedDisplaySet
}
/>
);
default:
@@ -20,6 +20,7 @@ const ThumbnailNoImage = ({
messages,
dragData,
isActive,
isHydratedForDerivedDisplaySet,
}) => {
const [collectedProps, drag, dragPreview] = useDrag({
type: 'displayset',
@@ -32,8 +33,8 @@ const ThumbnailNoImage = ({
return (
<div
className={classnames(
'flex flex-row flex-1 cursor-pointer outline-none border-transparent hover:border-blue-300 focus:border-blue-300 rounded select-none',
isActive ? 'border-2 border-primary-light' : 'border'
'flex flex-row flex-1 cursor-pointer outline-none hover:border-blue-300 focus:border-blue-300 rounded select-none',
isActive ? 'border-2 border-primary-light' : 'border border-transparent'
)}
style={{
padding: isActive ? '11px' : '12px',
@@ -48,12 +49,27 @@ const ThumbnailNoImage = ({
<div ref={drag}>
<div className="flex flex-col flex-1">
<div className="flex flex-row items-center flex-1 mb-2">
<Icon name="list-bullets" className="w-12 text-secondary-light" />
<Icon
name="list-bullets"
className={classnames(
'w-12',
isHydratedForDerivedDisplaySet
? 'text-primary-light'
: 'text-secondary-light'
)}
/>
<Tooltip
position="bottom"
content={<Typography>{modalityTooltip}</Typography>}
>
<div className="px-3 text-lg text-white rounded-sm bg-primary-main">
<div
className={classnames(
'px-3 text-lg rounded-sm',
isHydratedForDerivedDisplaySet
? 'text-black bg-primary-light'
: 'text-white bg-primary-main'
)}
>
{modality}
</div>
</Tooltip>
@@ -104,6 +120,7 @@ ThumbnailNoImage.propTypes = {
onDoubleClick: PropTypes.func.isRequired,
messages: PropTypes.object,
isActive: PropTypes.bool.isRequired,
isHydratedForDerivedDisplaySet: PropTypes.bool,
};
export default ThumbnailNoImage;