import React from 'react'; import ReactDOM from 'react-dom'; import coreModule from 'app/core/core_module'; import appEvents from 'app/core/app_events'; import { GrafanaRootScope } from 'app/routes/GrafanaCtrl'; import { AngularModalProxy } from '../components/modals/AngularModalProxy'; import { provideTheme } from '../utils/ConfigProvider'; import { HideModalEvent, ShowConfirmModalEvent, ShowConfirmModalPayload, ShowModalEvent, ShowModalReactEvent, } from '../../types/events'; import { ConfirmModal, ConfirmModalProps } from '@grafana/ui'; import { deprecationWarning, textUtil } from '@grafana/data'; export class UtilSrv { modalScope: any; reactModalRoot = document.body; reactModalNode = document.createElement('div'); /** @ngInject */ constructor(private $rootScope: GrafanaRootScope, private $modal: any) { this.reactModalNode.setAttribute('id', 'angular2ReactModalRoot'); } init() { appEvents.subscribe(ShowModalEvent, (e) => this.showModal(e.payload)); appEvents.subscribe(HideModalEvent, this.hideModal.bind(this)); appEvents.subscribe(ShowConfirmModalEvent, (e) => this.showConfirmModal(e.payload)); appEvents.subscribe(ShowModalReactEvent, (e) => this.showModalReact(e.payload)); } showModalReact(options: any) { const { component, props } = options; const modalProps = { component, props: { ...props, isOpen: true, onDismiss: this.onReactModalDismiss, }, }; const elem = React.createElement(provideTheme(AngularModalProxy), modalProps); this.reactModalRoot.appendChild(this.reactModalNode); ReactDOM.render(elem, this.reactModalNode); } onReactModalDismiss = () => { ReactDOM.unmountComponentAtNode(this.reactModalNode); this.reactModalRoot.removeChild(this.reactModalNode); }; /** * @deprecated use showModalReact instead that has this capability built in */ hideModal() { deprecationWarning('UtilSrv', 'hideModal', 'showModalReact'); if (this.modalScope && this.modalScope.dismiss) { this.modalScope.dismiss(); } } /** * @deprecated use showModalReact instead */ showModal(options: any) { deprecationWarning('UtilSrv', 'showModal', 'showModalReact'); if (this.modalScope && this.modalScope.dismiss) { this.modalScope.dismiss(); } this.modalScope = options.scope; if (options.model) { this.modalScope = this.$rootScope.$new(); this.modalScope.model = options.model; } else if (!this.modalScope) { this.modalScope = this.$rootScope.$new(); } const modal = this.$modal({ modalClass: options.modalClass, template: options.src, templateHtml: options.templateHtml, persist: false, show: false, scope: this.modalScope, keyboard: false, backdrop: options.backdrop, }); Promise.resolve(modal).then((modalEl) => { modalEl.modal('show'); }); } showConfirmModal(payload: ShowConfirmModalPayload) { const { confirmText, onConfirm = () => undefined, text2, altActionText, onAltAction, noText, text, text2htmlBind, yesText = 'Yes', icon, title = 'Confirm', } = payload; const props: ConfirmModalProps = { confirmText: yesText, confirmationText: confirmText, icon, title, body: text, description: text2 && text2htmlBind ? textUtil.sanitize(text2) : text2, isOpen: true, dismissText: noText, onConfirm: () => { onConfirm(); this.onReactModalDismiss(); }, onDismiss: this.onReactModalDismiss, onAlternative: onAltAction ? () => { onAltAction(); this.onReactModalDismiss(); } : undefined, alternativeText: altActionText, }; const modalProps = { component: ConfirmModal, props, }; const elem = React.createElement(provideTheme(AngularModalProxy), modalProps); this.reactModalRoot.appendChild(this.reactModalNode); ReactDOM.render(elem, this.reactModalNode); } } coreModule.service('utilSrv', UtilSrv);