| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import React, {
- useCallback,
- useEffect,
- useMemo,
- } from 'react';
- import { useCodeMirrorEditorIsolated } from '@growi/editor';
- import { useDrawioModalForEditor } from '@growi/editor/src/stores/use-drawio';
- import {
- Modal,
- ModalBody,
- } from 'reactstrap';
- import { getDiagramsNetLangCode } from '~/client/util/locale-utils';
- import { replaceFocusedDrawioWithEditor, getMarkdownDrawioMxfile } from '~/components/PageEditor/markdown-drawio-util-for-editor';
- import { useRendererConfig } from '~/stores/context';
- import { useDrawioModal } from '~/stores/modal';
- import { usePersonalSettings } from '~/stores/personal-settings';
- import loggerFactory from '~/utils/logger';
- import { type DrawioConfig, DrawioCommunicationHelper } from './DrawioCommunicationHelper';
- const logger = loggerFactory('growi:components:DrawioModal');
- const headerColor = '#334455';
- const fontFamily = "-apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif";
- const drawioConfig: DrawioConfig = {
- css: `
- .geMenubarContainer { background-color: ${headerColor} !important; }
- .geMenubar { background-color: ${headerColor} !important; }
- .geEditor { font-family: ${fontFamily} !important; }
- html td.mxPopupMenuItem {
- font-family: ${fontFamily} !important;
- font-size: 8pt !important;
- }
- `,
- customFonts: ['Charter'],
- compressXml: true,
- };
- export const DrawioModal = (): JSX.Element => {
- const { data: rendererConfig } = useRendererConfig();
- const { data: personalSettingsInfo } = usePersonalSettings({
- // make immutable
- revalidateIfStale: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- });
- const { data: drawioModalData, close: closeDrawioModal } = useDrawioModal();
- const { data: drawioModalDataInEditor, close: closeDrawioModalInEditor } = useDrawioModalForEditor();
- const editorKey = drawioModalDataInEditor?.editorKey ?? null;
- const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
- const editor = codeMirrorEditor?.view;
- const isOpenedInEditor = (drawioModalDataInEditor?.isOpened ?? false) && (editor != null);
- const isOpened = drawioModalData?.isOpened ?? false;
- const drawioUriWithParams = useMemo(() => {
- if (rendererConfig == null) {
- return undefined;
- }
- let url;
- try {
- url = new URL(rendererConfig.drawioUri);
- }
- catch (err) {
- logger.debug(err);
- return undefined;
- }
- // refs: https://desk.draw.io/support/solutions/articles/16000042546-what-url-parameters-are-supported-
- url.searchParams.append('spin', '1');
- url.searchParams.append('embed', '1');
- url.searchParams.append('lang', getDiagramsNetLangCode(personalSettingsInfo?.lang || 'en'));
- url.searchParams.append('ui', 'atlas');
- url.searchParams.append('configure', '1');
- return url;
- }, [rendererConfig, personalSettingsInfo?.lang]);
- const drawioCommunicationHelper = useMemo(() => {
- if (rendererConfig == null) {
- return undefined;
- }
- const save = editor != null ? (drawioMxFile: string) => {
- replaceFocusedDrawioWithEditor(editor, drawioMxFile);
- } : drawioModalData?.onSave;
- return new DrawioCommunicationHelper(
- rendererConfig.drawioUri,
- drawioConfig,
- { onClose: isOpened ? closeDrawioModal : closeDrawioModalInEditor, onSave: save },
- );
- }, [closeDrawioModal, closeDrawioModalInEditor, drawioModalData?.onSave, editor, isOpened, rendererConfig]);
- const receiveMessageHandler = useCallback((event: MessageEvent) => {
- if (drawioModalData == null) {
- return;
- }
- const drawioMxFile = editor != null ? getMarkdownDrawioMxfile(editor) : drawioModalData.drawioMxFile;
- drawioCommunicationHelper?.onReceiveMessage(event, drawioMxFile);
- }, [drawioCommunicationHelper, drawioModalData, editor]);
- useEffect(() => {
- if (isOpened || isOpenedInEditor) {
- window.addEventListener('message', receiveMessageHandler);
- }
- else {
- window.removeEventListener('message', receiveMessageHandler);
- }
- // clean up
- return function() {
- window.removeEventListener('message', receiveMessageHandler);
- };
- }, [isOpened, isOpenedInEditor, receiveMessageHandler]);
- return (
- <Modal
- isOpen={isOpened || isOpenedInEditor}
- toggle={() => (isOpened ? closeDrawioModal() : closeDrawioModalInEditor())}
- backdrop="static"
- className="drawio-modal grw-body-only-modal-expanded"
- size="xl"
- keyboard={false}
- >
- <ModalBody className="p-0">
- {/* Loading spinner */}
- <div className="w-100 h-100 position-absolute d-flex">
- <div className="mx-auto my-auto">
- <i className="fa fa-3x fa-spinner fa-pulse mx-auto text-muted"></i>
- </div>
- </div>
- {/* iframe */}
- { drawioUriWithParams != null && (
- <div className="w-100 h-100 position-absolute d-flex">
- { (isOpened || isOpenedInEditor) && (
- <iframe
- src={drawioUriWithParams.href}
- className="border-0 flex-grow-1"
- >
- </iframe>
- ) }
- </div>
- ) }
- </ModalBody>
- </Modal>
- );
- };
|