Merge remote-tracking branch 'origin/main' into feat/trigger

This commit is contained in:
lyzno1 2025-09-28 19:32:33 +08:00
commit 8fc88f8cbf
40 changed files with 83 additions and 74 deletions

View File

@ -42,6 +42,10 @@ class CacheEmbedding(Embeddings):
text_embeddings[i] = embedding.get_embedding() text_embeddings[i] = embedding.get_embedding()
else: else:
embedding_queue_indices.append(i) embedding_queue_indices.append(i)
# release database connection, because embedding may take a long time
db.session.close()
if embedding_queue_indices: if embedding_queue_indices:
embedding_queue_texts = [texts[i] for i in embedding_queue_indices] embedding_queue_texts = [texts[i] for i in embedding_queue_indices]
embedding_queue_embeddings = [] embedding_queue_embeddings = []

View File

@ -212,10 +212,11 @@ class ResponseStreamCoordinator:
edge = self._graph.edges[edge_id] edge = self._graph.edges[edge_id]
source_node = self._graph.nodes[edge.tail] source_node = self._graph.nodes[edge.tail]
# Check if node is a branch/container (original behavior) # Check if node is a branch, container, or response node
if source_node.execution_type in { if source_node.execution_type in {
NodeExecutionType.BRANCH, NodeExecutionType.BRANCH,
NodeExecutionType.CONTAINER, NodeExecutionType.CONTAINER,
NodeExecutionType.RESPONSE,
} or source_node.blocks_variable_output(variable_selectors): } or source_node.blocks_variable_output(variable_selectors):
blocking_edges.append(edge_id) blocking_edges.append(edge_id)

View File

