Преглед изворни кода

CI: add TS indentation check via esLint (#24810)

tags/1.8.1
Yongtao Huang пре 2 месеци
родитељ
комит
208ce4e774
No account linked to committer's email address
100 измењених фајлова са 368 додато и 403 уклоњено
  1. 3
    1
      .github/workflows/style.yml
  2. 1
    1
      web/__tests__/check-i18n.test.ts
  3. 2
    2
      web/__tests__/description-validation.test.tsx
  4. 1
    1
      web/__tests__/document-list-sorting.test.tsx
  5. 1
    1
      web/__tests__/plugin-tool-workflow-error.test.tsx
  6. 1
    1
      web/__tests__/real-browser-flicker.test.tsx
  7. 2
    2
      web/__tests__/workflow-parallel-limit.test.tsx
  8. 2
    2
      web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/__tests__/svg-attribute-error-reproduction.spec.tsx
  9. 1
    1
      web/app/account/(commonLayout)/account-page/AvatarWithEdit.tsx
  10. 2
    2
      web/app/components/app-sidebar/basic.tsx
  11. 2
    2
      web/app/components/app-sidebar/index.tsx
  12. 1
    1
      web/app/components/app-sidebar/sidebar-animation-issues.spec.tsx
  13. 1
    1
      web/app/components/app/annotation/index.tsx
  14. 5
    5
      web/app/components/app/configuration/config-var/config-modal/type-select.tsx
  15. 0
    1
      web/app/components/app/configuration/dataset-config/params-config/config-content.tsx
  16. 4
    4
      web/app/components/app/configuration/debug/chat-user-input.tsx
  17. 62
    62
      web/app/components/app/log/list.tsx
  18. 1
    1
      web/app/components/app/overview/app-card.tsx
  19. 4
    4
      web/app/components/app/overview/embedded/index.tsx
  20. 1
    1
      web/app/components/app/overview/settings/index.tsx
  21. 1
    1
      web/app/components/apps/list.tsx
  22. 6
    6
      web/app/components/base/chat/embedded-chatbot/inputs-form/content.tsx
  23. 6
    6
      web/app/components/base/checkbox/index.tsx
  24. 1
    1
      web/app/components/base/date-and-time-picker/utils/dayjs.ts
  25. 1
    1
      web/app/components/base/form/form-scenarios/demo/index.tsx
  26. 5
    5
      web/app/components/base/form/types.ts
  27. 3
    3
      web/app/components/base/mermaid/index.tsx
  28. 3
    3
      web/app/components/base/prompt-editor/plugins/current-block/component.tsx
  29. 3
    3
      web/app/components/base/prompt-editor/plugins/error-message-block/component.tsx
  30. 3
    3
      web/app/components/base/prompt-editor/plugins/last-run-block/component.tsx
  31. 24
    24
      web/app/components/base/select/index.tsx
  32. 1
    1
      web/app/components/base/tag-management/selector.tsx
  33. 1
    1
      web/app/components/base/toast/index.tsx
  34. 0
    1
      web/app/components/datasets/common/retrieval-param-config/index.tsx
  35. 0
    1
      web/app/components/datasets/create/website/base/options-wrap.tsx
  36. 1
    2
      web/app/components/datasets/create/website/index.tsx
  37. 0
    1
      web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx
  38. 1
    1
      web/app/components/datasets/documents/detail/batch-modal/csv-uploader.tsx
  39. 3
    3
      web/app/components/datasets/external-knowledge-base/create/InfoPanel.tsx
  40. 2
    2
      web/app/components/datasets/hit-testing/components/chunk-detail-modal.tsx
  41. 0
    1
      web/app/components/datasets/metadata/hooks/use-edit-dataset-metadata.ts
  42. 2
    2
      web/app/components/goto-anything/actions/commands/registry.ts
  43. 2
    2
      web/app/components/goto-anything/actions/index.ts
  44. 1
    1
      web/app/components/goto-anything/index.tsx
  45. 0
    1
      web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx
  46. 3
    3
      web/app/components/header/account-setting/model-provider-page/model-auth/add-credential-in-load-balancing.tsx
  47. 5
    5
      web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx
  48. 2
    2
      web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx
  49. 0
    3
      web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx
  50. 0
    6
      web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx
  51. 0
    1
      web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx
  52. 0
    1
      web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx
  53. 0
    1
      web/app/components/plugins/marketplace/context.tsx
  54. 14
    14
      web/app/components/plugins/plugin-auth/authorized/index.tsx
  55. 3
    3
      web/app/components/plugins/plugin-auth/hooks/use-plugin-auth-action.ts
  56. 1
    1
      web/app/components/plugins/plugin-detail-panel/app-selector/index.tsx
  57. 1
    1
      web/app/components/plugins/plugin-detail-panel/detail-header.tsx
  58. 2
    2
      web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx
  59. 1
    1
      web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx
  60. 6
    6
      web/app/components/plugins/plugin-detail-panel/tool-selector/reasoning-config-form.tsx
  61. 0
    1
      web/app/components/plugins/plugin-item/action.tsx
  62. 12
    12
      web/app/components/plugins/reference-setting-modal/auto-update-setting/index.tsx
  63. 6
    6
      web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.ts
  64. 1
    1
      web/app/components/plugins/update-plugin/downgrade-warning.tsx
  65. 38
    38
      web/app/components/plugins/update-plugin/from-market-place.tsx
  66. 0
    1
      web/app/components/tools/mcp/detail/content.tsx
  67. 3
    3
      web/app/components/tools/mcp/mcp-service-card.tsx
  68. 9
    9
      web/app/components/tools/utils/to-form-schema.ts
  69. 0
    1
      web/app/components/workflow-app/hooks/use-workflow-init.ts
  70. 0
    1
      web/app/components/workflow/block-selector/all-tools.tsx
  71. 0
    1
      web/app/components/workflow/block-selector/market-place-plugin/action.tsx
  72. 0
    1
      web/app/components/workflow/block-selector/market-place-plugin/list.tsx
  73. 0
    1
      web/app/components/workflow/block-selector/tool/tool.tsx
  74. 0
    1
      web/app/components/workflow/datasets-detail-store/provider.tsx
  75. 20
    20
      web/app/components/workflow/header/header-in-restoring.tsx
  76. 10
    10
      web/app/components/workflow/header/version-history-button.tsx
  77. 0
    1
      web/app/components/workflow/hooks-store/provider.tsx
  78. 28
    28
      web/app/components/workflow/hooks/use-inspect-vars-crud-common.ts
  79. 3
    3
      web/app/components/workflow/hooks/use-nodes-available-var-list.ts
  80. 1
    1
      web/app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-started.ts
  81. 1
    1
      web/app/components/workflow/nodes/_base/components/agent-strategy-selector.tsx
  82. 1
    1
      web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
  83. 4
    4
      web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx
  84. 0
    1
      web/app/components/workflow/nodes/_base/components/input-support-select-var.tsx
  85. 1
    1
      web/app/components/workflow/nodes/_base/components/mcp-tool-not-support-tooltip.tsx
  86. 2
    2
      web/app/components/workflow/nodes/_base/components/variable/utils.ts
  87. 5
    5
      web/app/components/workflow/nodes/_base/components/variable/var-list.tsx
  88. 1
    1
      web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx
  89. 2
    2
      web/app/components/workflow/nodes/_base/components/workflow-panel/index.tsx
  90. 5
    5
      web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/index.tsx
  91. 4
    4
      web/app/components/workflow/nodes/_base/hooks/use-output-var-list.ts
  92. 4
    4
      web/app/components/workflow/nodes/agent/panel.tsx
  93. 1
    1
      web/app/components/workflow/nodes/agent/use-single-run-form-params.ts
  94. 1
    1
      web/app/components/workflow/nodes/assigner/components/var-list/index.tsx
  95. 0
    2
      web/app/components/workflow/nodes/http/hooks/use-key-value-list.ts
  96. 0
    1
      web/app/components/workflow/nodes/http/use-config.ts
  97. 0
    1
      web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-trigger.tsx
  98. 0
    3
      web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts
  99. 0
    1
      web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx
  100. 0
    0
      web/app/components/workflow/nodes/parameter-extractor/use-config.ts

+ 3
- 1
.github/workflows/style.yml Прегледај датотеку

- name: Web style check - name: Web style check
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'
working-directory: ./web working-directory: ./web
run: pnpm run lint
run: |
pnpm run lint
pnpm run eslint


docker-compose-template: docker-compose-template:
name: Docker Compose Template name: Docker Compose Template

+ 1
- 1
web/__tests__/check-i18n.test.ts Прегледај датотеку

&& !trimmed.startsWith('//')) && !trimmed.startsWith('//'))
break break
} }
else {
else {
break break
} }



+ 2
- 2
web/__tests__/description-validation.test.tsx Прегледај датотеку

try { try {
validateDescriptionLength(invalidDescription) validateDescriptionLength(invalidDescription)
} }
catch (error) {
catch (error) {
expect((error as Error).message).toBe(expectedErrorMessage) expect((error as Error).message).toBe(expectedErrorMessage)
} }
}) })
expect(() => validateDescriptionLength(testDescription)).not.toThrow() expect(() => validateDescriptionLength(testDescription)).not.toThrow()
expect(validateDescriptionLength(testDescription)).toBe(testDescription) expect(validateDescriptionLength(testDescription)).toBe(testDescription)
} }
else {
else {
expect(() => validateDescriptionLength(testDescription)).toThrow( expect(() => validateDescriptionLength(testDescription)).toThrow(
'Description cannot exceed 400 characters.', 'Description cannot exceed 400 characters.',
) )

+ 1
- 1
web/__tests__/document-list-sorting.test.tsx Прегледај датотеку

const result = aValue.localeCompare(bValue) const result = aValue.localeCompare(bValue)
return order === 'asc' ? result : -result return order === 'asc' ? result : -result
} }
else {
else {
const result = aValue - bValue const result = aValue - bValue
return order === 'asc' ? result : -result return order === 'asc' ? result : -result
} }

+ 1
- 1
web/__tests__/plugin-tool-workflow-error.test.tsx Прегледај датотеку

