diff --git a/extensions/cornerstone/src/index.js b/extensions/cornerstone/src/index.js index 431948332..43f8a97b2 100644 --- a/extensions/cornerstone/src/index.js +++ b/extensions/cornerstone/src/index.js @@ -3,6 +3,7 @@ import init from './init.js'; import commandsModule from './commandsModule.js'; import toolbarModule from './toolbarModule.js'; import CornerstoneViewportDownloadForm from './CornerstoneViewportDownloadForm'; +import { version } from '../package.json'; const Component = React.lazy(() => { return import('./OHIFCornerstoneViewport'); @@ -24,6 +25,7 @@ export default { * Only required property. Should be a unique value across all extensions. */ id: 'cornerstone', + version, /** * diff --git a/extensions/dicom-p10-downloader/.webpack/webpack.dev.js b/extensions/debugging/.webpack/webpack.dev.js similarity index 100% rename from extensions/dicom-p10-downloader/.webpack/webpack.dev.js rename to extensions/debugging/.webpack/webpack.dev.js diff --git a/extensions/dicom-p10-downloader/.webpack/webpack.prod.js b/extensions/debugging/.webpack/webpack.prod.js similarity index 100% rename from extensions/dicom-p10-downloader/.webpack/webpack.prod.js rename to extensions/debugging/.webpack/webpack.prod.js diff --git a/extensions/dicom-p10-downloader/CHANGELOG.md b/extensions/debugging/CHANGELOG.md similarity index 100% rename from extensions/dicom-p10-downloader/CHANGELOG.md rename to extensions/debugging/CHANGELOG.md diff --git a/extensions/dicom-p10-downloader/LICENSE b/extensions/debugging/LICENSE similarity index 100% rename from extensions/dicom-p10-downloader/LICENSE rename to extensions/debugging/LICENSE diff --git a/extensions/dicom-p10-downloader/README.md b/extensions/debugging/README.md similarity index 100% rename from extensions/dicom-p10-downloader/README.md rename to extensions/debugging/README.md diff --git a/extensions/dicom-p10-downloader/package.json b/extensions/debugging/package.json similarity index 86% rename from extensions/dicom-p10-downloader/package.json rename to extensions/debugging/package.json index 74b371429..2fb4aa4ca 100644 --- a/extensions/dicom-p10-downloader/package.json +++ b/extensions/debugging/package.json @@ -1,7 +1,7 @@ { - "name": "@ohif/extension-dicom-p10-downloader", + "name": "@ohif/extension-debugging", "version": "0.1.2", - "description": "OHIF extension for downloading DICOM P10 files", + "description": "OHIF extension for debugging.", "author": "OHIF", "license": "MIT", "repository": "OHIF/Viewers", @@ -35,6 +35,7 @@ "@babel/runtime": "^7.5.5", "dicomweb-client": "^0.6.0", "file-saver": "^2.0.2", - "jszip": "^3.2.2" + "jszip": "^3.2.2", + "detect-browser": "5.1.1" } } diff --git a/extensions/debugging/src/DebugReportModal.css b/extensions/debugging/src/DebugReportModal.css new file mode 100644 index 000000000..c5b75a8fc --- /dev/null +++ b/extensions/debugging/src/DebugReportModal.css @@ -0,0 +1,4 @@ +.debugReportModalHeader { + padding: 10px 0 10px; + color: var(--active-color); +} diff --git a/extensions/debugging/src/DebugReportModal.js b/extensions/debugging/src/DebugReportModal.js new file mode 100644 index 000000000..bc0572127 --- /dev/null +++ b/extensions/debugging/src/DebugReportModal.js @@ -0,0 +1,161 @@ +import React from 'react'; +import { detect } from 'detect-browser'; +import './DebugReportModal.css'; + +const DubugReportModal = ({ + viewports, + studies, + servers, + extensionManager, +}) => { + return ( +
+ + {getAppVersion()} + {getExtensionVersions(extensionManager)} + {getBrowserInfo()} + {getCurrentStudyUrl()} + {getLayout(viewports)} +
+
+ ); +}; + +const getAppVersion = () => { + return ( + + + App + + + Version + {window.version} + + + ); +}; + +const getCurrentStudyUrl = () => { + return ( + + + App + + + URL + {window.location.href} + + + ); +}; + +const getExtensionVersions = extensionManager => { + const { registeredExtensionVesions } = extensionManager; + + const lineItems = Object.keys(registeredExtensionVesions).map(extensionId => { + const version = registeredExtensionVesions[extensionId]; + + return ( + + {extensionId} + {version} + + ); + }); + + return ( + + Extensions + {lineItems} + + ); +}; + +const getLayout = viewports => { + const { numRows, numColumns } = viewports; + + return ( + + + Viewports + + + Layout + + + Rows + {numRows} + + + Columns + {numColumns} + + + SeriesInstanceUIDs + + {getSeriesInstanceUIDsPerRow(viewports)} + + ); +}; + +const getBrowserInfo = () => { + const browser = detect(); + + const { name, os, type, version } = browser; + + return ( + + + Platform + + + name + {name} + + + os + {os} + + + type + {type} + + + version + {version} + + + ); +}; + +const getSeriesInstanceUIDsPerRow = viewports => { + const { viewportSpecificData, numColumns } = viewports; + + debugger; + + // NOTE viewportSpecificData is actually an object with numerical keys. + return Object.keys(viewportSpecificData).map(viewportIndex => { + const vsd = viewportSpecificData[viewportIndex]; + + const [row, column] = _viewportIndexToViewportPosition( + viewportIndex, + numColumns + ); + + return ( + + {`[${row},${column}]`} + {vsd.SeriesInstanceUID} + + ); + }); +}; + +const _viewportIndexToViewportPosition = (viewportIndex, numColumns) => { + const row = Math.floor(viewportIndex / numColumns); + const column = viewportIndex % numColumns; + + return [row, column]; +}; + +export default DubugReportModal; diff --git a/extensions/dicom-p10-downloader/src/commandsModule.js b/extensions/debugging/src/commandsModule.js similarity index 83% rename from extensions/dicom-p10-downloader/src/commandsModule.js rename to extensions/debugging/src/commandsModule.js index ce39ea8b1..a4b05a939 100644 --- a/extensions/dicom-p10-downloader/src/commandsModule.js +++ b/extensions/debugging/src/commandsModule.js @@ -8,12 +8,14 @@ import { getSOPInstanceReferencesFromViewports, } from './utils'; import _downloadAndZip, { downloadInstances } from './downloadAndZip'; +import DebugReportModal from './DebugReportModal'; +import React from 'react'; const { utils: { Queue }, } = OHIF; -export function getCommands(context) { +export function getCommands(context, servicesManager, extensionManager) { const queue = new Queue(1); const actions = { /** @@ -87,9 +89,32 @@ export function getCommands(context) { serverConfig ); }, + openDebugInfoModal({ viewports, studies, servers }) { + const { UIModalService } = servicesManager.services; + + const WrappedDebugReportModal = function() { + return ( + + ); + }; + + UIModalService.show({ + content: WrappedDebugReportModal, + title: `Debugging Information`, + }); + }, }; const definitions = { + openDebugInfoModal: { + commandFn: actions.openDebugInfoModal, + storeContexts: ['viewports', 'servers', 'studies'], + }, downloadAndZip: { commandFn: queue.bindSafe(actions.downloadAndZip, error), storeContexts: ['servers'], diff --git a/extensions/dicom-p10-downloader/src/downloadAndZip.js b/extensions/debugging/src/downloadAndZip.js similarity index 100% rename from extensions/dicom-p10-downloader/src/downloadAndZip.js rename to extensions/debugging/src/downloadAndZip.js diff --git a/extensions/dicom-p10-downloader/src/index.js b/extensions/debugging/src/index.js similarity index 68% rename from extensions/dicom-p10-downloader/src/index.js rename to extensions/debugging/src/index.js index 95fe623c4..88d509643 100644 --- a/extensions/dicom-p10-downloader/src/index.js +++ b/extensions/debugging/src/index.js @@ -1,5 +1,7 @@ import { getDicomWebClientFromConfig } from './utils'; import { getCommands } from './commandsModule'; +import { version } from '../package.json'; +import toolbarModule from './toolbarModule'; /** * Constants @@ -21,6 +23,7 @@ export default { * Only required property. Should be a unique value across all extensions. */ id: 'dicom-p10-downloader', + version, /** * LIFECYCLE HOOKS @@ -37,7 +40,11 @@ export default { * MODULE GETTERS */ - getCommandsModule() { - return getCommands(sharedContext); + getCommandsModule({ servicesManager, extensionManager }) { + return getCommands(sharedContext, servicesManager, extensionManager); + }, + + getToolbarModule() { + return toolbarModule; }, }; diff --git a/extensions/debugging/src/toolbarModule.js b/extensions/debugging/src/toolbarModule.js new file mode 100644 index 000000000..bafb7a4a2 --- /dev/null +++ b/extensions/debugging/src/toolbarModule.js @@ -0,0 +1,20 @@ +const TOOLBAR_BUTTON_TYPES = { + COMMAND: 'command', +}; + +const definitions = [ + { + id: 'Debug Info', + label: 'Debug Info', + icon: 'cog', + // + type: TOOLBAR_BUTTON_TYPES.COMMAND, + commandName: 'openDebugInfoModal', + context: 'VIEWER', + }, +]; + +export default { + definitions, + defaultContext: 'VIEWER', +}; diff --git a/extensions/dicom-p10-downloader/src/utils.js b/extensions/debugging/src/utils.js similarity index 100% rename from extensions/dicom-p10-downloader/src/utils.js rename to extensions/debugging/src/utils.js diff --git a/extensions/dicom-html/src/index.js b/extensions/dicom-html/src/index.js index ce7f58d56..128660d3a 100644 --- a/extensions/dicom-html/src/index.js +++ b/extensions/dicom-html/src/index.js @@ -1,5 +1,6 @@ import React from 'react'; import OHIFDicomHtmlSopClassHandler from './OHIFDicomHtmlSopClassHandler.js'; +import { version } from '../package.json'; const Component = React.lazy(() => { return import('./OHIFDicomHtmlViewport'); @@ -18,6 +19,7 @@ export default { * Only required property. Should be a unique value across all extensions. */ id: 'html', + version, getViewportModule() { return OHIFDicomHtmlViewport; diff --git a/extensions/dicom-microscopy/src/index.js b/extensions/dicom-microscopy/src/index.js index cc3e6d9ff..514f2ed12 100644 --- a/extensions/dicom-microscopy/src/index.js +++ b/extensions/dicom-microscopy/src/index.js @@ -1,5 +1,6 @@ import React from 'react'; import DicomMicroscopySopClassHandler from './DicomMicroscopySopClassHandler.js'; +import { version } from '../package.json'; const Component = React.lazy(() => { return import('./DicomMicroscopyViewport'); @@ -18,6 +19,7 @@ export default { * Only required property. Should be a unique value across all extensions. */ id: 'microscopy', + version, getViewportModule() { return DicomMicroscopyViewport; diff --git a/extensions/dicom-pdf/src/index.js b/extensions/dicom-pdf/src/index.js index 705caeb4b..b09af49bb 100644 --- a/extensions/dicom-pdf/src/index.js +++ b/extensions/dicom-pdf/src/index.js @@ -1,5 +1,6 @@ import React from 'react'; import OHIFDicomPDFSopClassHandler from './OHIFDicomPDFSopClassHandler.js'; +import { version } from '../package.json'; const Component = React.lazy(() => { return import('./ConnectedOHIFDicomPDFViewer'); @@ -18,6 +19,7 @@ export default { * Only required property. Should be a unique value across all extensions. */ id: 'pdf', + version, getViewportModule() { return ConnectedOHIFDicomPDFViewer; }, diff --git a/extensions/dicom-rt/src/index.js b/extensions/dicom-rt/src/index.js index 9d58e1ac0..44001d61b 100644 --- a/extensions/dicom-rt/src/index.js +++ b/extensions/dicom-rt/src/index.js @@ -1,15 +1,16 @@ import React from 'react'; - import init from './init.js'; import sopClassHandlerModule from './OHIFDicomRTStructSopClassHandler'; import id from './id.js'; import RTPanel from './components/RTPanel/RTPanel'; +import { version } from '../package.json'; export default { /** * Only required property. Should be a unique value across all extensions. */ id, + version, /** * diff --git a/extensions/dicom-segmentation/src/index.js b/extensions/dicom-segmentation/src/index.js index d8f49de43..d6c171490 100644 --- a/extensions/dicom-segmentation/src/index.js +++ b/extensions/dicom-segmentation/src/index.js @@ -1,15 +1,16 @@ import React from 'react'; - import init from './init.js'; import toolbarModule from './toolbarModule.js'; import getSopClassHandlerModule from './getOHIFDicomSegSopClassHandler.js'; import SegmentationPanel from './components/SegmentationPanel/SegmentationPanel.js'; +import { version } from '../package.json'; export default { /** * Only required property. Should be a unique value across all extensions. */ id: 'com.ohif.dicom-segmentation', + version, /** * diff --git a/extensions/lesion-tracker/src/index.js b/extensions/lesion-tracker/src/index.js index a521b2128..a3a6d0499 100644 --- a/extensions/lesion-tracker/src/index.js +++ b/extensions/lesion-tracker/src/index.js @@ -1,10 +1,12 @@ import MeasurementComparisonTable from './components/MeasurementComparisonTable'; +import { version } from '../package.json'; export default { /** * Only required property. Should be a unique value across all extensions. */ id: 'lesion-tracker', + version, /** * @param {object} params @@ -26,7 +28,7 @@ export default { component: MeasurementComparisonTable, }, ], - defaultContext: ['VIEWER'] + defaultContext: ['VIEWER'], }; }, diff --git a/extensions/vtk/src/index.js b/extensions/vtk/src/index.js index 6ee1d14e4..d327e16f3 100644 --- a/extensions/vtk/src/index.js +++ b/extensions/vtk/src/index.js @@ -3,6 +3,7 @@ import asyncComponent from './asyncComponent.js'; import commandsModule from './commandsModule.js'; import toolbarModule from './toolbarModule.js'; import withCommandsManager from './withCommandsManager.js'; +import { version } from '../package.json'; // This feels weird // import loadLocales from './loadLocales'; @@ -15,6 +16,7 @@ const vtkExtension = { * Only required property. Should be a unique value across all extensions. */ id: 'vtk', + version, getViewportModule({ commandsManager, servicesManager }) { const ExtendedVTKViewport = props => ( diff --git a/platform/core/src/extensions/ExtensionManager.js b/platform/core/src/extensions/ExtensionManager.js index bb32ab553..f1a81a9bb 100644 --- a/platform/core/src/extensions/ExtensionManager.js +++ b/platform/core/src/extensions/ExtensionManager.js @@ -5,6 +5,7 @@ export default class ExtensionManager { constructor({ commandsManager, servicesManager, api, appConfig = {} }) { this.modules = {}; this.registeredExtensionIds = []; + this.registeredExtensionVesions = {}; this.moduleTypeNames = Object.values(MODULE_TYPES); // this._commandsManager = commandsManager; @@ -51,6 +52,7 @@ export default class ExtensionManager { } let extensionId = extension.id; + const version = extension.version; if (!extensionId) { extensionId = Math.random() @@ -98,6 +100,8 @@ export default class ExtensionManager { // Track extension registration this.registeredExtensionIds.push(extensionId); + + this.registeredExtensionVesions[extensionId] = version; } /** @@ -120,7 +124,8 @@ export default class ExtensionManager { commandsManager: this._commandsManager, appConfig: this._appConfig, configuration, - api: this._api + api: this._api, + extensionManager: this, }); if (!extensionModule) { diff --git a/platform/core/src/extensions/ExtensionManager.test.js b/platform/core/src/extensions/ExtensionManager.test.js index 42965c4a1..d9c3ca235 100644 --- a/platform/core/src/extensions/ExtensionManager.test.js +++ b/platform/core/src/extensions/ExtensionManager.test.js @@ -184,6 +184,8 @@ describe('ExtensionManager.js', () => { commandsManager, appConfig, configuration: extensionConfiguration, + api: undefined, + extensionManager, }); } }); @@ -226,7 +228,7 @@ describe('ExtensionManager.js', () => { return { definitions: { exampleDefinition: { - commandFn: () => { }, + commandFn: () => {}, storeContexts: [], options: {}, }, diff --git a/platform/viewer/.recipes/Nginx-Dcm4che/docker-compose-dcm4che.yml b/platform/viewer/.recipes/Nginx-Dcm4che/docker-compose-dcm4che.yml index 40b6d8efe..84f5efc15 100644 --- a/platform/viewer/.recipes/Nginx-Dcm4che/docker-compose-dcm4che.yml +++ b/platform/viewer/.recipes/Nginx-Dcm4che/docker-compose-dcm4che.yml @@ -9,7 +9,7 @@ services: max-size: '10m' ports: - '389:389' - env_file: ./dcm4che/docker-compose-dcm4che.env + env_file: ./docker-compose-dcm4che.env volumes: - ./dcm4che/etc/localtime:/etc/localtime:ro - ./dcm4che/etc/timezone:/etc/timezone:ro @@ -25,7 +25,7 @@ services: max-size: '10m' ports: - '5432:5432' - env_file: ./dcm4che/docker-compose-dcm4che.env + env_file: ./docker-compose-dcm4che.env volumes: - ./dcm4che/etc/localtime:/etc/localtime:ro - ./dcm4che/etc/timezone:/etc/timezone:ro @@ -44,7 +44,7 @@ services: - '9990:9990' - '11112:11112' - '2575:2575' - env_file: ./dcm4che/docker-compose-dcm4che.env + env_file: ./docker-compose-dcm4che.env environment: WILDFLY_CHOWN: /opt/wildfly/standalone /storage WILDFLY_WAIT_FOR: ldap:389 db:5432 @@ -73,5 +73,4 @@ services: restart: always networks: - dcm4che_default - -networks: dcm4che_default: + networks: dcm4che_default: diff --git a/platform/viewer/package.json b/platform/viewer/package.json index a0260b324..4dd7b9cca 100644 --- a/platform/viewer/package.json +++ b/platform/viewer/package.json @@ -48,11 +48,11 @@ }, "dependencies": { "@babel/runtime": "^7.5.5", + "@ohif/extension-debugging": "^0.1.2", "@ohif/core": "^2.10.2", "@ohif/extension-cornerstone": "^2.9.3", "@ohif/extension-dicom-html": "^1.2.6", "@ohif/extension-dicom-microscopy": "^0.51.1", - "@ohif/extension-dicom-p10-downloader": "^0.1.2", "@ohif/extension-dicom-pdf": "^1.0.4", "@ohif/extension-dicom-rt": "^0.4.2", "@ohif/extension-dicom-segmentation": "^0.4.2", diff --git a/platform/viewer/src/appExtensions/GenericViewerCommands/index.js b/platform/viewer/src/appExtensions/GenericViewerCommands/index.js index 866055a79..3fcfe9403 100644 --- a/platform/viewer/src/appExtensions/GenericViewerCommands/index.js +++ b/platform/viewer/src/appExtensions/GenericViewerCommands/index.js @@ -2,6 +2,9 @@ import commandsModule from './commandsModule.js'; export default { id: 'generic-viewer-commands', + get version() { + return window.version; + }, getCommandsModule({ commandsManager }) { return commandsModule({ commandsManager }); }, diff --git a/platform/viewer/src/appExtensions/MeasurementsPanel/index.js b/platform/viewer/src/appExtensions/MeasurementsPanel/index.js index 41d1f2f99..93de3d7e9 100644 --- a/platform/viewer/src/appExtensions/MeasurementsPanel/index.js +++ b/platform/viewer/src/appExtensions/MeasurementsPanel/index.js @@ -9,6 +9,9 @@ export default { * Only required property. Should be a unique value across all extensions. */ id: 'measurements-table', + get version() { + return window.version; + }, preRegistration({ servicesManager, commandsManager, configuration = {} }) { init({ servicesManager, commandsManager, configuration }); diff --git a/platform/viewer/src/index.js b/platform/viewer/src/index.js index 4b6afde12..aa63f3724 100644 --- a/platform/viewer/src/index.js +++ b/platform/viewer/src/index.js @@ -29,7 +29,9 @@ import OHIFDicomSegmentationExtension from '@ohif/extension-dicom-segmentation'; import OHIFDicomRtExtension from '@ohif/extension-dicom-rt'; import OHIFDicomMicroscopyExtension from '@ohif/extension-dicom-microscopy'; import OHIFDicomPDFExtension from '@ohif/extension-dicom-pdf'; -import OHIFDicomP10DownloaderExtension from '@ohif/extension-dicom-p10-downloader'; +// Add this for Debugging purposes: +//import OHIFDebuggingExtension from '@ohif/extension-debugging'; +import { version } from '../package.json'; /* * Default Settings @@ -38,6 +40,8 @@ let config = {}; if (window) { config = window.config || {}; + + window.version = version; } const appProps = { @@ -49,7 +53,7 @@ const appProps = { OHIFDicomPDFExtension, OHIFDicomSegmentationExtension, OHIFDicomRtExtension, - OHIFDicomP10DownloaderExtension, + //OHIFDebuggingExtension, ], }; diff --git a/yarn.lock b/yarn.lock index 1ad783558..a0a26906f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6782,6 +6782,11 @@ detab@2.0.2, detab@^2.0.0: dependencies: repeat-string "^1.5.4" +detect-browser@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.1.1.tgz#a800db91d3fd60d0861669f5984f1be9ffbe009c" + integrity sha512-5n2aWI57qC3kZaK4j2zYsG6L1LrxgLptGCNhMQgdKhVn6cSdcq43pp6xHPfTHG3TYM6myF4tIPWiZtfdVDgb9w== + detect-file@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"