From 5baa7e3351de022e58d934140e297639f7814cc6 Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Sat, 5 Nov 2022 18:07:49 +0100 Subject: [PATCH] fix: Adjust mermaid chart to new types and use useAsync Signed-off-by: Tilman Vatteroth --- package.json | 1 - .../mermaid/mermaid-chart.tsx | 88 ++++++++----------- yarn.lock | 8 -- 3 files changed, 36 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 0bac3cfac..b58a1b1df 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,6 @@ "@types/markdown-it": "12.2.3", "@types/markdown-it-container": "2.0.5", "@types/markdown-it-plantuml": "1.4.1", - "@types/mermaid": "9.1.0", "@types/node": "18.11.9", "@types/react": "18.0.25", "@types/react-dom": "18.0.8", diff --git a/src/extensions/extra-integrations/mermaid/mermaid-chart.tsx b/src/extensions/extra-integrations/mermaid/mermaid-chart.tsx index b1f16ce91..909d860c7 100644 --- a/src/extensions/extra-integrations/mermaid/mermaid-chart.tsx +++ b/src/extensions/extra-integrations/mermaid/mermaid-chart.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react' +import React, { Fragment, useRef } from 'react' import { Alert } from 'react-bootstrap' import { useTranslation } from 'react-i18next' import styles from './mermaid.module.scss' @@ -12,15 +12,21 @@ import type { CodeProps } from '../../../components/markdown-renderer/replace-co import { cypressId } from '../../../utils/cypress-attribute' import { ShowIf } from '../../../components/common/show-if/show-if' import { Logger } from '../../../utils/logger' +import { useAsync } from 'react-use' const log = new Logger('MermaidChart') -interface MermaidParseError { - str: string -} - let mermaidInitialized = false +const loadMermaid = async (): Promise => { + try { + return import(/* webpackChunkName: "mermaid" */ 'mermaid') + } catch (error) { + log.error('Error while loading mermaid', error) + throw new Error('Error while loading mermaid') + } +} + /** * Renders a mermaid diagram. * @@ -29,61 +35,39 @@ let mermaidInitialized = false */ export const MermaidChart: React.FC = ({ code }) => { const diagramContainer = useRef(null) - const [error, setError] = useState() const { t } = useTranslation() - - useEffect(() => { - if (!mermaidInitialized) { - import(/* webpackChunkName: "mermaid" */ 'mermaid') - .then((mermaid) => { - mermaid.default.initialize({ startOnLoad: false }) - mermaidInitialized = true - }) - .catch((error: Error) => { - log.error('Error while loading mermaid', error) - }) - } - }, []) - - const showError = useCallback( - (error: string) => { - setError(error) - log.error(error) - if (!diagramContainer.current) { - return - } - diagramContainer.current.querySelectorAll('svg').forEach((child) => child.remove()) - }, - [setError] - ) - - useEffect(() => { + const { error } = useAsync(async () => { if (!diagramContainer.current) { return } - import(/* webpackChunkName: "mermaid" */ 'mermaid') - .then((mermaid) => { - try { - if (!diagramContainer.current) { - return - } - mermaid.default.parse(code) - delete diagramContainer.current.dataset.processed - diagramContainer.current.textContent = code - mermaid.default.init(diagramContainer.current) - setError(undefined) - } catch (error) { - const message = (error as MermaidParseError).str - showError(message || t('renderer.mermaid.unknownError')) - } - }) - .catch(() => showError('Error while loading mermaid')) - }, [code, showError, t]) + + const mermaid = await loadMermaid() + + if (!mermaidInitialized) { + mermaid.default.initialize({ startOnLoad: false }) + mermaidInitialized = true + } + + try { + if (!diagramContainer.current) { + return + } + mermaid.default.parse(code) + delete diagramContainer.current.dataset.processed + diagramContainer.current.textContent = code + await mermaid.default.init(undefined, diagramContainer.current) + } catch (error) { + const message = (error as Error).message + log.error(error) + diagramContainer.current?.querySelectorAll('svg').forEach((child) => child.remove()) + throw new Error(message || t('renderer.mermaid.unknownError')) + } + }, [code, t]) return ( - {error} + {error?.message}