const _pluginId = (tool.uniqueIdentifier as any).split(':')[0] const _pluginId = (tool.uniqueIdentifier as any).split(':')[0]
}).toThrow() }).toThrow()
} }
else {
else {
// Valid tools should work fine // Valid tools should work fine
expect(() => { expect(() => {
const _pluginId = tool.uniqueIdentifier.split(':')[0] const _pluginId = tool.uniqueIdentifier.split(':')[0]

+ 1
- 1
web/__tests__/real-browser-flicker.test.tsx Прегледај датотеку



if (hasStyleChange) if (hasStyleChange)
console.log('⚠️ Style changes detected - this causes visible flicker') console.log('⚠️ Style changes detected - this causes visible flicker')
else
else
console.log('✅ No style changes detected') console.log('✅ No style changes detected')


expect(timingData.length).toBeGreaterThan(1) expect(timingData.length).toBeGreaterThan(1)

+ 2
- 2
web/__tests__/workflow-parallel-limit.test.tsx Прегледај датотеку

function setupEnvironment(value?: string) { function setupEnvironment(value?: string) {
if (value) if (value)
process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT = value process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT = value
else
else
delete process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT delete process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT


// Clear module cache to force re-evaluation // Clear module cache to force re-evaluation
function restoreEnvironment() { function restoreEnvironment() {
if (originalEnv) if (originalEnv)
process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT = originalEnv process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT = originalEnv
else
else
delete process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT delete process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT


jest.resetModules() jest.resetModules()

+ 2
- 2
web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/__tests__/svg-attribute-error-reproduction.spec.tsx Прегледај датотеку

console.log(` ${index + 1}. ${error.substring(0, 100)}...`) console.log(` ${index + 1}. ${error.substring(0, 100)}...`)
}) })
} }
else {
else {
console.log('No inkscape errors found in this render') console.log('No inkscape errors found in this render')
} }




if (problematicKeys.length > 0) if (problematicKeys.length > 0)
console.log(`🚨 PROBLEM: Still found problematic attributes: ${problematicKeys.join(', ')}`) console.log(`🚨 PROBLEM: Still found problematic attributes: ${problematicKeys.join(', ')}`)
else
else
console.log('✅ No problematic attributes found after normalization') console.log('✅ No problematic attributes found after normalization')
}) })
}) })

+ 1
- 1
web/app/account/(commonLayout)/account-page/AvatarWithEdit.tsx Прегледај датотеку

onClick={() => { onClick={() => {
if (hoverArea === 'right' && !onAvatarError) if (hoverArea === 'right' && !onAvatarError)
setIsShowDeleteConfirm(true) setIsShowDeleteConfirm(true)
else
else
setIsShowAvatarPicker(true) setIsShowAvatarPicker(true)
}} }}
onMouseMove={(e) => { onMouseMove={(e) => {

+ 2
- 2
web/app/components/app-sidebar/basic.tsx Прегледај датотеку

</div>, </div>,
dataset: <AppIcon innerIcon={DatasetSvg} className='!border-[0.5px] !border-indigo-100 !bg-indigo-25' />, dataset: <AppIcon innerIcon={DatasetSvg} className='!border-[0.5px] !border-indigo-100 !bg-indigo-25' />,
webapp: <div className='rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-blue-brand-blue-brand-500 p-1 shadow-md'> webapp: <div className='rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-blue-brand-blue-brand-500 p-1 shadow-md'>
<WindowCursor className='h-4 w-4 text-text-primary-on-surface' />
</div>,
<WindowCursor className='h-4 w-4 text-text-primary-on-surface' />
</div>,
notion: <AppIcon innerIcon={NotionSvg} className='!border-[0.5px] !border-indigo-100 !bg-white' />, notion: <AppIcon innerIcon={NotionSvg} className='!border-[0.5px] !border-indigo-100 !bg-white' />,
} }



+ 2
- 2
web/app/components/app-sidebar/index.tsx Прегледај датотеку

}, [appSidebarExpand, setAppSiderbarExpand]) }, [appSidebarExpand, setAppSiderbarExpand])


if (inWorkflowCanvas && hideHeader) { if (inWorkflowCanvas && hideHeader) {
return (
return (
<div className='flex w-0 shrink-0'> <div className='flex w-0 shrink-0'>
<AppSidebarDropdown navigation={navigation} /> <AppSidebarDropdown navigation={navigation} />
</div> </div>
) )
}
}


return ( return (
<div <div

+ 1
- 1
web/app/components/app-sidebar/sidebar-animation-issues.spec.tsx Прегледај датотеку

})) }))
}) })


describe('Issue #1: Toggle Button Position Movement - FIXED', () => {
describe('Issue #1: Toggle Button Position Movement - FIXED', () => {
it('should verify consistent padding prevents button position shift', () => { it('should verify consistent padding prevents button position shift', () => {
let expanded = false let expanded = false
const handleToggle = () => { const handleToggle = () => {

+ 1
- 1
web/app/components/app/annotation/index.tsx Прегледај датотеку

setList(data as AnnotationItem[]) setList(data as AnnotationItem[])
setTotal(total) setTotal(total)
} }
finally {
finally {
setIsLoading(false) setIsLoading(false)
} }
} }

+ 5
- 5
web/app/components/app/configuration/config-var/config-modal/type-select.tsx Прегледај датотеку

> >
<div className='flex items-center'> <div className='flex items-center'>
<InputVarTypeIcon type={selectedItem?.value as InputVarType} className='size-4 shrink-0 text-text-secondary' /> <InputVarTypeIcon type={selectedItem?.value as InputVarType} className='size-4 shrink-0 text-text-secondary' />
<span
className={`
<span
className={`
ml-1.5 ${!selectedItem?.name && 'text-components-input-text-placeholder'} ml-1.5 ${!selectedItem?.name && 'text-components-input-text-placeholder'}
`} `}
>
{selectedItem?.name}
</span>
>
{selectedItem?.name}
</span>
</div> </div>
<div className='flex items-center space-x-1'> <div className='flex items-center space-x-1'>
<Badge uppercase={false}>{inputVarTypeToVarType(selectedItem?.value as InputVarType)}</Badge> <Badge uppercase={false}>{inputVarTypeToVarType(selectedItem?.value as InputVarType)}</Badge>

+ 0
- 1
web/app/components/app/configuration/dataset-config/params-config/config-content.tsx Прегледај датотеку

...datasetConfigs, ...datasetConfigs,
reranking_enable: enable, reranking_enable: enable,
}) })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentRerankModel, datasetConfigs, onChange]) }, [currentRerankModel, datasetConfigs, onChange])


return ( return (

+ 4
- 4
web/app/components/app/configuration/debug/chat-user-input.tsx Прегледај датотеку

> >
<div> <div>
{type !== 'checkbox' && ( {type !== 'checkbox' && (
<div className='system-sm-semibold mb-1 flex h-6 items-center gap-1 text-text-secondary'>
<div className='truncate'>{name || key}</div>
{!required && <span className='system-xs-regular text-text-tertiary'>{t('workflow.panel.optional')}</span>}
</div>
<div className='system-sm-semibold mb-1 flex h-6 items-center gap-1 text-text-secondary'>
<div className='truncate'>{name || key}</div>
{!required && <span className='system-xs-regular text-text-tertiary'>{t('workflow.panel.optional')}</span>}
</div>
)} )}
<div className='grow'> <div className='grow'>
{type === 'string' && ( {type === 'string' && (

+ 62
- 62
web/app/components/app/log/list.tsx Прегледај датотеку

const newChatList: IChatItem[] = [] const newChatList: IChatItem[] = []
try { try {
messages.forEach((item: ChatMessage) => { messages.forEach((item: ChatMessage) => {
const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || []
newChatList.push({
id: `question-${item.id}`,
content: item.inputs.query || item.inputs.default_input || item.query, // text generation: item.inputs.query; chat: item.query
isAnswer: false,
message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))),
parentMessageId: item.parent_message_id || undefined,
})
const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || []
newChatList.push({
id: `question-${item.id}`,
content: item.inputs.query || item.inputs.default_input || item.query, // text generation: item.inputs.query; chat: item.query
isAnswer: false,
message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))),
parentMessageId: item.parent_message_id || undefined,
})


const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || []
newChatList.push({
id: item.id,
content: item.answer,
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
feedback: item.feedbacks.find(item => item.from_source === 'user'), // user feedback
adminFeedback: item.feedbacks.find(item => item.from_source === 'admin'), // admin feedback
feedbackDisabled: false,
isAnswer: true,
message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))),
log: [
...item.message,
...(item.message[item.message.length - 1]?.role !== 'assistant'
? [
{
role: 'assistant',
text: item.answer,
files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
},
]
: []),
] as IChatItem['log'],
workflow_run_id: item.workflow_run_id,
conversationId,
input: {
inputs: item.inputs,
query: item.query,
},
more: {
time: dayjs.unix(item.created_at).tz(timezone).format(format),
tokens: item.answer_tokens + item.message_tokens,
latency: item.provider_response_latency.toFixed(2),
},
citation: item.metadata?.retriever_resources,
annotation: (() => {
if (item.annotation_hit_history) {
return {
id: item.annotation_hit_history.annotation_id,
authorName: item.annotation_hit_history.annotation_create_account?.name || 'N/A',
created_at: item.annotation_hit_history.created_at,
const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || []
newChatList.push({
id: item.id,
content: item.answer,
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
feedback: item.feedbacks.find(item => item.from_source === 'user'), // user feedback
adminFeedback: item.feedbacks.find(item => item.from_source === 'admin'), // admin feedback
feedbackDisabled: false,
isAnswer: true,
message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))),
log: [
...item.message,
...(item.message[item.message.length - 1]?.role !== 'assistant'
? [
{
role: 'assistant',
text: item.answer,
files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
},
]
: []),
] as IChatItem['log'],
workflow_run_id: item.workflow_run_id,
conversationId,
input: {
inputs: item.inputs,
query: item.query,
},
more: {
time: dayjs.unix(item.created_at).tz(timezone).format(format),
tokens: item.answer_tokens + item.message_tokens,
latency: item.provider_response_latency.toFixed(2),
},
citation: item.metadata?.retriever_resources,
annotation: (() => {
if (item.annotation_hit_history) {
return {
id: item.annotation_hit_history.annotation_id,
authorName: item.annotation_hit_history.annotation_create_account?.name || 'N/A',
created_at: item.annotation_hit_history.created_at,
}
} }
}


if (item.annotation) {
return {
id: item.annotation.id,
authorName: item.annotation.account.name,
logAnnotation: item.annotation,
created_at: 0,
if (item.annotation) {
return {
id: item.annotation.id,
authorName: item.annotation.account.name,
logAnnotation: item.annotation,
created_at: 0,
}
} }
}


return undefined
})(),
parentMessageId: `question-${item.id}`,
return undefined
})(),
parentMessageId: `question-${item.id}`,
})
}) })
})