@ -66,8 +66,8 @@ def load_into_variable_pool(
# NOTE(QuantumGhost): this logic needs to be in sync with # NOTE(QuantumGhost): this logic needs to be in sync with
# `WorkflowEntry.mapping_user_inputs_to_variable_pool`. # `WorkflowEntry.mapping_user_inputs_to_variable_pool`.
node_variable_list = key.split(".") node_variable_list = key.split(".")
if len(node_variable_list) < 1: if len(node_variable_list) < 2:
raise ValueError(f"Invalid variable key: {key}. It should have at least one element.") raise ValueError(f"Invalid variable key: {key}. It should have at least two elements.")
if key in user_inputs: if key in user_inputs:
continue continue
node_variable_key = ".".join(node_variable_list[1:]) node_variable_key = ".".join(node_variable_list[1:])

View File

@ -54,7 +54,7 @@ const DocumentDetailWithFix = ({ datasetId, documentId }: { datasetId: string; d
return ( return (
<div data-testid="document-detail-fixed"> <div data-testid="document-detail-fixed">
<button data-testid="back-button-fixed" onClick={backToPrev}> <button type="button" data-testid="back-button-fixed" onClick={backToPrev}>
Back to Documents Back to Documents
</button> </button>
<div data-testid="document-info"> <div data-testid="document-info">

View File

@ -284,7 +284,7 @@ const AppInfo = ({ expand, onlyShowDetail = false, openState = false, onDetailEx
return ( return (
<div> <div>
{!onlyShowDetail && ( {!onlyShowDetail && (
<button <button type="button"
onClick={() => { onClick={() => {
if (isCurrentWorkspaceEditor) if (isCurrentWorkspaceEditor)
setOpen(v => !v) setOpen(v => !v)

View File

@ -51,7 +51,7 @@ const MockSidebarToggleButton = ({ expand, onToggle }: { expand: boolean; onTogg
className="shrink-0 px-4 py-3" className="shrink-0 px-4 py-3"
data-testid="toggle-section" data-testid="toggle-section"
> >
<button <button type="button"
className='flex h-6 w-6 cursor-pointer items-center justify-center' className='flex h-6 w-6 cursor-pointer items-center justify-center'
onClick={onToggle} onClick={onToggle}
data-testid="toggle-button" data-testid="toggle-button"
@ -66,7 +66,7 @@ const MockSidebarToggleButton = ({ expand, onToggle }: { expand: boolean; onTogg
const MockAppInfo = ({ expand }: { expand: boolean }) => { const MockAppInfo = ({ expand }: { expand: boolean }) => {
return ( return (
<div data-testid="app-info" data-expand={expand}> <div data-testid="app-info" data-expand={expand}>
<button className='block w-full'> <button type="button" className='block w-full'>
{/* Container with layout mode switching - reproduces issue #3 */} {/* Container with layout mode switching - reproduces issue #3 */}
<div className={`flex rounded-lg ${expand ? 'flex-col gap-2 p-2 pb-2.5' : 'items-start justify-center gap-1 p-1'}`}> <div className={`flex rounded-lg ${expand ? 'flex-col gap-2 p-2 pb-2.5' : 'items-start justify-center gap-1 p-1'}`}>
{/* Icon container with justify-between to flex-col switch - reproduces issue #3 */} {/* Icon container with justify-between to flex-col switch - reproduces issue #3 */}

View File

@ -100,7 +100,7 @@ const HeaderOptions: FC<Props> = ({
const Operations = () => { const Operations = () => {
return ( return (
<div className="w-full py-1"> <div className="w-full py-1">
<button className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50' onClick={() => { <button type="button" className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50' onClick={() => {
setShowBulkImportModal(true) setShowBulkImportModal(true)
}}> }}>
<FilePlus02 className='h-4 w-4 text-text-tertiary' /> <FilePlus02 className='h-4 w-4 text-text-tertiary' />
@ -135,17 +135,17 @@ const HeaderOptions: FC<Props> = ({
...list.map(item => [item.question, item.answer]), ...list.map(item => [item.question, item.answer]),
]} ]}
> >
<button disabled={annotationUnavailable} className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50'> <button type="button" disabled={annotationUnavailable} className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50'>
<span className='system-sm-regular grow text-left text-text-secondary'>CSV</span> <span className='system-sm-regular grow text-left text-text-secondary'>CSV</span>
</button> </button>
</CSVDownloader> </CSVDownloader>
<button disabled={annotationUnavailable} className={cn('mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50', '!border-0')} onClick={JSONLOutput}> <button type="button" disabled={annotationUnavailable} className={cn('mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50', '!border-0')} onClick={JSONLOutput}>
<span className='system-sm-regular grow text-left text-text-secondary'>JSONL</span> <span className='system-sm-regular grow text-left text-text-secondary'>JSONL</span>
</button> </button>
</MenuItems> </MenuItems>
</Transition> </Transition>
</Menu> </Menu>
<button <button type="button"
onClick={handleClearAll} onClick={handleClearAll}
className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 text-red-600 hover:bg-red-50 disabled:opacity-50' className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 text-red-600 hover:bg-red-50 disabled:opacity-50'
> >

View File

@ -141,7 +141,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
</div> </div>
<div> <div>
<div className='mb-2 flex items-center'> <div className='mb-2 flex items-center'>
<button <button type="button"
className='flex cursor-pointer items-center border-0 bg-transparent p-0' className='flex cursor-pointer items-center border-0 bg-transparent p-0'
onClick={() => setIsAppTypeExpanded(!isAppTypeExpanded)} onClick={() => setIsAppTypeExpanded(!isAppTypeExpanded)}
> >

View File

@ -263,16 +263,17 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
<span className='system-sm-regular text-text-secondary'>{t('app.editApp')}</span> <span className='system-sm-regular text-text-secondary'>{t('app.editApp')}</span>
</button> </button>
<Divider className="my-1" /> <Divider className="my-1" />
<button className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickDuplicate}> <button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickDuplicate}>
<span className='system-sm-regular text-text-secondary'>{t('app.duplicate')}</span> <span className='system-sm-regular text-text-secondary'>{t('app.duplicate')}</span>
</button> </button>
<button className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickExport}> <button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickExport}>
<span className='system-sm-regular text-text-secondary'>{t('app.export')}</span> <span className='system-sm-regular text-text-secondary'>{t('app.export')}</span>
</button> </button>
{(app.mode === 'completion' || app.mode === 'chat') && ( {(app.mode === 'completion' || app.mode === 'chat') && (
<> <>
<Divider className="my-1" /> <Divider className="my-1" />
<button <button
type="button"
className='mx-1 flex h-8 cursor-pointer items-center rounded-lg px-3 hover:bg-state-base-hover' className='mx-1 flex h-8 cursor-pointer items-center rounded-lg px-3 hover:bg-state-base-hover'
onClick={onClickSwitch} onClick={onClickSwitch}
> >
@ -284,14 +285,14 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
(!systemFeatures.webapp_auth.enabled) (!systemFeatures.webapp_auth.enabled)
? <> ? <>
<Divider className="my-1" /> <Divider className="my-1" />
<button className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}> <button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span> <span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
</button> </button>
</> </>
: !(isGettingUserCanAccessApp || !userCanAccessApp?.result) && ( : !(isGettingUserCanAccessApp || !userCanAccessApp?.result) && (
<> <>
<Divider className="my-1" /> <Divider className="my-1" />
<button className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}> <button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span> <span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
</button> </button>
</> </>
@ -300,13 +301,14 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
<Divider className="my-1" /> <Divider className="my-1" />
{ {
systemFeatures.webapp_auth.enabled && isCurrentWorkspaceEditor && <> systemFeatures.webapp_auth.enabled && isCurrentWorkspaceEditor && <>
<button className='mx-1 flex h-8 cursor-pointer items-center rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickAccessControl}> <button type="button" className='mx-1 flex h-8 cursor-pointer items-center rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickAccessControl}>
<span className='text-sm leading-5 text-text-secondary'>{t('app.accessControl')}</span> <span className='text-sm leading-5 text-text-secondary'>{t('app.accessControl')}</span>
</button> </button>
<Divider className='my-1' /> <Divider className='my-1' />
</> </>
} }
<button <button
type="button"
className='group mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-destructive-hover' className='group mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-destructive-hover'
onClick={onClickDelete} onClick={onClickDelete}
> >

View File

@ -59,15 +59,16 @@ const CreateAppCard = ({
> >
<div className='grow rounded-t-xl p-2'> <div className='grow rounded-t-xl p-2'>
<div className='px-6 pb-1 pt-2 text-xs font-medium leading-[18px] text-text-tertiary'>{t('app.createApp')}</div> <div className='px-6 pb-1 pt-2 text-xs font-medium leading-[18px] text-text-tertiary'>{t('app.createApp')}</div>
<button className='mb-1 flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppModal(true)}> <button type="button" className='mb-1 flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppModal(true)}>
<FilePlus01 className='mr-2 h-4 w-4 shrink-0' /> <FilePlus01 className='mr-2 h-4 w-4 shrink-0' />
{t('app.newApp.startFromBlank')} {t('app.newApp.startFromBlank')}
</button> </button>
<button className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppTemplateDialog(true)}> <button type="button" className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppTemplateDialog(true)}>
<FilePlus02 className='mr-2 h-4 w-4 shrink-0' /> <FilePlus02 className='mr-2 h-4 w-4 shrink-0' />
{t('app.newApp.startFromTemplate')} {t('app.newApp.startFromTemplate')}
</button> </button>
<button <button
type="button"
onClick={() => setShowCreateFromDSLModal(true)} onClick={() => setShowCreateFromDSLModal(true)}
className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary'> className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary'>
<FileArrow01 className='mr-2 h-4 w-4 shrink-0' /> <FileArrow01 className='mr-2 h-4 w-4 shrink-0' />

View File

@ -106,7 +106,7 @@ const ImageInput: FC<UploaderProps> = ({
<ImagePlus className="pointer-events-none mb-3 h-[30px] w-[30px]" /> <ImagePlus className="pointer-events-none mb-3 h-[30px] w-[30px]" />
<div className="mb-[2px] text-sm font-medium"> <div className="mb-[2px] text-sm font-medium">
<span className="pointer-events-none">{t('common.imageInput.dropImageHere')}&nbsp;</span> <span className="pointer-events-none">{t('common.imageInput.dropImageHere')}&nbsp;</span>
<button className="text-components-button-primary-bg" onClick={() => inputRef.current?.click()}>{t('common.imageInput.browse')}</button> <button type="button" className="text-components-button-primary-bg" onClick={() => inputRef.current?.click()}>{t('common.imageInput.browse')}</button>
<input <input
ref={inputRef} type="file" className="hidden" ref={inputRef} type="file" className="hidden"
onClick={e => ((e.target as HTMLInputElement).value = '')} onClick={e => ((e.target as HTMLInputElement).value = '')}

View File

@ -117,7 +117,7 @@ const AppIconPicker: FC<AppIconPickerProps> = ({
{!DISABLE_UPLOAD_IMAGE_AS_ICON && <div className="w-full p-2 pb-0"> {!DISABLE_UPLOAD_IMAGE_AS_ICON && <div className="w-full p-2 pb-0">
<div className='flex items-center justify-center gap-2 rounded-xl bg-background-body p-1 text-text-primary'> <div className='flex items-center justify-center gap-2 rounded-xl bg-background-body p-1 text-text-primary'>
{tabs.map(tab => ( {tabs.map(tab => (
<button <button type="button"
key={tab.key} key={tab.key}
className={cn( className={cn(
'system-sm-medium flex h-8 flex-1 shrink-0 items-center justify-center rounded-lg p-2 text-text-tertiary', 'system-sm-medium flex h-8 flex-1 shrink-0 items-center justify-center rounded-lg p-2 text-text-tertiary',

View File

@ -85,7 +85,7 @@ const AudioBtn = ({
<Tooltip <Tooltip
popupContent={tooltipContent} popupContent={tooltipContent}
> >
<button <button type="button"
disabled={audioState === 'loading'} disabled={audioState === 'loading'}
className={`box-border flex h-6 w-6 cursor-pointer items-center justify-center ${isAudition ? 'p-0.5' : 'rounded-md bg-white p-0'}`} className={`box-border flex h-6 w-6 cursor-pointer items-center justify-center ${isAudition ? 'p-0.5' : 'rounded-md bg-white p-0'}`}
onClick={handleToggle} onClick={handleToggle}

View File

@ -288,7 +288,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ src }) => {
return ( return (
<div className='flex h-9 min-w-[240px] max-w-[420px] items-end gap-2 rounded-[10px] border border-components-panel-border-subtle bg-components-chat-input-audio-bg-alt p-2 shadow-xs backdrop-blur-sm'> <div className='flex h-9 min-w-[240px] max-w-[420px] items-end gap-2 rounded-[10px] border border-components-panel-border-subtle bg-components-chat-input-audio-bg-alt p-2 shadow-xs backdrop-blur-sm'>
<audio ref={audioRef} src={src} preload="auto"/> <audio ref={audioRef} src={src} preload="auto"/>
<button className='inline-flex shrink-0 cursor-pointer items-center justify-center border-none text-text-accent transition-all hover:text-text-accent-secondary disabled:text-components-button-primary-bg-disabled' onClick={togglePlay} disabled={!isAudioAvailable}> <button type="button" className='inline-flex shrink-0 cursor-pointer items-center justify-center border-none text-text-accent transition-all hover:text-text-accent-secondary disabled:text-components-button-primary-bg-disabled' onClick={togglePlay} disabled={!isAudioAvailable}>
{isPlaying {isPlaying
? ( ? (
<RiPauseCircleFill className='h-5 w-5' /> <RiPauseCircleFill className='h-5 w-5' />

View File

@ -16,7 +16,7 @@ export default function ContentSwitch({
return ( return (
count && count > 1 && currentIndex !== undefined && ( count && count > 1 && currentIndex !== undefined && (
<div className="flex items-center justify-center pt-3.5 text-sm"> <div className="flex items-center justify-center pt-3.5 text-sm">
<button <button type="button"
className={`${prevDisabled ? 'opacity-30' : 'opacity-100'}`} className={`${prevDisabled ? 'opacity-30' : 'opacity-100'}`}
disabled={prevDisabled} disabled={prevDisabled}
onClick={() => !prevDisabled && switchSibling('prev')} onClick={() => !prevDisabled && switchSibling('prev')}
@ -26,7 +26,7 @@ export default function ContentSwitch({
<span className="px-2 text-xs text-text-primary"> <span className="px-2 text-xs text-text-primary">
{currentIndex + 1} / {count} {currentIndex + 1} / {count}
</span> </span>
<button <button type="button"
className={`${nextDisabled ? 'opacity-30' : 'opacity-100'}`} className={`${nextDisabled ? 'opacity-30' : 'opacity-100'}`}
disabled={nextDisabled} disabled={nextDisabled}
onClick={() => !nextDisabled && switchSibling('next')} onClick={() => !nextDisabled && switchSibling('next')}

View File

@ -13,7 +13,7 @@ const Item: FC<CalendarItemProps> = ({
const isToday = date.isSame(dayjs(), 'date') const isToday = date.isSame(dayjs(), 'date')
return ( return (
<button <button type="button"
onClick={() => onClick(date)} onClick={() => onClick(date)}
className={cn( className={cn(
'system-sm-medium relative flex items-center justify-center rounded-lg px-1 py-2', 'system-sm-medium relative flex items-center justify-center rounded-lg px-1 py-2',

View File

@ -14,7 +14,7 @@ const Header: FC<DatePickerHeaderProps> = ({
return ( return (
<div className='mx-2 mt-2 flex items-center'> <div className='mx-2 mt-2 flex items-center'>
<div className='flex-1'> <div className='flex-1'>
<button <button type="button"
onClick={handleOpenYearMonthPicker} onClick={handleOpenYearMonthPicker}
className='system-md-semibold flex items-center gap-x-0.5 rounded-lg px-2 py-1.5 text-text-primary hover:bg-state-base-hover' className='system-md-semibold flex items-center gap-x-0.5 rounded-lg px-2 py-1.5 text-text-primary hover:bg-state-base-hover'
> >
@ -22,13 +22,13 @@ const Header: FC<DatePickerHeaderProps> = ({
<RiArrowDownSLine className='h-4 w-4 text-text-tertiary' /> <RiArrowDownSLine className='h-4 w-4 text-text-tertiary' />
</button> </button>
</div> </div>
<button <button type="button"
onClick={onClickPrevMonth} onClick={onClickPrevMonth}
className='rounded-lg p-1.5 hover:bg-state-base-hover' className='rounded-lg p-1.5 hover:bg-state-base-hover'
> >
<RiArrowUpSLine className='h-[18px] w-[18px] text-text-secondary' /> <RiArrowUpSLine className='h-[18px] w-[18px] text-text-secondary' />
</button> </button>
<button <button type="button"
onClick={onClickNextMonth} onClick={onClickNextMonth}
className='rounded-lg p-1.5 hover:bg-state-base-hover' className='rounded-lg p-1.5 hover:bg-state-base-hover'
> >

View File

@ -13,7 +13,7 @@ const Header: FC<YearAndMonthPickerHeaderProps> = ({
return ( return (
<div className='flex border-b-[0.5px] border-divider-regular p-2 pb-1'> <div className='flex border-b-[0.5px] border-divider-regular p-2 pb-1'>
{/* Year and Month */} {/* Year and Month */}
<button <button type="button"
onClick={onClick} onClick={onClick}
className='system-md-semibold flex items-center gap-x-0.5 rounded-lg px-2 py-1.5 text-text-primary hover:bg-state-base-hover' className='system-md-semibold flex items-center gap-x-0.5 rounded-lg px-2 py-1.5 text-text-primary hover:bg-state-base-hover'
> >

View File

@ -541,7 +541,7 @@ const Flowchart = (props: FlowchartProps) => {
{svgString && ( {svgString && (
<div className={themeClasses.mermaidDiv} style={{ objectFit: 'cover' }} onClick={handlePreviewClick}> <div className={themeClasses.mermaidDiv} style={{ objectFit: 'cover' }} onClick={handlePreviewClick}>
<div className="absolute bottom-2 left-2 z-[100]"> <div className="absolute bottom-2 left-2 z-[100]">
<button <button type="button"
onClick={(e) => { onClick={(e) => {
e.stopPropagation() e.stopPropagation()
toggleTheme() toggleTheme()

View File

@ -30,7 +30,7 @@ export const PrevButton = ({
className, className,
children, children,
dataTestId, dataTestId,
as = <button />, as = <button type="button" />,
...buttonProps ...buttonProps
}: ButtonProps) => { }: ButtonProps) => {
const pagination = React.useContext(PaginationContext) const pagination = React.useContext(PaginationContext)
@ -65,7 +65,7 @@ export const NextButton = ({
className, className,
children, children,
dataTestId, dataTestId,
as = <button />, as = <button type="button" />,
...buttonProps ...buttonProps
}: ButtonProps) => { }: ButtonProps) => {
const pagination = React.useContext(PaginationContext) const pagination = React.useContext(PaginationContext)

View File

@ -39,7 +39,7 @@ export default function LocaleSigninSelect({
<div className="max-h-96 overflow-y-auto px-1 py-1 [mask-image:linear-gradient(to_bottom,transparent_0px,black_8px,black_calc(100%-8px),transparent_100%)]"> <div className="max-h-96 overflow-y-auto px-1 py-1 [mask-image:linear-gradient(to_bottom,transparent_0px,black_8px,black_calc(100%-8px),transparent_100%)]">
{items.map((item) => { {items.map((item) => {
return <MenuItem key={item.value}> return <MenuItem key={item.value}>
<button <button type="button"
className={'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-text-secondary data-[active]:bg-state-base-hover'} className={'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-text-secondary data-[active]:bg-state-base-hover'}
onClick={(evt) => { onClick={(evt) => {
evt.preventDefault() evt.preventDefault()

View File

@ -39,7 +39,7 @@ export default function Select({
<div className="px-1 py-1 "> <div className="px-1 py-1 ">
{items.map((item) => { {items.map((item) => {
return <MenuItem key={item.value}> return <MenuItem key={item.value}>
<button <button type="button"
className={'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-text-secondary data-[active]:bg-state-base-hover'} className={'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-text-secondary data-[active]:bg-state-base-hover'}
onClick={(evt) => { onClick={(evt) => {
evt.preventDefault() evt.preventDefault()

View File

@ -54,7 +54,7 @@ export default function ThemeSelector() {
</PortalToFollowElemTrigger> </PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1000]'> <PortalToFollowElemContent className='z-[1000]'>
<div className='flex w-[144px] flex-col items-start rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 shadow-lg'> <div className='flex w-[144px] flex-col items-start rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 shadow-lg'>
<button <button type="button"
className='flex w-full items-center gap-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover' className='flex w-full items-center gap-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover'
onClick={() => handleThemeChange('light')} onClick={() => handleThemeChange('light')}
> >
@ -66,7 +66,7 @@ export default function ThemeSelector() {
<RiCheckLine className='h-4 w-4 text-text-accent' /> <RiCheckLine className='h-4 w-4 text-text-accent' />
</div>} </div>}
</button> </button>
<button <button type="button"
className='flex w-full items-center gap-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover' className='flex w-full items-center gap-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover'
onClick={() => handleThemeChange('dark')} onClick={() => handleThemeChange('dark')}
> >
@ -78,7 +78,7 @@ export default function ThemeSelector() {
<RiCheckLine className='h-4 w-4 text-text-accent' /> <RiCheckLine className='h-4 w-4 text-text-accent' />
</div>} </div>}
</button> </button>
<button <button type="button"
className='flex w-full items-center gap-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover' className='flex w-full items-center gap-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover'
onClick={() => handleThemeChange('system')} onClick={() => handleThemeChange('system')}
> >

View File

@ -13,10 +13,10 @@ const TestComponent = () => {
return ( return (
<div> <div>
<button onClick={() => notify({ message: 'Notification message', type: 'info' })}> <button type="button" onClick={() => notify({ message: 'Notification message', type: 'info' })}>
Show Toast Show Toast
</button> </button>
<button onClick={close}>Close Toast</button> <button type="button" onClick={close}>Close Toast</button>
</div> </div>
) )
} }

View File

@ -234,13 +234,13 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ src }) => {
</div> </div>
<div className={styles.controlsContent}> <div className={styles.controlsContent}>
<div className={styles.leftControls}> <div className={styles.leftControls}>
<button className={styles.playPauseButton} onClick={togglePlayPause}> <button type="button" className={styles.playPauseButton} onClick={togglePlayPause}>
{isPlaying ? <PauseIcon /> : <PlayIcon />} {isPlaying ? <PauseIcon /> : <PlayIcon />}
</button> </button>
{!isSmallSize && (<span className={styles.time}>{formatTime(currentTime)} / {formatTime(duration)}</span>)} {!isSmallSize && (<span className={styles.time}>{formatTime(currentTime)} / {formatTime(duration)}</span>)}
</div> </div>
<div className={styles.rightControls}> <div className={styles.rightControls}>
<button className={styles.muteButton} onClick={toggleMute}> <button type="button" className={styles.muteButton} onClick={toggleMute}>
{isMuted ? <UnmuteIcon /> : <MuteIcon />} {isMuted ? <UnmuteIcon /> : <MuteIcon />}
</button> </button>
{!isSmallSize && ( {!isSmallSize && (
@ -264,7 +264,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ src }) => {
</div> </div>
</div> </div>
)} )}
<button className={styles.fullscreenButton} onClick={toggleFullscreen}> <button type="button" className={styles.fullscreenButton} onClick={toggleFullscreen}>
<FullscreenIcon /> <FullscreenIcon />
</button> </button>
</div> </div>

View File

@ -31,7 +31,7 @@ const Button = ({
}, [theme]) }, [theme])
return ( return (
<button <button type="button"
className={cn( className={cn(
'system-xl-semibold flex items-center gap-x-2 py-3 pl-5 pr-4', 'system-xl-semibold flex items-center gap-x-2 py-3 pl-5 pr-4',
BUTTON_CLASSNAME[plan], BUTTON_CLASSNAME[plan],

View File

@ -99,7 +99,7 @@ const EditPipelineInfo = ({
{t('datasetPipeline.editPipelineInfo')} {t('datasetPipeline.editPipelineInfo')}
</span> </span>
</div> </div>
<button <button type="button"
className='absolute right-5 top-5 flex size-8 items-center justify-center' className='absolute right-5 top-5 flex size-8 items-center justify-center'
onClick={onClose} onClick={onClose}
> >

View File

@ -61,7 +61,7 @@ const Website: FC<Props> = ({
{t('datasetCreation.stepOne.website.chooseProvider')} {t('datasetCreation.stepOne.website.chooseProvider')}
</div> </div>
<div className='flex space-x-2'> <div className='flex space-x-2'>
{ENABLE_WEBSITE_JINAREADER && <button {ENABLE_WEBSITE_JINAREADER && <button type="button"
className={cn('flex items-center justify-center rounded-lg px-4 py-2', className={cn('flex items-center justify-center rounded-lg px-4 py-2',
selectedProvider === DataSourceProvider.jinaReader selectedProvider === DataSourceProvider.jinaReader
? 'system-sm-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary' ? 'system-sm-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary'
@ -76,7 +76,7 @@ const Website: FC<Props> = ({
<span className={cn(s.jinaLogo, 'mr-2')} /> <span className={cn(s.jinaLogo, 'mr-2')} />
<span>Jina Reader</span> <span>Jina Reader</span>
</button>} </button>}
{ENABLE_WEBSITE_FIRECRAWL && <button {ENABLE_WEBSITE_FIRECRAWL && <button type="button"
className={cn('rounded-lg px-4 py-2', className={cn('rounded-lg px-4 py-2',
selectedProvider === DataSourceProvider.fireCrawl selectedProvider === DataSourceProvider.fireCrawl
? 'system-sm-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary' ? 'system-sm-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary'
@ -90,7 +90,7 @@ const Website: FC<Props> = ({
> >
🔥 Firecrawl 🔥 Firecrawl
</button>} </button>}
{ENABLE_WEBSITE_WATERCRAWL && <button {ENABLE_WEBSITE_WATERCRAWL && <button type="button"
className={cn('flex items-center justify-center rounded-lg px-4 py-2', className={cn('flex items-center justify-center rounded-lg px-4 py-2',
selectedProvider === DataSourceProvider.waterCrawl selectedProvider === DataSourceProvider.waterCrawl
? 'system-sm-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary' ? 'system-sm-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary'

View File

@ -200,7 +200,7 @@ const DocumentDetail: FC<DocumentDetailProps> = ({ datasetId, documentId }) => {
onUpdate={handleOperate} onUpdate={handleOperate}
className='!w-[200px]' className='!w-[200px]'
/> />
<button <button type="button"
className={style.layoutRightIcon} className={style.layoutRightIcon}
onClick={() => setShowMetadata(!showMetadata)} onClick={() => setShowMetadata(!showMetadata)}
> >

View File

@ -107,7 +107,7 @@ const IconButton: FC<{
<Tooltip <Tooltip
popupContent={metadataMap[type].text} popupContent={metadataMap[type].text}
> >
<button className={cn(s.iconWrapper, 'group', isChecked ? s.iconCheck : '')}> <button type="button" className={cn(s.iconWrapper, 'group', isChecked ? s.iconCheck : '')}>
<TypeIcon <TypeIcon
iconName={metadataMap[type].iconName || ''} iconName={metadataMap[type].iconName || ''}
className={`group-hover:bg-primary-600 ${isChecked ? '!bg-primary-600' : ''}`} className={`group-hover:bg-primary-600 ${isChecked ? '!bg-primary-600' : ''}`}

View File

@ -177,7 +177,7 @@ const Operations = ({
popupClassName='text-text-secondary system-xs-medium' popupClassName='text-text-secondary system-xs-medium'
needsDelay={false} needsDelay={false}
> >
<button <button type="button"
className={cn('mr-2 cursor-pointer rounded-lg', className={cn('mr-2 cursor-pointer rounded-lg',
!isListScene !isListScene
? 'border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg p-2 shadow-xs shadow-shadow-shadow-3 backdrop-blur-[5px] hover:border-components-button-secondary-border-hover hover:bg-components-button-secondary-bg-hover' ? 'border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg p-2 shadow-xs shadow-shadow-shadow-3 backdrop-blur-[5px] hover:border-components-button-secondary-border-hover hover:bg-components-button-secondary-bg-hover'

View File

@ -168,7 +168,7 @@ const Doc = ({ appDetail }: IDocProps) => {
<span className="text-xs font-medium uppercase tracking-wide text-text-tertiary"> <span className="text-xs font-medium uppercase tracking-wide text-text-tertiary">
{t('appApi.develop.toc')} {t('appApi.develop.toc')}
</span> </span>
<button <button type="button"
onClick={() => setIsTocExpanded(false)} onClick={() => setIsTocExpanded(false)}
className="group flex h-6 w-6 items-center justify-center rounded-md transition-colors hover:bg-state-base-hover" className="group flex h-6 w-6 items-center justify-center rounded-md transition-colors hover:bg-state-base-hover"
aria-label="Close" aria-label="Close"
@ -224,7 +224,7 @@ const Doc = ({ appDetail }: IDocProps) => {
</nav> </nav>
) )
: ( : (
<button <button type="button"
onClick={() => setIsTocExpanded(true)} onClick={() => setIsTocExpanded(true)}
className="group flex h-11 w-11 items-center justify-center rounded-full border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg transition-all duration-150 hover:bg-background-default-hover hover:shadow-xl" className="group flex h-11 w-11 items-center justify-center rounded-full border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg transition-all duration-150 hover:bg-background-default-hover hover:shadow-xl"
aria-label="Open table of contents" aria-label="Open table of contents"

View File

@ -99,6 +99,7 @@ const SchemaNode: FC<SchemaNodeProps> = ({
indentLeft[depth - 1], indentLeft[depth - 1],
)}> )}>
<button <button
type="button"
onClick={handleExpand} onClick={handleExpand}
className='py-0.5 text-text-tertiary hover:text-text-accent' className='py-0.5 text-text-tertiary hover:text-text-accent'
> >

View File

@ -109,7 +109,7 @@ const TracingPanel: FC<TracingPanelProps> = ({
onMouseLeave={handleParallelMouseLeave} onMouseLeave={handleParallelMouseLeave}
> >
<div className="mb-1 flex items-center"> <div className="mb-1 flex items-center">
<button <button type="button"
onClick={() => toggleCollapse(node.id)} onClick={() => toggleCollapse(node.id)}
className={cn( className={cn(
'mr-2 transition-colors', 'mr-2 transition-colors',

View File

@ -93,7 +93,7 @@ export default function CheckCode() {
<form action=""> <form action="">
<label htmlFor="code" className='system-md-semibold mb-1 text-text-secondary'>{t('login.checkCode.verificationCode')}</label> <label htmlFor="code" className='system-md-semibold mb-1 text-text-secondary'>{t('login.checkCode.verificationCode')}</label>
<Input value={code} onChange={e => setVerifyCode(e.target.value)} max-length={6} className='mt-1' placeholder={t('login.checkCode.verificationCodePlaceholder') as string} /> <Input value={code} onChange={e => setVerifyCode(e.target.value)} maxLength={6} className='mt-1' placeholder={t('login.checkCode.verificationCodePlaceholder') as string} />
<Button loading={loading} disabled={loading} className='my-3 w-full' variant='primary' onClick={verify}>{t('login.checkCode.verify')}</Button> <Button loading={loading} disabled={loading} className='my-3 w-full' variant='primary' onClick={verify}>{t('login.checkCode.verify')}</Button>
<Countdown onResend={resendCode} /> <Countdown onResend={resendCode} />
</form> </form>

View File

@ -1,5 +1,5 @@
'use client' 'use client'
import { noop } from 'lodash' import { noop } from 'lodash-es'
import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'

View File

@ -1,7 +1,7 @@
const translation = { const translation = {
creation: { creation: {
createFromScratch: { createFromScratch: {
title: '空白の知識パイプライン', title: '空白のナレッジパイプライン',
description: 'データ処理と構造を完全に制御できるカスタムパイプラインをゼロから作成します。', description: 'データ処理と構造を完全に制御できるカスタムパイプラインをゼロから作成します。',
}, },
backToKnowledge: 'ナレッジベースに戻る', backToKnowledge: 'ナレッジベースに戻る',
@ -77,11 +77,11 @@ const translation = {
inputFieldPanel: { inputFieldPanel: {
uniqueInputs: { uniqueInputs: {
title: '各入口のユニークな入力', title: '各入口のユニークな入力',
tooltip: 'ユニークな入力は、選択したデータソースおよびその下流ノードにのみアクセス可能です。他のデータソースを選択する際、ユーザーはこれを記入する必要はありません。最初のステップ(データソース)には、データソース変数で参照される入力フィールドのみが表示されます。他のフィールドは、第二のステップ(ドキュメントの処理)で表示されます。', tooltip: 'ユニークな入力は選択したデータソースとその下流ノードのみがアクセス可能です。他のデータソースを選択する際、ユーザーはこれを記入する必要がありません。データソース変数で参照される入力フィールドのみが最初のステップ(データソース)に表示され、他のフィールドは第二のステップ(ドキュメント処理)で表示されます。',
}, },
globalInputs: { globalInputs: {
title: 'すべての入口に対するグローバル入力', title: 'すべての入口に対するグローバル入力',
tooltip: 'グローバル入力はすべてのノードで共有されます。ユーザーは任意のデータソースを選択するときにそれらを入力する必要があります。たとえば、区切り文字や最大チャンク長のようなフィールドは、複数のデータソースに一様に適用できます。データソース変数によって参照される入力フィールドのみが最初のステップ(データソース)に表示されます。他のフィールドは2番目のステップ文書処理)に表示されます。', tooltip: 'グローバル入力はすべてのノードで共有されます。ユーザーは任意のデータソースを選択する際にこれらを入力する必要があります。区切り文字や最大チャンク長などのフィールドは複数のデータソースに一様に適用できます。データソース変数で参照される入力フィールドのみが最初のステップ(データソース)に表示され、他のフィールドは第二のステップ(ドキュメント処理)に表示されます。',
}, },
preview: { preview: {
stepOneTitle: 'データソース', stepOneTitle: 'データソース',

View File

@ -87,11 +87,11 @@ const translation = {
description: '用户输入字段用于定义和收集知识流水线执行过程中所需的变量,用户可以自定义字段类型,并灵活配置输入,以满足不同数据源或文档处理的需求。', description: '用户输入字段用于定义和收集知识流水线执行过程中所需的变量,用户可以自定义字段类型,并灵活配置输入,以满足不同数据源或文档处理的需求。',
uniqueInputs: { uniqueInputs: {
title: '非共享输入', title: '非共享输入',
tooltip: '非共享输入只能被选定的数据源及其下游节点访问。用户在选择其他数据源时不需要填写它。只有数据源变量引用的输入字段才会出现在第一步(数据源)中。所有其他字段将在第二步(Process Documents)中显示。', tooltip: '非共享输入只能被选定的数据源及其下游节点访问。用户在选择其他数据源时不需要填写它。只有数据源变量引用的输入字段才会出现在第一步(数据源)中。所有其他字段将在第二步(处理文档)中显示。',
}, },
globalInputs: { globalInputs: {
title: '全局共享输入', title: '全局共享输入',
tooltip: '全局共享输入在所有节点之间共享。用户在选择任何数据源时都需要填写它们。例如,像分隔符delimiter和最大块长度Maximum Chunk Length这样的字段可以跨多个数据源统一应用。只有数据源变量引用的输入字段才会出现在第一步(数据源)中。所有其他字段都显示在第二步(Process Documents)中。', tooltip: '全局共享输入在所有节点之间共享。用户在选择任何数据源时都需要填写它们。例如,像分隔符和最大块长度这样的字段可以跨多个数据源统一应用。只有数据源变量引用的输入字段才会出现在第一步(数据源)中。所有其他字段都显示在第二步(处理文档)中。',
}, },
addInputField: '添加输入字段', addInputField: '添加输入字段',
editInputField: '编辑输入字段', editInputField: '编辑输入字段',

View File

@ -1,8 +1,8 @@
const translation = { const translation = {
creation: { creation: {
createFromScratch: { createFromScratch: {
title: '空白知識管道', title: '空白知識流水線',
description: '從頭開始建立自訂管道,並完全控制資料處理和結構。', description: '從頭開始建立自訂流水線,並完全控制資料處理和結構。',
}, },
caution: '小心', caution: '小心',
backToKnowledge: '返回知識', backToKnowledge: '返回知識',
@ -18,12 +18,12 @@ const translation = {
convert: '轉換', convert: '轉換',
saveAndProcess: '儲存和處理', saveAndProcess: '儲存和處理',
choose: '選擇', choose: '選擇',
useTemplate: '使用此知識管道', useTemplate: '使用此知識流水線',
dataSource: '資料來源', dataSource: '資料來源',
editInfo: '編輯資訊', editInfo: '編輯資訊',
process: '處理', process: '處理',
backToDataSource: '返回資料來源', backToDataSource: '返回資料來源',
exportPipeline: '匯出知識流水線', exportPipeline: '匯出流水線',
details: '詳情', details: '詳情',
preview: '預覽', preview: '預覽',
}, },
@ -33,15 +33,15 @@ const translation = {
}, },
publishPipeline: { publishPipeline: {
success: { success: {
message: '知識管道已發布', message: '知識流水線已發布',
}, },
error: { error: {
message: '無法發佈知識管道', message: '無法發佈知識流水線',
}, },
}, },
publishTemplate: { publishTemplate: {
success: { success: {
message: '管道範本已發佈', message: '流水線範本已發佈',
tip: '您可以在建立頁面上使用此範本。', tip: '您可以在建立頁面上使用此範本。',
learnMore: '瞭解詳情', learnMore: '瞭解詳情',
}, },
@ -134,17 +134,17 @@ const translation = {
title: '證實', title: '證實',
content: '此動作是永久性的。您將無法恢復到以前的方法。請確認轉換。', content: '此動作是永久性的。您將無法恢復到以前的方法。請確認轉換。',
}, },
title: '轉換為知識管道', title: '轉換為知識流水線',
warning: '此動作無法復原。', warning: '此動作無法復原。',
descriptionChunk2: '— 一種更開放和靈活的方法,可以訪問我們市場中的插件。這會將新的處理方法套用至所有未來的文件。', descriptionChunk2: '— 一種更開放和靈活的方法,可以訪問我們市場中的插件。這會將新的處理方法套用至所有未來的文件。',
successMessage: '已成功將資料集轉換成線', successMessage: '已成功將資料集轉換成流水線',
errorMessage: '無法將資料集轉換成線', errorMessage: '無法將資料集轉換成流水線',
descriptionChunk1: '您現在可以轉換現有的知識庫,以使用知識管道進行文件處理', descriptionChunk1: '您現在可以轉換現有的知識庫,以使用知識流水線進行文件處理',
}, },
knowledgeDescription: '知識說明', knowledgeDescription: '知識說明',
knowledgeNameAndIconPlaceholder: '請輸入知識庫的名稱', knowledgeNameAndIconPlaceholder: '請輸入知識庫的名稱',
knowledgeDescriptionPlaceholder: '描述此知識庫中的內容。詳細的描述使人工智慧能夠更準確地存取資料集的內容。如果為空Dify 將使用預設命中策略。(選用)', knowledgeDescriptionPlaceholder: '描述此知識庫中的內容。詳細的描述使人工智慧能夠更準確地存取資料集的內容。如果為空Dify 將使用預設命中策略。(選用)',
pipelineNameAndIcon: '線名稱 & 圖示', pipelineNameAndIcon: '流水線名稱 & 圖示',
knowledgeNameAndIcon: '知識名稱和圖示', knowledgeNameAndIcon: '知識名稱和圖示',
inputField: '輸入欄位', inputField: '輸入欄位',
knowledgePermissions: '權限', knowledgePermissions: '權限',

View File

@ -51,7 +51,7 @@ const Service: FC = () => {
</div> </div>
<div> <div>
<button onClick={handleCreateApp}>Click me to Create App</button> <button type="button" onClick={handleCreateApp}>Click me to Create App</button>
</div> </div>
<div> <div>