Fix: allow to move to root directory (#21969)

This commit is contained in:
Wang Qi authored and GitHub committed 2026-11-04 17:15:44 +08:00
1 parent 8b8ccbf478
commit d6a22acfaf
2 files changed
+27 -3

No files matched your search

+21 -2
View File
@@ -6,7 +6,14 @@ import {
import { cn } from '@/lib/utils';
import { isEmpty } from 'lodash';
import { ChevronDown, ChevronRight, Loader2, X } from 'lucide-react';
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react';
import {
ReactNode,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { useTranslation } from 'react-i18next';
import { Button } from './button';
import { SearchInput } from './input';
@@ -28,6 +35,7 @@ type AsyncTreeSelectProps = {
onChange?(value: TreeId): void;
loadData?(node: TreeNodeType): Promise<any>;
canSelect?(node: TreeNodeType): boolean;
defaultExpandRoot?: boolean;
// When false, hides the clear button and disables re-click deselection.
allowClear?: boolean;
};
@@ -45,6 +53,7 @@ export function AsyncTreeSelect({
loadData,
onChange,
canSelect,
defaultExpandRoot = false,
allowClear = true,
}: AsyncTreeSelectProps) {
const [open, setOpen] = useState(false);
@@ -52,6 +61,7 @@ export function AsyncTreeSelect({
const { t } = useTranslation();
const [expandedKeys, setExpandedKeys] = useState<TreeId[]>([]);
const rootExpansionInitialized = useRef(false);
const [loadingId, setLoadingId] = useState<TreeId>('');
const selectedTitle = useMemo(() => {
@@ -246,8 +256,17 @@ export function AsyncTreeSelect({
useEffect(() => {
if (isEmpty(treeData)) {
loadData?.({ id: '', parentId: '', title: '' });
} else if (defaultExpandRoot && !rootExpansionInitialized.current) {
rootExpansionInitialized.current = true;
setExpandedKeys(
treeData
.filter((node) =>
treeData.every((parent) => node.parentId !== parent.id),
)
.map((node) => node.id),
);
}
}, [treeData, loadData]);
}, [treeData, loadData, defaultExpandRoot]);
return (
<Popover open={open} onOpenChange={handleOpenChange}>
+6 -1
View File
@@ -24,15 +24,19 @@ export function MoveDialog({ hideModal, onOk, loading }: IModalProps<any>) {
const [treeValue, setTreeValue] = useState<number | string>();
const [treeData, setTreeData] = useState([]);
const [treeData, setTreeData] = useState<TreeNodeType[]>([]);
const onLoadData = useCallback(
async ({ id }: TreeNodeType) => {
const ret = await fetchList({ parentId: id as string });
if (ret.code === 0) {
setTreeData((tree) => {
const rootNodes: TreeNodeType[] = id
? []
: [{ id: ret.data.parent_folder.id, parentId: '', title: '/' }];
return uniqBy(
tree.concat(
rootNodes,
ret.data.files
.filter((x: IFile) => x.type === 'folder')
.map((x: IFile) => ({
@@ -65,6 +69,7 @@ export function MoveDialog({ hideModal, onOk, loading }: IModalProps<any>) {
</DialogHeader>
<div>
<AsyncTreeSelect
defaultExpandRoot
treeData={treeData}
value={treeValue}
onChange={setTreeValue}