return newChatList return newChatList
} }


setThreadChatItems(getThreadMessages(tree, newAllChatItems.at(-1)?.id)) setThreadChatItems(getThreadMessages(tree, newAllChatItems.at(-1)?.id))
} }
catch (error) {
catch (error) {
console.error(error) console.error(error)
setHasMore(false) setHasMore(false)
} }
if (outerDiv && outerDiv.scrollHeight > outerDiv.clientHeight) { if (outerDiv && outerDiv.scrollHeight > outerDiv.clientHeight) {
scrollContainer = outerDiv scrollContainer = outerDiv
} }
else if (scrollableDiv && scrollableDiv.scrollHeight > scrollableDiv.clientHeight) {
else if (scrollableDiv && scrollableDiv.scrollHeight > scrollableDiv.clientHeight) {
scrollContainer = scrollableDiv scrollContainer = scrollableDiv
} }
else if (chatContainer && chatContainer.scrollHeight > chatContainer.clientHeight) { else if (chatContainer && chatContainer.scrollHeight > chatContainer.clientHeight) {

+ 1
- 1
web/app/components/app/overview/app-card.tsx Прегледај датотеку

setAppDetail(res) setAppDetail(res)
setShowAccessControl(false) setShowAccessControl(false)
} }
catch (error) {
catch (error) {
console.error('Failed to fetch app detail:', error) console.error('Failed to fetch app detail:', error)
} }
}, [appDetail, setAppDetail]) }, [appDetail, setAppDetail])

+ 4
- 4
web/app/components/app/overview/embedded/index.tsx Прегледај датотеку

`<script> `<script>
window.difyChatbotConfig = { window.difyChatbotConfig = {
token: '${token}'${isTestEnv token: '${token}'${isTestEnv
? `,
? `,
isDev: true` isDev: true`
: ''}${IS_CE_EDITION
? `,
: ''}${IS_CE_EDITION
? `,
baseUrl: '${url}${basePath}'` baseUrl: '${url}${basePath}'`
: ''},
: ''},
inputs: { inputs: {
// You can define the inputs from the Start node here // You can define the inputs from the Start node here
// key is the variable name // key is the variable name

+ 1
- 1
web/app/components/app/overview/settings/index.tsx Прегледај датотеку

<Link href={docLink('/guides/application-publishing/launch-your-webapp-quickly/README', { <Link href={docLink('/guides/application-publishing/launch-your-webapp-quickly/README', {
'zh-Hans': '/guides/application-publishing/launch-your-webapp-quickly/readme', 'zh-Hans': '/guides/application-publishing/launch-your-webapp-quickly/readme',
})} })}
target='_blank' rel='noopener noreferrer' className='text-text-accent'>{t('common.operation.learnMore')}</Link>
target='_blank' rel='noopener noreferrer' className='text-text-accent'>{t('common.operation.learnMore')}</Link>
</div> </div>
</div> </div>
{/* form body */} {/* form body */}

+ 1
- 1
web/app/components/apps/list.tsx Прегледај датотеку



const List = () => { const List = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { systemFeatures } = useGlobalPublicStore()
const { systemFeatures } = useGlobalPublicStore()
const router = useRouter() const router = useRouter()
const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator } = useAppContext() const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator } = useAppContext()
const showTagManagementModal = useTagStore(s => s.showTagManagementModal) const showTagManagementModal = useTagStore(s => s.showTagManagementModal)

+ 6
- 6
web/app/components/base/chat/embedded-chatbot/inputs-form/content.tsx Прегледај датотеку

{visibleInputsForms.map(form => ( {visibleInputsForms.map(form => (
<div key={form.variable} className='space-y-1'> <div key={form.variable} className='space-y-1'>
{form.type !== InputVarType.checkbox && ( {form.type !== InputVarType.checkbox && (
<div className='flex h-6 items-center gap-1'>
<div className='system-md-semibold text-text-secondary'>{form.label}</div>
{!form.required && (
<div className='system-xs-regular text-text-tertiary'>{t('appDebug.variableTable.optional')}</div>
)}
</div>
<div className='flex h-6 items-center gap-1'>
<div className='system-md-semibold text-text-secondary'>{form.label}</div>
{!form.required && (
<div className='system-xs-regular text-text-tertiary'>{t('appDebug.variableTable.optional')}</div>
)}
</div>
)} )}
{form.type === InputVarType.textInput && ( {form.type === InputVarType.textInput && (
<Input <Input

+ 6
- 6
web/app/components/base/checkbox/index.tsx Прегледај датотеку

} }


const Checkbox = ({ const Checkbox = ({
id,
checked,
onCheck,
className,
disabled,
indeterminate,
id,
checked,
onCheck,
className,
disabled,
indeterminate,
}: CheckboxProps) => { }: CheckboxProps) => {
const checkClassName = (checked || indeterminate) const checkClassName = (checked || indeterminate)
? 'bg-components-checkbox-bg text-components-checkbox-icon hover:bg-components-checkbox-bg-hover' ? 'bg-components-checkbox-bg text-components-checkbox-icon hover:bg-components-checkbox-bg-hover'

+ 1
- 1
web/app/components/base/date-and-time-picker/utils/dayjs.ts Прегледај датотеку

// Output format with time // Output format with time
return date.format('YYYY-MM-DDTHH:mm:ss.SSSZ') return date.format('YYYY-MM-DDTHH:mm:ss.SSSZ')
} }
else {
else {
// Date-only output format without timezone // Date-only output format without timezone
return date.format('YYYY-MM-DD') return date.format('YYYY-MM-DD')
} }

+ 1
- 1
web/app/components/base/form/form-scenarios/demo/index.tsx Прегледај датотеку

}, },
}) })


const name = useStore(form.store, state => state.values.name)
const name = useStore(form.store, state => state.values.name)


return ( return (
<form <form

+ 5
- 5
web/app/components/base/form/types.ts Прегледај датотеку

needCheckValidatedValues?: boolean needCheckValidatedValues?: boolean
} }
export type FormRefObject = { export type FormRefObject = {
getForm: () => AnyFormApi
getFormValues: (obj: GetValuesOptions) => {
values: Record<string, any>
isCheckValidated: boolean
}
getForm: () => AnyFormApi
getFormValues: (obj: GetValuesOptions) => {
values: Record<string, any>
isCheckValidated: boolean
}
} }
export type FormRef = ForwardedRef<FormRefObject> export type FormRef = ForwardedRef<FormRefObject>

+ 3
- 3
web/app/components/base/mermaid/index.tsx Прегледај датотеку

{isLoading && !svgString && ( {isLoading && !svgString && (
<div className='px-[26px] py-4'> <div className='px-[26px] py-4'>
<LoadingAnim type='text'/> <LoadingAnim type='text'/>
<div className="mt-2 text-sm text-gray-500">
{t('common.wait_for_completion', 'Waiting for diagram code to complete...')}
</div>
<div className="mt-2 text-sm text-gray-500">
{t('common.wait_for_completion', 'Waiting for diagram code to complete...')}
</div>
</div> </div>
)} )}



+ 3
- 3
web/app/components/base/prompt-editor/plugins/current-block/component.tsx Прегледај датотеку



const Icon = generatorType === GeneratorType.prompt ? MagicEdit : CodeAssistant const Icon = generatorType === GeneratorType.prompt ? MagicEdit : CodeAssistant
useEffect(() => { useEffect(() => {
if (!editor.hasNodes([CurrentBlockNode]))
throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
}, [editor])
if (!editor.hasNodes([CurrentBlockNode]))
throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
}, [editor])


return ( return (
<div <div

+ 3
- 3
web/app/components/base/prompt-editor/plugins/error-message-block/component.tsx Прегледај датотеку

const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_ERROR_MESSAGE_COMMAND) const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_ERROR_MESSAGE_COMMAND)


useEffect(() => { useEffect(() => {
if (!editor.hasNodes([ErrorMessageBlockNode]))
throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
}, [editor])
if (!editor.hasNodes([ErrorMessageBlockNode]))
throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
}, [editor])


return ( return (
<div <div

+ 3
- 3
web/app/components/base/prompt-editor/plugins/last-run-block/component.tsx Прегледај датотеку

const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_LAST_RUN_COMMAND) const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_LAST_RUN_COMMAND)


useEffect(() => { useEffect(() => {
if (!editor.hasNodes([LastRunBlockNode]))
throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
}, [editor])
if (!editor.hasNodes([LastRunBlockNode]))
throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
}, [editor])


return ( return (
<div <div

+ 24
- 24
web/app/components/base/select/index.tsx Прегледај датотеку

{renderTrigger && <ListboxButton className='w-full'>{renderTrigger(selectedItem)}</ListboxButton>} {renderTrigger && <ListboxButton className='w-full'>{renderTrigger(selectedItem)}</ListboxButton>}
{!renderTrigger && ( {!renderTrigger && (
<ListboxButton onClick={() => { <ListboxButton onClick={() => {
onOpenChange?.(open)
onOpenChange?.(open)
}} className={classNames(`flex h-full w-full items-center rounded-lg border-0 bg-components-input-bg-normal pl-3 pr-10 focus-visible:bg-state-base-hover-alt focus-visible:outline-none group-hover/simple-select:bg-state-base-hover-alt sm:text-sm sm:leading-6 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}> }} className={classNames(`flex h-full w-full items-center rounded-lg border-0 bg-components-input-bg-normal pl-3 pr-10 focus-visible:bg-state-base-hover-alt focus-visible:outline-none group-hover/simple-select:bg-state-base-hover-alt sm:text-sm sm:leading-6 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}>
<span className={classNames('system-sm-regular block truncate text-left text-components-input-text-filled', !selectedItem?.name && 'text-components-input-text-placeholder')}>{selectedItem?.name ?? localPlaceholder}</span> <span className={classNames('system-sm-regular block truncate text-left text-components-input-text-filled', !selectedItem?.name && 'text-components-input-text-placeholder')}>{selectedItem?.name ?? localPlaceholder}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2"> <span className="absolute inset-y-0 right-0 flex items-center pr-2">
{isLoading ? <RiLoader4Line className='h-3.5 w-3.5 animate-spin text-text-secondary' /> {isLoading ? <RiLoader4Line className='h-3.5 w-3.5 animate-spin text-text-secondary' />
: (selectedItem && !notClearable)
? (
<XMarkIcon
onClick={(e) => {
e.stopPropagation()
setSelectedItem(null)
onSelect({ name: '', value: '' })
}}
className="h-4 w-4 cursor-pointer text-text-quaternary"
aria-hidden="false"
/>
)
: (
open ? (
<ChevronUpIcon
className="h-4 w-4 text-text-quaternary group-hover/simple-select:text-text-secondary"
aria-hidden="true"
/>
) : (
<ChevronDownIcon
className="h-4 w-4 text-text-quaternary group-hover/simple-select:text-text-secondary"
aria-hidden="true"
: (selectedItem && !notClearable)
? (
<XMarkIcon
onClick={(e) => {
e.stopPropagation()
setSelectedItem(null)
onSelect({ name: '', value: '' })
}}
className="h-4 w-4 cursor-pointer text-text-quaternary"
aria-hidden="false"
/> />
) )
)}
: (
open ? (
<ChevronUpIcon
className="h-4 w-4 text-text-quaternary group-hover/simple-select:text-text-secondary"
aria-hidden="true"
/>
) : (
<ChevronDownIcon
className="h-4 w-4 text-text-quaternary group-hover/simple-select:text-text-secondary"
aria-hidden="true"
/>
)
)}
</span> </span>
</ListboxButton> </ListboxButton>
)} )}

+ 1
- 1
web/app/components/base/tag-management/selector.tsx Прегледај датотеку

const res = await fetchTagList(type) const res = await fetchTagList(type)
setTagList(res) setTagList(res)
} }
catch (error) {
catch (error) {
setTagList([]) setTagList([])
} }
} }

+ 1
- 1
web/app/components/base/toast/index.tsx Прегледај датотеку

|| (type === 'warning' && 'bg-toast-warning-bg') || (type === 'warning' && 'bg-toast-warning-bg')
|| (type === 'error' && 'bg-toast-error-bg') || (type === 'error' && 'bg-toast-error-bg')
|| (type === 'info' && 'bg-toast-info-bg') || (type === 'info' && 'bg-toast-info-bg')
}`}
}`}
/> />
<div className={`flex ${size === 'md' ? 'gap-1' : 'gap-0.5'}`}> <div className={`flex ${size === 'md' ? 'gap-1' : 'gap-0.5'}`}>
<div className={`flex items-center justify-center ${size === 'md' ? 'p-0.5' : 'p-1'}`}> <div className={`flex items-center justify-center ${size === 'md' ? 'p-0.5' : 'p-1'}`}>

+ 0
- 1
web/app/components/datasets/common/retrieval-param-config/index.tsx Прегледај датотеку

...value, ...value,
reranking_enable: enable, reranking_enable: enable,
}) })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentModel, onChange, value]) }, [currentModel, onChange, value])


