UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

219 lines 9.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useCollectionsActions = useCollectionsActions; const react_1 = require("react"); const hooks_1 = require("../../store/hooks"); const collectionsSlice_1 = require("../../store/slices/collectionsSlice"); const collectionsApi_1 = require("../../store/api/collectionsApi"); const handleError_1 = require("../../utils/handleError"); /** * Redux-powered hook that provides all collection actions * This replaces the individual hooks and provides a centralized way to manage collections */ function useCollectionsActions() { const dispatch = (0, hooks_1.useReplykeDispatch)(); // Use a ref so removeFromCollection can read the latest entities without being in deps const entitiesByCollectionId = (0, hooks_1.useReplykeSelector)((state) => state.replyke.collections.entitiesByCollectionId); const entitiesByCollectionIdRef = (0, react_1.useRef)(entitiesByCollectionId); entitiesByCollectionIdRef.current = entitiesByCollectionId; // RTK Query hooks const [fetchRootCollectionQuery] = (0, collectionsApi_1.useLazyFetchRootCollectionQuery)(); const [fetchSubCollectionsQuery] = (0, collectionsApi_1.useLazyFetchSubCollectionsQuery)(); const [createCollectionMutation] = (0, collectionsApi_1.useCreateCollectionMutation)(); const [updateCollectionMutation] = (0, collectionsApi_1.useUpdateCollectionMutation)(); const [deleteCollectionMutation] = (0, collectionsApi_1.useDeleteCollectionMutation)(); const [addToCollectionMutation] = (0, collectionsApi_1.useAddToCollectionMutation)(); const [removeFromCollectionMutation] = (0, collectionsApi_1.useRemoveFromCollectionMutation)(); // Navigation actions const openCollectionAction = (0, react_1.useCallback)((collection) => { dispatch((0, collectionsSlice_1.openCollection)(collection)); }, [dispatch]); const goBackAction = (0, react_1.useCallback)(() => { dispatch((0, collectionsSlice_1.goBack)()); }, [dispatch]); const goToRootAction = (0, react_1.useCallback)(() => { dispatch((0, collectionsSlice_1.goToRoot)()); }, [dispatch]); // Fetch root collection const fetchRootCollection = (0, react_1.useCallback)(async ({ projectId }) => { if (!projectId) { console.warn("Can't fetch root collection without projectId."); return; } dispatch((0, collectionsSlice_1.setLoading)(true)); try { const result = await fetchRootCollectionQuery({ projectId }).unwrap(); if (result) { // Set parentId to null for root collection const rootCollection = { ...result, parentId: null }; dispatch((0, collectionsSlice_1.setCurrentCollection)(rootCollection)); } } catch (err) { (0, handleError_1.handleError)(err, "Failed fetching root collection"); dispatch((0, collectionsSlice_1.handleError)()); } finally { dispatch((0, collectionsSlice_1.setLoading)(false)); } }, [dispatch, fetchRootCollectionQuery]); // Fetch sub-collections const fetchSubCollections = (0, react_1.useCallback)(async ({ projectId, collectionId }) => { if (!projectId || !collectionId) { console.warn("Can't fetch sub-collections without projectId and collectionId."); return; } dispatch((0, collectionsSlice_1.setLoading)(true)); try { const result = await fetchSubCollectionsQuery({ projectId, collectionId }).unwrap(); if (result) { dispatch((0, collectionsSlice_1.setSubCollections)({ collections: result, parentCollectionId: collectionId })); } } catch (err) { (0, handleError_1.handleError)(err, "Failed fetching sub-collections"); dispatch((0, collectionsSlice_1.handleError)()); } finally { dispatch((0, collectionsSlice_1.setLoading)(false)); } }, [dispatch, fetchSubCollectionsQuery]); // Create collection const createCollection = (0, react_1.useCallback)(async ({ projectId, parentCollectionId, collectionName, }) => { if (!projectId || !parentCollectionId || !collectionName) { console.error("Missing required parameters for creating collection."); return; } try { const result = await createCollectionMutation({ projectId, parentCollectionId, collectionName, }).unwrap(); if (result) { dispatch((0, collectionsSlice_1.addNewCollectionAndNavigate)(result)); } } catch (err) { (0, handleError_1.handleError)(err, "Failed to create collection"); } }, [createCollectionMutation, dispatch]); // Update collection const updateCollection = (0, react_1.useCallback)(async ({ projectId, collectionId, update, }) => { if (!projectId || !collectionId) { console.error("Missing required parameters for updating collection."); return; } try { const result = await updateCollectionMutation({ projectId, collectionId, update, }).unwrap(); if (result) { // Check if it's the current collection or a sub-collection dispatch((0, collectionsSlice_1.updateCollectionInSubCollections)(result)); } } catch (err) { (0, handleError_1.handleError)(err, "Failed to update collection"); } }, [updateCollectionMutation, dispatch]); // Delete collection const deleteCollection = (0, react_1.useCallback)(async ({ projectId, collection, }) => { if (!projectId || !collection) { console.error("Missing required parameters for deleting collection."); return; } try { await deleteCollectionMutation({ projectId, collectionId: collection.id, }).unwrap(); dispatch((0, collectionsSlice_1.handleCollectionDeletion)({ collectionId: collection.id, parentId: collection.parentId })); } catch (err) { (0, handleError_1.handleError)(err, "Failed to delete collection"); } }, [deleteCollectionMutation, dispatch]); // Add entity to collection — optimistically prepends to Redux state, reverts on error const addToCollection = (0, react_1.useCallback)(async ({ projectId, collectionId, entity, }) => { if (!projectId || !collectionId || !entity?.id) { console.error("Missing required parameters for adding to collection."); return; } dispatch((0, collectionsSlice_1.prependCollectionEntity)({ collectionId, entity })); try { await addToCollectionMutation({ projectId, collectionId, entityId: entity.id, }).unwrap(); } catch (err) { dispatch((0, collectionsSlice_1.removeCollectionEntity)({ collectionId, entityId: entity.id })); (0, handleError_1.handleError)(err, "Failed to add entity to collection"); throw err; } }, [addToCollectionMutation, dispatch]); // Remove entity from collection — optimistically removes from Redux state, reverts on error const removeFromCollection = (0, react_1.useCallback)(async ({ projectId, collectionId, entityId, }) => { if (!projectId || !collectionId || !entityId) { console.error("Missing required parameters for removing from collection."); return; } const currentList = entitiesByCollectionIdRef.current[collectionId] ?? []; const originalIndex = currentList.findIndex((e) => e.id === entityId); const entityToRestore = originalIndex !== -1 ? currentList[originalIndex] : undefined; dispatch((0, collectionsSlice_1.removeCollectionEntity)({ collectionId, entityId })); try { await removeFromCollectionMutation({ projectId, collectionId, entityId, }).unwrap(); } catch (err) { if (entityToRestore) { dispatch((0, collectionsSlice_1.insertCollectionEntityAt)({ collectionId, entity: entityToRestore, index: originalIndex })); } (0, handleError_1.handleError)(err, "Failed to remove entity from collection"); throw err; } }, [removeFromCollectionMutation, dispatch]); // Reset collections const resetCollectionsAction = (0, react_1.useCallback)(() => { dispatch((0, collectionsSlice_1.resetCollections)()); }, [dispatch]); return (0, react_1.useMemo)(() => ({ // Navigation openCollection: openCollectionAction, goBack: goBackAction, goToRoot: goToRootAction, // Data fetching fetchRootCollection, fetchSubCollections, // CRUD operations createCollection, updateCollection, deleteCollection, addToCollection, removeFromCollection, // Utility resetCollections: resetCollectionsAction, }), [ openCollectionAction, goBackAction, goToRootAction, fetchRootCollection, fetchSubCollections, createCollection, updateCollection, deleteCollection, addToCollection, removeFromCollection, resetCollectionsAction, ]); } exports.default = useCollectionsActions; //# sourceMappingURL=useCollectionsActions.js.map