Compare commits

...
Author SHA1 Message Date
ohif-bot 17447baf44 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.0.2
 - @ohif/core@2.0.2
 - @ohif/viewer@3.0.2
2019-12-11 03:31:18 +00:00
Igor Octaviano daa3ddccdb refactor: 💡 ServicesManager factory functions vs instances (#1272)
* refactor: 💡 ServicesManager factory functions vs instances

Refactor servicesManager to take factory functions instead of instances

Closes: #1265

* Remove testing code
2019-12-10 22:28:23 -05:00
Danny Brown 29bac8df7a chore: don't mark CI/Tooling tasks as stale 2019-12-10 11:37:39 -05:00
Danny Brown 319c67c389 docs: swap out "always red" badge for viewer-dev.ohif.org badge 2019-12-10 08:57:03 -05:00
Danny Brown b9836f6c71 docs: templates in P_R_T directory can only be set w/ query string; removing 2019-12-09 22:06:01 -05:00
Danny Brown 6a6e2d7df3 docs: shift pr template up a dir 2019-12-09 22:05:05 -05:00
Danny Brown 2f8c408ed2 docs: contributing guidelines 2019-12-09 22:02:29 -05:00
Danny Brown 27910239e0 docs: code of conduct 2019-12-09 22:00:17 -05:00
ohif-bot 719bfd02eb chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.0.1
 - @ohif/extension-vtk@1.0.1
 - @ohif/core@2.0.1
 - @ohif/ui@1.0.1
 - @ohif/viewer@3.0.1
2019-12-09 18:58:37 +00:00
dannyrb 994818faeb Merge branch 'master' of github.com:OHIF/Viewers into ups-master 2019-12-09 13:55:04 -05:00
dannyrb f06ef53e83 docs: beginnings of SOPClassHandlerModule docs 2019-12-09 13:53:35 -05:00
29 changed files with 452 additions and 217 deletions

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ daysUntilClose: 7
exemptLabels:
- 'Story :raised_hands:'
- 'Bug: Verified :bug:'
- 'Task: CI/Tooling 🤖'
- 'Task: CI/Tooling :robot:'
- 'Task: Docs 📖'
- 'Task: Docs :book:'
- 'Task: Refactor 🛠'
+76
View File
@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at danny.ri.brown+OHIFcoc@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
+1
View File
@@ -0,0 +1 @@
See our contributing guidelines at [`https://docs.ohif.org`](https://docs.ohif.org/development/contributing.html)
+2 -2
View File
@@ -271,8 +271,8 @@ MIT © [OHIF](https://github.com/OHIF)
<!-- Badges -->
[lerna-image]: https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg
[lerna-url]: https://lerna.js.org/
[netlify-image]: https://api.netlify.com/api/v1/badges/a5d369ab-18a6-41c3-bcde-83805205ac7f/deploy-status
[netlify-url]: https://app.netlify.com/sites/ohif/deploys
[netlify-image]: https://api.netlify.com/api/v1/badges/32708787-c9b0-4634-b50f-7ca41952da77/deploy-status
[netlify-url]: https://app.netlify.com/sites/ohif-dev/deploys
[all-contributors-image]: https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square
[circleci-image]: https://circleci.com/gh/OHIF/Viewers.svg?style=svg
[circleci-url]: https://circleci.com/gh/OHIF/Viewers
@@ -1,6 +1,37 @@
# Module: SOP Class Handler
...
An extension can register a SOP Class Handler Module by defining a
`getSopClassHandlerModule` method. The SOP Class Handler is a bit different from
the other modules, as it doesn't provide a `1:1` schema for UI or provide it's
own components. It instead defines:
- `sopClassUids`: an array of string SOP Class UIDs that the
`getDisplaySetFromSeries` method should be applied to.
- `getDisplaySetFromSeries`: a method that maps series and study metadata to a
display set
A `displaySet` has the following shape:
```js
return {
plugin: 'html',
modality: 'SR',
displaySetInstanceUid: 0,
wadoRoot: study.getData().wadoRoot,
wadoUri: instance.getData().wadouri,
sopInstanceUid: instance.getSOPInstanceUID(),
seriesInstanceUid: series.getSeriesInstanceUID(),
studyInstanceUid: study.getStudyInstanceUID(),
authorizationHeaders,
};
```
Where the `plugin` key is used to influence the default `ViewportComponent` for
rendering the `displaySet`. Additional properties are passed to the
`ViewportComponent` and used by the default `StudyBrowser` to render
"thumbnails" for each `displaySet`
## Example SOP Class Handler Module
```js
const SOP_CLASS_UIDS = {
@@ -8,29 +39,52 @@ const SOP_CLASS_UIDS = {
ENHANCED_SR: '1.2.840.10008.5.1.4.1.1.88.22',
};
const sopClassHandlerModule = {
id: 'OHIFDicomHtmlSopClassHandler',
sopClassUids: Object.values(SOP_CLASS_UIDS),
export default {
id: 'example-sop-class-handler-module',
/**
* @param {object} series -
* @param {object} study -
* @param {object} dicomWebClient -
* @param {object} authorizationHeaders -
*/
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();
/**
* @param {object} params
* @param {ServicesManager} params.servicesManager
* @param {CommandsManager} params.commandsManager
*/
getSopClassHandlerModule({ servicesManager, commandsManager }) {
return {
id: 'OHIFDicomHtmlSopClassHandler',
sopClassUids: Object.values(SOP_CLASS_UIDS),
return {
plugin: 'html',
displaySetInstanceUid: 0,
wadoRoot: study.getData().wadoRoot,
wadoUri: instance.getData().wadouri,
sopInstanceUid: instance.getSOPInstanceUID(),
seriesInstanceUid: series.getSeriesInstanceUID(),
studyInstanceUid: study.getStudyInstanceUID(),
authorizationHeaders,
};
},
/**
* @param {object} series -
* @param {object} study -
* @param {object} dicomWebClient -
* @param {object} authorizationHeaders -
*/
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();
return {
plugin: 'html',
displaySetInstanceUid: 0,
wadoRoot: study.getData().wadoRoot,
wadoUri: instance.getData().wadouri,
sopInstanceUid: instance.getSOPInstanceUID(),
seriesInstanceUid: series.getSeriesInstanceUID(),
studyInstanceUid: study.getStudyInstanceUID(),
authorizationHeaders,
};
},
}
};
```
## `@ohif/viewer` usage
We use the `sopClassHandlerModule`s in three different places:
- `ViewerLocalFileData.js`
- `ViewerRetrieveStudyData.js`
- `StandaloneRouting.js`
Each time, it is used to map study and series data to `displaySets`. It does
this by working alongside the `StudyMetadataManager` in `@ohif/core`. That
manager has the method `createDisplaySets` that takes an array of
`sopClassHandlerModules`.
+1 -1
View File
@@ -43,7 +43,7 @@ translate to in practice?
```js
// In the application
const UINotificationService = createUINotificationService();
import UINotificationService from '@ohif/core';
const servicesManager = new ServicesManager();
servicesManager.registerService(UINotificationService);
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.0.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.0.0...@ohif/extension-cornerstone@2.0.1) (2019-12-09)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [2.0.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@1.7.2...@ohif/extension-cornerstone@2.0.0) (2019-12-09)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "2.0.0",
"version": "2.0.1",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.0.1...@ohif/extension-vtk@1.0.2) (2019-12-11)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.0.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.0.0...@ohif/extension-vtk@1.0.1) (2019-12-09)
**Note:** Version bump only for package @ohif/extension-vtk
# [1.0.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@0.54.6...@ohif/extension-vtk@1.0.0) (2019-12-09)
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-vtk",
"version": "1.0.0",
"version": "1.0.2",
"description": "OHIF extension for VTK.js",
"author": "OHIF",
"license": "MIT",
@@ -52,8 +52,8 @@
"react-vtkjs-viewport": "^0.3.9"
},
"devDependencies": {
"@ohif/core": "^2.0.0",
"@ohif/ui": "^1.0.0",
"@ohif/core": "^2.0.2",
"@ohif/ui": "^1.0.1",
"cornerstone-tools": "^4.8.0",
"cornerstone-wado-image-loader": "^3.0.0",
"dcmjs": "^0.6.1",
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.0.2](https://github.com/OHIF/Viewers/compare/@ohif/core@2.0.1...@ohif/core@2.0.2) (2019-12-11)
**Note:** Version bump only for package @ohif/core
## [2.0.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.0.0...@ohif/core@2.0.1) (2019-12-09)
**Note:** Version bump only for package @ohif/core
# [2.0.0](https://github.com/OHIF/Viewers/compare/@ohif/core@1.13.3...@ohif/core@2.0.0) (2019-12-09)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/core",
"version": "2.0.0",
"version": "2.0.2",
"description": "Generic business logic for web-based medical imaging applications",
"author": "OHIF Core Team",
"license": "MIT",
+15 -15
View File
@@ -20,11 +20,11 @@ import user from './user.js';
import utils from './utils/';
import {
createUINotificationService,
createUIModalService,
createUIDialogService,
createUIContextMenuService,
createUILabellingFlowService,
UINotificationService,
UIModalService,
UIDialogService,
UIContextMenuService,
UILabellingFlowService,
} from './services';
const OHIF = {
@@ -52,11 +52,11 @@ const OHIF = {
measurements,
hangingProtocols,
//
createUINotificationService,
createUIModalService,
createUIDialogService,
createUIContextMenuService,
createUILabellingFlowService,
UINotificationService,
UIModalService,
UIDialogService,
UIContextMenuService,
UILabellingFlowService,
};
export {
@@ -83,11 +83,11 @@ export {
measurements,
hangingProtocols,
//
createUINotificationService,
createUIModalService,
createUIDialogService,
createUIContextMenuService,
createUILabellingFlowService,
UINotificationService,
UIModalService,
UIDialogService,
UIContextMenuService,
UILabellingFlowService,
};
export { OHIF };
+5 -5
View File
@@ -10,11 +10,11 @@ describe('Top level exports', () => {
'HotkeysManager',
'ServicesManager',
//
'createUINotificationService',
'createUIModalService',
'createUIDialogService',
'createUIContextMenuService',
'createUILabellingFlowService',
'UINotificationService',
'UIModalService',
'UIDialogService',
'UIContextMenuService',
'UILabellingFlowService',
//
'utils',
'studies',
+26 -11
View File
@@ -7,10 +7,12 @@ export default class ServicesManager {
}
/**
* Registers a new service.
*
* @param {Object} service
* @param {Object} configuration
*/
registerService(service) {
registerService(service, configuration = {}) {
if (!service) {
log.warn(
'Attempting to register a null/undefined service. Exiting early.'
@@ -18,32 +20,45 @@ export default class ServicesManager {
return;
}
let serviceName = service.name;
if (!serviceName) {
if (!service.name) {
log.warn(`Service name not set. Exiting early.`);
return;
}
if (this.registeredServiceNames.includes(serviceName)) {
if (this.registeredServiceNames.includes(service.name)) {
log.warn(
`Extension name ${serviceName} has already been registered. Exiting before duplicating services.`
`Service name ${service.name} has already been registered. Exiting before duplicating services.`
);
return;
}
this.services[service.name] = service;
if (service.create) {
this.services[service.name] = service.create({ configuration });
} else {
log.warn(`Service create factory function not defined. Exiting early.`);
return;
}
// Track service registration
this.registeredServiceNames.push(serviceName);
/* Track service registration */
this.registeredServiceNames.push(service.name);
}
/**
* An array of services.
* An array of services, or an array of arrays that contains service
* configuration pairs.
*
* @param {Object[]} services - Array of services
*/
registerServices(services) {
services.forEach(service => this.registerService(service));
services.forEach(service => {
const hasConfiguration = Array.isArray(service);
if (hasConfiguration) {
const [ohifService, configuration] = service;
this.registerService(ohifService, configuration);
} else {
this.registerService(service);
}
});
}
}
@@ -16,18 +16,32 @@ describe('ServicesManager.js', () => {
it('calls registerService() for each service', () => {
servicesManager.registerService = jest.fn();
const fakeServices = [
{ name: 'UINotificationTestService', hide: jest.fn() },
{ name: 'UIModalTestService', hide: jest.fn() },
];
servicesManager.registerServices(fakeServices);
servicesManager.registerServices([
{ name: 'UINotificationTestService', create: jest.fn() },
{ name: 'UIModalTestService', create: jest.fn() },
]);
expect(servicesManager.registerService.mock.calls.length).toBe(2);
});
it('calls registerService() for each service passing its configuration if tuple', () => {
servicesManager.registerService = jest.fn();
const fakeConfiguration = { testing: true };
servicesManager.registerServices([
{ name: 'UINotificationTestService', create: jest.fn() },
[{ name: 'UIModalTestService', create: jest.fn() }, fakeConfiguration],
]);
expect(servicesManager.registerService.mock.calls[1]).toContain(
fakeConfiguration
);
});
});
describe('registerService()', () => {
const fakeService = { name: 'UINotificationService', create: jest.fn() };
it('logs a warning if the service is null or undefined', () => {
const undefinedService = undefined;
const nullService = null;
@@ -39,8 +53,8 @@ describe('ServicesManager.js', () => {
});
it('logs a warning if the service does not have a name', () => {
const serviceWithEmptyName = { name: '', hide: jest.fn() };
const serviceWithoutName = { hide: jest.fn() };
const serviceWithEmptyName = { name: '', create: jest.fn() };
const serviceWithoutName = { create: jest.fn() };
servicesManager.registerService(serviceWithEmptyName);
servicesManager.registerService(serviceWithoutName);
@@ -48,23 +62,37 @@ describe('ServicesManager.js', () => {
expect(log.warn.mock.calls.length).toBe(2);
});
it('tracks which services have been registered', () => {
const service = {
name: 'UINotificationService',
};
it('logs a warning if the service does not have a create factory function', () => {
const serviceWithoutCreate = { name: 'UINotificationService' };
servicesManager.registerService(service);
expect(servicesManager.registeredServiceNames).toContain(service.name);
});
it('logs a warning if the service has an name that has already been registered', () => {
const service = { name: 'UINotificationService' };
servicesManager.registerService(service);
servicesManager.registerService(service);
servicesManager.registerService(serviceWithoutCreate);
expect(log.warn.mock.calls.length).toBe(1);
});
it('tracks which services have been registered', () => {
servicesManager.registerService(fakeService);
expect(servicesManager.registeredServiceNames).toContain(
fakeService.name
);
});
it('logs a warning if the service has an name that has already been registered', () => {
servicesManager.registerService(fakeService);
servicesManager.registerService(fakeService);
expect(log.warn.mock.calls.length).toBe(1);
});
it('pass configuration to service create factory function', () => {
const configuration = { config: 'Some configuration' };
servicesManager.registerService(fakeService, configuration);
expect(fakeService.create.mock.calls[0][0]).toEqual({
configuration,
});
});
});
});
@@ -5,29 +5,27 @@
* @property {Event} event The event with tool information.
*/
const uiContextMenuServicePublicAPI = {
name: 'UIContextMenuService',
hide,
show,
const name = 'UIContextMenuService';
const publicAPI = {
name,
hide: _hide,
show: _show,
setServiceImplementation,
};
const uiContextMenuServiceImplementation = {
const serviceImplementation = {
_show: () => console.warn('show() NOT IMPLEMENTED'),
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
};
function createUIContextMenuService() {
return uiContextMenuServicePublicAPI;
}
/**
* Show a new UI ContextMenu dialog;
*
* @param {ContextMenuProps} props { event }
*/
function show({ event }) {
return uiContextMenuServiceImplementation._show({
function _show({ event }) {
return serviceImplementation._show({
event,
});
}
@@ -36,8 +34,8 @@ function show({ event }) {
* Hide a UI ContextMenu dialog;
*
*/
function hide() {
return uiContextMenuServiceImplementation._hide();
function _hide() {
return serviceImplementation._hide();
}
/**
@@ -53,11 +51,16 @@ function setServiceImplementation({
hide: hideImplementation,
}) {
if (showImplementation) {
uiContextMenuServiceImplementation._show = showImplementation;
serviceImplementation._show = showImplementation;
}
if (hideImplementation) {
uiContextMenuServiceImplementation._hide = hideImplementation;
serviceImplementation._hide = hideImplementation;
}
}
export default createUIContextMenuService;
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
};
@@ -25,30 +25,28 @@
* @property {Function} onDrag Called while dragging.
*/
const uiDialogServicePublicAPI = {
name: 'UIDialogService',
dismiss,
dismissAll,
create,
const name = 'UIDialogService';
const publicAPI = {
name,
dismiss: _dismiss,
dismissAll: _dismissAll,
create: _create,
setServiceImplementation,
};
const uiDialogServiceImplementation = {
const serviceImplementation = {
_dismiss: () => console.warn('dismiss() NOT IMPLEMENTED'),
_dismissAll: () => console.warn('dismissAll() NOT IMPLEMENTED'),
_create: () => console.warn('create() NOT IMPLEMENTED'),
};
function createUIDialogService() {
return uiDialogServicePublicAPI;
}
/**
* Show a new UI dialog;
*
* @param {DialogProps} props { id, content, contentProps, onStart, onDrag, onStop, centralize, isDraggable, showOverlay, preservePosition, defaultPosition }
*/
function create({
function _create({
id,
content,
contentProps,
@@ -61,7 +59,7 @@ function create({
showOverlay = false,
defaultPosition,
}) {
return uiDialogServiceImplementation._create({
return serviceImplementation._create({
id,
content,
contentProps,
@@ -81,8 +79,8 @@ function create({
*
* @returns void
*/
function dismissAll() {
return uiDialogServiceImplementation._dismissAll();
function _dismissAll() {
return serviceImplementation._dismissAll();
}
/**
@@ -90,8 +88,8 @@ function dismissAll() {
*
* @returns void
*/
function dismiss({ id }) {
return uiDialogServiceImplementation._dismiss({ id });
function _dismiss({ id }) {
return serviceImplementation._dismiss({ id });
}
/**
@@ -109,14 +107,19 @@ function setServiceImplementation({
create: createImplementation,
}) {
if (dismissImplementation) {
uiDialogServiceImplementation._dismiss = dismissImplementation;
serviceImplementation._dismiss = dismissImplementation;
}
if (dismissAllImplementation) {
uiDialogServiceImplementation._dismissAll = dismissAllImplementation;
serviceImplementation._dismissAll = dismissAllImplementation;
}
if (createImplementation) {
uiDialogServiceImplementation._create = createImplementation;
serviceImplementation._create = createImplementation;
}
}
export default createUIDialogService;
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
};
@@ -8,28 +8,26 @@
*
*/
const uiLabellingFlowServicePublicAPI = {
name: 'UILabellingFlowService',
show,
hide,
const name = 'UILabellingFlowService';
const publicAPI = {
name,
show: _show,
hide: _hide,
setServiceImplementation,
};
const uiLabellingFlowServiceImplementation = {
const serviceImplementation = {
_show: () => console.warn('show() NOT IMPLEMENTED'),
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
};
function createUILabellingFlowService() {
return uiLabellingFlowServicePublicAPI;
}
/**
* Hide a UI LabellingFlow dialog;
*
*/
function hide() {
return uiLabellingFlowServiceImplementation._hide();
function _hide() {
return serviceImplementation._hide();
}
/**
@@ -37,8 +35,8 @@ function hide() {
*
* @param {LabellingFlowProps} props { defaultPosition, centralize, props }
*/
function show({ defaultPosition, centralize, props }) {
return uiLabellingFlowServiceImplementation._show({
function _show({ defaultPosition, centralize, props }) {
return serviceImplementation._show({
defaultPosition,
centralize,
props,
@@ -58,11 +56,16 @@ function setServiceImplementation({
hide: hideImplementation,
}) {
if (showImplementation) {
uiLabellingFlowServiceImplementation._show = showImplementation;
serviceImplementation._show = showImplementation;
}
if (hideImplementation) {
uiLabellingFlowServiceImplementation._hide = hideImplementation;
serviceImplementation._hide = hideImplementation;
}
}
export default createUILabellingFlowService;
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
};
@@ -11,28 +11,26 @@
* @property {string} [customClassName=null] The custom class to style the modal.
*/
const uiModalServicePublicAPI = {
name: 'UIModalService',
hide,
show,
const name = 'UIModalService';
const publicAPI = {
name,
hide: _hide,
show: _show,
setServiceImplementation,
};
const uiModalServiceImplementation = {
const serviceImplementation = {
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
_show: () => console.warn('show() NOT IMPLEMENTED'),
};
function createUIModalService() {
return uiModalServicePublicAPI;
}
/**
* Show a new UI modal;
*
* @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, closeButton, title, customClassName }
*/
function show({
function _show({
content = null,
contentProps = null,
shouldCloseOnEsc = false,
@@ -41,7 +39,7 @@ function show({
title = null,
customClassName = null,
}) {
return uiModalServiceImplementation._show({
return serviceImplementation._show({
content,
contentProps,
shouldCloseOnEsc,
@@ -57,8 +55,8 @@ function show({
*
* @returns void
*/
function hide() {
return uiModalServiceImplementation._hide();
function _hide() {
return serviceImplementation._hide();
}
/**
@@ -74,11 +72,16 @@ function setServiceImplementation({
show: showImplementation,
}) {
if (hideImplementation) {
uiModalServiceImplementation._hide = hideImplementation;
serviceImplementation._hide = hideImplementation;
}
if (showImplementation) {
uiModalServiceImplementation._show = showImplementation;
serviceImplementation._show = showImplementation;
}
}
export default createUIModalService;
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
};
@@ -10,22 +10,20 @@
* @property {boolean} [autoClose=true]
*/
const uiNotificationServicePublicAPI = {
name: 'UINotificationService',
hide,
show,
const name = 'UINotificationService';
const publicAPI = {
name,
hide: _hide,
show: _show,
setServiceImplementation,
};
const uiNotificationServiceImplementation = {
const serviceImplementation = {
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
_show: () => console.warn('show() NOT IMPLEMENTED'),
};
function createUINotificationService() {
return uiNotificationServicePublicAPI;
}
/**
* Create and show a new UI notification; returns the
* ID of the created notification.
@@ -33,7 +31,7 @@ function createUINotificationService() {
* @param {Notification} notification { title, message, duration, position, type, autoClose}
* @returns {number} id
*/
function show({
function _show({
title,
message,
duration = 5000,
@@ -41,7 +39,7 @@ function show({
type = 'info',
autoClose = true,
}) {
return uiNotificationServiceImplementation._show({
return serviceImplementation._show({
title,
message,
duration,
@@ -57,8 +55,8 @@ function show({
* @param {number} id - id of the notification to hide/dismiss
* @returns undefined
*/
function hide(id) {
return uiNotificationServiceImplementation._hide({ id });
function _hide(id) {
return serviceImplementation._hide({ id });
}
/**
@@ -74,11 +72,16 @@ function setServiceImplementation({
show: showImplementation,
}) {
if (hideImplementation) {
uiNotificationServiceImplementation._hide = hideImplementation;
serviceImplementation._hide = hideImplementation;
}
if (showImplementation) {
uiNotificationServiceImplementation._show = showImplementation;
serviceImplementation._show = showImplementation;
}
}
export default createUINotificationService;
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
};
+10 -10
View File
@@ -1,15 +1,15 @@
import ServicesManager from './ServicesManager.js';
import createUINotificationService from './UINotificationService';
import createUIModalService from './UIModalService';
import createUIDialogService from './UIDialogService';
import createUIContextMenuService from './UIContextMenuService';
import createUILabellingFlowService from './UILabellingFlowService';
import UINotificationService from './UINotificationService';
import UIModalService from './UIModalService';
import UIDialogService from './UIDialogService';
import UIContextMenuService from './UIContextMenuService';
import UILabellingFlowService from './UILabellingFlowService';
export {
createUINotificationService,
createUIModalService,
createUIDialogService,
createUIContextMenuService,
createUILabellingFlowService,
UINotificationService,
UIModalService,
UIDialogService,
UIContextMenuService,
UILabellingFlowService,
ServicesManager,
};
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.0.0...@ohif/ui@1.0.1) (2019-12-09)
**Note:** Version bump only for package @ohif/ui
# [1.0.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@0.65.4...@ohif/ui@1.0.0) (2019-12-09)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/ui",
"version": "1.0.0",
"version": "1.0.1",
"description": "A set of React components for Medical Imaging Viewers",
"author": "OHIF Contributors",
"license": "MIT",
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.0.2](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.0.1...@ohif/viewer@3.0.2) (2019-12-11)
**Note:** Version bump only for package @ohif/viewer
## [3.0.1](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.0.0...@ohif/viewer@3.0.1) (2019-12-09)
**Note:** Version bump only for package @ohif/viewer
# [3.0.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@2.11.8...@ohif/viewer@3.0.0) (2019-12-09)
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/viewer",
"version": "3.0.0",
"version": "3.0.2",
"description": "OHIF Viewer",
"author": "OHIF Contributors",
"license": "MIT",
@@ -45,14 +45,14 @@
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"@ohif/core": "^2.0.0",
"@ohif/extension-cornerstone": "^2.0.0",
"@ohif/core": "^2.0.2",
"@ohif/extension-cornerstone": "^2.0.1",
"@ohif/extension-dicom-html": "^1.0.2",
"@ohif/extension-dicom-microscopy": "^0.50.6",
"@ohif/extension-dicom-pdf": "^1.0.0",
"@ohif/extension-vtk": "^1.0.0",
"@ohif/extension-vtk": "^1.0.2",
"@ohif/i18n": "^0.52.2",
"@ohif/ui": "^1.0.0",
"@ohif/ui": "^1.0.1",
"@tanem/react-nprogress": "^1.1.25",
"classnames": "^2.2.6",
"core-js": "^3.2.1",
+13 -12
View File
@@ -28,11 +28,11 @@ import {
ExtensionManager,
ServicesManager,
HotkeysManager,
createUINotificationService,
createUIModalService,
createUIDialogService,
createUIContextMenuService,
createUILabellingFlowService,
UINotificationService,
UIModalService,
UIDialogService,
UIContextMenuService,
UILabellingFlowService,
utils,
redux as reduxOHIF,
} from '@ohif/core';
@@ -70,13 +70,6 @@ const commandsManagerConfig = {
getActiveContexts: () => getActiveContexts(store.getState()),
};
/** Services */
const UINotificationService = createUINotificationService();
const UIModalService = createUIModalService();
const UIDialogService = createUIDialogService();
const UIContextMenuService = createUIContextMenuService();
const UILabellingFlowService = createUILabellingFlowService();
/** Managers */
const commandsManager = new CommandsManager(commandsManagerConfig);
const hotkeysManager = new HotkeysManager(commandsManager);
@@ -165,6 +158,14 @@ class App extends Component {
render() {
const { whiteLabelling, routerBasename } = this._appConfig;
const {
UINotificationService,
UIDialogService,
UILabellingFlowService,
UIModalService,
UIContextMenuService,
} = servicesManager.services;
if (this._userManager) {
return (
<AppContext.Provider value={{ appConfig: this._appConfig }}>
+1 -20
View File
@@ -2654,16 +2654,6 @@
dependencies:
"@types/node" "^12.11.1"
"@ohif/extension-cornerstone@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@ohif/extension-cornerstone/-/extension-cornerstone-2.0.0.tgz#b4ee3b594212502192cdd311a100354857280548"
integrity sha512-hvJ3t2GRcu906NiYpUWaJIB9ja/M/MKEYLy19t4XBFpqf4VqoezR2KJpZelmZjQscXGaDQeZgvr3DJO5Nva8Uw==
dependencies:
"@babel/runtime" "^7.5.5"
classnames "^2.2.6"
lodash.throttle "^4.1.1"
react-cornerstone-viewport "0.1.30"
"@ohif/i18n@^0.2.3":
version "0.2.5"
resolved "https://registry.yarnpkg.com/@ohif/i18n/-/i18n-0.2.5.tgz#2b92a78109823ce0f50dd590201d980a5fd64974"
@@ -13103,7 +13093,7 @@ modify-values@^1.0.0:
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
moment@2.24.0, moment@>=1.6.0, moment@^2.23.0, moment@^2.24.0:
moment@2.24.0, moment@>=1.6.0, moment@^2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
@@ -15839,15 +15829,6 @@ react-codemirror2@^6.0.0:
resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-6.0.0.tgz#180065df57a64026026cde569a9708fdf7656525"
integrity sha512-D7y9qZ05FbUh9blqECaJMdDwKluQiO3A9xB+fssd5jKM7YAXucRuEOlX32mJQumUvHUkHRHqXIPBjm6g0FW0Ag==
react-cornerstone-viewport@0.1.30:
version "0.1.30"
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.30.tgz#3546a5164feef5f1f3b45ade10fd9a66f82fd101"
integrity sha512-DGxdpS7FJvWi57NhpKhKMdaW3go/Fs/zfWJFtaEzGVHq2zQnEEV5G1pamC4ttRhKMfzy7T7y4h14xUVzE7IqPA==
dependencies:
lodash.debounce "^4.0.8"
moment "^2.23.0"
stylus "^0.54.5"
react-cornerstone-viewport@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-2.1.0.tgz#1f353e3b0a57c45add70e5040b819290d9f55f4b"