const rerankModel = useMemo(() => { const rerankModel = useMemo(() => {

+ 0
- 1
web/app/components/datasets/create/website/base/options-wrap.tsx Прегледај датотеку

useEffect(() => { useEffect(() => {
if (controlFoldOptions) if (controlFoldOptions)
foldHide() foldHide()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [controlFoldOptions]) }, [controlFoldOptions])
return ( return (
<div className={cn(className, !fold ? 'mb-0' : 'mb-3')}> <div className={cn(className, !fold ? 'mb-0' : 'mb-3')}>

+ 1
- 2
web/app/components/datasets/create/website/index.tsx Прегледај датотеку

checkSetApiKey().then(() => { checkSetApiKey().then(() => {
setIsLoaded(true) setIsLoaded(true)
}) })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
const handleOnConfig = useCallback(() => { const handleOnConfig = useCallback(() => {
setShowAccountSettingModal({ setShowAccountSettingModal({
<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
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'

+ 0
- 1
web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx Прегледај датотеку

useEffect(() => { useEffect(() => {
if (controlFoldOptions) if (controlFoldOptions)
foldHide() foldHide()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [controlFoldOptions]) }, [controlFoldOptions])
return ( return (
<div className={cn(className, !fold ? 'mb-0' : 'mb-3')}> <div className={cn(className, !fold ? 'mb-0' : 'mb-3')}>

+ 1
- 1
web/app/components/datasets/documents/detail/batch-modal/csv-uploader.tsx Прегледај датотеку

const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => { const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => {
const currentFile = e.target.files?.[0] const currentFile = e.target.files?.[0]
if (!isValid(currentFile)) if (!isValid(currentFile))
return
return


initialUpload(currentFile) initialUpload(currentFile)
} }

+ 3
- 3
web/app/components/datasets/external-knowledge-base/create/InfoPanel.tsx Прегледај датотеку

{t('dataset.connectDatasetIntro.content.end')} {t('dataset.connectDatasetIntro.content.end')}
</span> </span>
<a className='system-sm-regular self-stretch text-text-accent' <a className='system-sm-regular self-stretch text-text-accent'
href={docLink('/guides/knowledge-base/connect-external-knowledge-base')}
target='_blank'
rel="noopener noreferrer">
href={docLink('/guides/knowledge-base/connect-external-knowledge-base')}
target='_blank'
rel="noopener noreferrer">
{t('dataset.connectDatasetIntro.learnMore')} {t('dataset.connectDatasetIntro.learnMore')}
</a> </a>
</p> </p>

+ 2
- 2
web/app/components/datasets/hit-testing/components/chunk-detail-modal.tsx Прегледај датотеку

<div> <div>
<div className='flex gap-x-1'> <div className='flex gap-x-1'>
<div className='w-4 shrink-0 text-[13px] font-medium leading-[20px] text-text-tertiary'>Q</div> <div className='w-4 shrink-0 text-[13px] font-medium leading-[20px] text-text-tertiary'>Q</div>
<div className={cn('body-md-regular text-text-secondary line-clamp-20')}>
<div className={cn('body-md-regular line-clamp-20 text-text-secondary')}>
{content} {content}
</div> </div>
</div> </div>
<div className='flex gap-x-1'> <div className='flex gap-x-1'>
<div className='w-4 shrink-0 text-[13px] font-medium leading-[20px] text-text-tertiary'>A</div> <div className='w-4 shrink-0 text-[13px] font-medium leading-[20px] text-text-tertiary'>A</div>
<div className={cn('body-md-regular text-text-secondary line-clamp-20')}>
<div className={cn('body-md-regular line-clamp-20 text-text-secondary')}>
{answer} {answer}
</div> </div>
</div> </div>

+ 0
- 1
web/app/components/datasets/metadata/hooks/use-edit-dataset-metadata.ts Прегледај датотеку

showEditModal() showEditModal()
localStorage.removeItem(isShowManageMetadataLocalStorageKey) localStorage.removeItem(isShowManageMetadataLocalStorageKey)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


const { data: datasetMetaData } = useDatasetMetaData(datasetId) const { data: datasetMetaData } = useDatasetMetaData(datasetId)

+ 2
- 2
web/app/components/goto-anything/actions/commands/registry.ts Прегледај датотеку

try { try {
return await handler.search(args, locale) return await handler.search(args, locale)
} }
catch (error) {
catch (error) {
console.warn(`Command search failed for ${commandName}:`, error) console.warn(`Command search failed for ${commandName}:`, error)
return [] return []
} }
try { try {
return await handler.search(args, locale) return await handler.search(args, locale)
} }
catch (error) {
catch (error) {
console.warn(`Command search failed for ${handler.name}:`, error) console.warn(`Command search failed for ${handler.name}:`, error)
return [] return []
} }

+ 2
- 2
web/app/components/goto-anything/actions/index.ts Прегледај датотеку

const results = await action.search(query, query, locale) const results = await action.search(query, query, locale)
return { success: true, data: results, actionType: action.key } return { success: true, data: results, actionType: action.key }
} }
catch (error) {
catch (error) {
console.warn(`Search failed for ${action.key}:`, error) console.warn(`Search failed for ${action.key}:`, error)
return { success: false, data: [], actionType: action.key, error } return { success: false, data: [], actionType: action.key, error }
} }
if (result.status === 'fulfilled' && result.value.success) { if (result.status === 'fulfilled' && result.value.success) {
allResults.push(...result.value.data) allResults.push(...result.value.data)
} }
else {
else {
const actionKey = globalSearchActions[index]?.key || 'unknown' const actionKey = globalSearchActions[index]?.key || 'unknown'
failedActions.push(actionKey) failedActions.push(actionKey)
} }

+ 1
- 1
web/app/components/goto-anything/index.tsx Прегледај датотеку

acc[result.type].push(result) acc[result.type].push(result)
return acc return acc
}, {} as { [key: string]: SearchResult[] }), }, {} as { [key: string]: SearchResult[] }),
[searchResults])
[searchResults])


const emptyResult = useMemo(() => { const emptyResult = useMemo(() => {
if (searchResults.length || !searchQuery.trim() || isLoading || isCommandsMode) if (searchResults.length || !searchQuery.trim() || isLoading || isCommandsMode)

+ 0
- 1
web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx Прегледај датотеку



useEffect(() => { useEffect(() => {
checkSetApiKey() checkSetApiKey()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


const [configTarget, setConfigTarget] = useState<DataSourceProvider | null>(null) const [configTarget, setConfigTarget] = useState<DataSourceProvider | null>(null)

+ 3
- 3
web/app/components/header/account-setting/model-provider-page/model-auth/add-credential-in-load-balancing.tsx Прегледај датотеку

asChild asChild
popupContent={t('plugin.auth.credentialUnavailable')} popupContent={t('plugin.auth.credentialUnavailable')}
> >
{Item}
</Tooltip>
)
{Item}
</Tooltip>
)
} }
return Item return Item
}, [notAllowCustomCredential, t, customModel]) }, [notAllowCustomCredential, t, customModel])

+ 5
- 5
web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx Прегледај датотеку

onClick={() => handleEdit( onClick={() => handleEdit(
undefined, undefined,
currentCustomConfigurationModelFixedFields currentCustomConfigurationModelFixedFields
? {
model: currentCustomConfigurationModelFixedFields.__model_name,
model_type: currentCustomConfigurationModelFixedFields.__model_type,
}
: undefined,
? {
model: currentCustomConfigurationModelFixedFields.__model_name,
model_type: currentCustomConfigurationModelFixedFields.__model_type,
}
: undefined,
)} )}
className='system-xs-medium flex h-[30px] cursor-pointer items-center px-3 text-text-accent-light-mode-only' className='system-xs-medium flex h-[30px] cursor-pointer items-center px-3 text-text-accent-light-mode-only'
> >

+ 2
- 2
web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx Прегледај датотеку

<div className='grow'> <div className='grow'>
<div className='text-sm text-text-secondary'>{ <div className='text-sm text-text-secondary'>{
providerFormSchemaPredefined providerFormSchemaPredefined
? t('common.modelProvider.auth.providerManaged')
: t('common.modelProvider.auth.specifyModelCredential')
? t('common.modelProvider.auth.providerManaged')
: t('common.modelProvider.auth.specifyModelCredential')
}</div> }</div>
<div className='text-xs text-text-tertiary'>{ <div className='text-xs text-text-tertiary'>{
providerFormSchemaPredefined providerFormSchemaPredefined

+ 0
- 3
web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx Прегледај датотеку

onFetchedPayload(payload) onFetchedPayload(payload)
setPayload({ ...payload, from: dependency.type }) setPayload({ ...payload, from: dependency.type })
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]) }, [data])
useEffect(() => { useEffect(() => {
if (error) if (error)
onFetchError() onFetchError()

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [error]) }, [error])
if (!payload) return <Loading /> if (!payload) return <Loading />
return ( return (

+ 0
- 6
web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx Прегледај датотеку

if (failedIndex.length > 0) if (failedIndex.length > 0)
setErrorIndexes([...errorIndexes, ...failedIndex]) setErrorIndexes([...errorIndexes, ...failedIndex])
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFetchingMarketplaceDataById]) }, [isFetchingMarketplaceDataById])


useEffect(() => { useEffect(() => {
if (failedIndex.length > 0) if (failedIndex.length > 0)
setErrorIndexes([...errorIndexes, ...failedIndex]) setErrorIndexes([...errorIndexes, ...failedIndex])
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFetchingDataByMeta]) }, [isFetchingDataByMeta])


useEffect(() => { useEffect(() => {
// get info all failed // get info all failed
if (infoByMetaError || infoByIdError) if (infoByMetaError || infoByIdError)
setErrorIndexes([...errorIndexes, ...marketPlaceInDSLIndex]) setErrorIndexes([...errorIndexes, ...marketPlaceInDSLIndex])

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [infoByMetaError, infoByIdError]) }, [infoByMetaError, infoByIdError])


const isLoadedAllData = (plugins.filter(p => !!p).length + errorIndexes.length) === allPlugins.length const isLoadedAllData = (plugins.filter(p => !!p).length + errorIndexes.length) === allPlugins.length
useEffect(() => { useEffect(() => {
if (isLoadedAllData && installedInfo) if (isLoadedAllData && installedInfo)
onLoadedAllPlugin(installedInfo!) onLoadedAllPlugin(installedInfo!)

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoadedAllData, installedInfo]) }, [isLoadedAllData, installedInfo])


const handleSelect = useCallback((index: number) => { const handleSelect = useCallback((index: number) => {

+ 0
- 1
web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx Прегледај датотеку

useEffect(() => { useEffect(() => {
if (hasInstalled && uniqueIdentifier === installedInfoPayload.uniqueIdentifier) if (hasInstalled && uniqueIdentifier === installedInfoPayload.uniqueIdentifier)
onInstalled() onInstalled()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasInstalled]) }, [hasInstalled])


const handleInstall = async () => { const handleInstall = async () => {

+ 0
- 1
web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx Прегледај датотеку



React.useEffect(() => { React.useEffect(() => {
handleUpload() handleUpload()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
return ( return (
<> <>

+ 0
- 1
web/app/components/plugins/marketplace/context.tsx Прегледај датотеку

}) })
} }
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [queryPlugins, queryMarketplaceCollectionsAndPlugins, isSuccess, exclude]) }, [queryPlugins, queryMarketplaceCollectionsAndPlugins, isSuccess, exclude])


const handleQueryMarketplaceCollectionsAndPlugins = useCallback(() => { const handleQueryMarketplaceCollectionsAndPlugins = useCallback(() => {

+ 14
- 14
web/app/components/plugins/plugin-auth/authorized/index.tsx Прегледај датотеку

}, [setPluginDefaultCredential, onUpdate, notify, t, handleSetDoingAction]) }, [setPluginDefaultCredential, onUpdate, notify, t, handleSetDoingAction])
const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload) const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload)
const handleRename = useCallback(async (payload: { const handleRename = useCallback(async (payload: {
credential_id: string
name: string
}) => {
credential_id: string
name: string
}) => {
if (doingActionRef.current) if (doingActionRef.current)
return return
try { try {
!notAllowCustomCredential && ( !notAllowCustomCredential && (
<> <>
<div className='h-[1px] bg-divider-subtle'></div> <div className='h-[1px] bg-divider-subtle'></div>
<div className='p-2'>
<Authorize
pluginPayload={pluginPayload}
theme='secondary'
showDivider={false}
canOAuth={canOAuth}
canApiKey={canApiKey}
disabled={disabled}
onUpdate={onUpdate}
/>
</div>
<div className='p-2'>
<Authorize
pluginPayload={pluginPayload}
theme='secondary'
showDivider={false}
canOAuth={canOAuth}
canApiKey={canApiKey}
disabled={disabled}
onUpdate={onUpdate}
/>
</div>
</> </>
) )
} }

+ 3
- 3
web/app/components/plugins/plugin-auth/hooks/use-plugin-auth-action.ts Прегледај датотеку

}, [setPluginDefaultCredential, onUpdate, notify, t, handleSetDoingAction]) }, [setPluginDefaultCredential, onUpdate, notify, t, handleSetDoingAction])
const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload) const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload)
const handleRename = useCallback(async (payload: { const handleRename = useCallback(async (payload: {
credential_id: string
name: string
}) => {
credential_id: string
name: string
}) => {
if (doingActionRef.current) if (doingActionRef.current)
return return
try { try {

+ 1
- 1
web/app/components/plugins/plugin-detail-panel/app-selector/index.tsx Прегледај датотеку

try { try {
await setSize((size: number) => size + 1) await setSize((size: number) => size + 1)
} }
finally {
finally {
// Add a small delay to ensure state updates are complete // Add a small delay to ensure state updates are complete
setTimeout(() => { setTimeout(() => {
setIsLoadingMore(false) setIsLoadingMore(false)

+ 1
- 1
web/app/components/plugins/plugin-detail-panel/detail-header.tsx Прегледај датотеку

onUpdate, onUpdate,
}: Props) => { }: Props) => {
const { t } = useTranslation() const { t } = useTranslation()
const { userProfile: { timezone } } = useAppContext()
const { userProfile: { timezone } } = useAppContext()


const { theme } = useTheme() const { theme } = useTheme()
const locale = useGetLanguage() const locale = useGetLanguage()

+ 2
- 2
web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx Прегледај датотеку

const value = processedCredential[field.name] const value = processedCredential[field.name]
if (typeof value === 'string') if (typeof value === 'string')
processedCredential[field.name] = value === 'true' || value === '1' || value === 'True' processedCredential[field.name] = value === 'true' || value === '1' || value === 'True'
else if (typeof value === 'number')
else if (typeof value === 'number')
processedCredential[field.name] = value === 1 processedCredential[field.name] = value === 1
else if (typeof value === 'boolean')
else if (typeof value === 'boolean')
processedCredential[field.name] = value processedCredential[field.name] = value
} }
}) })

+ 1
- 1
web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx Прегледај датотеку

canChooseMCPTool, canChooseMCPTool,
}: Props) => { }: Props) => {
const { t } = useTranslation() const { t } = useTranslation()
const { data: mcpTools } = useAllMCPTools()
const { data: mcpTools } = useAllMCPTools()
const enabledCount = value.filter((item) => { const enabledCount = value.filter((item) => {
const isMCPTool = mcpTools?.find(tool => tool.id === item.provider_name) const isMCPTool = mcpTools?.find(tool => tool.id === item.provider_name)
if(isMCPTool) if(isMCPTool)

+ 6
- 6
web/app/components/plugins/plugin-detail-panel/tool-selector/reasoning-config-form.tsx Прегледај датотеку

{t('workflow.nodes.agent.clickToViewParameterSchema')} {t('workflow.nodes.agent.clickToViewParameterSchema')}
</div>} </div>}
asChild={false}> asChild={false}>
<div
className='ml-0.5 cursor-pointer rounded-[4px] p-px text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary'
onClick={() => showSchema(input_schema as SchemaRoot, label[language] || label.en_US)}
>
<RiBracesLine className='size-3.5'/>
</div>
<div
className='ml-0.5 cursor-pointer rounded-[4px] p-px text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary'
onClick={() => showSchema(input_schema as SchemaRoot, label[language] || label.en_US)}
>
<RiBracesLine className='size-3.5'/>
</div>
</Tooltip> </Tooltip>
)} )}



+ 0
- 1
web/app/components/plugins/plugin-item/action.tsx Прегледај датотеку

hideDeleteConfirm() hideDeleteConfirm()
onDelete() onDelete()
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [installationId, onDelete]) }, [installationId, onDelete])
return ( return (
<div className='flex space-x-1'> <div className='flex space-x-1'>

+ 12
- 12
web/app/components/plugins/reference-setting-modal/auto-update-setting/index.tsx Прегледај датотеку



const renderTimePickerTrigger = useCallback(({ inputElem, onClick, isOpen }: TriggerParams) => { const renderTimePickerTrigger = useCallback(({ inputElem, onClick, isOpen }: TriggerParams) => {
return ( return (
<div
className='group float-right flex h-8 w-[160px] cursor-pointer items-center justify-between rounded-lg bg-components-input-bg-normal px-2 hover:bg-state-base-hover-alt'
onClick={onClick}
>
<div className='flex w-0 grow items-center gap-x-1'>
<RiTimeLine className={cn(
'h-4 w-4 shrink-0 text-text-tertiary',
isOpen ? 'text-text-secondary' : 'group-hover:text-text-secondary',
)} />
{inputElem}
</div>
<div className='system-sm-regular text-text-tertiary'>{convertTimezoneToOffsetStr(timezone)}</div>
<div
className='group float-right flex h-8 w-[160px] cursor-pointer items-center justify-between rounded-lg bg-components-input-bg-normal px-2 hover:bg-state-base-hover-alt'
onClick={onClick}
>
<div className='flex w-0 grow items-center gap-x-1'>
<RiTimeLine className={cn(
'h-4 w-4 shrink-0 text-text-tertiary',
isOpen ? 'text-text-secondary' : 'group-hover:text-text-secondary',
)} />
{inputElem}
</div> </div>
<div className='system-sm-regular text-text-tertiary'>{convertTimezoneToOffsetStr(timezone)}</div>
</div>
) )
}, [timezone]) }, [timezone])



+ 6
- 6
web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.ts Прегледај датотеку

} }


export const convertUTCDaySecondsToLocalSeconds = (utcDaySeconds: number, localTimezone: string): number => { export const convertUTCDaySecondsToLocalSeconds = (utcDaySeconds: number, localTimezone: string): number => {
const utcDayStart = dayjs().utc().startOf('day')
const utcTargetTime = utcDayStart.add(utcDaySeconds, 'second')
const localTargetTime = utcTargetTime.tz(localTimezone)
const localDayStart = localTargetTime.startOf('day')
const secondsInLocalDay = localTargetTime.diff(localDayStart, 'second')
return secondsInLocalDay
const utcDayStart = dayjs().utc().startOf('day')
const utcTargetTime = utcDayStart.add(utcDaySeconds, 'second')
const localTargetTime = utcTargetTime.tz(localTimezone)
const localDayStart = localTargetTime.startOf('day')
const secondsInLocalDay = localTargetTime.diff(localDayStart, 'second')
return secondsInLocalDay
} }

+ 1
- 1
web/app/components/plugins/update-plugin/downgrade-warning.tsx Прегледај датотеку

<div className='flex flex-col items-start gap-2 self-stretch'> <div className='flex flex-col items-start gap-2 self-stretch'>
<div className='title-2xl-semi-bold text-text-primary'>{t(`${i18nPrefix}.title`)}</div> <div className='title-2xl-semi-bold text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
<div className='system-md-regular text-text-secondary'> <div className='system-md-regular text-text-secondary'>
{t(`${i18nPrefix}.description`)}
{t(`${i18nPrefix}.description`)}
</div> </div>
</div> </div>
<div className='mt-9 flex items-start justify-end space-x-2 self-stretch'> <div className='mt-9 flex items-start justify-end space-x-2 self-stretch'>

+ 38
- 38
web/app/components/plugins/update-plugin/from-market-place.tsx Прегледај датотеку

onExcludeAndDowngrade={handleExcludeAndDownload} onExcludeAndDowngrade={handleExcludeAndDownload}
/> />
)} )}
{!doShowDowngradeWarningModal && (
<>
<div className='system-md-regular mb-2 mt-3 text-text-secondary'>
{t(`${i18nPrefix}.description`)}
</div>
<div className='flex flex-wrap content-start items-start gap-1 self-stretch rounded-2xl bg-background-section-burn p-2'>
<Card
installed={uploadStep === UploadStep.installed}
payload={pluginManifestToCardPluginProps({
...originalPackageInfo.payload,
icon: icon!,
})}
className='w-full'
titleLeft={
<>
<Badge className='mx-1' size="s" state={BadgeState.Warning}>
{`${originalPackageInfo.payload.version} -> ${targetPackageInfo.version}`}
</Badge>
</>
}
/>
</div>
<div className='flex items-center justify-end gap-2 self-stretch pt-5'>
{uploadStep === UploadStep.notStarted && (
{!doShowDowngradeWarningModal && (
<>
<div className='system-md-regular mb-2 mt-3 text-text-secondary'>
{t(`${i18nPrefix}.description`)}
</div>
<div className='flex flex-wrap content-start items-start gap-1 self-stretch rounded-2xl bg-background-section-burn p-2'>
<Card
installed={uploadStep === UploadStep.installed}
payload={pluginManifestToCardPluginProps({
...originalPackageInfo.payload,
icon: icon!,
})}
className='w-full'
titleLeft={
<>
<Badge className='mx-1' size="s" state={BadgeState.Warning}>
{`${originalPackageInfo.payload.version} -> ${targetPackageInfo.version}`}
</Badge>
</>
}
/>
</div>
<div className='flex items-center justify-end gap-2 self-stretch pt-5'>
{uploadStep === UploadStep.notStarted && (
<Button
onClick={handleCancel}
>
{t('common.operation.cancel')}
</Button>
)}
<Button <Button
onClick={handleCancel}
variant='primary'
loading={uploadStep === UploadStep.upgrading}
onClick={handleConfirm}
disabled={uploadStep === UploadStep.upgrading}
> >
{t('common.operation.cancel')}
{configBtnText}
</Button> </Button>
)}
<Button
variant='primary'
loading={uploadStep === UploadStep.upgrading}
onClick={handleConfirm}
disabled={uploadStep === UploadStep.upgrading}
>
{configBtnText}
</Button>
</div>
</>
)}
</div>
</>
)}


