|
@@ -1,5 +1,5 @@
|
|
|
import type { FC } from 'react';
|
|
import type { FC } from 'react';
|
|
|
-import { useCallback, useMemo } from 'react';
|
|
|
|
|
|
|
+import { useCallback, useEffect, useMemo } from 'react';
|
|
|
import { useTree } from '@headless-tree/react';
|
|
import { useTree } from '@headless-tree/react';
|
|
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
|
import { useTranslation } from 'next-i18next';
|
|
import { useTranslation } from 'next-i18next';
|
|
@@ -11,8 +11,6 @@ import { useSWRxRootPage } from '~/stores/page-listing';
|
|
|
import { ROOT_PAGE_VIRTUAL_ID } from '../constants/_inner';
|
|
import { ROOT_PAGE_VIRTUAL_ID } from '../constants/_inner';
|
|
|
import {
|
|
import {
|
|
|
useAutoExpandAncestors,
|
|
useAutoExpandAncestors,
|
|
|
- useCheckboxChangeNotification,
|
|
|
|
|
- useCheckboxState,
|
|
|
|
|
useDataLoader,
|
|
useDataLoader,
|
|
|
useExpandParentOnCreate,
|
|
useExpandParentOnCreate,
|
|
|
useScrollToSelectedItem,
|
|
useScrollToSelectedItem,
|
|
@@ -20,7 +18,6 @@ import {
|
|
|
useTreeItemHandlers,
|
|
useTreeItemHandlers,
|
|
|
useTreeRevalidation,
|
|
useTreeRevalidation,
|
|
|
} from '../hooks/_inner';
|
|
} from '../hooks/_inner';
|
|
|
-import { usePageDnd } from '../hooks/use-page-dnd';
|
|
|
|
|
import { useSocketUpdateDescCount } from '../hooks/use-socket-update-desc-count';
|
|
import { useSocketUpdateDescCount } from '../hooks/use-socket-update-desc-count';
|
|
|
import type { TreeItemProps } from '../interfaces';
|
|
import type { TreeItemProps } from '../interfaces';
|
|
|
import { useTriggerTreeRebuild } from '../states/_inner';
|
|
import { useTriggerTreeRebuild } from '../states/_inner';
|
|
@@ -84,18 +81,16 @@ export const ItemsTree: FC<Props> = (props: Props) => {
|
|
|
const { getItemName, isItemFolder, handleRename, creatingParentId } =
|
|
const { getItemName, isItemFolder, handleRename, creatingParentId } =
|
|
|
useTreeItemHandlers(triggerTreeRebuild);
|
|
useTreeItemHandlers(triggerTreeRebuild);
|
|
|
|
|
|
|
|
- // Configure tree features based on options
|
|
|
|
|
- const features = useTreeFeatures({
|
|
|
|
|
|
|
+ // Configure tree features and get checkbox state and D&D handlers
|
|
|
|
|
+ const { features, checkboxProperties, dndProperties } = useTreeFeatures({
|
|
|
enableRenaming,
|
|
enableRenaming,
|
|
|
enableCheckboxes,
|
|
enableCheckboxes,
|
|
|
enableDragAndDrop,
|
|
enableDragAndDrop,
|
|
|
|
|
+ initialCheckedItems,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // Page move (drag and drop) handlers
|
|
|
|
|
- const { canDrag, canDrop, onDrop, renderDragLine } = usePageDnd(enableDragAndDrop);
|
|
|
|
|
-
|
|
|
|
|
- // Subscribe to Socket.io UpdateDescCount events
|
|
|
|
|
- useSocketUpdateDescCount();
|
|
|
|
|
|
|
+ const { setCheckedItems, createNotifyEffect } = checkboxProperties;
|
|
|
|
|
+ const { canDrag, canDrop, onDrop, renderDragLine } = dndProperties;
|
|
|
|
|
|
|
|
// Wrap onDrop to show toast notifications
|
|
// Wrap onDrop to show toast notifications
|
|
|
const handleDrop = useCallback(
|
|
const handleDrop = useCallback(
|
|
@@ -112,12 +107,6 @@ export const ItemsTree: FC<Props> = (props: Props) => {
|
|
|
[onDrop, t],
|
|
[onDrop, t],
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- // Manage checkbox state (must be called before useTree to get setCheckedItems)
|
|
|
|
|
- const { checkedItemIds, setCheckedItems } = useCheckboxState({
|
|
|
|
|
- enabled: enableCheckboxes,
|
|
|
|
|
- initialCheckedItems,
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
// Stable initial state
|
|
// Stable initial state
|
|
|
// biome-ignore lint/correctness/useExhaustiveDependencies: initialCheckedItems is intentionally not in deps to avoid reinitializing on every change
|
|
// biome-ignore lint/correctness/useExhaustiveDependencies: initialCheckedItems is intentionally not in deps to avoid reinitializing on every change
|
|
|
const initialState = useMemo(
|
|
const initialState = useMemo(
|
|
@@ -146,17 +135,19 @@ export const ItemsTree: FC<Props> = (props: Props) => {
|
|
|
canDrag,
|
|
canDrag,
|
|
|
canDrop,
|
|
canDrop,
|
|
|
onDrop: handleDrop,
|
|
onDrop: handleDrop,
|
|
|
- canDropInbetween: false, // No reordering, only drop as child
|
|
|
|
|
|
|
+ canDropInbetween: false,
|
|
|
}),
|
|
}),
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// Notify parent when checked items change
|
|
// Notify parent when checked items change
|
|
|
- useCheckboxChangeNotification({
|
|
|
|
|
- enabled: enableCheckboxes,
|
|
|
|
|
- checkedItemIds,
|
|
|
|
|
|
|
+ // biome-ignore lint/correctness/useExhaustiveDependencies: createNotifyEffect already includes checkedItemIds in its closure
|
|
|
|
|
+ useEffect(createNotifyEffect(tree, onCheckedItemsChange), [
|
|
|
|
|
+ createNotifyEffect,
|
|
|
tree,
|
|
tree,
|
|
|
- onCheckedItemsChange,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ // Subscribe to Socket.io UpdateDescCount events
|
|
|
|
|
+ useSocketUpdateDescCount();
|
|
|
|
|
|
|
|
// Handle tree revalidation and items count tracking
|
|
// Handle tree revalidation and items count tracking
|
|
|
useTreeRevalidation({ tree, triggerTreeRebuild });
|
|
useTreeRevalidation({ tree, triggerTreeRebuild });
|
|
@@ -232,7 +223,7 @@ export const ItemsTree: FC<Props> = (props: Props) => {
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
})}
|
|
})}
|
|
|
- {/* Drag line indicator (rendered by usePageDnd when D&D is enabled) */}
|
|
|
|
|
|
|
+ {/* Drag line indicator (rendered by dndProperties when D&D is enabled) */}
|
|
|
{renderDragLine(tree)}
|
|
{renderDragLine(tree)}
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|