Compare commits

...
Author SHA1 Message Date
ohif-bot a436436def chore(release): publish [skip ci]
- @ohif/extension-vtk@1.2.2
 - @ohif/ui@1.1.7
 - @ohif/viewer@3.3.2
2019-12-20 19:10:48 +00:00
Mirna Silva d6d92afbda test: Refactoring toolbar data-cy selectors (#1323) 2019-12-20 14:07:00 -05:00
ohif-bot e1142910e4 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.2.1
 - @ohif/ui@1.1.6
 - @ohif/viewer@3.3.1
2019-12-20 18:57:38 +00:00
Mirna Silva 067e6c769b test: Save Measurements Functionality (#1300)
* E2E Tests: Save Measurements Functionality

* Moving test file to PWA only. Script-tag doesn't have the required Study

* Removing data-cy selector from cornerstone toolbar
2019-12-20 13:54:59 -05:00
ohif-bot d375d02a4b chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.2.0
 - @ohif/extension-vtk@1.2.0
 - @ohif/core@2.3.0
 - @ohif/viewer@3.3.0
2019-12-20 17:18:56 +00:00
Igor OctavianoandDanny Brown 63594d36b0 feat: 🎸 Configuration so viewer tools can nix handles (#1304)
* feat: 🎸 Configuration so viewer tools can nix handles

Adds a key to cornerstone configuration that allows to toggle on/off
handle rendering

Closes: #1223

* Update extension docs

* Update doc

* docs: include hideHandles configuration in our configuration docs

* chore: default to hiding handles for annotations

* chore: switch to drawHandlesOnHover to mimic legacy viewer functionality

* Flip logic for drawHandlesOnHover; reverse of hideHandles

* Don't hide the handles of ellipse or rectangle roi

* invert check

Co-authored-by: Danny Brown <danny.ri.brown@gmail.com>
2019-12-20 12:15:40 -05:00
ohif-bot 6c160f517f chore(release): publish [skip ci]
- @ohif/extension-vtk@1.1.7
 - @ohif/ui@1.1.5
 - @ohif/viewer@3.2.2
2019-12-19 15:15:49 +00:00
Gustavo André Lelis 23305cec9c fix: 🐛 Fix drag-n-drop of local files into OHIF (#1319)
* fix: 🐛 Fix drag-n-drop of local files into OHIF

Closes: #1307

* CR Update: Centralize dialogs
2019-12-19 10:14:05 -05:00
ohif-bot 36a741f0bc chore(release): publish [skip ci]
- @ohif/extension-vtk@1.1.6
 - @ohif/core@2.2.1
 - @ohif/viewer@3.2.1
2019-12-18 18:29:28 +00:00
Igor Octaviano 695ad732e1 refactor: 💡 Move DICOMSR code to @ohif/core project (#1310)
* Move DICOMSR to @ohif/core

* refactor: 💡 Move DICOMSR code to @ohif/core project

We've just merged support for DICOM Structured Reports. Today, support
for this feature lives in the @ohif/viewer project in it's lib folder.
Ideally, it should be moved to @ohif/core and given a clear public API
and unit tests.

Closes: #1282

* Update imports

* CR Update: Update imports
2019-12-18 13:25:53 -05:00
38 changed files with 557 additions and 158 deletions

No files matched your search

+14 -3
View File
@@ -1,6 +1,9 @@
# Viewer: Configuration # Viewer: Configuration
We maintain a number of common viewer application configurations at [`<root>/platform/viewer/public/configs`][config-dir]. How these values are passed to the viewer depend on how it's deployed, but the two most common paths are: We maintain a number of common viewer application configurations at
[`<root>/platform/viewer/public/configs`][config-dir]. How these values are
passed to the viewer depend on how it's deployed, but the two most common paths
are:
- `index.html` looks for `https://your-website.com/app-config.js` OR - `index.html` looks for `https://your-website.com/app-config.js` OR
- `index.html` passes the values to `OHIF.installViewer()` - `index.html` passes the values to `OHIF.installViewer()`
@@ -42,8 +45,16 @@ window.config = {
keys: ['v'], keys: ['v'],
}, },
], ],
// Config to pass to the bundled cornerstone extension /* Configuration passed to the bundled cornerstone extension
cornerstoneExtensionConfig: {}, *
* The cornerstone extension is currently tightly coupled to the platform.
* Until we're able to decouple it, this key will serve as a workaround to
* pass it configuration.
*/
cornerstoneExtensionConfig: {
/* Whether to show/hide annotation "handles" */
hideHandles: true,
},
}; };
``` ```
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.2.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.1.1...@ohif/extension-cornerstone@2.2.0) (2019-12-20)
### Features
* 🎸 Configuration so viewer tools can nix handles ([#1304](https://github.com/OHIF/Viewers/issues/1304)) ([63594d3](https://github.com/OHIF/Viewers/commit/63594d36b0bdba59f0901095aed70b75fb05172d)), closes [#1223](https://github.com/OHIF/Viewers/issues/1223)
## [2.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.1.0...@ohif/extension-cornerstone@2.1.1) (2019-12-16) ## [2.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.1.0...@ohif/extension-cornerstone@2.1.1) (2019-12-16)
+14
View File
@@ -85,6 +85,20 @@ Tools can be configured through extension configuration using the tools key:
... ...
``` ```
## Annotate Tools Configuration
*We currently support one property for annotation tools.*
### Hide handles
This extension configuration allows you to toggle on/off handle rendering for all annotate tools:
```js
...
cornerstoneExtensionConfig: {
hideHandles: true,
},
...
## Resources ## Resources
### Repositories ### Repositories
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@ohif/extension-cornerstone", "name": "@ohif/extension-cornerstone",
"version": "2.1.1", "version": "2.2.0",
"description": "OHIF extension for Cornerstone", "description": "OHIF extension for Cornerstone",
"author": "OHIF", "author": "OHIF",
"license": "MIT", "license": "MIT",
@@ -32,7 +32,7 @@
"@ohif/ui": "^0.50.0", "@ohif/ui": "^0.50.0",
"cornerstone-core": "^2.2.8", "cornerstone-core": "^2.2.8",
"cornerstone-math": "^0.1.8", "cornerstone-math": "^0.1.8",
"cornerstone-tools": "^4.8.0", "cornerstone-tools": "^4.9.0",
"cornerstone-wado-image-loader": "^3.0.0", "cornerstone-wado-image-loader": "^3.0.0",
"dcmjs": "^0.8.2", "dcmjs": "^0.8.2",
"dicom-parser": "^1.8.3", "dicom-parser": "^1.8.3",
+65 -26
View File
@@ -76,31 +76,35 @@ export default function init({ servicesManager, configuration }) {
initCornerstoneTools(defaultCsToolsConfig); initCornerstoneTools(defaultCsToolsConfig);
// ~~ Toooools 🙌 const toolsGroupedByType = {
const tools = [ touch: [csTools.PanMultiTouchTool, csTools.ZoomTouchPinchTool],
csTools.PanTool, annotations: [
csTools.ZoomTool, csTools.ArrowAnnotateTool,
csTools.WwwcTool, csTools.EraserTool,
csTools.WwwcRegionTool, csTools.BidirectionalTool,
csTools.MagnifyTool, csTools.LengthTool,
csTools.StackScrollTool, csTools.AngleTool,
csTools.StackScrollMouseWheelTool, csTools.FreehandRoiTool,
// Touch csTools.EllipticalRoiTool,
csTools.PanMultiTouchTool, csTools.DragProbeTool,
csTools.ZoomTouchPinchTool, csTools.RectangleRoiTool,
// Annotations ],
csTools.ArrowAnnotateTool, segmentation: [csTools.BrushTool],
csTools.EraserTool, other: [
csTools.BidirectionalTool, csTools.PanTool,
csTools.LengthTool, csTools.ZoomTool,
csTools.AngleTool, csTools.WwwcTool,
csTools.FreehandRoiTool, csTools.WwwcRegionTool,
csTools.EllipticalRoiTool, csTools.MagnifyTool,
csTools.DragProbeTool, csTools.StackScrollTool,
csTools.RectangleRoiTool, csTools.StackScrollMouseWheelTool,
// Segmentation ],
csTools.BrushTool, };
];
let tools = [];
Object.keys(toolsGroupedByType).forEach(toolsGroup =>
tools.push(...toolsGroupedByType[toolsGroup])
);
/* Add extension tools configuration here. */ /* Add extension tools configuration here. */
const internalToolsConfig = { const internalToolsConfig = {
@@ -114,13 +118,48 @@ export default function init({ servicesManager, configuration }) {
}, },
}; };
/* Abstract tools configuration using extension configuration. */
const parseToolProps = (props, tool) => {
const { annotations } = toolsGroupedByType;
// An alternative approach would be to remove the `drawHandlesOnHover` config
// from the supported configuration properties in `cornerstone-tools`
const toolsWithHideableHandles = annotations.filter(
tool => !['RectangleRoiTool', 'EllipticalRoiTool'].includes(tool.name)
);
let parsedProps = { ...props };
/**
* drawHandles - Never/Always show handles
* drawHandlesOnHover - Only show handles on handle hover (pointNearHandle)
*
* Does not apply to tools where handles aren't placed in predictable
* locations.
*/
if (
configuration.hideHandles !== false &&
toolsWithHideableHandles.includes(tool)
) {
if (props.configuration) {
parsedProps.configuration.drawHandlesOnHover = true;
} else {
parsedProps.configuration = { drawHandlesOnHover: true };
}
}
return parsedProps;
};
/* Add tools with its custom props through extension configuration. */ /* Add tools with its custom props through extension configuration. */
tools.forEach(tool => { tools.forEach(tool => {
const toolName = tool.name.replace('Tool', ''); const toolName = tool.name.replace('Tool', '');
const externalToolsConfig = configuration.tools || {}; const externalToolsConfig = configuration.tools || {};
const externalToolProps = externalToolsConfig[toolName] || {}; const externalToolProps = externalToolsConfig[toolName] || {};
const internalToolProps = internalToolsConfig[toolName] || {}; const internalToolProps = internalToolsConfig[toolName] || {};
const props = merge(internalToolProps, externalToolProps); const props = merge(
internalToolProps,
parseToolProps(externalToolProps, tool)
);
csTools.addTool(tool, props); csTools.addTool(tool, props);
}); });
+43
View File
@@ -3,6 +3,49 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.2.1...@ohif/extension-vtk@1.2.2) (2019-12-20)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.2.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.2.0...@ohif/extension-vtk@1.2.1) (2019-12-20)
**Note:** Version bump only for package @ohif/extension-vtk
# [1.2.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.1.7...@ohif/extension-vtk@1.2.0) (2019-12-20)
### Features
* 🎸 Configuration so viewer tools can nix handles ([#1304](https://github.com/OHIF/Viewers/issues/1304)) ([63594d3](https://github.com/OHIF/Viewers/commit/63594d36b0bdba59f0901095aed70b75fb05172d)), closes [#1223](https://github.com/OHIF/Viewers/issues/1223)
## [1.1.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.1.6...@ohif/extension-vtk@1.1.7) (2019-12-19)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.1.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.1.5...@ohif/extension-vtk@1.1.6) (2019-12-18)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.1.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.1.4...@ohif/extension-vtk@1.1.5) (2019-12-16) ## [1.1.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.1.4...@ohif/extension-vtk@1.1.5) (2019-12-16)
**Note:** Version bump only for package @ohif/extension-vtk **Note:** Version bump only for package @ohif/extension-vtk
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "@ohif/extension-vtk", "name": "@ohif/extension-vtk",
"version": "1.1.5", "version": "1.2.2",
"description": "OHIF extension for VTK.js", "description": "OHIF extension for VTK.js",
"author": "OHIF", "author": "OHIF",
"license": "MIT", "license": "MIT",
@@ -52,9 +52,9 @@
"react-vtkjs-viewport": "^0.3.9" "react-vtkjs-viewport": "^0.3.9"
}, },
"devDependencies": { "devDependencies": {
"@ohif/core": "^2.2.0", "@ohif/core": "^2.3.0",
"@ohif/ui": "^1.1.4", "@ohif/ui": "^1.1.7",
"cornerstone-tools": "^4.8.0", "cornerstone-tools": "^4.9.0",
"cornerstone-wado-image-loader": "^3.0.0", "cornerstone-wado-image-loader": "^3.0.0",
"dicom-parser": "^1.8.3", "dicom-parser": "^1.8.3",
"gh-pages": "^2.0.1", "gh-pages": "^2.0.1",
+19
View File
@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.3.0](https://github.com/OHIF/Viewers/compare/@ohif/core@2.2.1...@ohif/core@2.3.0) (2019-12-20)
### Features
* 🎸 Configuration so viewer tools can nix handles ([#1304](https://github.com/OHIF/Viewers/issues/1304)) ([63594d3](https://github.com/OHIF/Viewers/commit/63594d36b0bdba59f0901095aed70b75fb05172d)), closes [#1223](https://github.com/OHIF/Viewers/issues/1223)
## [2.2.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.2.0...@ohif/core@2.2.1) (2019-12-18)
**Note:** Version bump only for package @ohif/core
# [2.2.0](https://github.com/OHIF/Viewers/compare/@ohif/core@2.1.1...@ohif/core@2.2.0) (2019-12-16) # [2.2.0](https://github.com/OHIF/Viewers/compare/@ohif/core@2.1.1...@ohif/core@2.2.0) (2019-12-16)
+3 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@ohif/core", "name": "@ohif/core",
"version": "2.2.0", "version": "2.3.0",
"description": "Generic business logic for web-based medical imaging applications", "description": "Generic business logic for web-based medical imaging applications",
"author": "OHIF Core Team", "author": "OHIF Core Team",
"license": "MIT", "license": "MIT",
@@ -32,13 +32,14 @@
}, },
"peerDependencies": { "peerDependencies": {
"cornerstone-core": "^2.2.8", "cornerstone-core": "^2.2.8",
"cornerstone-tools": "^4.8.0", "cornerstone-tools": "^4.9.0",
"cornerstone-wado-image-loader": "^3.0.0", "cornerstone-wado-image-loader": "^3.0.0",
"dicom-parser": "^1.8.3" "dicom-parser": "^1.8.3"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.5.5", "@babel/runtime": "^7.5.5",
"ajv": "^6.10.0", "ajv": "^6.10.0",
"dcmjs": "^0.8.3",
"dicomweb-client": "^0.5.2", "dicomweb-client": "^0.5.2",
"isomorphic-base64": "^1.0.2", "isomorphic-base64": "^1.0.2",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
@@ -1,5 +1,10 @@
import { log, studies, utils } from '@ohif/core'; import log from '../log';
import { retrieveMeasurementFromSR, stowSRFromMeasurements } from './handleStructuredReport'; import studies from '../studies';
import utils from '../utils';
import {
retrieveMeasurementFromSR,
stowSRFromMeasurements,
} from './handleStructuredReport';
import findMostRecentStructuredReport from './utils/findMostRecentStructuredReport'; import findMostRecentStructuredReport from './utils/findMostRecentStructuredReport';
/** /**
@@ -65,7 +70,9 @@ const storeMeasurements = async (measurementData, filter, server) => {
message: 'Measurements were saved with success', message: 'Measurements were saved with success',
}; };
} catch (error) { } catch (error) {
log.error(`[DICOMSR] Error while saving the measurements: ${error.message}`); log.error(
`[DICOMSR] Error while saving the measurements: ${error.message}`
);
throw new Error('Error while saving the measurements.'); throw new Error('Error while saving the measurements.');
} }
}; };
@@ -1,11 +1,11 @@
import * as dcmjs from 'dcmjs'; import * as dcmjs from 'dcmjs';
import { DICOMWeb } from '@ohif/core'; import { api } from 'dicomweb-client';
import DICOMWeb from '../DICOMWeb';
import parseDicomStructuredReport from './parseDicomStructuredReport'; import parseDicomStructuredReport from './parseDicomStructuredReport';
import parseMeasurementsData from './parseMeasurementsData'; import parseMeasurementsData from './parseMeasurementsData';
import getAllDisplaySets from './utils/getAllDisplaySets'; import getAllDisplaySets from './utils/getAllDisplaySets';
import { api } from 'dicomweb-client';
const VERSION_NAME = 'dcmjs-0.0'; const VERSION_NAME = 'dcmjs-0.0';
const TRANSFER_SYNTAX_UID = '1.2.840.10008.1.2.1'; const TRANSFER_SYNTAX_UID = '1.2.840.10008.1.2.1';
@@ -34,7 +34,10 @@ const retrieveMeasurementFromSR = async (series, studies, serverUrl) => {
const part10SRArrayBuffer = await dicomWeb.retrieveInstance(options); const part10SRArrayBuffer = await dicomWeb.retrieveInstance(options);
const displaySets = getAllDisplaySets(studies); const displaySets = getAllDisplaySets(studies);
const measurementsData = parseDicomStructuredReport(part10SRArrayBuffer, displaySets); const measurementsData = parseDicomStructuredReport(
part10SRArrayBuffer,
displaySets
);
return measurementsData; return measurementsData;
}; };
@@ -47,13 +50,10 @@ const retrieveMeasurementFromSR = async (series, studies, serverUrl) => {
* @returns {Promise} * @returns {Promise}
*/ */
const stowSRFromMeasurements = async (measurements, serverUrl) => { const stowSRFromMeasurements = async (measurements, serverUrl) => {
const { dataset } = parseMeasurementsData( const { dataset } = parseMeasurementsData(measurements);
measurements
);
const { DicomMetaDictionary, DicomDict } = dcmjs.data; const { DicomMetaDictionary, DicomDict } = dcmjs.data;
const meta = { const meta = {
FileMetaInformationVersion: FileMetaInformationVersion: dataset._meta.FileMetaInformationVersion.Value,
dataset._meta.FileMetaInformationVersion.Value,
MediaStorageSOPClassUID: dataset.SOPClassUID, MediaStorageSOPClassUID: dataset.SOPClassUID,
MediaStorageSOPInstanceUID: dataset.SOPInstanceUID, MediaStorageSOPInstanceUID: dataset.SOPInstanceUID,
TransferSyntaxUID: TRANSFER_SYNTAX_UID, TransferSyntaxUID: TRANSFER_SYNTAX_UID,
File renamed without changes.
@@ -1,4 +1,5 @@
import * as dcmjs from 'dcmjs'; import * as dcmjs from 'dcmjs';
import findInstanceMetadataBySopInstanceUid from './utils/findInstanceMetadataBySopInstanceUid'; import findInstanceMetadataBySopInstanceUid from './utils/findInstanceMetadataBySopInstanceUid';
/** /**
@@ -37,7 +38,12 @@ const parseDicomStructuredReport = (part10SRArrayBuffer, displaySets) => {
const { studyInstanceUid, patientId } = study; const { studyInstanceUid, patientId } = study;
const { seriesInstanceUid } = series; const { seriesInstanceUid } = series;
const { sopInstanceUid, frameIndex } = measurement; const { sopInstanceUid, frameIndex } = measurement;
const imagePath = getImagePath(studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex); const imagePath = getImagePath(
studyInstanceUid,
seriesInstanceUid,
sopInstanceUid,
frameIndex
);
const imageId = instanceMetadata.getImageId(); const imageId = instanceMetadata.getImageId();
if (!imageId) { if (!imageId) {
@@ -75,8 +81,15 @@ const parseDicomStructuredReport = (part10SRArrayBuffer, displaySets) => {
* @param {string} frameIndex * @param {string} frameIndex
* @returns * @returns
*/ */
const getImagePath = (studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex) => { const getImagePath = (
return [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join('_'); studyInstanceUid,
} seriesInstanceUid,
sopInstanceUid,
frameIndex
) => {
return [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join(
'_'
);
};
export default parseDicomStructuredReport; export default parseDicomStructuredReport;
@@ -1,6 +1,8 @@
import * as dcmjs from 'dcmjs'; import * as dcmjs from 'dcmjs';
import { log, measurements } from '@ohif/core';
import cornerstone from 'cornerstone-core'; import cornerstone from 'cornerstone-core';
import log from '../log';
import measurements from '../measurements';
import isToolSupported from './utils/isToolSupported'; import isToolSupported from './utils/isToolSupported';
/** /**
@@ -11,7 +11,9 @@ const findInstanceMetadataBySopInstanceUid = (displaySets, sopInstanceUid) => {
displaySets.find(displaySet => { displaySets.find(displaySet => {
if (!displaySet.images) return false; if (!displaySet.images) return false;
instanceFound = displaySet.images.find(instanceMetadata => instanceMetadata._sopInstanceUID === sopInstanceUid); instanceFound = displaySet.images.find(
instanceMetadata => instanceMetadata._sopInstanceUID === sopInstanceUid
);
return !!instanceFound; return !!instanceFound;
}); });
@@ -4,15 +4,17 @@
* @param {Array} studies * @param {Array} studies
* @returns {Object} Series * @returns {Object} Series
*/ */
const findMostRecentStructuredReport = (studies) => { const findMostRecentStructuredReport = studies => {
let mostRecentStructuredReport; let mostRecentStructuredReport;
studies.forEach(study => { studies.forEach(study => {
const allSeries = study.getSeries ? study.getSeries() : []; const allSeries = study.getSeries ? study.getSeries() : [];
allSeries.forEach(series => { allSeries.forEach(series => {
if (isStructuredReportSeries(series)) { if (isStructuredReportSeries(series)) {
if (!mostRecentStructuredReport || compareSeriesDate(series, mostRecentStructuredReport)) { if (
!mostRecentStructuredReport ||
compareSeriesDate(series, mostRecentStructuredReport)
) {
mostRecentStructuredReport = series; mostRecentStructuredReport = series;
} }
} }
@@ -28,7 +30,7 @@ const findMostRecentStructuredReport = (studies) => {
* @param {Object} series - Series metadata * @param {Object} series - Series metadata
* @returns {boolean} * @returns {boolean}
*/ */
const isStructuredReportSeries = (series) => { const isStructuredReportSeries = series => {
const supportedSopClassUIDs = [ const supportedSopClassUIDs = [
'1.2.840.10008.5.1.4.1.1.88.22', '1.2.840.10008.5.1.4.1.1.88.22',
'1.2.840.10008.5.1.4.1.1.11.1', '1.2.840.10008.5.1.4.1.1.11.1',
@@ -38,7 +40,7 @@ const isStructuredReportSeries = (series) => {
const sopClassUid = firstInstance._instance.sopClassUid; const sopClassUid = firstInstance._instance.sopClassUid;
return supportedSopClassUIDs.includes(sopClassUid); return supportedSopClassUIDs.includes(sopClassUid);
} };
/** /**
* Checkes if series1 is newer than series2 * Checkes if series1 is newer than series2
@@ -48,10 +50,11 @@ const isStructuredReportSeries = (series) => {
* @returns {boolean} true/false if series1 is newer than series2 * @returns {boolean} true/false if series1 is newer than series2
*/ */
const compareSeriesDate = (series1, series2) => { const compareSeriesDate = (series1, series2) => {
return series1._data.seriesDate > series2._data.seriesDate || return (
series1._data.seriesDate > series2._data.seriesDate ||
(series1._data.seriesDate === series2._data.seriesDate && (series1._data.seriesDate === series2._data.seriesDate &&
series1._data.seriesTime > series2._data.seriesTime); series1._data.seriesTime > series2._data.seriesTime)
} );
};
export default findMostRecentStructuredReport; export default findMostRecentStructuredReport;
@@ -4,7 +4,7 @@
* @param {Object} studies - List of studies loaded into the viewer * @param {Object} studies - List of studies loaded into the viewer
* @returns {Object} List of DisplaySets * @returns {Object} List of DisplaySets
*/ */
const getAllDisplaySets = (studies) => { const getAllDisplaySets = studies => {
let allDisplaySets = []; let allDisplaySets = [];
studies.forEach(study => { studies.forEach(study => {
+3
View File
@@ -5,6 +5,7 @@ import { ServicesManager } from './services';
import classes, { CommandsManager, HotkeysManager } from './classes/'; import classes, { CommandsManager, HotkeysManager } from './classes/';
import DICOMWeb from './DICOMWeb'; import DICOMWeb from './DICOMWeb';
import DICOMSR from './DICOMSR';
import cornerstone from './cornerstone.js'; import cornerstone from './cornerstone.js';
import hangingProtocols from './hanging-protocols'; import hangingProtocols from './hanging-protocols';
import header from './header.js'; import header from './header.js';
@@ -46,6 +47,7 @@ const OHIF = {
object, object,
log, log,
DICOMWeb, DICOMWeb,
DICOMSR,
viewer: {}, viewer: {},
measurements, measurements,
hangingProtocols, hangingProtocols,
@@ -76,6 +78,7 @@ export {
object, object,
log, log,
DICOMWeb, DICOMWeb,
DICOMSR,
measurements, measurements,
hangingProtocols, hangingProtocols,
// //
+1
View File
@@ -28,6 +28,7 @@ describe('Top level exports', () => {
'object', 'object',
'log', 'log',
'DICOMWeb', 'DICOMWeb',
'DICOMSR',
'OHIF', // 'OHIF', //
'measurements', 'measurements',
'hangingProtocols', 'hangingProtocols',
+27
View File
@@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.7](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.6...@ohif/ui@1.1.7) (2019-12-20)
**Note:** Version bump only for package @ohif/ui
## [1.1.6](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.5...@ohif/ui@1.1.6) (2019-12-20)
**Note:** Version bump only for package @ohif/ui
## [1.1.5](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.4...@ohif/ui@1.1.5) (2019-12-19)
### Bug Fixes
* 🐛 Fix drag-n-drop of local files into OHIF ([#1319](https://github.com/OHIF/Viewers/issues/1319)) ([23305ce](https://github.com/OHIF/Viewers/commit/23305cec9c0f514e73a8dd17f984ffc87ad8d131)), closes [#1307](https://github.com/OHIF/Viewers/issues/1307)
## [1.1.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.3...@ohif/ui@1.1.4) (2019-12-16) ## [1.1.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.1.3...@ohif/ui@1.1.4) (2019-12-16)
**Note:** Version bump only for package @ohif/ui **Note:** Version bump only for package @ohif/ui
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@ohif/ui", "name": "@ohif/ui",
"version": "1.1.4", "version": "1.1.7",
"description": "A set of React components for Medical Imaging Viewers", "description": "A set of React components for Medical Imaging Viewers",
"author": "OHIF Contributors", "author": "OHIF Contributors",
"license": "MIT", "license": "MIT",
@@ -79,7 +79,11 @@ class MeasurementTable extends Component {
</ScrollableArea> </ScrollableArea>
<div className="measurementTableFooter"> <div className="measurementTableFooter">
{saveFunction && ( {saveFunction && (
<button onClick={this.saveFunction} className="saveBtn"> <button
onClick={this.saveFunction}
className="saveBtn"
data-cy="save-measurements-btn"
>
<Icon name="save" width="14px" height="14px" /> <Icon name="save" width="14px" height="14px" />
Save measurements Save measurements
</button> </button>
@@ -43,6 +43,7 @@ const renderTabsHeader = (tabs, activeTabIndex, onHeaderChanged) => {
? tabs.map((tab, index) => { ? tabs.map((tab, index) => {
const { name, hidden = false } = tab; const { name, hidden = false } = tab;
const cypressSelectorId = name.toLowerCase();
const tabClass = const tabClass =
index === activeTabIndex ? 'nav-link active' : 'nav-link'; index === activeTabIndex ? 'nav-link active' : 'nav-link';
return !hidden ? ( return !hidden ? (
@@ -52,6 +53,7 @@ const renderTabsHeader = (tabs, activeTabIndex, onHeaderChanged) => {
onHeaderChanged(index); onHeaderChanged(index);
}} }}
className={tabClass} className={tabClass}
data-cy={cypressSelectorId}
> >
<button>{name}</button> <button>{name}</button>
</li> </li>
@@ -152,6 +152,7 @@ const DialogProvider = ({ children, service }) => {
onStart, onStart,
onStop, onStop,
onDrag, onDrag,
showOverlay,
} = dialog; } = dialog;
let position = let position =
@@ -160,7 +161,7 @@ const DialogProvider = ({ children, service }) => {
position = centerPositions.find(position => position.id === id); position = centerPositions.find(position => position.id === id);
} }
return ( const dragableItem = () => (
<Draggable <Draggable
key={id} key={id}
disabled={!isDraggable} disabled={!isDraggable}
@@ -217,6 +218,16 @@ const DialogProvider = ({ children, service }) => {
</div> </div>
</Draggable> </Draggable>
); );
return (
showOverlay ? (
<div className="Overlay" key={id}>
{dragableItem()}
</div>
) : (
dragableItem()
)
);
}); });
/** /**
@@ -238,13 +249,11 @@ const DialogProvider = ({ children, service }) => {
return ( return (
<DialogContext.Provider value={{ create, dismiss, dismissAll, isEmpty }}> <DialogContext.Provider value={{ create, dismiss, dismissAll, isEmpty }}>
<div className="DraggableArea"> {!isEmpty() &&
{dialogs.some(dialog => dialog.showOverlay) ? ( <div className="DraggableArea">
<div className="Overlay active">{renderDialogs()}</div> {renderDialogs()}
) : ( </div>
renderDialogs() }
)}
</div>
{children} {children}
</DialogContext.Provider> </DialogContext.Provider>
); );
@@ -6,17 +6,16 @@
div div
cursor: grabbing !important cursor: grabbing !important
.DraggableArea, .Overlay .DraggableArea
width: 100% width: 100%
height: 100% height: 100%
position: absolute position: absolute
.Overlay
.Overlay.active position: fixed
position: fixed z-index: 999
z-index: 999 left: 0
left: 0 top: 0
top: 0 width: 100%
width: 100% height: 100%
height: 100% overflow: auto
overflow: auto background: rgba(0,0,0,.1)
background: rgba(0,0,0,.1)
+7 -1
View File
@@ -23,8 +23,14 @@ export function ToolbarButton(props) {
} }
}; };
const cypressSelectorId = props.label.toLowerCase();
return ( return (
<div className={className} onClick={handleClick}> <div
className={className}
onClick={handleClick}
data-cy={cypressSelectorId}
>
{iconProps && <Icon {...iconProps} />} {iconProps && <Icon {...iconProps} />}
<div className="toolbar-button-label"> <div className="toolbar-button-label">
{t(label)} {t(label)}
+46
View File
@@ -3,6 +3,52 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.3.2](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.3.1...@ohif/viewer@3.3.2) (2019-12-20)
**Note:** Version bump only for package @ohif/viewer
## [3.3.1](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.3.0...@ohif/viewer@3.3.1) (2019-12-20)
**Note:** Version bump only for package @ohif/viewer
# [3.3.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.2.2...@ohif/viewer@3.3.0) (2019-12-20)
### Features
* 🎸 Configuration so viewer tools can nix handles ([#1304](https://github.com/OHIF/Viewers/issues/1304)) ([63594d3](https://github.com/OHIF/Viewers/commit/63594d36b0bdba59f0901095aed70b75fb05172d)), closes [#1223](https://github.com/OHIF/Viewers/issues/1223)
## [3.2.2](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.2.1...@ohif/viewer@3.2.2) (2019-12-19)
### Bug Fixes
* 🐛 Fix drag-n-drop of local files into OHIF ([#1319](https://github.com/OHIF/Viewers/issues/1319)) ([23305ce](https://github.com/OHIF/Viewers/commit/23305cec9c0f514e73a8dd17f984ffc87ad8d131)), closes [#1307](https://github.com/OHIF/Viewers/issues/1307)
## [3.2.1](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.2.0...@ohif/viewer@3.2.1) (2019-12-18)
**Note:** Version bump only for package @ohif/viewer
# [3.2.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.1.12...@ohif/viewer@3.2.0) (2019-12-16) # [3.2.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.1.12...@ohif/viewer@3.2.0) (2019-12-16)
@@ -266,7 +266,7 @@ describe('OHIF Cornerstone Toolbar', () => {
let iconName; let iconName;
//Click on one of the secondary tools from the overlay //Click on one of the secondary tools from the overlay
cy.get('.tooltip-inner > :nth-child(1)') cy.get('[data-cy="magnify"]')
.click() .click()
.then($magnifyBtn => { .then($magnifyBtn => {
cy.wrap($magnifyBtn) cy.wrap($magnifyBtn)
@@ -407,9 +407,7 @@ describe('OHIF Cornerstone Toolbar', () => {
.as('toolbarOverlay') .as('toolbarOverlay')
.should('be.visible'); .should('be.visible');
//Click on Clear button //Click on Clear button
cy.get('.tooltip-inner') cy.get('[data-cy="clear"]').click();
.contains('Clear')
.click();
//Verify if measurements were removed from the measurements panel //Verify if measurements were removed from the measurements panel
cy.get('.measurementItem').should('not.exist'); cy.get('.measurementItem').should('not.exist');
@@ -446,9 +444,7 @@ describe('OHIF Cornerstone Toolbar', () => {
.should('be.visible') .should('be.visible')
.then(() => { .then(() => {
//Click Eraser button //Click Eraser button
cy.get('.tooltip-inner') cy.get('[data-cy="eraser"]').click({ force: true });
.contains('Eraser')
.click({ force: true });
}); });
//Erase measurement #1 and Verify if it was removed from the measurements panel //Erase measurement #1 and Verify if it was removed from the measurements panel
@@ -471,9 +467,7 @@ describe('OHIF Cornerstone Toolbar', () => {
cy.get('.tooltip-toolbar-overlay').should('be.visible'); cy.get('.tooltip-toolbar-overlay').should('be.visible');
// Click on Invert button // Click on Invert button
cy.get('.tooltip-inner') cy.get('[data-cy="invert"]').click();
.contains('Invert')
.click();
// Visual comparison // Visual comparison
cy.screenshot('Invert tool - Should Invert Canvas'); cy.screenshot('Invert tool - Should Invert Canvas');
@@ -488,9 +482,7 @@ describe('OHIF Cornerstone Toolbar', () => {
.should('be.visible') .should('be.visible')
.then(() => { .then(() => {
//Click on Rotate button //Click on Rotate button
cy.get('.tooltip-inner') cy.get('[data-cy="rotate right"]').click({ force: true });
.contains('Rotate')
.click({ force: true });
}); });
// Visual comparison // Visual comparison
@@ -505,9 +497,7 @@ describe('OHIF Cornerstone Toolbar', () => {
cy.get('.tooltip-toolbar-overlay').should('be.visible'); cy.get('.tooltip-toolbar-overlay').should('be.visible');
//Click on Flip H button //Click on Flip H button
cy.get('.tooltip-inner') cy.get('[data-cy="flip h"]').click();
.contains('Flip H')
.click();
// Visual comparison // Visual comparison
cy.screenshot('Flip H tool - Should Flip Image on Y axis'); cy.screenshot('Flip H tool - Should Flip Image on Y axis');
@@ -521,9 +511,7 @@ describe('OHIF Cornerstone Toolbar', () => {
cy.get('.tooltip-toolbar-overlay').should('be.visible'); cy.get('.tooltip-toolbar-overlay').should('be.visible');
//Click on Flip V button //Click on Flip V button
cy.get('.tooltip-inner') cy.get('[data-cy="flip v"]').click();
.contains('Flip V')
.click();
// Visual comparison // Visual comparison
cy.screenshot('Flip V tool - Should Flip Image on X axis'); cy.screenshot('Flip V tool - Should Flip Image on X axis');
@@ -27,7 +27,7 @@ describe('OHIF VTK Extension', () => {
.wait(1000); // TODO: Once issue #1167 is fixed, the wait command should be removed. (https://github.com/OHIF/Viewers/issues/1167) .wait(1000); // TODO: Once issue #1167 is fixed, the wait command should be removed. (https://github.com/OHIF/Viewers/issues/1167)
//Select 2D MPR button //Select 2D MPR button
cy.get('.PluginSwitch > .toolbar-button').click(); cy.get('[data-cy="2d mpr"]').click();
//Wait Reformatting Images //Wait Reformatting Images
cy.waitVTKReformatting(); cy.waitVTKReformatting();
@@ -0,0 +1,149 @@
describe('OHIF Save Measurements', function() {
before(() => {
cy.openStudy('Fall 1');
cy.expectMinimumThumbnails(2);
});
beforeEach(() => {
// Drags Study thumbnail into viewport
cy.get('[data-cy="thumbnail-list"]:nth-child(1)')
.scrollIntoView()
.drag('.viewport-drop-target');
// Wait image to load on viewport
cy.wait(2000);
cy.resetViewport();
cy.initCommonElementsAliases();
});
it('saves new measurement annotation', function() {
// Add measurement in the viewport
cy.addLengthMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.at.least', 1);
// Save new measurement
cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that success message overlay is displayed
cy.get('.sb-success')
.should('be.visible')
.and('contains.text', 'Measurements were saved with success');
// Visual test comparison
cy.screenshot('Save Measurements - new measurement added');
cy.percyCanvasSnapshot('Save Measurements - new measurement added');
});
it('retrieves saved measurements', function() {
// Add measurement in the viewport
cy.addLengthMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementDisplayText') // Get label size of the recently added measurement
.last()
.then($measurementSizeLabel => {
// Save new measurement
cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that success message overlay is displayed
cy.get('.sb-success').should('be.visible');
// Reload the page
cy.reload();
//Verify that recently added measurement was retrieved
cy.get('@measurementsBtn').click();
cy.get('.measurementDisplayText') // Get label size of the recently added measurement
.last()
.then($retrivedMeasurementSizeLabel => {
expect($retrivedMeasurementSizeLabel.textContent).to.eq(
$measurementSizeLabel.textContent
);
});
});
});
it('checks error message when saving without any measurement', function() {
// Checks that measurement list is empty
cy.get('.numberOfItems').should('have.text', '0');
// Click on Save Measurement button
cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that error message overlay is displayed
cy.get('.sb-error')
.should('be.visible')
.and('contains.text', 'Error while saving the measurements');
// Close message overlay
cy.get('.sb-closeIcon').click();
});
it('checks if warning message is displayed on measurements of unsupported tools', function() {
// Add measurement for unsupported tool in the viewport
cy.addAngleMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.at.least', 1);
// Check that warning is displayed for unsupported tool
cy.get('.hasWarnings').should('be.visible');
// Save new measurement
cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that error message overlay is displayed
cy.get('.sb-error')
.should('be.visible')
.and('contains.text', 'Error while saving the measurements');
// Close message overlay
cy.get('.sb-closeIcon').click();
// Close Measurements panel
cy.get('@measurementsBtn').click();
});
it('checks if measurements of unsupported tools were not saved', function() {
// Add measurement for supported tool in the viewport
cy.addLengthMeasurement();
// Add measurement for unsupported tool in the viewport
cy.addAngleMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.eq', 2);
// Check that warning is displayed for unsupported tool
cy.get('.hasWarnings').should('be.visible');
// Save new measurement
cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that success message overlay is displayed
cy.get('.sb-success')
.should('be.visible')
.and('contains.text', 'Measurements were saved with success');
// Reload the page
cy.reload();
//Verify that measurement for unsupported tool was not saved
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.eq', 1);
// Close Measurements panel
cy.get('@measurementsBtn').click();
});
});
+17 -22
View File
@@ -1,16 +1,16 @@
//Creating aliases for Cornerstone tools buttons //Creating aliases for Cornerstone tools buttons
export function initCornerstoneToolsAliases() { export function initCornerstoneToolsAliases() {
cy.get('.ToolbarRow > :nth-child(2)').as('stackScrollBtn'); cy.get('[data-cy="stack scroll"]').as('stackScrollBtn');
cy.get('.ToolbarRow > :nth-child(3)').as('zoomBtn'); cy.get('[data-cy="zoom"]').as('zoomBtn');
cy.get('.ToolbarRow > :nth-child(4)').as('levelsBtn'); cy.get('[data-cy="levels"]').as('levelsBtn');
cy.get('.ToolbarRow > :nth-child(5)').as('panBtn'); cy.get('[data-cy="pan"]').as('panBtn');
cy.get('.ToolbarRow > :nth-child(6)').as('lengthBtn'); cy.get('[data-cy="length"]').as('lengthBtn');
cy.get('.ToolbarRow > :nth-child(7)').as('annotateBtn'); cy.get('[data-cy="annotate"]').as('annotateBtn');
cy.get('.ToolbarRow > :nth-child(8)').as('angleBtn'); cy.get('[data-cy="angle"]').as('angleBtn');
cy.get('.ToolbarRow > :nth-child(9)').as('resetBtn'); cy.get('[data-cy="reset"]').as('resetBtn');
cy.get('.ToolbarRow > :nth-child(10)').as('cineBtn'); cy.get('[data-cy="cine"]').as('cineBtn');
cy.get('.expandableToolMenu').as('moreBtn'); cy.get('[data-cy="more"]').as('moreBtn');
cy.get('.btn-group > .toolbar-button').as('layoutBtn'); cy.get('[data-cy="layout"]').as('layoutBtn');
cy.get('.viewport-element').as('viewport'); cy.get('.viewport-element').as('viewport');
} }
@@ -44,14 +44,13 @@ export function initRouteAliases() {
//Creating aliases for VTK tools buttons //Creating aliases for VTK tools buttons
export function initVTKToolsAliases() { export function initVTKToolsAliases() {
cy.get('.PluginSwitch > .toolbar-button').as('twodmprBtn'); cy.get('[data-cy="crosshairs"]').as('crosshairsBtn');
cy.get('.ToolbarRow > :nth-child(2)').as('crosshairsBtn'); cy.get('[data-cy="wwwc"]').as('wwwcBtn');
cy.get('.ToolbarRow > :nth-child(3)').as('wwwcBtn'); cy.get('[data-cy="rotate"]').as('rotateBtn');
cy.get('.ToolbarRow > :nth-child(4)').as('rotateBtn');
cy.get('.slab-thickness').as('slabSlider'); cy.get('.slab-thickness').as('slabSlider');
cy.get('.select-ohif').as('modeDropdown'); cy.get('.select-ohif').as('modeDropdown');
cy.get('.ohif-check-label').as('modeCheckbox'); cy.get('.ohif-check-label').as('modeCheckbox');
cy.get('.btn-group > .toolbar-button').as('layoutBtn'); cy.get('[data-cy="layout"]').as('layoutBtn');
} }
//Creating aliases for Study List page elements on Desktop experience //Creating aliases for Study List page elements on Desktop experience
@@ -82,12 +81,8 @@ export function initStudyListAliasesOnTablet() {
//Creating aliases for User Preferences modal //Creating aliases for User Preferences modal
export function initPreferencesModalAliases() { export function initPreferencesModalAliases() {
cy.get('.OHIFModal').as('preferencesModal'); cy.get('.OHIFModal').as('preferencesModal');
cy.get('.nav-link') cy.get('[data-cy="hotkeys"]').as('userPreferencesHotkeysTab');
.first() cy.get('[data-cy="general"]').as('userPreferencesGeneralTab');
.as('userPreferencesHotkeysTab');
cy.get('.nav-link')
.last()
.as('userPreferencesGeneralTab');
cy.get('[data-cy="reset-default-btn"]').as('restoreBtn'); cy.get('[data-cy="reset-default-btn"]').as('restoreBtn');
cy.get('[data-cy="cancel-btn"]').as('cancelBtn'); cy.get('[data-cy="cancel-btn"]').as('cancelBtn');
cy.get('[data-cy="save-btn"]').as('saveBtn'); cy.get('[data-cy="save-btn"]').as('saveBtn');
+10 -12
View File
@@ -209,7 +209,7 @@ Cypress.Commands.add('waitDicomImage', (timeout = 20000) => {
//Command to reset and clear all the changes made to the viewport //Command to reset and clear all the changes made to the viewport
Cypress.Commands.add('resetViewport', () => { Cypress.Commands.add('resetViewport', () => {
//Click on More button //Click on More button
cy.get('.expandableToolMenu') cy.get('[data-cy="more"]')
.as('moreBtn') .as('moreBtn')
.click(); .click();
//Verify if overlay is displayed //Verify if overlay is displayed
@@ -219,11 +219,11 @@ Cypress.Commands.add('resetViewport', () => {
} }
}); });
//Click on Clear button //Click on Clear button
cy.get('.tooltip-inner > :nth-child(10)') cy.get('[data-cy="clear"]')
.as('clearBtn') .as('clearBtn')
.click(); .click();
//Click on Reset button //Click on Reset button
cy.get('.ToolbarRow > :nth-child(9)') cy.get('[data-cy="reset"]')
.as('resetBtn') .as('resetBtn')
.click(); .click();
}); });
@@ -284,9 +284,8 @@ Cypress.Commands.add('initStudyListAliasesOnTablet', () => {
Cypress.Commands.add( Cypress.Commands.add(
'addLengthMeasurement', 'addLengthMeasurement',
(firstClick = [150, 100], secondClick = [130, 170]) => { (firstClick = [150, 100], secondClick = [130, 170]) => {
cy.initCornerstoneToolsAliases(); cy.get('[data-cy="length"]').click();
cy.get('@lengthBtn').click(); cy.addLine('.viewport-element', firstClick, secondClick);
cy.addLine('@viewport', firstClick, secondClick);
} }
); );
@@ -294,9 +293,8 @@ Cypress.Commands.add(
Cypress.Commands.add( Cypress.Commands.add(
'addAngleMeasurement', 'addAngleMeasurement',
(initPos = [180, 390], midPos = [300, 410], finalPos = [180, 450]) => { (initPos = [180, 390], midPos = [300, 410], finalPos = [180, 450]) => {
cy.initCornerstoneToolsAliases(); cy.get('[data-cy="angle"]').click();
cy.get('@angleBtn').click(); cy.addAngle('.viewport-element', initPos, midPos, finalPos);
cy.addAngle('@viewport', initPos, midPos, finalPos);
} }
); );
@@ -369,7 +367,7 @@ Cypress.Commands.add('percyCanvasSnapshot', (name, options = {}) => {
}); });
Cypress.Commands.add('setLayout', (columns = 1, rows = 1) => { Cypress.Commands.add('setLayout', (columns = 1, rows = 1) => {
cy.get('.btn-group > .toolbar-button').click(); cy.get('[data-cy="layout"]').click();
cy.get('.layoutChooser') cy.get('.layoutChooser')
.find('tr') .find('tr')
@@ -471,12 +469,12 @@ Cypress.Commands.add(
Cypress.Commands.add('openDownloadImageModal', () => { Cypress.Commands.add('openDownloadImageModal', () => {
// Click on More button // Click on More button
cy.get('.expandableToolMenu') cy.get('[data-cy="more"]')
.as('moreBtn') .as('moreBtn')
.click(); .click();
// Click on Download button // Click on Download button
cy.get('.tooltip-inner > :nth-child(13)') cy.get('[data-cy="download"]')
.as('downloadBtn') .as('downloadBtn')
.click(); .click();
}); });
+6 -6
View File
@@ -1,6 +1,6 @@
{ {
"name": "@ohif/viewer", "name": "@ohif/viewer",
"version": "3.2.0", "version": "3.3.2",
"description": "OHIF Viewer", "description": "OHIF Viewer",
"author": "OHIF Contributors", "author": "OHIF Contributors",
"license": "MIT", "license": "MIT",
@@ -45,20 +45,20 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.5.5", "@babel/runtime": "^7.5.5",
"@ohif/core": "^2.2.0", "@ohif/core": "^2.3.0",
"@ohif/extension-cornerstone": "^2.1.1", "@ohif/extension-cornerstone": "^2.2.0",
"@ohif/extension-dicom-html": "^1.1.0", "@ohif/extension-dicom-html": "^1.1.0",
"@ohif/extension-dicom-microscopy": "^0.50.6", "@ohif/extension-dicom-microscopy": "^0.50.6",
"@ohif/extension-dicom-pdf": "^1.0.1", "@ohif/extension-dicom-pdf": "^1.0.1",
"@ohif/extension-vtk": "^1.1.5", "@ohif/extension-vtk": "^1.2.2",
"@ohif/i18n": "^0.52.4", "@ohif/i18n": "^0.52.4",
"@ohif/ui": "^1.1.4", "@ohif/ui": "^1.1.7",
"@tanem/react-nprogress": "^1.1.25", "@tanem/react-nprogress": "^1.1.25",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"core-js": "^3.2.1", "core-js": "^3.2.1",
"cornerstone-core": "^2.2.8", "cornerstone-core": "^2.2.8",
"cornerstone-math": "^0.1.8", "cornerstone-math": "^0.1.8",
"cornerstone-tools": "^4.8.0", "cornerstone-tools": "^4.9.0",
"cornerstone-wado-image-loader": "^3.0.0", "cornerstone-wado-image-loader": "^3.0.0",
"dcmjs": "^0.8.2", "dcmjs": "^0.8.2",
"dicom-parser": "^1.8.3", "dicom-parser": "^1.8.3",
@@ -1,9 +1,8 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { MeasurementTable } from '@ohif/ui'; import { MeasurementTable } from '@ohif/ui';
import OHIF from '@ohif/core'; import OHIF, { DICOMSR } from '@ohif/core';
import moment from 'moment'; import moment from 'moment';
import cornerstone from 'cornerstone-core'; import cornerstone from 'cornerstone-core';
import DICOMSR from './../../lib/DICOMSR';
import jumpToRowItem from './jumpToRowItem.js'; import jumpToRowItem from './jumpToRowItem.js';
@@ -32,9 +31,7 @@ function groupBy(list, props) {
*/ */
function getAllTools(toolGroups = []) { function getAllTools(toolGroups = []) {
let tools = []; let tools = [];
toolGroups.forEach( toolGroups.forEach(toolGroup => (tools = tools.concat(toolGroup.childTools)));
toolGroup => (tools = tools.concat(toolGroup.childTools))
);
return tools; return tools;
} }
@@ -80,6 +80,7 @@ export default function init({
id: 'labelling', id: 'labelling',
isDraggable: false, isDraggable: false,
showOverlay: true, showOverlay: true,
centralize: true,
content: LabellingFlow, content: LabellingFlow,
contentProps: { contentProps: {
measurementData, measurementData,
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { MODULE_TYPES } from '@ohif/core'; import { MODULE_TYPES } from '@ohif/core';
import OHIF from '@ohif/core'; import OHIF, { DICOMSR } from '@ohif/core';
import { withDialog } from '@ohif/ui'; import { withDialog } from '@ohif/ui';
import moment from 'moment'; import moment from 'moment';
import ConnectedHeader from './ConnectedHeader.js'; import ConnectedHeader from './ConnectedHeader.js';
@@ -12,7 +12,6 @@ import ConnectedStudyBrowser from './ConnectedStudyBrowser.js';
import ConnectedViewerMain from './ConnectedViewerMain.js'; import ConnectedViewerMain from './ConnectedViewerMain.js';
import SidePanel from './../components/SidePanel.js'; import SidePanel from './../components/SidePanel.js';
import { extensionManager } from './../App.js'; import { extensionManager } from './../App.js';
import DICOMSR from '../lib/DICOMSR';
// Contexts // Contexts
import WhiteLabellingContext from '../context/WhiteLabellingContext.js'; import WhiteLabellingContext from '../context/WhiteLabellingContext.js';
+14 -4
View File
@@ -5962,10 +5962,10 @@ cornerstone-math@^0.1.8:
resolved "https://registry.yarnpkg.com/cornerstone-math/-/cornerstone-math-0.1.8.tgz#68ab1f9e4fdcd7c5cb23a0d2eb4263f9f894f1c5" resolved "https://registry.yarnpkg.com/cornerstone-math/-/cornerstone-math-0.1.8.tgz#68ab1f9e4fdcd7c5cb23a0d2eb4263f9f894f1c5"
integrity sha512-x7NEQHBtVG7j1yeyj/aRoKTpXv1Vh2/H9zNLMyqYJDtJkNng8C4Q8M3CgZ1qer0Yr7eVq2x+Ynmj6kfOm5jXKw== integrity sha512-x7NEQHBtVG7j1yeyj/aRoKTpXv1Vh2/H9zNLMyqYJDtJkNng8C4Q8M3CgZ1qer0Yr7eVq2x+Ynmj6kfOm5jXKw==
cornerstone-tools@^4.8.0: cornerstone-tools@^4.9.0:
version "4.8.0" version "4.9.0"
resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-4.8.0.tgz#1972546e13e9a09b8aa25a3541ffc345283eec01" resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-4.9.0.tgz#8b68603c32aceb84baf860f4dd0d36ac176e8b75"
integrity sha512-PO7/jYbVwc+ddF9JW/o/JXqNPFZV7y1PUTzlRATC9FeXLXNKIkSFBCF5SA1EGJoyjzRYGDBgTZuTYhfm96AlAA== integrity sha512-6yHzXm4qn7VuHMRiaV/oS3khdMidtTho6P1OIYICqZ2pmorsH8jN8LvNgqz+Ky9Nf+wvrvi7ul8ZzcD1sJTkWA==
dependencies: dependencies:
"@babel/runtime" "7.1.2" "@babel/runtime" "7.1.2"
cornerstone-math "0.1.7" cornerstone-math "0.1.7"
@@ -6545,6 +6545,16 @@ dcmjs@^0.8.2:
loglevelnext "^3.0.1" loglevelnext "^3.0.1"
ndarray "^1.0.18" ndarray "^1.0.18"
dcmjs@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.8.3.tgz#fff1b030b6cb2d6e2afb1aa99840bfa853724c31"
integrity sha512-eXQjqgtJf9+oseraKDNDm2A5F3Th4B2GJeZtjStj0IFXxjlbPOzdq3PfCyxdwfRaKOBIwr0q3YK/Vfs2CpQY8Q==
dependencies:
"@babel/polyfill" "^7.6.0"
"@babel/runtime" "^7.6.3"
loglevelnext "^3.0.1"
ndarray "^1.0.18"
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.1, debug@^2.6.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.1, debug@^2.6.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
version "2.6.9" version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"