</Modal> </Modal>
) )

+ 0
- 1
web/app/components/tools/mcp/detail/content.tsx Прегледај датотеку

useEffect(() => { useEffect(() => {
if (isTriggerAuthorize) if (isTriggerAuthorize)
handleAuthorize() handleAuthorize()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


if (!detail) if (!detail)

+ 3
- 3
web/app/components/tools/mcp/mcp-service-card.tsx Прегледај датотеку

> >


<div className="flex items-center justify-center gap-[1px]"> <div className="flex items-center justify-center gap-[1px]">
<RiEditLine className="h-3.5 w-3.5" />
<div className="system-xs-medium px-[3px] text-text-tertiary">{serverPublished ? t('tools.mcp.server.edit') : t('tools.mcp.server.addDescription')}</div>
</div>
<RiEditLine className="h-3.5 w-3.5" />
<div className="system-xs-medium px-[3px] text-text-tertiary">{serverPublished ? t('tools.mcp.server.edit') : t('tools.mcp.server.addDescription')}</div>
</div>
</Button> </Button>
</div> </div>
</div> </div>

+ 9
- 9
web/app/components/tools/utils/to-form-schema.ts Прегледај датотеку

if (formSchema.type === 'boolean' && itemValue !== undefined && itemValue !== null && itemValue !== '') { if (formSchema.type === 'boolean' && itemValue !== undefined && itemValue !== null && itemValue !== '') {
if (typeof itemValue === 'string') if (typeof itemValue === 'string')
newValues[formSchema.variable] = itemValue === 'true' || itemValue === '1' || itemValue === 'True' newValues[formSchema.variable] = itemValue === 'true' || itemValue === '1' || itemValue === 'True'
else if (typeof itemValue === 'number')
else if (typeof itemValue === 'number')
newValues[formSchema.variable] = itemValue === 1 newValues[formSchema.variable] = itemValue === 1
else if (typeof itemValue === 'boolean')
else if (typeof itemValue === 'boolean')
newValues[formSchema.variable] = itemValue newValues[formSchema.variable] = itemValue
} }
}) })
} }


