mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-06-03 08:28:54 -04: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": "12.2.3",
|
||||||
"@types/markdown-it-container": "2.0.5",
|
"@types/markdown-it-container": "2.0.5",
|
||||||
"@types/markdown-it-plantuml": "1.4.1",
|
"@types/markdown-it-plantuml": "1.4.1",
|
||||||
"@types/mermaid": "9.1.0",
|
|
||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "18.0.25",
|
||||||
"@types/react-dom": "18.0.8",
|
"@types/react-dom": "18.0.8",
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* 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 { Alert } from 'react-bootstrap'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styles from './mermaid.module.scss'
|
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 { cypressId } from '../../../utils/cypress-attribute'
|
||||||
import { ShowIf } from '../../../components/common/show-if/show-if'
|
import { ShowIf } from '../../../components/common/show-if/show-if'
|
||||||
import { Logger } from '../../../utils/logger'
|
import { Logger } from '../../../utils/logger'
|
||||||
|
import { useAsync } from 'react-use'
|
||||||
|
|
||||||
const log = new Logger('MermaidChart')
|
const log = new Logger('MermaidChart')
|
||||||
|
|
||||||
interface MermaidParseError {
|
|
||||||
str: string
|
|
||||||
}
|
|
||||||
|
|
||||||
let mermaidInitialized = false
|
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.
|
* Renders a mermaid diagram.
|
||||||
*
|
*
|
||||||
|
@ -29,61 +35,39 @@ let mermaidInitialized = false
|
||||||
*/
|
*/
|
||||||
export const MermaidChart: React.FC<CodeProps> = ({ code }) => {
|
export const MermaidChart: React.FC<CodeProps> = ({ code }) => {
|
||||||
const diagramContainer = useRef<HTMLDivElement>(null)
|
const diagramContainer = useRef<HTMLDivElement>(null)
|
||||||
const [error, setError] = useState<string>()
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const { error } = useAsync(async () => {
|
||||||
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(() => {
|
|
||||||
if (!diagramContainer.current) {
|
if (!diagramContainer.current) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
import(/* webpackChunkName: "mermaid" */ 'mermaid')
|
|
||||||
.then((mermaid) => {
|
const mermaid = await loadMermaid()
|
||||||
try {
|
|
||||||
if (!diagramContainer.current) {
|
if (!mermaidInitialized) {
|
||||||
return
|
mermaid.default.initialize({ startOnLoad: false })
|
||||||
}
|
mermaidInitialized = true
|
||||||
mermaid.default.parse(code)
|
}
|
||||||
delete diagramContainer.current.dataset.processed
|
|
||||||
diagramContainer.current.textContent = code
|
try {
|
||||||
mermaid.default.init(diagramContainer.current)
|
if (!diagramContainer.current) {
|
||||||
setError(undefined)
|
return
|
||||||
} catch (error) {
|
}
|
||||||
const message = (error as MermaidParseError).str
|
mermaid.default.parse(code)
|
||||||
showError(message || t('renderer.mermaid.unknownError'))
|
delete diagramContainer.current.dataset.processed
|
||||||
}
|
diagramContainer.current.textContent = code
|
||||||
})
|
await mermaid.default.init(undefined, diagramContainer.current)
|
||||||
.catch(() => showError('Error while loading mermaid'))
|
} catch (error) {
|
||||||
}, [code, showError, t])
|
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 (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<ShowIf condition={!!error}>
|
<ShowIf condition={!!error}>
|
||||||
<Alert variant={'warning'}>{error}</Alert>
|
<Alert variant={'warning'}>{error?.message}</Alert>
|
||||||
</ShowIf>
|
</ShowIf>
|
||||||
<div
|
<div
|
||||||
{...cypressId('mermaid-frame')}
|
{...cypressId('mermaid-frame')}
|
||||||
|
|
|
@ -1964,7 +1964,6 @@ __metadata:
|
||||||
"@types/markdown-it": 12.2.3
|
"@types/markdown-it": 12.2.3
|
||||||
"@types/markdown-it-container": 2.0.5
|
"@types/markdown-it-container": 2.0.5
|
||||||
"@types/markdown-it-plantuml": 1.4.1
|
"@types/markdown-it-plantuml": 1.4.1
|
||||||
"@types/mermaid": 9.1.0
|
|
||||||
"@types/node": 18.11.9
|
"@types/node": 18.11.9
|
||||||
"@types/react": 18.0.25
|
"@types/react": 18.0.25
|
||||||
"@types/react-dom": 18.0.8
|
"@types/react-dom": 18.0.8
|
||||||
|
@ -3483,13 +3482,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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:*":
|
"@types/node@npm:*":
|
||||||
version: 18.11.4
|
version: 18.11.4
|
||||||
resolution: "@types/node@npm:18.11.4"
|
resolution: "@types/node@npm:18.11.4"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue