in uui-core/src/data/processing/views/tree/hooks/strategies/asyncTree/useAsyncTree.ts [13:173]
export function useAsyncTree<TItem, TId, TFilter = any>(
props: AsyncTreeProps<TItem, TId, TFilter>,
deps: [],
): UseTreeResult<TItem, TId, TFilter> {
const {
getId,
complexIds,
getParentId,
getFilter,
getSearchFields,
sortBy,
sortSearchByRelevance = true,
rowOptions,
getRowOptions,
setDataSourceState,
isFoldedByDefault,
cascadeSelection,
showSelectedOnly,
patch,
isDeleted,
getNewItemPosition,
itemsStatusMap,
selectAll,
isLoaded,
getItemTemporaryOrder,
fixItemBetweenSortings,
} = props;
const { itemsMap, setItems } = useItemsStorage({
itemsMap: props.itemsMap,
setItems: props.setItems,
params: { getId, complexIds },
});
const [isForceReload, setIsForceReload] = useState(false);
const baseTree = useMemo(() => {
if (isLoaded) {
return TreeState.createFromItemsMap(itemsMap, setItems, { getId, getParentId, complexIds });
}
return TreeState.blank({ getId, getParentId, complexIds }, itemsMap, setItems);
}, [...deps, isLoaded]);
const [incommingTree, setIncommingTree] = useState(baseTree);
const prevIsForceReload = usePrevious(isForceReload);
const dataSourceState = useDataSourceStateWithDefaults({ dataSourceState: props.dataSourceState });
useEffect(() => {
setIncommingTree(baseTree);
}, [baseTree]);
const { tree: treeWithData, itemsStatusCollector, isLoaded: isTreeLoaded, isLoading, isFetching } = useLoadData({
getId,
complexIds,
api: () => props.api().then((items) => ({ items })),
tree: incommingTree,
dataSourceState: {
visibleCount: dataSourceState.visibleCount,
topIndex: dataSourceState.topIndex,
checked: dataSourceState.checked,
selectedId: dataSourceState.selectedId,
},
itemsStatusCollector: props.itemsStatusCollector,
forceReload: isForceReload,
onForceReloadComplete: () => setIsForceReload(false),
showSelectedOnly,
isLoaded,
itemsStatusMap,
}, [...deps, isForceReload, incommingTree]);
const actualTree = useActualItemsStorage({ tree: treeWithData, itemsMap, setItems });
const prevIsFetching = usePrevious(isFetching);
useEffect(() => {
if (prevIsForceReload !== isForceReload && isForceReload
&& prevIsFetching !== isFetching && !isFetching) {
setIsForceReload(false);
}
}, [actualTree]);
const reload = useCallback(() => {
setIncommingTree(TreeState.blank({ getId, getParentId, complexIds }, itemsMap, setItems));
setIsForceReload(true);
}, [setIsForceReload]);
const isTreeLoading = !isTreeLoaded || isLoading || isFetching;
const filteredTree = useFilterTree(
{ tree: actualTree, getFilter, dataSourceState, isLoading: isTreeLoading },
[actualTree, isTreeLoading],
);
const sortTree = useSortTree(
{ tree: filteredTree, sortBy, dataSourceState, isLoading: isTreeLoading },
[filteredTree, isTreeLoading],
);
const searchTree = useSearchTree(
{
tree: sortTree,
getSearchFields,
sortSearchByRelevance,
dataSourceState,
isLoading: isTreeLoading,
},
[sortTree, isTreeLoading],
);
const treeWithSelectedOnly = useSelectedOnlyTree({
tree: searchTree,
dataSourceState,
isLoading: isTreeLoading,
}, [searchTree, isTreeLoading]);
const treeWithNewItemsMap = useActualItemsStorage({
tree: treeWithSelectedOnly,
itemsMap,
setItems,
});
const { tree, applyPatch } = usePatchTree({
tree: treeWithNewItemsMap,
patch: showSelectedOnly ? null : patch,
isDeleted,
getNewItemPosition,
getItemTemporaryOrder,
fixItemBetweenSortings,
sorting: dataSourceState.sorting,
sortBy,
});
const totalCount = useMemo(() => {
const { totalCount: rootTotalCount } = tree.visible.getItems(undefined);
return rootTotalCount ?? tree.visible.getTotalCount?.() ?? 0;
}, [tree.visible]);
return {
tree: showSelectedOnly ? tree.selectedOnly : tree.visible,
treeWithoutPatch: treeWithNewItemsMap.visible,
selectionTree: tree.full,
reload,
totalCount,
getItemStatus: itemsStatusCollector.getItemStatus(itemsMap),
rowOptions,
getRowOptions,
getParentId,
getId,
dataSourceState,
setDataSourceState,
isFoldedByDefault,
cascadeSelection,
showSelectedOnly,
selectAll,
applyPatch,
isLoading,
isFetching,
};
}