mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-08 08:28:02 +08:00
Fix: dataset tag file setting cannot be saved (#17428)
This commit is contained in:
@@ -81,7 +81,7 @@ const ExtractorForm = ({
|
||||
|
||||
const ownerTenantId = useOwnerTenantId();
|
||||
|
||||
const { treeData, loadData } = useTagFileTree();
|
||||
const { treeData, loadData } = useTagFileTree(form.watch('tag_file_id'));
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
|
||||
@@ -2,9 +2,10 @@ import { TreeNodeType } from '@/components/ui/async-tree-select';
|
||||
import { useFetchPureFileList } from '@/hooks/use-file-request';
|
||||
import { IFile } from '@/interfaces/database/file-manager';
|
||||
import { isFolderType } from '@/pages/files/util';
|
||||
import fileManagerService from '@/services/file-manager-service';
|
||||
import { getExtension } from '@/utils/document-util';
|
||||
import { uniqBy } from 'lodash';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
const AllowedExtensions = ['xlsx', 'xls', 'csv', 'txt'];
|
||||
|
||||
@@ -12,41 +13,77 @@ export function canSelectTagFile(node: TreeNodeType) {
|
||||
return Boolean(node.isLeaf);
|
||||
}
|
||||
|
||||
export function useTagFileTree() {
|
||||
function toTreeNode(x: IFile): TreeNodeType {
|
||||
return {
|
||||
id: x.id,
|
||||
parentId: x.parent_id,
|
||||
title: x.name,
|
||||
// has_child_folder only counts child folders, so folders
|
||||
// must always be expandable to reach files inside them
|
||||
isLeaf: !isFolderType(x.type),
|
||||
};
|
||||
}
|
||||
|
||||
export function useTagFileTree(value?: string) {
|
||||
const { fetchList } = useFetchPureFileList();
|
||||
|
||||
const [treeData, setTreeData] = useState<TreeNodeType[]>([]);
|
||||
|
||||
const appendFiles = useCallback((files: IFile[]) => {
|
||||
setTreeData((tree) =>
|
||||
uniqBy(
|
||||
tree.concat(
|
||||
files
|
||||
.filter(
|
||||
(x) =>
|
||||
(isFolderType(x.type) && x.name.toLowerCase() !== 'skills') ||
|
||||
AllowedExtensions.includes(getExtension(x.name)),
|
||||
)
|
||||
.map(toTreeNode),
|
||||
),
|
||||
'id',
|
||||
),
|
||||
);
|
||||
}, []);
|
||||
|
||||
const loadData = useCallback(
|
||||
async ({ id }: TreeNodeType) => {
|
||||
const ret = await fetchList(id as string);
|
||||
if (ret.code === 0) {
|
||||
setTreeData((tree) =>
|
||||
uniqBy(
|
||||
tree.concat(
|
||||
ret.data.files
|
||||
.filter(
|
||||
(x: IFile) =>
|
||||
(isFolderType(x.type) &&
|
||||
x.name.toLowerCase() !== 'skills') ||
|
||||
AllowedExtensions.includes(getExtension(x.name)),
|
||||
)
|
||||
.map((x: IFile) => ({
|
||||
id: x.id,
|
||||
parentId: x.parent_id,
|
||||
title: x.name,
|
||||
// has_child_folder only counts child folders, so folders
|
||||
// must always be expandable to reach files inside them
|
||||
isLeaf: !isFolderType(x.type),
|
||||
})),
|
||||
),
|
||||
'id',
|
||||
),
|
||||
);
|
||||
appendFiles(ret.data.files);
|
||||
}
|
||||
},
|
||||
[fetchList],
|
||||
[fetchList, appendFiles],
|
||||
);
|
||||
|
||||
// Resolve a previously saved selection: the tree is lazy-loaded, so a file
|
||||
// nested in subfolders is not in treeData on mount and its title cannot be
|
||||
// displayed. Walk the ancestor chain top-down and load each level.
|
||||
const resolvedValueRef = useRef<string>('');
|
||||
useEffect(() => {
|
||||
if (
|
||||
!value ||
|
||||
resolvedValueRef.current === value ||
|
||||
treeData.some((x) => x.id === value)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
resolvedValueRef.current = value;
|
||||
(async () => {
|
||||
const { data } = await fileManagerService.getAllParentFolder(
|
||||
{},
|
||||
`${value}/ancestors`,
|
||||
);
|
||||
const folders: IFile[] = data?.data?.parent_folders?.toReversed() ?? [];
|
||||
setTreeData((tree) => uniqBy(tree.concat(folders.map(toTreeNode)), 'id'));
|
||||
for (const folder of folders) {
|
||||
const ret = await fetchList(folder.id);
|
||||
if (ret.code === 0) {
|
||||
appendFiles(ret.data.files);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [value, treeData, fetchList, appendFiles]);
|
||||
|
||||
return { treeData, loadData };
|
||||
}
|
||||
|
||||
@@ -10,10 +10,7 @@ import {
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip';
|
||||
import { GenerateStatus, GenerateType } from '@/constants/knowledge';
|
||||
import {
|
||||
ITraceInfo,
|
||||
useGenerateStatus,
|
||||
} from '@/hooks/use-dataset-generate';
|
||||
import { ITraceInfo, useGenerateStatus } from '@/hooks/use-dataset-generate';
|
||||
|
||||
import { UpdateRunProgress } from './update-run-progress';
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ type UseWikiUpdateOptions = {
|
||||
|
||||
export function useWikiUpdate({ onUpdate }: UseWikiUpdateOptions = {}) {
|
||||
const { data, loading: queryLoading } = useFetchArtifactAlteration('wiki');
|
||||
const { runArtifactIndex, loading: mutationLoading } = useRunArtifactIndex('wiki');
|
||||
const { runArtifactIndex, loading: mutationLoading } =
|
||||
useRunArtifactIndex('wiki');
|
||||
|
||||
const newlyUploaded = data?.newly_uploaded ?? 0;
|
||||
const removed = data?.removed ?? 0;
|
||||
|
||||
@@ -2,10 +2,7 @@ import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { GenerateStatus, GenerateType } from '@/constants/knowledge';
|
||||
import {
|
||||
ITraceInfo,
|
||||
useGenerateStatus,
|
||||
} from '@/hooks/use-dataset-generate';
|
||||
import { ITraceInfo, useGenerateStatus } from '@/hooks/use-dataset-generate';
|
||||
import { IArtifact } from '@/interfaces/database/dataset';
|
||||
import { Trash2 } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
@@ -138,7 +138,13 @@ const ChatCard = forwardRef(function ChatCard(
|
||||
// resend with the card's model settings (llm_id, temperature, ...).
|
||||
const sendCardMessage = useCallback(
|
||||
({ message, messages }: { message: IMessage; messages?: IMessage[] }) =>
|
||||
sendMessage({ message, messages, ...form.getValues(), storeHistoryMessages: false, omitSessionId: true }),
|
||||
sendMessage({
|
||||
message,
|
||||
messages,
|
||||
...form.getValues(),
|
||||
storeHistoryMessages: false,
|
||||
omitSessionId: true,
|
||||
}),
|
||||
[sendMessage, form],
|
||||
);
|
||||
|
||||
@@ -181,7 +187,12 @@ const ChatCard = forwardRef(function ChatCard(
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
(): HandlePressEnterType => (params) =>
|
||||
handlePressEnter({ ...params, ...form.getValues(), storeHistoryMessages: false, omitSessionId: true }),
|
||||
handlePressEnter({
|
||||
...params,
|
||||
...form.getValues(),
|
||||
storeHistoryMessages: false,
|
||||
omitSessionId: true,
|
||||
}),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user