feat: convert components to dynamic imports for improved performance (#22614)

This commit is contained in:
Wu Tianwei
2025-07-18 11:43:37 +08:00
committed by GitHub
parent 1f9cd99bc2
commit b035f3f884
37 changed files with 493 additions and 472 deletions

View File

@@ -6,6 +6,7 @@ import {
} from 'react'
import { useTranslation } from 'react-i18next'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import {
RiArrowDownSLine,
RiArrowRightSLine,
@@ -48,6 +49,7 @@ import { useAppWhiteListSubjects, useGetUserCanAccessApp } from '@/service/acces
import { AccessMode } from '@/models/access-control'
import { fetchAppDetail } from '@/service/apps'
import { useGlobalPublicStore } from '@/context/global-public-context'
dayjs.extend(relativeTime)
export type AppPublisherProps = {
disabled?: boolean
@@ -116,6 +118,7 @@ const AppPublisher = ({
}
}, [appAccessSubjects, appDetail])
const language = useGetLanguage()
const formatTimeFromNow = useCallback((time: number) => {
return dayjs(time).locale(language === 'zh_Hans' ? 'zh-cn' : language.replace('_', '-')).fromNow()
}, [language])
@@ -180,8 +183,7 @@ const AppPublisher = ({
if (publishDisabled || published)
return
handlePublish()
},
{ exactMatch: true, useCapture: true })
}, { exactMatch: true, useCapture: true })
return (
<>

View File

@@ -20,8 +20,8 @@ const SuggestedAction = ({ icon, link, disabled, children, className, onClick, .
target='_blank'
rel='noreferrer'
className={classNames(
'flex justify-start items-center gap-2 py-2 px-2.5 bg-background-section-burn rounded-lg text-text-secondary transition-colors [&:not(:first-child)]:mt-1',
disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'text-text-secondary hover:bg-state-accent-hover hover:text-text-accent cursor-pointer',
'flex items-center justify-start gap-2 rounded-lg bg-background-section-burn px-2.5 py-2 text-text-secondary transition-colors [&:not(:first-child)]:mt-1',
disabled ? 'cursor-not-allowed opacity-30 shadow-xs' : 'cursor-pointer text-text-secondary hover:bg-state-accent-hover hover:text-text-accent',
className,
)}
onClick={handleClick}

View File

@@ -65,6 +65,44 @@ const AppTypeSelector = ({ value, onChange }: AppSelectorProps) => {
export default AppTypeSelector
type AppTypeIconProps = {
type: AppMode
style?: React.CSSProperties
className?: string
wrapperClassName?: string
}
export const AppTypeIcon = React.memo(({ type, className, wrapperClassName, style }: AppTypeIconProps) => {
const wrapperClassNames = cn('inline-flex h-5 w-5 items-center justify-center rounded-md border border-divider-regular', wrapperClassName)
const iconClassNames = cn('h-3.5 w-3.5 text-components-avatar-shape-fill-stop-100', className)
if (type === 'chat') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-blue-solid')}>
<ChatBot className={iconClassNames} />
</div>
}
if (type === 'agent-chat') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-violet-solid')}>
<Logic className={iconClassNames} />
</div>
}
if (type === 'advanced-chat') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-blue-light-solid')}>
<BubbleTextMod className={iconClassNames} />
</div>
}
if (type === 'workflow') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-indigo-solid')}>
<RiExchange2Fill className={iconClassNames} />
</div>
}
if (type === 'completion') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-teal-solid')}>
<ListSparkle className={iconClassNames} />
</div>
}
return null
})
function AppTypeSelectTrigger({ values }: { values: AppSelectorProps['value'] }) {
const { t } = useTranslation()
if (!values || values.length === 0) {
@@ -108,44 +146,6 @@ function AppTypeSelectorItem({ checked, type, onClick }: AppTypeSelectorItemProp
</li>
}
type AppTypeIconProps = {
type: AppMode
style?: React.CSSProperties
className?: string
wrapperClassName?: string
}
export function AppTypeIcon({ type, className, wrapperClassName, style }: AppTypeIconProps) {
const wrapperClassNames = cn('inline-flex h-5 w-5 items-center justify-center rounded-md border border-divider-regular', wrapperClassName)
const iconClassNames = cn('h-3.5 w-3.5 text-components-avatar-shape-fill-stop-100', className)
if (type === 'chat') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-blue-solid')}>
<ChatBot className={iconClassNames} />
</div>
}
if (type === 'agent-chat') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-violet-solid')}>
<Logic className={iconClassNames} />
</div>
}
if (type === 'advanced-chat') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-blue-light-solid')}>
<BubbleTextMod className={iconClassNames} />
</div>
}
if (type === 'workflow') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-indigo-solid')}>
<RiExchange2Fill className={iconClassNames} />
</div>
}
if (type === 'completion') {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-teal-solid')}>
<ListSparkle className={iconClassNames} />
</div>
}
return null
}
type AppTypeLabelProps = {
type: AppMode
className?: string