diff --git a/web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx b/web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx index 5f0ad94d86..d3ee89f28c 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx @@ -21,10 +21,12 @@ type Value = { type WeightedScoreProps = { value: Value onChange: (value: Value) => void + readonly?: boolean } const WeightedScore = ({ value, onChange = noop, + readonly = false, }: WeightedScoreProps) => { const { t } = useTranslation() @@ -37,7 +39,7 @@ const WeightedScore = ({ min={0} step={0.1} value={value.value[0]} - onChange={v => onChange({ value: [v, (10 - v * 10) / 10] })} + onChange={v => !readonly && onChange({ value: [v, (10 - v * 10) / 10] })} trackClassName='weightedScoreSliderTrack' />
diff --git a/web/app/components/workflow/hooks/index.ts b/web/app/components/workflow/hooks/index.ts index a365570272..317ca23d4a 100644 --- a/web/app/components/workflow/hooks/index.ts +++ b/web/app/components/workflow/hooks/index.ts @@ -18,3 +18,4 @@ export * from './use-format-time-from-now' export * from './use-nodes-meta-data' export * from './use-available-blocks' export * from './use-workflow-refresh-draft' +export * from './use-tool-icon' diff --git a/web/app/components/workflow/hooks/use-tool-icon.ts b/web/app/components/workflow/hooks/use-tool-icon.ts new file mode 100644 index 0000000000..9d72815554 --- /dev/null +++ b/web/app/components/workflow/hooks/use-tool-icon.ts @@ -0,0 +1,34 @@ +import { + useMemo, +} from 'react' +import type { + Node, +} from '../types' +import { + BlockEnum, +} from '../types' +import { + useStore, +} from '../store' +import { CollectionType } from '@/app/components/tools/types' +import { canFindTool } from '@/utils' + +export const useToolIcon = (data: Node['data']) => { + const buildInTools = useStore(s => s.buildInTools) + const customTools = useStore(s => s.customTools) + const workflowTools = useStore(s => s.workflowTools) + const toolIcon = useMemo(() => { + if (data.type === BlockEnum.Tool) { + let targetTools = buildInTools + if (data.provider_type === CollectionType.builtIn) + targetTools = buildInTools + else if (data.provider_type === CollectionType.custom) + targetTools = customTools + else + targetTools = workflowTools + return targetTools.find(toolWithProvider => canFindTool(toolWithProvider.id, data.provider_id))?.icon + } + }, [data, buildInTools, customTools, workflowTools]) + + return toolIcon +} diff --git a/web/app/components/workflow/hooks/use-workflow.ts b/web/app/components/workflow/hooks/use-workflow.ts index 5d5d6e85b8..6587b44fa3 100644 --- a/web/app/components/workflow/hooks/use-workflow.ts +++ b/web/app/components/workflow/hooks/use-workflow.ts @@ -1,6 +1,5 @@ import { useCallback, - useMemo, } from 'react' import { uniqBy } from 'lodash-es' import { useTranslation } from 'react-i18next' @@ -39,11 +38,9 @@ import { fetchAllCustomTools, fetchAllWorkflowTools, } from '@/service/tools' -import { CollectionType } from '@/app/components/tools/types' import { CUSTOM_ITERATION_START_NODE } from '@/app/components/workflow/nodes/iteration-start/constants' import { CUSTOM_LOOP_START_NODE } from '@/app/components/workflow/nodes/loop-start/constants' import { basePath } from '@/utils/var' -import { canFindTool } from '@/utils' export const useIsChatMode = () => { const appDetail = useAppStore(s => s.appDetail) @@ -489,26 +486,6 @@ export const useNodesReadOnly = () => { } } -export const useToolIcon = (data: Node['data']) => { - const buildInTools = useStore(s => s.buildInTools) - const customTools = useStore(s => s.customTools) - const workflowTools = useStore(s => s.workflowTools) - const toolIcon = useMemo(() => { - if (data.type === BlockEnum.Tool) { - let targetTools = buildInTools - if (data.provider_type === CollectionType.builtIn) - targetTools = buildInTools - else if (data.provider_type === CollectionType.custom) - targetTools = customTools - else - targetTools = workflowTools - return targetTools.find(toolWithProvider => canFindTool(toolWithProvider.id, data.provider_id))?.icon - } - }, [data, buildInTools, customTools, workflowTools]) - - return toolIcon -} - export const useIsNodeInIteration = (iterationId: string) => { const store = useStoreApi() diff --git a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/index.tsx b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/index.tsx index 3c972d177f..6e4555d56a 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/index.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/index.tsx @@ -8,10 +8,12 @@ import { useChunkStructure } from './hooks' type ChunkStructureProps = { chunkStructure: ChunkStructureEnum onChunkStructureChange: (value: ChunkStructureEnum) => void + readonly?: boolean } const ChunkStructure = ({ chunkStructure, onChunkStructureChange, + readonly = false, }: ChunkStructureProps) => { const { options, @@ -28,6 +30,7 @@ const ChunkStructure = ({ options={options} value={chunkStructure} onChange={onChunkStructureChange} + readonly={readonly} /> ), }} diff --git a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/selector.tsx b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/selector.tsx index b05fd4775e..99dc49f6e3 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/selector.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/selector.tsx @@ -13,11 +13,13 @@ type SelectorProps = { options: Option[] value: ChunkStructureEnum onChange: (key: ChunkStructureEnum) => void + readonly?: boolean } const Selector = ({ options, value, onChange, + readonly, }: SelectorProps) => { const [open, setOpen] = useState(false) @@ -31,7 +33,11 @@ const Selector = ({ open={open} onOpenChange={setOpen} > - setOpen(!open)}> + { + if (readonly) + return + setOpen(!open) + }}>
void + readonly?: boolean } const InputVariable = ({ nodeId, inputVariable = [], onInputVariableChange, + readonly = false, }: InputVariableProps) => { return ( ) diff --git a/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx b/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx index 73c1c3ba17..7ba7a28154 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx @@ -31,6 +31,7 @@ type OptionCardProps = { effectColor?: string showEffectColor?: boolean onClick?: (id: T) => void + readonly?: boolean } const OptionCard = memo(({ id, @@ -47,14 +48,16 @@ const OptionCard = memo(({ effectColor, showEffectColor, onClick, + readonly, }) => { return (
onClick?.(id)} + onClick={() => !readonly && onClick?.(id)} >
void hybridSearchMode: HybridSearchModeEnum @@ -24,6 +25,7 @@ type RetrievalSettingProps = { } & RerankingModelSelectorProps & TopKAndScoreThresholdProps const RetrievalSetting = ({ + readonly, searchMethod, onRetrievalSearchMethodChange, hybridSearchMode, @@ -84,6 +86,7 @@ const RetrievalSetting = ({ onScoreThresholdEnabledChange={onScoreThresholdEnabledChange} rerankingModel={rerankingModel} onRerankingModelChange={onRerankingModelChange} + readonly={readonly} /> )) } diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx index 84788637c4..81e131b2a2 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx @@ -11,10 +11,12 @@ import type { RerankingModel } from '../../types' export type RerankingModelSelectorProps = { rerankingModel?: RerankingModel onRerankingModelChange?: (model: RerankingModel) => void + readonly?: boolean } const RerankingModelSelector = ({ rerankingModel, onRerankingModelChange, + readonly = false, }: RerankingModelSelectorProps) => { const { modelList: rerankModelList, @@ -41,6 +43,7 @@ const RerankingModelSelector = ({ defaultModel={rerankModel && { provider: rerankModel.providerName, model: rerankModel.modelName }} modelList={rerankModelList} onSelect={handleRerankingModelChange} + readonly={readonly} /> ) } diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx index 339fa1c821..42c0d8713e 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx @@ -23,6 +23,7 @@ import type { RerankingModelSelectorProps } from './reranking-model-selector' import RerankingModelSelector from './reranking-model-selector' type SearchMethodOptionProps = { + readonly?: boolean option: Option hybridSearchModeOptions: HybridSearchModeOption[] searchMethod: RetrievalSearchMethodEnum @@ -33,6 +34,7 @@ type SearchMethodOptionProps = { onWeightedScoreChange: (value: { value: number[] }) => void } & RerankingModelSelectorProps & TopKAndScoreThresholdProps const SearchMethodOption = ({ + readonly, option, hybridSearchModeOptions, searchMethod, @@ -89,6 +91,7 @@ const SearchMethodOption = ({ showChildren={isActive} showHighlightBorder={isActive} showEffectColor={isActive} + readonly={readonly} >
{ @@ -105,6 +108,7 @@ const SearchMethodOption = ({ showRadio radioIsActive={hybridOption.id === hybridSearchMode} onClick={onHybridSearchModeChange} + readonly={readonly} /> )) } @@ -116,6 +120,7 @@ const SearchMethodOption = ({ ) } @@ -124,6 +129,7 @@ const SearchMethodOption = ({ ) } @@ -134,6 +140,7 @@ const SearchMethodOption = ({ onScoreThresholdChange={onScoreThresholdChange} isScoreThresholdEnabled={isScoreThresholdEnabled} onScoreThresholdEnabledChange={onScoreThresholdEnabledChange} + readonly={readonly} />
diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx index 3ce4ca21cb..aac2439689 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx @@ -10,6 +10,7 @@ export type TopKAndScoreThresholdProps = { onScoreThresholdChange?: (value: number) => void isScoreThresholdEnabled?: boolean onScoreThresholdEnabledChange?: (value: boolean) => void + readonly?: boolean } const TopKAndScoreThreshold = ({ topK, @@ -18,6 +19,7 @@ const TopKAndScoreThreshold = ({ onScoreThresholdChange, isScoreThresholdEnabled, onScoreThresholdEnabledChange, + readonly, }: TopKAndScoreThresholdProps) => { const handleTopKChange = (e: React.ChangeEvent) => { const value = Number(e.target.value) @@ -47,6 +49,7 @@ const TopKAndScoreThreshold = ({ type='number' value={topK} onChange={handleTopKChange} + disabled={readonly} />
@@ -55,6 +58,7 @@ const TopKAndScoreThreshold = ({ className='mr-2' defaultValue={isScoreThresholdEnabled} onChange={onScoreThresholdEnabledChange} + disabled={readonly} />
Score Threshold @@ -68,6 +72,7 @@ const TopKAndScoreThreshold = ({ type='number' value={scoreThreshold} onChange={handleScoreThresholdChange} + disabled={readonly} />
diff --git a/web/app/components/workflow/nodes/knowledge-base/panel.tsx b/web/app/components/workflow/nodes/knowledge-base/panel.tsx index 5884a870c6..a0d24d713a 100644 --- a/web/app/components/workflow/nodes/knowledge-base/panel.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/panel.tsx @@ -18,11 +18,13 @@ import { GroupWithBox, } from '@/app/components/workflow/nodes/_base/components/layout' import Split from '../_base/components/split' +import { useNodesReadOnly } from '@/app/components/workflow/hooks' const Panel: FC> = ({ id, data, }) => { + const { nodesReadOnly } = useNodesReadOnly() const { handleChunkStructureChange, handleIndexMethodChange, @@ -45,6 +47,7 @@ const Panel: FC> = ({ nodeId={id} inputVariable={data.index_chunk_variable_selector} onInputVariableChange={handleInputVariableChange} + readonly={nodesReadOnly} /> > = ({ @@ -63,6 +67,7 @@ const Panel: FC> = ({ onIndexMethodChange={handleIndexMethodChange} keywordNumber={data.keyword_number} onKeywordNumberChange={handleKeywordNumberChange} + readonly={nodesReadOnly} /> { data.indexing_technique === IndexMethodEnum.QUALIFIED && ( @@ -70,6 +75,7 @@ const Panel: FC> = ({ embeddingModel={data.embedding_model} embeddingModelProvider={data.embedding_model_provider} onEmbeddingModelChange={handleEmbeddingModelChange} + readonly={nodesReadOnly} /> ) } @@ -91,6 +97,7 @@ const Panel: FC> = ({ onScoreThresholdChange={handleScoreThresholdChange} isScoreThresholdEnabled={data.retrieval_model.score_threshold_enabled} onScoreThresholdEnabledChange={handleScoreThresholdEnabledChange} + readonly={nodesReadOnly} />