From 9104e7be509b702c8131deffc66223d68656fb0d Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 14 Nov 2019 10:19:33 -0300 Subject: [PATCH] Add new modal service --- platform/core/src/index.js | 8 +- platform/core/src/index.test.js | 3 +- .../core/src/services/UIModalService/index.js | 89 +++++++++++++++++++ .../services/UINotificationService/index.js | 4 +- platform/core/src/services/index.js | 5 +- platform/ui/src/utils/ModalProvider.js | 28 +++++- platform/ui/src/utils/SnackbarProvider.js | 5 ++ platform/viewer/src/App.js | 15 ++-- 8 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 platform/core/src/services/UIModalService/index.js diff --git a/platform/core/src/index.js b/platform/core/src/index.js index 6cec02db8..cb482e505 100644 --- a/platform/core/src/index.js +++ b/platform/core/src/index.js @@ -19,7 +19,7 @@ import ui from './ui'; import user from './user.js'; import utils from './utils/'; -import { createUiNotificationService } from './services'; +import { createUINotificationService, createUIModalService } from './services'; const OHIF = { MODULE_TYPES, @@ -46,7 +46,8 @@ const OHIF = { measurements, hangingProtocols, // - createUiNotificationService, + createUINotificationService, + createUIModalService, }; export { @@ -73,7 +74,8 @@ export { measurements, hangingProtocols, // - createUiNotificationService, + createUINotificationService, + createUIModalService, }; export { OHIF }; diff --git a/platform/core/src/index.test.js b/platform/core/src/index.test.js index a017a8a39..b06073e12 100644 --- a/platform/core/src/index.test.js +++ b/platform/core/src/index.test.js @@ -10,7 +10,8 @@ describe('Top level exports', () => { 'HotkeysManager', 'ServicesManager', // - 'createUiNotificationService', + 'createUINotificationService', + 'createUIModalService', // 'utils', 'studies', diff --git a/platform/core/src/services/UIModalService/index.js b/platform/core/src/services/UIModalService/index.js new file mode 100644 index 000000000..b8901e013 --- /dev/null +++ b/platform/core/src/services/UIModalService/index.js @@ -0,0 +1,89 @@ +/** + * A UI Element + * + * @typedef {HTMLElement} Modal + */ + +/** + * UI Modal + * + * @typedef {Object} ModalProps + * @property {string} [backdrop=false] - + * @property {string} [keyboard=false] - + * @property {number} [show=true] - + * @property {string} [closeButton=true] - + * @property {string} [title=null] - 'Modal Title' + * @property {boolean} [customClassName=null] - '.ModalClass' + */ + +const uiModalServicePublicApi = { + name: 'UIModalService', + hide, + show, + setServiceImplementation, +}; + +const uiModalServiceImplementation = { + _hide: () => console.warn('hide() NOT IMPLEMENTED'), + _show: () => console.warn('show() NOT IMPLEMENTED'), +}; + +function createUiModalService() { + return uiModalServicePublicApi; +} + +/** + * Show a new UI modal; + * + * @param {Modal} component + * @param {ModalProps} props { backdrop, keyboard, show, closeButton, title, customClassName } + */ +function show(component, props) { + const { + backdrop = false, + keyboard = false, + show = true, + closeButton = true, + title = null, + customClassName = null, + } = props; + return uiModalServiceImplementation._show(component, { + backdrop, + keyboard, + show, + closeButton, + title, + customClassName, + }); +} + +/** + * Hides/dismisses the modal, if currently shown + * + * @returns void + */ +function hide() { + return uiModalServiceImplementation._hide(); +} + +/** + * + * + * @param {*} { + * hide: hideImplementation, + * show: showImplementation, + * } + */ +function setServiceImplementation({ + hide: hideImplementation, + show: showImplementation, +}) { + if (hideImplementation) { + uiModalServiceImplementation._hide = hideImplementation; + } + if (showImplementation) { + uiModalServiceImplementation._show = showImplementation; + } +} + +export default createUiModalService; diff --git a/platform/core/src/services/UINotificationService/index.js b/platform/core/src/services/UINotificationService/index.js index 97db61040..86e6e1f56 100644 --- a/platform/core/src/services/UINotificationService/index.js +++ b/platform/core/src/services/UINotificationService/index.js @@ -22,7 +22,7 @@ const uiNotificationServiceImplementation = { _show: () => console.warn('show() NOT IMPLEMENTED'), }; -function createUiNotificationService() { +function createUINotificationService() { return uiNotificationServicePublicApi; } @@ -81,4 +81,4 @@ function setServiceImplementation({ } } -export default createUiNotificationService; +export default createUINotificationService; diff --git a/platform/core/src/services/index.js b/platform/core/src/services/index.js index ded69e822..033dee202 100644 --- a/platform/core/src/services/index.js +++ b/platform/core/src/services/index.js @@ -1,4 +1,5 @@ import ServicesManager from './ServicesManager.js'; -import createUiNotificationService from './UINotificationService'; +import createUINotificationService from './UINotificationService'; +import createUIModalService from './UIModalService'; -export { createUiNotificationService, ServicesManager }; +export { createUINotificationService, createUIModalService, ServicesManager }; diff --git a/platform/ui/src/utils/ModalProvider.js b/platform/ui/src/utils/ModalProvider.js index c1734cfb1..cbf07c220 100644 --- a/platform/ui/src/utils/ModalProvider.js +++ b/platform/ui/src/utils/ModalProvider.js @@ -1,4 +1,10 @@ -import React, { useState, createContext, useContext } from 'react'; +import React, { + useState, + createContext, + useContext, + useCallback, + useEffect, +} from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; @@ -7,7 +13,7 @@ const { Provider, Consumer } = ModalContext; export const useModal = () => useContext(ModalContext); -const ModalProvider = ({ children, modal: Modal }) => { +const ModalProvider = ({ children, modal: Modal, service }) => { const DEFAULT_OPTIONS = { component: null /* The component instance inside the modal. */, backdrop: false /* Should the modal render a backdrop overlay. */, @@ -20,20 +26,31 @@ const ModalProvider = ({ children, modal: Modal }) => { const [options, setOptions] = useState(DEFAULT_OPTIONS); + /** + * Sets the implementation of a modal service that can be used by extensions. + * + * @returns void + */ + useEffect(() => { + service.setServiceImplementation({ hide, show }); + }, [hide, service, show]); + /** * Show the modal and override its configuration props. * * @returns void */ - const show = (component, props = {}) => + const show = useCallback((component, props = {}) => { setOptions(Object.assign({}, options, props, { component })); + console.log(component, props); + }); /** * Hide the modal and set its properties to default. * * @returns void */ - const hide = () => setOptions(DEFAULT_OPTIONS); + const hide = useCallback(() => setOptions(DEFAULT_OPTIONS)); return ( @@ -65,6 +82,9 @@ const ModalProvider = ({ children, modal: Modal }) => { ModalProvider.propTypes = { children: PropTypes.node, modal: PropTypes.node, + service: PropTypes.shape({ + setServiceImplementation: PropTypes.func, + }), }; /** diff --git a/platform/ui/src/utils/SnackbarProvider.js b/platform/ui/src/utils/SnackbarProvider.js index 4151aec53..ed603003c 100644 --- a/platform/ui/src/utils/SnackbarProvider.js +++ b/platform/ui/src/utils/SnackbarProvider.js @@ -25,6 +25,11 @@ const SnackbarProvider = ({ children, service }) => { const [count, setCount] = useState(1); const [snackbarItems, setSnackbarItems] = useState([]); + /** + * Sets the implementation of a notification service that can be used by extensions. + * + * @returns void + */ useEffect(() => { service.setServiceImplementation({ hide, show }); }, [service, hide, show]); diff --git a/platform/viewer/src/App.js b/platform/viewer/src/App.js index 862a2c2ba..c496b5428 100644 --- a/platform/viewer/src/App.js +++ b/platform/viewer/src/App.js @@ -8,7 +8,8 @@ import { ExtensionManager, ServicesManager, HotkeysManager, - createUiNotificationService, + createUINotificationService, + createUIModalService, utils, } from '@ohif/core'; import React, { Component } from 'react'; @@ -44,7 +45,8 @@ const commandsManagerConfig = { }; // Services -const UINotificationService = createUiNotificationService(); +const UINotificationService = createUINotificationService(); +const UIModalService = createUIModalService(); const commandsManager = new CommandsManager(commandsManagerConfig); const hotkeysManager = new HotkeysManager(commandsManager); @@ -89,7 +91,7 @@ class App extends Component { const { servers, extensions, hotkeys, oidc } = props; this.initUserManager(oidc); - _initServices([UINotificationService]); + _initServices([UINotificationService, UIModalService]); _initExtensions(extensions, hotkeys); _initServers(servers); initWebWorkers(); @@ -112,7 +114,10 @@ class App extends Component { - + @@ -133,7 +138,7 @@ class App extends Component { - +