const getVarKindType = (type: FormTypeEnum) => { const getVarKindType = (type: FormTypeEnum) => {
if (type === FormTypeEnum.file || type === FormTypeEnum.files)
return VarKindType.variable
if (type === FormTypeEnum.select || type === FormTypeEnum.boolean || type === FormTypeEnum.textNumber)
return VarKindType.constant
if (type === FormTypeEnum.textInput || type === FormTypeEnum.secretInput)
return VarKindType.mixed
}
if (type === FormTypeEnum.file || type === FormTypeEnum.files)
return VarKindType.variable
if (type === FormTypeEnum.select || type === FormTypeEnum.boolean || type === FormTypeEnum.textNumber)
return VarKindType.constant
if (type === FormTypeEnum.textInput || type === FormTypeEnum.secretInput)
return VarKindType.mixed
}


export const generateAgentToolValue = (value: Record<string, any>, formSchemas: { variable: string; default?: any; type: string }[], isReasoning = false) => { export const generateAgentToolValue = (value: Record<string, any>, formSchemas: { variable: string; default?: any; type: string }[], isReasoning = false) => {
const newValues = {} as any const newValues = {} as any

+ 0
- 1
web/app/components/workflow-app/hooks/use-workflow-init.ts Прегледај датотеку



useEffect(() => { useEffect(() => {
handleGetInitialWorkflowData() handleGetInitialWorkflowData()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


const handleFetchPreloadData = useCallback(async () => { const handleFetchPreloadData = useCallback(async () => {

+ 0
- 1
web/app/components/workflow/block-selector/all-tools.tsx Прегледај датотеку

category: PluginType.tool, category: PluginType.tool,
}) })
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchText, tags, enable_marketplace]) }, [searchText, tags, enable_marketplace])


const pluginRef = useRef<ListRef>(null) const pluginRef = useRef<ListRef>(null)

+ 0
- 1
web/app/components/workflow/block-selector/market-place-plugin/action.tsx Прегледај датотеку

downloadFile({ data: blob, fileName }) downloadFile({ data: blob, fileName })
setNeedDownload(false) setNeedDownload(false)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [blob]) }, [blob])
return ( return (
<PortalToFollowElem <PortalToFollowElem

+ 0
- 1
web/app/components/workflow/block-selector/market-place-plugin/list.tsx Прегледај датотеку



useEffect(() => { useEffect(() => {
handleScroll() handleScroll()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [list]) }, [list])


const handleHeadClick = () => { const handleHeadClick = () => {

+ 0
- 1
web/app/components/workflow/block-selector/tool/tool.tsx Прегледај датотеку

} }
if (!hasSearchText && !isFold) if (!hasSearchText && !isFold)
setFold(true) setFold(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasSearchText]) }, [hasSearchText])


const FoldIcon = isFold ? RiArrowRightSLine : RiArrowDownSLine const FoldIcon = isFold ? RiArrowRightSLine : RiArrowDownSLine

+ 0
- 1
web/app/components/workflow/datasets-detail-store/provider.tsx Прегледај датотеку

}, []) }, [])
if (allDatasetIds.length === 0) return if (allDatasetIds.length === 0) return
updateDatasetsDetail(allDatasetIds) updateDatasetsDetail(allDatasetIds)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


