refactor(web): mark Props of base/ components as read-only (#25219) (#37161)

This commit is contained in:
Evan 2026-06-08 13:48:04 +08:00 committed by GitHub
parent d46a4c05b1
commit 6291452020
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 36 additions and 36 deletions

View File

@ -15,12 +15,12 @@ import { fetchAgentLogDetail } from '@/service/log'
import ResultPanel from './result'
import TracingPanel from './tracing'
type AgentLogDetailProps = {
type AgentLogDetailProps = Readonly<{
activeTab?: 'DETAIL' | 'TRACING'
conversationID: string
log: IChatItem
messageID: string
}
}>
const AgentLogDetail: FC<AgentLogDetailProps> = ({ activeTab = 'DETAIL', conversationID, messageID, log }) => {
const { t } = useTranslation()
const [currentTab, setCurrentTab] = useState<string>(activeTab)

View File

@ -7,11 +7,11 @@ import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import AgentLogDetail from './detail'
type AgentLogModalProps = {
type AgentLogModalProps = Readonly<{
currentLogItem?: IChatItem
width: number
onCancel: () => void
}
}>
const AgentLogModal: FC<AgentLogModalProps> = ({
currentLogItem,
width,

View File

@ -6,11 +6,11 @@ import { useTranslation } from 'react-i18next'
import Divider from '@/app/components/base/divider'
import ToolCall from './tool-call'
type Props = {
type Props = Readonly<{
isFinal: boolean
index: number
iterationInfo: AgentIteration
}
}>
const Iteration: FC<Props> = ({ iterationInfo, isFinal, index }) => {
const { t } = useTranslation()

View File

@ -6,7 +6,7 @@ import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import StatusPanel from '@/app/components/workflow/run/status'
import useTimestamp from '@/hooks/use-timestamp'
type ResultPanelProps = {
type ResultPanelProps = Readonly<{
status: string
elapsed_time?: number
total_tokens?: number
@ -18,7 +18,7 @@ type ResultPanelProps = {
agentMode?: string
tools?: string[]
iterations?: number
}
}>
const ResultPanel: FC<ResultPanelProps> = ({
elapsed_time,

View File

@ -15,14 +15,14 @@ import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import { BlockEnum } from '@/app/components/workflow/types'
import { useLocale } from '@/context/i18n'
type Props = {
type Props = Readonly<{
toolCall: ToolCall
isLLM: boolean
isFinal?: boolean
tokens?: number
observation?: any
finalAnswer?: any
}
}>
const ToolCallItem: FC<Props> = ({ toolCall, isLLM = false, isFinal, tokens, observation, finalAnswer }) => {
const [collapseState, setCollapseState] = useState<boolean>(true)

View File

@ -3,9 +3,9 @@ import type { FC } from 'react'
import type { AgentIteration } from '@/models/log'
import Iteration from './iteration'
type TracingPanelProps = {
type TracingPanelProps = Readonly<{
list: AgentIteration[]
}
}>
const TracingPanel: FC<TracingPanelProps> = ({ list }) => {
return (

View File

@ -6,10 +6,10 @@ import { useTranslation } from 'react-i18next'
import useTheme from '@/hooks/use-theme'
import { Theme } from '@/types/app'
type AudioPlayerProps = {
type AudioPlayerProps = Readonly<{
src?: string // Keep backward compatibility
srcs?: string[] // Support multiple sources
}
}>
const AudioPlayer: React.FC<AudioPlayerProps> = ({ src, srcs }) => {
const { t } = useTranslation()
const [isPlaying, setIsPlaying] = useState(false)

View File

@ -1,9 +1,9 @@
import * as React from 'react'
import AudioPlayer from './AudioPlayer'
type Props = {
type Props = Readonly<{
srcs: string[]
}
}>
const AudioGallery: React.FC<Props> = ({ srcs }) => {
const validSrcs = srcs.filter(src => src)

View File

@ -26,14 +26,14 @@ const BadgeVariants = cva(
},
)
type BadgeProps = {
type BadgeProps = Readonly<{
size?: 's' | 'm' | 'l'
iconOnly?: boolean
uppercase?: boolean
state?: BadgeState
styleCss?: CSSProperties
children?: ReactNode
} & React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof BadgeVariants>
}> & React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof BadgeVariants>
function getBadgeState(state: BadgeState) {
switch (state) {

View File

@ -10,11 +10,11 @@ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
type CarouselOptions = UseCarouselParameters[0]
type CarouselPlugin = UseCarouselParameters[1]
type CarouselProps = {
type CarouselProps = Readonly<{
opts?: CarouselOptions
plugins?: CarouselPlugin
orientation?: 'horizontal' | 'vertical'
}
}>
type CarouselContextValue = {
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
@ -160,9 +160,9 @@ const CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLD
)
CarouselItem.displayName = 'CarouselItem'
type CarouselActionProps = {
type CarouselActionProps = Readonly<{
children?: React.ReactNode
} & Omit<React.HTMLAttributes<HTMLButtonElement>, 'disabled' | 'onClick'>
}> & Omit<React.HTMLAttributes<HTMLButtonElement>, 'disabled' | 'onClick'>
const CarouselPrevious = React.forwardRef<HTMLButtonElement, CarouselActionProps>(
({ children, ...props }, ref) => {

View File

@ -8,11 +8,11 @@ import AppIcon from '@/app/components/base/app-icon'
import Link from '@/next/link'
import { AppModeEnum } from '@/types/app'
type ILikedItemProps = {
type ILikedItemProps = Readonly<{
appStatus?: boolean
detail: RelatedApp
isMobile: boolean
}
}>
const appTypeMap = {
[AppModeEnum.CHAT]: 'Chatbot',
@ -40,10 +40,10 @@ const LikedItem = ({
)
}
type Props = {
type Props = Readonly<{
relatedApps: RelatedApp[]
isMobile: boolean
}
}>
const LinkedAppsPanel: FC<Props> = ({
relatedApps,

View File

@ -4,10 +4,10 @@ import { cn } from '@langgenius/dify-ui/cn'
import { useTranslation } from 'react-i18next'
import './style.css'
type ILoadingProps = {
type ILoadingProps = Readonly<{
type?: 'area' | 'app'
className?: string
}
}>
const Loading = (props?: ILoadingProps) => {
const { type = 'area', className } = props || {}

View File

@ -9,11 +9,11 @@ import ActionButton, { ActionButtonState } from '@/app/components/base/action-bu
import { AudioPlayerManager } from '@/app/components/base/audio-btn/audio.player.manager'
import { useParams, usePathname } from '@/next/navigation'
type AudioBtnProps = {
type AudioBtnProps = Readonly<{
id?: string
voice?: string
value?: string
}
}>
type AudioState = 'initial' | 'loading' | 'playing' | 'paused' | 'ended'

View File

@ -12,14 +12,14 @@ type Item = {
disabled?: boolean
}
export type ITabHeaderProps = {
export type ITabHeaderProps = Readonly<{
items: Item[]
value: string
itemClassName?: string
itemWrapClassName?: string
activeItemClassName?: string
onChange: (value: string) => void
}
}>
const TabHeader: FC<ITabHeaderProps> = ({
items,

View File

@ -8,13 +8,13 @@ type Option = {
text: string | React.JSX.Element
}
type ItemProps = {
type ItemProps = Readonly<{
className?: string
isActive: boolean
onClick: (v: string) => void
option: Option
smallItem?: boolean
}
}>
const Item: FC<ItemProps> = ({
className,
isActive,
@ -51,7 +51,7 @@ const Item: FC<ItemProps> = ({
)
}
type Props = {
type Props = Readonly<{
className?: string
value: string
onChange: (v: string) => void
@ -59,7 +59,7 @@ type Props = {
noBorderBottom?: boolean
smallItem?: boolean
itemClassName?: string
}
}>
const TabSlider: FC<Props> = ({
className,