Skip to content

Commit

Permalink
fix(bugs): fixing lots of bugs regarding release candidate (#3700)
Browse files Browse the repository at this point in the history
  • Loading branch information
sedghi authored Oct 6, 2023
1 parent 29aeb07 commit 8bc12a3
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 76 deletions.
1 change: 1 addition & 0 deletions .webpack/webpack.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dotenv.config();
const defineValues = {
/* Application */
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.NODE_DEBUG': JSON.stringify(process.env.NODE_DEBUG),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL || '/'),
'process.env.BUILD_NUM': JSON.stringify(BUILD_NUM),
Expand Down
37 changes: 24 additions & 13 deletions extensions/cornerstone/src/commandsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ function commandsModule({
toolGroupService,
cineService,
toolbarService,
stateSyncService,
uiDialogService,
cornerstoneViewportService,
uiNotificationService,
Expand Down Expand Up @@ -155,7 +154,7 @@ function commandsModule({
* @param props - containing the updates to apply
* @param props.measurementKey - chooses the measurement key to apply the
* code to. This will typically be finding or site to apply a
* finind code or a findingSites code.
* finding code or a findingSites code.
* @param props.code - A coding scheme value from DICOM, including:
* * CodeValue - the language independent code, for example '1234'
* * CodingSchemeDesignator - the issue of the code value
Expand Down Expand Up @@ -225,6 +224,25 @@ function commandsModule({
arrowTextCallback: ({ callback, data }) => {
callInputDialog(uiDialogService, data, callback);
},
cleanUpCrosshairs: () => {
// if the crosshairs tool is active, deactivate it and set window level active
// since we are going back to main non-mpr HP
const activeViewportToolGroup = toolGroupService.getToolGroup(null);

if (activeViewportToolGroup._toolInstances?.Crosshairs?.mode === Enums.ToolModes.Active) {
actions.toolbarServiceRecordInteraction({
interactionType: 'tool',
commands: [
{
commandOptions: {
toolName: 'WindowLevel',
},
context: 'CORNERSTONE',
},
],
});
}
},
toggleCine: () => {
const { viewports } = viewportGridService.getState();
const { isCineEnabled } = cineService.getState();
Expand Down Expand Up @@ -294,18 +312,8 @@ function commandsModule({
}

const toolGroup = toolGroupService.getToolGroup(toolGroupId);
const toolGroupViewportIds = toolGroup?.getViewportIds?.();

// if toolGroup has been destroyed, or its viewports have been removed
if (!toolGroupViewportIds || !toolGroupViewportIds.length) {
return;
}

const filteredViewports = Array.from(viewports.values()).filter(viewport => {
return toolGroupViewportIds.includes(viewport.viewportId);
});

if (!filteredViewports.length) {
if (!toolGroup) {
return;
}

Expand Down Expand Up @@ -708,6 +716,9 @@ function commandsModule({
setToolbarToggled: {
commandFn: actions.setToolbarToggled,
},
cleanUpCrosshairs: {
commandFn: actions.cleanUpCrosshairs,
},
};

return {
Expand Down
13 changes: 1 addition & 12 deletions extensions/cornerstone/src/getHangingProtocolModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,7 @@ const mpr: Types.HangingProtocol.Protocol = {
// Turns off crosshairs when switching out of MPR mode
onProtocolExit: [
{
commandName: 'toolbarServiceRecordInteraction',
commandOptions: {
interactionType: 'tool',
commands: [
{
commandOptions: {
toolName: 'WindowLevel',
},
context: 'CORNERSTONE',
},
],
},
commandName: 'cleanUpCrosshairs',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,11 @@ class CornerstoneCacheService {
const segDisplaySetInstanceUID = segmentation.displaySetInstanceUID;
const segDisplaySet = displaySetService.getDisplaySetByUID(segDisplaySetInstanceUID);

const instance = segDisplaySet.instances?.[0] || segDisplaySet.instance;

const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(
viewportDisplaySetInstanceUIDs,
segDisplaySet.instances[0].FrameOfReferenceUID
instance.FrameOfReferenceUID
);

if (shouldDisplaySeg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export default class StaticWadoClient extends api.DICOMwebClient {
if (!valueElem) {
return false;
}
if (valueElem.vr == 'DA') {
if (valueElem.vr === 'DA' && valueElem.Value?.[0]) {
return this.compareDateRange(testValue, valueElem.Value[0]);
}
const value = valueElem.Value;
Expand Down
7 changes: 0 additions & 7 deletions extensions/default/src/Panels/PanelStudyBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ function PanelStudyBrowser({
const [studyDisplayList, setStudyDisplayList] = useState([]);
const [displaySets, setDisplaySets] = useState([]);
const [thumbnailImageSrcMap, setThumbnailImageSrcMap] = useState({});
const isMounted = useRef(true);

const onDoubleClickThumbnailHandler = displaySetInstanceUID => {
let updatedViewports = [];
Expand Down Expand Up @@ -120,17 +119,11 @@ function PanelStudyBrowser({
}
// When the image arrives, render it and store the result in the thumbnailImgSrcMap
newImageSrcEntry[dSet.displaySetInstanceUID] = await getImageSrc(imageId);
if (!isMounted.current) {
return;
}

setThumbnailImageSrcMap(prevState => {
return { ...prevState, ...newImageSrcEntry };
});
});
return () => {
isMounted.current = false;
};
}, [StudyInstanceUIDs, dataSource, displaySetService, getImageSrc]);

// ~~ displaySets
Expand Down
28 changes: 26 additions & 2 deletions extensions/default/src/commandsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ const commandsModule = ({
stageIndex,
reset = false,
}: HangingProtocolParams): boolean => {
const primaryToolBeforeHPChange = toolbarService.getActivePrimaryTool();
try {
// Stores in the state the display set selector id to displaySetUID mapping
// Pass in viewportId for the active viewport. This item will get set as
Expand Down Expand Up @@ -241,7 +242,29 @@ const commandsModule = ({
stateSyncService.store(stateSyncReduce);
// This is a default action applied
const { protocol } = hangingProtocolService.getActiveProtocol();
actions.toggleHpTools(protocol);
actions.toggleHpTools();

// try to use the same tool in the new hanging protocol stage
const primaryButton = toolbarService.getButton(primaryToolBeforeHPChange);
if (primaryButton) {
// is there any type of interaction on this button, if not it might be in the
// items. This is a bit of a hack, but it works for now.

let interactionType = primaryButton.props?.interactionType;

if (!interactionType && primaryButton.props?.items) {
const firstItem = primaryButton.props.items[0];
interactionType = firstItem.props?.interactionType || firstItem.props?.type;
}

if (interactionType) {
toolbarService.recordInteraction({
interactionType,
...primaryButton.props,
});
}
}

// Send the notification about updating the state
if (protocolId !== hpInfo.protocolId) {
// The old protocol callbacks are used for turning off things
Expand All @@ -253,7 +276,8 @@ const commandsModule = ({
commandsManager.run(protocol.callbacks?.onProtocolEnter);
return true;
} catch (e) {
actions.toggleHpTools(hangingProtocolService.getActiveProtocol());
console.error(e);
actions.toggleHpTools();
uiNotificationService.show({
title: 'Apply Hanging Protocol',
message: 'The hanging protocol could not be applied.',
Expand Down
3 changes: 2 additions & 1 deletion platform/app/src/routes/DataSourceWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ function DataSourceWrapper(props) {
!isSamePage || (!isLoading && (newOffset !== previousOffset || isLocationUpdated));

if (isDataInvalid) {
getData().catch(() => {
getData().catch(e => {
console.error(e);
// If there is a data source configuration API, then the Worklist will popup the dialog to attempt to configure it
// and attempt to resolve this issue.
if (dataSource.getConfig().configurationAPI) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function _getInstance(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID) {
return;
}

return series.instances.find(instance => instance.SOPInstanceUID === SOPInstanceUID);
return series.getInstance(SOPInstanceUID);
}

function _getInstanceByImageId(imageId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
function createSeriesMetadata(instances) {
const { SeriesInstanceUID } = instances[0];
function createSeriesMetadata(SeriesInstanceUID) {
const instances = [];
const instancesMap = new Map();

return {
SeriesInstanceUID,
instances,
addInstance: function (newInstance) {
this.addInstances([newInstance]);
},
addInstances: function (newInstances) {
for (let i = 0, len = newInstances.length; i < len; i++) {
const instance = newInstances[i];

if (!instancesMap.has(instance.SOPInstanceUID)) {
instancesMap.set(instance.SOPInstanceUID, instance);
instances.push(instance);
}
}
},
getInstance: function (SOPInstanceUID) {
return instancesMap.get(SOPInstanceUID);
},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,29 @@ function createStudyMetadata(StudyInstanceUID) {
isLoaded: false,
series: [],
/**
*
* @param {object} instance
* @returns {bool} true if series were added; false if series already exist
*/
addInstanceToSeries: function (instance) {
const { SeriesInstanceUID } = instance;
if (!this.StudyDescription) {
this.StudyDescription = instance.StudyDescription;
}
const existingSeries = this.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID);

if (existingSeries) {
existingSeries.instances.push(instance);
} else {
const series = createSeriesMetadata([instance]);
this.series.push(series);
const { Modality } = series;
if (this.ModalitiesInStudy.indexOf(Modality) === -1) {
this.ModalitiesInStudy.push(Modality);
}
}
this.addInstancesToSeries([instance]);
},
/**
*
* @param {object[]} instances
* @param {string} instances[].SeriesInstanceUID
* @param {string} instances[].StudyDescription
* @returns {bool} true if series were added; false if series already exist
*/
addInstancesToSeries: function (instances) {
const { SeriesInstanceUID } = instances[0];
if (!this.StudyDescription) {
this.StudyDescription = instances[0].StudyDescription;
}
const existingSeries = this.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID);
let series = this.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID);

if (existingSeries) {
// Only add instances not already present, so generate a map
// of existing instances and filter the to add by things
// already present.
const sopMap = {};
existingSeries.instances.forEach(it => (sopMap[it.SOPInstanceUID] = it));
const newInstances = instances.filter(it => !sopMap[it.SOPInstanceUID]);
existingSeries.instances.push(...newInstances);
} else {
const series = createSeriesMetadata(instances);
if (!series) {
const series = createSeriesMetadata(SeriesInstanceUID);
this.series.push(series);
}

series.addInstances(instances);
},

setSeriesMetadata: function (SeriesInstanceUID, seriesMetadata) {
Expand All @@ -64,7 +39,8 @@ function createStudyMetadata(StudyInstanceUID) {
if (existingSeries) {
existingSeries = Object.assign(existingSeries, seriesMetadata);
} else {
this.series.push(Object.assign({ instances: [] }, seriesMetadata));
const series = createSeriesMetadata(SeriesInstanceUID);
this.series.push(Object.assign(series, seriesMetadata));
}
},
};
Expand Down
16 changes: 14 additions & 2 deletions platform/core/src/services/ToolBarService/ToolbarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ export default class ToolbarService extends PubSubService {
return;
}
const commandsManager = this._commandsManager;
const { groupId, itemId, interactionType, commands } = interaction;
const { groupId, itemId, commands, type } = interaction;
let { interactionType } = interaction;

// if not interaction type, assume the type can be used
if (!interactionType) {
interactionType = type;
}

switch (interactionType) {
case 'action': {
Expand Down Expand Up @@ -228,6 +234,10 @@ export default class ToolbarService extends PubSubService {
return activeTools;
}

getActivePrimaryTool() {
return this.state.primaryToolId;
}

/** Sets the toggle state of a button to the isToggled state */
public setToggled(id: string, isToggled: boolean): void {
if (isToggled) {
Expand Down Expand Up @@ -259,7 +269,9 @@ export default class ToolbarService extends PubSubService {
}
for (const buttonId of Object.keys(this.buttons)) {
const { primary, items } = this.buttons[buttonId].props || {};
if (primary?.id === id) { return primary; }
if (primary?.id === id) {
return primary;
}
const found = items?.find(childButton => childButton.id === id);
if (found) {
return found;
Expand Down
11 changes: 11 additions & 0 deletions platform/docs/docs/configuration/dataSources/dicom-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,14 @@ directly from
Your public folder should look like this:

![](../../assets/img/dicom-json-public.png)


:::note
When hosting the DICOM JSON files, it is important to be aware that certain providers
do not automatically handle the 404 error and fallback to index.html. For example, Netlify
handles this, but Azure does not. Consequently, when you attempt to access a link with a
specific URL, a 404 error will be displayed.

This issue also occurs locally, where the http-server does not handle it. However,
if you utilize the `serve` package (npx serve ./dist -l 8080 -s), it effectively addresses this problem.
:::
4 changes: 3 additions & 1 deletion platform/docs/docs/configuration/dataSources/static-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ It can be compiled with Java and Gradle, and then run against a set of dicom, in
the example located in /dicom/study1 outputting to /dicomweb, and then a server
run against that data, like this:

```
```bash
git clone https://github.com/OHIF/static-wado
cd static-wado
./gradlew installDist
StaticWado/build/install/StaticWado/bin/StaticWado -d /dicomweb /dicom/study1
cd /dicomweb
npx http-server -p 5000 --cors -g

# you can use npx serve ./dist -l 8080 -s as an alternative to http-server
```

There is then a dev environment in the platform/app directory which can be
Expand Down
2 changes: 2 additions & 0 deletions platform/docs/docs/deployment/build-for-production.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ yarn global add http-server
# Serve the files in our current directory
# Accessible at: `http://localhost:8080`
npx http-server ./dist

# you can use npx serve ./dist -l 8080 -s as an alternative to http-server
```

:::caution
Expand Down
Loading

0 comments on commit 8bc12a3

Please sign in to comment.