return ( return (

+ 20
- 20
web/app/components/workflow/header/header-in-restoring.tsx Прегледај датотеку

<RestoringTitle /> <RestoringTitle />
</div> </div>
<div className=' flex items-center justify-end gap-x-2'> <div className=' flex items-center justify-end gap-x-2'>
<Button
onClick={handleRestore}
disabled={!currentVersion || currentVersion.version === WorkflowVersion.Draft}
variant='primary'
className={cn(
theme === 'dark' && 'rounded-lg border border-black/5 bg-white/10 backdrop-blur-sm',
)}
>
{t('workflow.common.restore')}
</Button>
<Button
onClick={handleCancelRestore}
className={cn(
'text-components-button-secondary-accent-text',
theme === 'dark' && 'rounded-lg border border-black/5 bg-white/10 backdrop-blur-sm',
)}
>
<div className='flex items-center gap-x-0.5'>
<RiHistoryLine className='h-4 w-4' />
<span className='px-0.5'>{t('workflow.common.exitVersions')}</span>
<Button
onClick={handleRestore}
disabled={!currentVersion || currentVersion.version === WorkflowVersion.Draft}
variant='primary'
className={cn(
theme === 'dark' && 'rounded-lg border border-black/5 bg-white/10 backdrop-blur-sm',
)}
>
{t('workflow.common.restore')}
</Button>
<Button
onClick={handleCancelRestore}
className={cn(
'text-components-button-secondary-accent-text',
theme === 'dark' && 'rounded-lg border border-black/5 bg-white/10 backdrop-blur-sm',
)}
>
<div className='flex items-center gap-x-0.5'>
<RiHistoryLine className='h-4 w-4' />
<span className='px-0.5'>{t('workflow.common.exitVersions')}</span>
</div> </div>
</Button> </Button>
</div> </div>

+ 10
- 10
web/app/components/workflow/header/version-history-button.tsx Прегледај датотеку

e.preventDefault() e.preventDefault()
handleViewVersionHistory() handleViewVersionHistory()
}, },
{ exactMatch: true, useCapture: true })
{ exactMatch: true, useCapture: true })


return <Tooltip return <Tooltip
popupContent={<PopupContent />} popupContent={<PopupContent />}
popupClassName='rounded-lg border-[0.5px] border-components-panel-border bg-components-tooltip-bg popupClassName='rounded-lg border-[0.5px] border-components-panel-border bg-components-tooltip-bg
shadow-lg shadow-shadow-shadow-5 backdrop-blur-[5px] p-1.5' shadow-lg shadow-shadow-shadow-5 backdrop-blur-[5px] p-1.5'
> >
<Button
className={cn(
'p-2',
theme === 'dark' && 'rounded-lg border border-black/5 bg-white/10 backdrop-blur-sm',
)}
onClick={handleViewVersionHistory}
>
<RiHistoryLine className='h-4 w-4 text-components-button-secondary-text' />
</Button>
<Button
className={cn(
'p-2',
theme === 'dark' && 'rounded-lg border border-black/5 bg-white/10 backdrop-blur-sm',
)}
onClick={handleViewVersionHistory}
>
<RiHistoryLine className='h-4 w-4 text-components-button-secondary-text' />
</Button>
</Tooltip> </Tooltip>
} }



+ 0
- 1
web/app/components/workflow/hooks-store/provider.tsx Прегледај датотеку

useEffect(() => { useEffect(() => {
if (storeRef.current && d3Selection && d3Zoom) if (storeRef.current && d3Selection && d3Zoom)
storeRef.current.getState().refreshAll(restProps) storeRef.current.getState().refreshAll(restProps)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [d3Selection, d3Zoom]) }, [d3Selection, d3Zoom])


if (!storeRef.current) if (!storeRef.current)

+ 28
- 28
web/app/components/workflow/hooks/use-inspect-vars-crud-common.ts Прегледај датотеку

if (!node) if (!node)
return undefined return undefined
const varId = node.vars.find((varItem) => { const varId = node.vars.find((varItem) => {
return varItem.selector[1] === varName
})?.id
return varId
return varItem.selector[1] === varName
})?.id
return varId
}, [getNodeInspectVars]) }, [getNodeInspectVars])


const getInspectVar = useCallback((nodeId: string, name: string): VarInInspect | undefined => { const getInspectVar = useCallback((nodeId: string, name: string): VarInInspect | undefined => {
}, [getNodeInspectVars]) }, [getNodeInspectVars])


const hasSetInspectVar = useCallback((nodeId: string, name: string, sysVars: VarInInspect[], conversationVars: VarInInspect[]) => { const hasSetInspectVar = useCallback((nodeId: string, name: string, sysVars: VarInInspect[], conversationVars: VarInInspect[]) => {
const isEnv = isENV([nodeId])
if (isEnv) // always have value
return true
const isSys = isSystemVar([nodeId])
if (isSys)
return sysVars.some(varItem => varItem.selector?.[1]?.replace('sys.', '') === name)
const isChatVar = isConversationVar([nodeId])
if (isChatVar)
return conversationVars.some(varItem => varItem.selector?.[1] === name)
return getInspectVar(nodeId, name) !== undefined
const isEnv = isENV([nodeId])
if (isEnv) // always have value
return true
const isSys = isSystemVar([nodeId])
if (isSys)
return sysVars.some(varItem => varItem.selector?.[1]?.replace('sys.', '') === name)
const isChatVar = isConversationVar([nodeId])
if (isChatVar)
return conversationVars.some(varItem => varItem.selector?.[1] === name)
return getInspectVar(nodeId, name) !== undefined
}, [getInspectVar]) }, [getInspectVar])


const hasNodeInspectVars = useCallback((nodeId: string) => { const hasNodeInspectVars = useCallback((nodeId: string) => {
} = workflowStore.getState() } = workflowStore.getState()
const nodes = produce(nodesWithInspectVars, (draft) => { const nodes = produce(nodesWithInspectVars, (draft) => {
const nodeInfo = allNodes.find(node => node.id === nodeId) const nodeInfo = allNodes.find(node => node.id === nodeId)
if (nodeInfo) {
const index = draft.findIndex(node => node.nodeId === nodeId)
if (index === -1) {
draft.unshift({
nodeId,
nodeType: nodeInfo.data.type,
title: nodeInfo.data.title,
vars: payload,
nodePayload: nodeInfo.data,
})
}
else {
draft[index].vars = payload
if (nodeInfo) {
const index = draft.findIndex(node => node.nodeId === nodeId)
if (index === -1) {
draft.unshift({
nodeId,
nodeType: nodeInfo.data.type,
title: nodeInfo.data.title,
vars: payload,
nodePayload: nodeInfo.data,
})
}
else {
draft[index].vars = payload
// put the node to the topAdd commentMore actions // put the node to the topAdd commentMore actions
draft.unshift(draft.splice(index, 1)[0])
}
draft.unshift(draft.splice(index, 1)[0])
} }
}
}) })
setNodesWithInspectVars(nodes) setNodesWithInspectVars(nodes)
handleCancelNodeSuccessStatus(nodeId) handleCancelNodeSuccessStatus(nodeId)

+ 3
- 3
web/app/components/workflow/hooks/use-nodes-available-var-list.ts Прегледај датотеку

hideChatVar = false, hideChatVar = false,
passedInAvailableNodes, passedInAvailableNodes,
}: Params = { }: Params = {
onlyLeafNodeVar: false,
filterVar: () => true,
}) => {
onlyLeafNodeVar: false,
filterVar: () => true,
}) => {
const { getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent } = useWorkflow() const { getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent } = useWorkflow()
const { getNodeAvailableVars } = useWorkflowVariables() const { getNodeAvailableVars } = useWorkflowVariables()
const isChatMode = useIsChatMode() const isChatMode = useIsChatMode()

+ 1
- 1
web/app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-started.ts Прегледај датотеку

incomeEdges.forEach((edge) => { incomeEdges.forEach((edge) => {
const incomeNode = nodes.find(node => node.id === edge.source)! const incomeNode = nodes.find(node => node.id === edge.source)!
if (!incomeNode || !('data' in incomeNode)) if (!incomeNode || !('data' in incomeNode))
return
return


if ( if (
(!incomeNode.data._runningBranchId && edge.sourceHandle === 'source') (!incomeNode.data._runningBranchId && edge.sourceHandle === 'source')

+ 1
- 1
web/app/components/workflow/nodes/_base/components/agent-strategy-selector.tsx Прегледај датотеку

} }


export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => { export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => {
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)


const { value, onChange, canChooseMCPTool } = props const { value, onChange, canChooseMCPTool } = props
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)

+ 1
- 1
web/app/components/workflow/nodes/_base/components/agent-strategy.tsx Прегледај датотеку

'zh-Hans': '/guides/workflow/node/agent#选择-agent-策略', 'zh-Hans': '/guides/workflow/node/agent#选择-agent-策略',
'ja-JP': '/guides/workflow/node/agent#エージェント戦略の選択', 'ja-JP': '/guides/workflow/node/agent#エージェント戦略の選択',
})} })}
className='text-text-accent-secondary' target='_blank'>
className='text-text-accent-secondary' target='_blank'>
{t('workflow.nodes.agent.learnMore')} {t('workflow.nodes.agent.learnMore')}
</Link> </Link>
</div>} </div>}

+ 4
- 4
web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx Прегледај датотеку

