fix: Adjust mermaid chart to new types and use useAsync

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2022-11-05 18:07:49 +01:00
parent e714313011
commit 5baa7e3351
3 changed files with 36 additions and 61 deletions

View file

@ -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",

View file

@ -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<typeof import('mermaid')> => {
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<CodeProps> = ({ code }) => {
const diagramContainer = useRef<HTMLDivElement>(null)
const [error, setError] = useState<string>()
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 (
<Fragment>
<ShowIf condition={!!error}>
<Alert variant={'warning'}>{error}</Alert>
<Alert variant={'warning'}>{error?.message}</Alert>
</ShowIf>
<div
{...cypressId('mermaid-frame')}

View file

@ -1964,7 +1964,6 @@ __metadata:
"@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
@ -3483,13 +3482,6 @@ __metadata:
languageName: node
linkType: hard
"@types/mermaid@npm:9.1.0":
version: 9.1.0
resolution: "@types/mermaid@npm:9.1.0"
checksum: ea3756826c89c85efd4e182c6ef025ea24a20ee70dc168673390b1125f158f57ae231f36cb2c700ef0ea6e9c322551963404759f8d019e0e48fb7cb5d6da1f96
languageName: node
linkType: hard
"@types/node@npm:*":
version: 18.11.4
resolution: "@types/node@npm:18.11.4"