move-dialog.tsx
Overview
move-dialog.tsx defines a React functional component MoveDialog that provides a user interface dialog for moving files or folders within a file management system. The dialog presents a tree-based folder selector loaded asynchronously, allowing users to pick a destination folder to move an item to. Once a destination is selected, users can confirm the move operation.
Key functionalities include:
Displaying a modal dialog with a folder tree selector.
Dynamically loading folder nodes on demand (lazy loading).
Managing and validating user selection.
Invoking a callback with the selected folder ID on confirmation.
The component is designed to be reusable, localized via react-i18next, and integrates with custom UI components and hooks from the broader application ecosystem.
Detailed Explanation
MoveDialog Component
function MoveDialog({ hideModal, onOk, loading }: IModalProps<any>)
Purpose
MoveDialog renders a modal dialog that allows the user to select a folder to move an item into. It fetches folder data lazily and maintains the current selection state internally.
Props (IModalProps<any>)
hideModal:
() => void
Callback function to close the dialog/modal.onOk:
(value: any) => void
Callback function invoked when the user confirms the selection. Receives the selected folder ID as an argument.loading:
boolean
Controls the loading state of the confirmation button, typically to indicate an ongoing operation.
Internal State
treeValue:
number | string
Stores the currently selected folder's ID in the tree selector.treeData:
Array<TreeNodeType>
Holds the currently loaded nodes of the folder tree. Initially empty and populated as folders are loaded.
Hooks and Utilities Used
useTranslationfromreact-i18nextfor localization of UI strings (tfunction).useFetchPureFileList(custom hook) to fetch child folders given a folder ID.useStateanduseCallbackfrom React to manage state and memoize handlers.isEmptyfromlodashto check if there is a selection.
Internal Methods
onLoadData
const onLoadData = useCallback(
async ({ id }: TreeNodeType) => { ... },
[fetchList]
);
Purpose: Lazy-load child folders when a tree node is expanded.
Parameters:
id(string or number): The ID of the folder node to fetch children for.
Returns:
Promise<void>Implementation details:
CallsfetchList(id)to retrieve child files/folders of the given folder ID. Filters the results to only include folders, maps these into tree nodes with necessary properties (id,parentId,title,isLeaf), and appends them to the existingtreeData.
handleSubmit
const handleSubmit = useCallback(() => {
onOk?.(treeValue);
}, [onOk, treeValue]);
Purpose: Triggered when the user confirms their folder selection.
Parameters: None.
Returns: None.
Behavior: Calls the
onOkcallback with the currently selected folder ID (treeValue).
JSX Structure and Usage
<Dialog open onOpenChange={hideModal}>
<DialogContent>
<DialogHeader>
<DialogTitle>{t('common.move')}</DialogTitle>
</DialogHeader>
<AsyncTreeSelect
treeData={treeData}
value={treeValue}
onChange={setTreeValue}
loadData={onLoadData}
/>
<DialogFooter>
<ButtonLoading
type="submit"
onClick={handleSubmit}
disabled={isEmpty(treeValue)}
loading={loading}
>
{t('common.save')}
</ButtonLoading>
</DialogFooter>
</DialogContent>
</Dialog>
The component renders a modal dialog (
Dialog).Inside, a localized title "Move" is shown.
The main interactive component is
AsyncTreeSelect— a tree selector UI that supports asynchronous loading (loadData).The footer contains a loading button (
ButtonLoading) for saving the selection. The button is disabled until a folder is selected.The dialog closes when
hideModalis triggered.
Important Implementation Details
Lazy Loading of Tree Nodes:
The folder tree loads children only when a node is expanded, reducing initial load time and memory usage. This is implemented in theonLoadDatacallback that concatenates newly fetched folders totreeData.Tree Node Structure:
Each folder node has the following shape:{ id: string | number, parentId: string | number, title: string, isLeaf: boolean }isLeafindicates whether the folder has any child folders, which controls UI expandability.Localization Support:
The component uses thet()function for all user-facing text, enabling multilingual support.Reusability:
The component accepts callbacks and loading state via props to integrate flexibly with any parent component or workflow.
Interaction with Other System Parts
AsyncTreeSelectComponent:
This component is imported from a UI library and provides the tree selection UI with asynchronous node loading. It consumes thetreeData,value, andloadDataprops.useFetchPureFileListHook:
This custom hook provides thefetchListfunction to fetch files/folders from the backend or data store. It abstracts the data-fetching logic from the UI.ButtonLoadingandDialogComponents:
Custom UI components from the project UI library that provide consistent styling and behavior for buttons and modal dialogs.Localization (
react-i18next):
Enables the component to show translated strings based on the user's language preference.Parent Components:
The parent component controls when to show/hide the dialog and handles the confirmation action viaonOk.
Usage Example
function ParentComponent() {
const [showMoveDialog, setShowMoveDialog] = useState(false);
const [loading, setLoading] = useState(false);
const handleMove = (targetFolderId: string | number) => {
setLoading(true);
// Perform move operation here...
moveFileToFolder(selectedFileId, targetFolderId).then(() => {
setLoading(false);
setShowMoveDialog(false);
});
};
return (
<>
<button onClick={() => setShowMoveDialog(true)}>Move File</button>
{showMoveDialog && (
<MoveDialog
hideModal={() => setShowMoveDialog(false)}
onOk={handleMove}
loading={loading}
/>
)}
</>
);
}
Mermaid Diagram
componentDiagram
MoveDialog --> AsyncTreeSelect
MoveDialog --> ButtonLoading
MoveDialog --> Dialog
MoveDialog --> useFetchPureFileList
MoveDialog --> useTranslation
component MoveDialog {
+hideModal: () => void
+onOk: (value: any) => void
+loading: boolean
-treeValue: string | number
-treeData: Array<TreeNodeType>
-onLoadData(node: TreeNodeType): Promise<void>
-handleSubmit(): void
}
component AsyncTreeSelect {
+treeData: Array<TreeNodeType>
+value: string | number
+onChange(value): void
+loadData(node: TreeNodeType): Promise<void>
}
component ButtonLoading {
+onClick(): void
+disabled: boolean
+loading: boolean
}
component Dialog {
+open: boolean
+onOpenChange: () => void
}
Summary
The move-dialog.tsx file implements a modal dialog component for selecting a target folder to move files into. It leverages asynchronous tree loading to efficiently handle large folder structures, maintains internal state for user selection, and integrates with application-specific UI components and data-fetching hooks. This component encapsulates the move dialog's UI and logic, enabling consistent and localized user experiences across the file management system.