language={CodeLanguage.json} language={CodeLanguage.json}
onChange={onChange} onChange={onChange}
noWrapper noWrapper
className='bg h-[80px] overflow-y-auto rounded-[10px] bg-components-input-bg-normal p-1'
placeholder={
<div className='whitespace-pre'>{payload.json_schema}</div>
}
className='bg h-[80px] overflow-y-auto rounded-[10px] bg-components-input-bg-normal p-1'
placeholder={
<div className='whitespace-pre'>{payload.json_schema}</div>
}
/> />
)} )}
{(type === InputVarType.singleFile) && ( {(type === InputVarType.singleFile) && (

+ 0
- 1
web/app/components/workflow/nodes/_base/components/input-support-select-var.tsx Прегледај датотеку



useEffect(() => { useEffect(() => {
onFocusChange?.(isFocus) onFocusChange?.(isFocus)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocus]) }, [isFocus])


return ( return (

+ 1
- 1
web/app/components/workflow/nodes/_base/components/mcp-tool-not-support-tooltip.tsx Прегледај датотеку

<Tooltip <Tooltip
popupContent={ popupContent={
<div className='w-[256px]'> <div className='w-[256px]'>
{t('plugin.detailPanel.toolSelector.unsupportedMCPTool')}
{t('plugin.detailPanel.toolSelector.unsupportedMCPTool')}
</div> </div>
} }
> >

+ 2
- 2
web/app/components/workflow/nodes/_base/components/variable/utils.ts Прегледај датотеку

curr = Array.isArray(curr) ? curr.find(v => v.variable === key) : [] curr = Array.isArray(curr) ? curr.find(v => v.variable === key) : []


if (isLast) if (isLast)
arrayType = curr?.type
arrayType = curr?.type
else if (curr?.type === VarType.object || curr?.type === VarType.file) else if (curr?.type === VarType.object || curr?.type === VarType.file)
curr = curr.children || []
curr = curr.children || []
} }
} }



+ 5
- 5
web/app/components/workflow/nodes/_base/components/variable/var-list.tsx Прегледај датотеку

const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true) const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)
if (!isValid) { if (!isValid) {
setToastHandle(Toast.notify({ setToastHandle(Toast.notify({
type: 'error',
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
}))
return
}
type: 'error',
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
}))
return
}
if (list.some(item => item.variable?.trim() === newKey.trim())) { if (list.some(item => item.variable?.trim() === newKey.trim())) {
console.log('new key', newKey.trim()) console.log('new key', newKey.trim())
setToastHandle(Toast.notify({ setToastHandle(Toast.notify({

+ 1
- 1
web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx Прегледај датотеку

const data = await fetchDynamicOptions() const data = await fetchDynamicOptions()
setDynamicOptions(data?.options || []) setDynamicOptions(data?.options || [])
} }
finally {
finally {
setIsLoading(false) setIsLoading(false)
} }
} }

+ 2
- 2
web/app/components/workflow/nodes/_base/components/workflow-panel/index.tsx Прегледај датотеку



if(logParams.showSpecialResultPanel) { if(logParams.showSpecialResultPanel) {
return ( return (
<div className={cn(
<div className={cn(
'relative mr-1 h-full', 'relative mr-1 h-full',
)}> )}>
<div <div
> >
{ {
isSingleRunning ? <Stop className='h-4 w-4 text-text-tertiary' /> isSingleRunning ? <Stop className='h-4 w-4 text-text-tertiary' />
: <RiPlayLargeLine className='h-4 w-4 text-text-tertiary' />
: <RiPlayLargeLine className='h-4 w-4 text-text-tertiary' />
} }
</div> </div>
</Tooltip> </Tooltip>

+ 5
- 5
web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/index.tsx Прегледај датотеку

}, [nodeId]) }, [nodeId])


const handlePageVisibilityChange = useCallback(() => { const handlePageVisibilityChange = useCallback(() => {
if (document.visibilityState === 'hidden')
setPageHasHide(true)
else
setPageShowed(true)
}, [])
if (document.visibilityState === 'hidden')
setPageHasHide(true)
else
setPageShowed(true)
}, [])
useEffect(() => { useEffect(() => {
document.addEventListener('visibilitychange', handlePageVisibilityChange) document.addEventListener('visibilitychange', handlePageVisibilityChange)



+ 4
- 4
web/app/components/workflow/nodes/_base/hooks/use-output-var-list.ts Прегледај датотеку

const [removedVar, setRemovedVar] = useState<ValueSelector>([]) const [removedVar, setRemovedVar] = useState<ValueSelector>([])
const removeVarInNode = useCallback(() => { const removeVarInNode = useCallback(() => {
const varId = nodesWithInspectVars.find(node => node.nodeId === id)?.vars.find((varItem) => { const varId = nodesWithInspectVars.find(node => node.nodeId === id)?.vars.find((varItem) => {
return varItem.name === removedVar[1]
})?.id
return varItem.name === removedVar[1]
})?.id
if(varId) if(varId)
deleteInspectVar(id, varId) deleteInspectVar(id, varId)
removeUsedVarInNodes(removedVar) removeUsedVarInNodes(removedVar)
setInputs(newInputs) setInputs(newInputs)
onOutputKeyOrdersChange(outputKeyOrders.filter((_, i) => i !== index)) onOutputKeyOrdersChange(outputKeyOrders.filter((_, i) => i !== index))
const varId = nodesWithInspectVars.find(node => node.nodeId === id)?.vars.find((varItem) => { const varId = nodesWithInspectVars.find(node => node.nodeId === id)?.vars.find((varItem) => {
return varItem.name === key
})?.id
return varItem.name === key
})?.id
if(varId) if(varId)
deleteInspectVar(id, varId) deleteInspectVar(id, varId)
}, [outputKeyOrders, isVarUsedInNodes, id, inputs, setInputs, onOutputKeyOrdersChange, nodesWithInspectVars, deleteInspectVar, showRemoveVarConfirm, varKey]) }, [outputKeyOrders, isVarUsedInNodes, id, inputs, setInputs, onOutputKeyOrdersChange, nodesWithInspectVars, deleteInspectVar, showRemoveVarConfirm, varKey])

+ 4
- 4
web/app/components/workflow/nodes/agent/panel.tsx Прегледај датотеку

const resetEditor = useStore(s => s.setControlPromptEditorRerenderKey) const resetEditor = useStore(s => s.setControlPromptEditorRerenderKey)
return <div className='my-2'> return <div className='my-2'>
<Field <Field
required
title={t('workflow.nodes.agent.strategy.label')}
className='px-4 py-2'
tooltip={t('workflow.nodes.agent.strategy.tooltip')} >
required
title={t('workflow.nodes.agent.strategy.label')}
className='px-4 py-2'
tooltip={t('workflow.nodes.agent.strategy.tooltip')} >
<AgentStrategy <AgentStrategy
strategy={inputs.agent_strategy_name ? { strategy={inputs.agent_strategy_name ? {
agent_strategy_provider_name: inputs.agent_strategy_provider_name!, agent_strategy_provider_name: inputs.agent_strategy_provider_name!,

+ 1
- 1
web/app/components/workflow/nodes/agent/use-single-run-form-params.ts Прегледај датотеку

return formatTracing([runResult], t)[0] return formatTracing([runResult], t)[0]
}, [runResult, t]) }, [runResult, t])


const getDependentVars = () => {
const getDependentVars = () => {
return varInputs.map((item) => { return varInputs.map((item) => {
// Guard against null/undefined variable to prevent app crash // Guard against null/undefined variable to prevent app crash
if (!item.variable || typeof item.variable !== 'string') if (!item.variable || typeof item.variable !== 'string')

+ 1
- 1
web/app/components/workflow/nodes/assigner/components/var-list/index.tsx Прегледај датотеку

if (item.value === WriteMode.set || item.value === WriteMode.increment || item.value === WriteMode.decrement if (item.value === WriteMode.set || item.value === WriteMode.increment || item.value === WriteMode.decrement
|| item.value === WriteMode.multiply || item.value === WriteMode.divide) { || item.value === WriteMode.multiply || item.value === WriteMode.divide) {
if(varType === VarType.boolean) if(varType === VarType.boolean)
draft[index].value = false
draft[index].value = false
draft[index].input_type = AssignerNodeInputType.constant draft[index].input_type = AssignerNodeInputType.constant
} }
else { else {

+ 0
- 2
web/app/components/workflow/nodes/http/hooks/use-key-value-list.ts Прегледај датотеку

const newValue = list.filter(item => item.key && item.value).map(item => `${item.key}:${item.value}`).join('\n') const newValue = list.filter(item => item.key && item.value).map(item => `${item.key}:${item.value}`).join('\n')
if (newValue !== value) if (newValue !== value)
onChange(newValue) onChange(newValue)

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [list, noFilter]) }, [list, noFilter])
const addItem = useCallback(() => { const addItem = useCallback(() => {
setList([...list, { setList([...list, {

+ 0
- 1
web/app/components/workflow/nodes/http/use-config.ts Прегледај датотеку

setInputs(newInputs) setInputs(newInputs)
setIsDataReady(true) setIsDataReady(true)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultConfig]) }, [defaultConfig])


const handleMethodChange = useCallback((method: Method) => { const handleMethodChange = useCallback((method: Method) => {

+ 0
- 1
web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-trigger.tsx Прегледај датотеку

handleRemoveCondition(condition.id) handleRemoveCondition(condition.id)
}) })
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [metadataList, handleRemoveCondition, selectedDatasetsLoaded]) }, [metadataList, handleRemoveCondition, selectedDatasetsLoaded])


return ( return (

+ 0
- 3
web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts Прегледај датотеку

} }
}) })
setInputs(newInput) setInputs(newInput)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentProvider?.provider, currentModel, currentRerankModel, rerankDefaultModel]) }, [currentProvider?.provider, currentModel, currentRerankModel, rerankDefaultModel])
const [selectedDatasets, setSelectedDatasets] = useState<DataSet[]>([]) const [selectedDatasets, setSelectedDatasets] = useState<DataSet[]>([])
const [rerankModelOpen, setRerankModelOpen] = useState(false) const [rerankModelOpen, setRerankModelOpen] = useState(false)
setInputs(newInputs) setInputs(newInputs)
setSelectedDatasetsLoaded(true) setSelectedDatasetsLoaded(true)
})() })()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


useEffect(() => { useEffect(() => {
setInputs(produce(inputs, (draft) => { setInputs(produce(inputs, (draft) => {
draft.query_variable_selector = query_variable_selector draft.query_variable_selector = query_variable_selector
})) }))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


const handleOnDatasetsChange = useCallback((newDatasets: DataSet[]) => { const handleOnDatasetsChange = useCallback((newDatasets: DataSet[]) => {

+ 0
- 1
web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx Прегледај датотеку

const rect = importBtnRef.current.getBoundingClientRect() const rect = importBtnRef.current.getBoundingClientRect()
updateBtnWidth(rect.width) updateBtnWidth(rect.width)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])


const handleTrigger = useCallback((e: React.MouseEvent<HTMLElement, MouseEvent>) => { const handleTrigger = useCallback((e: React.MouseEvent<HTMLElement, MouseEvent>) => {

+ 0
- 0
web/app/components/workflow/nodes/parameter-extractor/use-config.ts Прегледај датотеку


Неке датотеке нису приказане због велике количине промена

Loading…
Откажи
Сачувај