mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-01-27 00:53:33 +00:00
fix: Adjust mermaid chart to new types and use useAsync
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
e714313011
commit
5baa7e3351
3 changed files with 36 additions and 61 deletions
|
@ -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",
|
||||
|
|
|
@ -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')}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue