Add new modal service

This commit is contained in:
Igor 2019-11-14 10:19:33 -03:00
parent 81ad25b39f
commit 9104e7be50
8 changed files with 140 additions and 17 deletions

View File

@ -19,7 +19,7 @@ import ui from './ui';
import user from './user.js'; import user from './user.js';
import utils from './utils/'; import utils from './utils/';
import { createUiNotificationService } from './services'; import { createUINotificationService, createUIModalService } from './services';
const OHIF = { const OHIF = {
MODULE_TYPES, MODULE_TYPES,
@ -46,7 +46,8 @@ const OHIF = {
measurements, measurements,
hangingProtocols, hangingProtocols,
// //
createUiNotificationService, createUINotificationService,
createUIModalService,
}; };
export { export {
@ -73,7 +74,8 @@ export {
measurements, measurements,
hangingProtocols, hangingProtocols,
// //
createUiNotificationService, createUINotificationService,
createUIModalService,
}; };
export { OHIF }; export { OHIF };

View File

@ -10,7 +10,8 @@ describe('Top level exports', () => {
'HotkeysManager', 'HotkeysManager',
'ServicesManager', 'ServicesManager',
// //
'createUiNotificationService', 'createUINotificationService',
'createUIModalService',
// //
'utils', 'utils',
'studies', 'studies',

View File

@ -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;

View File

@ -22,7 +22,7 @@ const uiNotificationServiceImplementation = {
_show: () => console.warn('show() NOT IMPLEMENTED'), _show: () => console.warn('show() NOT IMPLEMENTED'),
}; };
function createUiNotificationService() { function createUINotificationService() {
return uiNotificationServicePublicApi; return uiNotificationServicePublicApi;
} }
@ -81,4 +81,4 @@ function setServiceImplementation({
} }
} }
export default createUiNotificationService; export default createUINotificationService;

View File

@ -1,4 +1,5 @@
import ServicesManager from './ServicesManager.js'; import ServicesManager from './ServicesManager.js';
import createUiNotificationService from './UINotificationService'; import createUINotificationService from './UINotificationService';
import createUIModalService from './UIModalService';
export { createUiNotificationService, ServicesManager }; export { createUINotificationService, createUIModalService, ServicesManager };

View File

@ -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 PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
@ -7,7 +13,7 @@ const { Provider, Consumer } = ModalContext;
export const useModal = () => useContext(ModalContext); export const useModal = () => useContext(ModalContext);
const ModalProvider = ({ children, modal: Modal }) => { const ModalProvider = ({ children, modal: Modal, service }) => {
const DEFAULT_OPTIONS = { const DEFAULT_OPTIONS = {
component: null /* The component instance inside the modal. */, component: null /* The component instance inside the modal. */,
backdrop: false /* Should the modal render a backdrop overlay. */, backdrop: false /* Should the modal render a backdrop overlay. */,
@ -20,20 +26,31 @@ const ModalProvider = ({ children, modal: Modal }) => {
const [options, setOptions] = useState(DEFAULT_OPTIONS); 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. * Show the modal and override its configuration props.
* *
* @returns void * @returns void
*/ */
const show = (component, props = {}) => const show = useCallback((component, props = {}) => {
setOptions(Object.assign({}, options, props, { component })); setOptions(Object.assign({}, options, props, { component }));
console.log(component, props);
});
/** /**
* Hide the modal and set its properties to default. * Hide the modal and set its properties to default.
* *
* @returns void * @returns void
*/ */
const hide = () => setOptions(DEFAULT_OPTIONS); const hide = useCallback(() => setOptions(DEFAULT_OPTIONS));
return ( return (
<Provider value={{ ...options, show, hide }}> <Provider value={{ ...options, show, hide }}>
@ -65,6 +82,9 @@ const ModalProvider = ({ children, modal: Modal }) => {
ModalProvider.propTypes = { ModalProvider.propTypes = {
children: PropTypes.node, children: PropTypes.node,
modal: PropTypes.node, modal: PropTypes.node,
service: PropTypes.shape({
setServiceImplementation: PropTypes.func,
}),
}; };
/** /**

View File

@ -25,6 +25,11 @@ const SnackbarProvider = ({ children, service }) => {
const [count, setCount] = useState(1); const [count, setCount] = useState(1);
const [snackbarItems, setSnackbarItems] = useState([]); const [snackbarItems, setSnackbarItems] = useState([]);
/**
* Sets the implementation of a notification service that can be used by extensions.
*
* @returns void
*/
useEffect(() => { useEffect(() => {
service.setServiceImplementation({ hide, show }); service.setServiceImplementation({ hide, show });
}, [service, hide, show]); }, [service, hide, show]);

View File

@ -8,7 +8,8 @@ import {
ExtensionManager, ExtensionManager,
ServicesManager, ServicesManager,
HotkeysManager, HotkeysManager,
createUiNotificationService, createUINotificationService,
createUIModalService,
utils, utils,
} from '@ohif/core'; } from '@ohif/core';
import React, { Component } from 'react'; import React, { Component } from 'react';
@ -44,7 +45,8 @@ const commandsManagerConfig = {
}; };
// Services // Services
const UINotificationService = createUiNotificationService(); const UINotificationService = createUINotificationService();
const UIModalService = createUIModalService();
const commandsManager = new CommandsManager(commandsManagerConfig); const commandsManager = new CommandsManager(commandsManagerConfig);
const hotkeysManager = new HotkeysManager(commandsManager); const hotkeysManager = new HotkeysManager(commandsManager);
@ -89,7 +91,7 @@ class App extends Component {
const { servers, extensions, hotkeys, oidc } = props; const { servers, extensions, hotkeys, oidc } = props;
this.initUserManager(oidc); this.initUserManager(oidc);
_initServices([UINotificationService]); _initServices([UINotificationService, UIModalService]);
_initExtensions(extensions, hotkeys); _initExtensions(extensions, hotkeys);
_initServers(servers); _initServers(servers);
initWebWorkers(); initWebWorkers();
@ -112,7 +114,10 @@ class App extends Component {
<Router basename={routerBasename}> <Router basename={routerBasename}>
<WhiteLabellingContext.Provider value={whiteLabelling}> <WhiteLabellingContext.Provider value={whiteLabelling}>
<SnackbarProvider service={UINotificationService}> <SnackbarProvider service={UINotificationService}>
<ModalProvider modal={OHIFModal}> <ModalProvider
modal={OHIFModal}
service={UIModalService}
>
<OHIFStandaloneViewer userManager={userManager} /> <OHIFStandaloneViewer userManager={userManager} />
</ModalProvider> </ModalProvider>
</SnackbarProvider> </SnackbarProvider>
@ -133,7 +138,7 @@ class App extends Component {
<Router basename={routerBasename}> <Router basename={routerBasename}>
<WhiteLabellingContext.Provider value={whiteLabelling}> <WhiteLabellingContext.Provider value={whiteLabelling}>
<SnackbarProvider service={UINotificationService}> <SnackbarProvider service={UINotificationService}>
<ModalProvider modal={OHIFModal}> <ModalProvider modal={OHIFModal} service={UIModalService}>
<OHIFStandaloneViewer /> <OHIFStandaloneViewer />
</ModalProvider> </ModalProvider>
</SnackbarProvider> </SnackbarProvider>