Skip to content

Commit

Permalink
Update mermaid (#11356)
Browse files Browse the repository at this point in the history
Co-authored-by: luowei <glpat-EjySCyNjWiLqAED-YmwM>
Co-authored-by: crazywoola <[email protected]>
Co-authored-by: crazywoola <[email protected]>
  • Loading branch information
3 people authored Dec 5, 2024
1 parent d60ca16 commit 7c979e6
Show file tree
Hide file tree
Showing 5 changed files with 455 additions and 135 deletions.
94 changes: 70 additions & 24 deletions web/app/components/base/mermaid/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import React, { useEffect, useRef, useState } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import mermaid from 'mermaid'
import { usePrevious } from 'ahooks'
import CryptoJS from 'crypto-js'
import { useTranslation } from 'react-i18next'
import { ExclamationTriangleIcon } from '@heroicons/react/24/outline'
import LoadingAnim from '@/app/components/base/chat/chat/loading-anim'
import cn from '@/utils/classnames'
import ImagePreview from '@/app/components/base/image-uploader/image-preview'

let mermaidAPI: any
mermaidAPI = null

if (typeof window !== 'undefined') {
mermaid.initialize({
startOnLoad: true,
theme: 'default',
flowchart: {
htmlLabels: true,
useMaxWidth: true,
},
})
if (typeof window !== 'undefined')
mermaidAPI = mermaid.mermaidAPI
}

const style = {
minWidth: '480px',
Expand All @@ -40,14 +34,21 @@ const svgToBase64 = (svgGraph: string) => {
const Flowchart = React.forwardRef((props: {
PrimitiveCode: string
}, ref) => {
const { t } = useTranslation()
const [svgCode, setSvgCode] = useState(null)
const [look, setLook] = useState<'classic' | 'handDrawn'>('classic')

const chartId = useRef(`flowchart_${CryptoJS.MD5(props.PrimitiveCode).toString()}`)
const prevPrimitiveCode = usePrevious(props.PrimitiveCode)
const [isLoading, setIsLoading] = useState(true)
const timeRef = useRef<NodeJS.Timeout>()
const [errMsg, setErrMsg] = useState('')
const [imagePreviewUrl, setImagePreviewUrl] = useState('')

const renderFlowchart = useCallback(async (PrimitiveCode: string) => {
setSvgCode(null)
setIsLoading(true)

const renderFlowchart = async (PrimitiveCode: string) => {
try {
if (typeof window !== 'undefined' && mermaidAPI) {
const svgGraph = await mermaidAPI.render(chartId.current, PrimitiveCode)
Expand All @@ -64,10 +65,28 @@ const Flowchart = React.forwardRef((props: {
setErrMsg((error as Error).message)
}
}
}
}, [props.PrimitiveCode])

useEffect(() => {
if (typeof window !== 'undefined') {
mermaid.initialize({
startOnLoad: true,
theme: 'neutral',
look,
flowchart: {
htmlLabels: true,
useMaxWidth: true,
},
})

localStorage.removeItem(chartId.current)
renderFlowchart(props.PrimitiveCode)
}
}, [look])

useEffect(() => {
const cachedSvg: any = localStorage.getItem(chartId.current)

if (cachedSvg) {
setSvgCode(cachedSvg)
setIsLoading(false)
Expand All @@ -85,24 +104,51 @@ const Flowchart = React.forwardRef((props: {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
<div ref={ref}>
<div className="msh-segmented msh-segmented-sm css-23bs09 css-var-r1">
<div className="msh-segmented-group">
<label className="msh-segmented-item flex items-center space-x-1 m-2 w-[200px]">
<div key='classic'
className={cn('flex items-center justify-center mb-4 w-[calc((100%-8px)/2)] h-8 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg cursor-pointer system-sm-medium text-text-secondary',
look === 'classic' && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary',
)}

onClick={() => setLook('classic')}
>
<div className="msh-segmented-item-label">{t('app.mermaid.classic')}</div>
</div>
<div key='handDrawn'
className={cn(
'flex items-center justify-center mb-4 w-[calc((100%-8px)/2)] h-8 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg cursor-pointer system-sm-medium text-text-secondary',
look === 'handDrawn' && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary',
)}
onClick={() => setLook('handDrawn')}
>
<div className="msh-segmented-item-label">{t('app.mermaid.handDrawn')}</div>
</div>
</label>
</div>
</div>
{
svgCode
&& <div className="mermaid" style={style}>
{svgCode && <img src={svgCode} style={{ width: '100%', height: 'auto' }} alt="Mermaid chart" />}
</div>
&& <div className="mermaid cursor-pointer" style={style} onClick={() => setImagePreviewUrl(svgCode)}>
{svgCode && <img src={svgCode} style={{ width: '100%', height: 'auto' }} alt="mermaid_chart" />}
</div>
}
{isLoading
&& <div className='py-4 px-[26px]'>
<LoadingAnim type='text' />
</div>
&& <div className='py-4 px-[26px]'>
<LoadingAnim type='text'/>
</div>
}
{
errMsg
&& <div className='py-4 px-[26px]'>
<ExclamationTriangleIcon className='w-6 h-6 text-red-500' />
&nbsp;
{errMsg}
</div>
&& <div className='py-4 px-[26px]'>
<ExclamationTriangleIcon className='w-6 h-6 text-red-500'/>
&nbsp;
{errMsg}
</div>
}
{
imagePreviewUrl && (<ImagePreview title='mermaid_chart' url={imagePreviewUrl} onCancel={() => setImagePreviewUrl('')} />)
}
</div>
)
Expand Down
4 changes: 4 additions & 0 deletions web/i18n/en-US/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const translation = {
completion: 'Completion',
},
duplicate: 'Duplicate',
mermaid: {
handDrawn: 'Hand Drawn',
classic: 'Classic',
},
duplicateTitle: 'Duplicate App',
export: 'Export DSL',
exportFailed: 'Export DSL failed.',
Expand Down
4 changes: 4 additions & 0 deletions web/i18n/zh-Hans/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const translation = {
completion: '文本生成',
},
duplicate: '复制',
mermaid: {
handDrawn: '手绘',
classic: '经典',
},
duplicateTitle: '复制应用',
export: '导出 DSL',
exportFailed: '导出 DSL 失败',
Expand Down
4 changes: 2 additions & 2 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"lamejs": "^1.2.1",
"lexical": "^0.16.0",
"lodash-es": "^4.17.21",
"mermaid": "10.9.3",
"mermaid": "11.4.1",
"mime": "^4.0.4",
"negotiator": "^0.6.3",
"next": "^14.2.10",
Expand Down Expand Up @@ -144,7 +144,7 @@
"@types/uuid": "^9.0.8",
"autoprefixer": "^10.4.14",
"bing-translate-api": "^4.0.2",
"code-inspector-plugin": "^0.13.0",
"code-inspector-plugin": "^0.18.1",
"cross-env": "^7.0.3",
"eslint": "^8.36.0",
"eslint-config-next": "^14.0.4",
Expand Down
Loading

0 comments on commit 7c979e6

Please sign in to comment.