@adventurelabs/scout-core
Version:
Core utilities and helpers for Adventure Labs Scout applications
154 lines (153 loc) • 5.7 kB
JavaScript
import { useSelector } from "react-redux";
import { useInfiniteSessionsByHerd, useInfiniteEventsByHerd, useInfiniteArtifactsByHerd, } from "./useInfiniteQuery";
/**
* Comprehensive hook for accessing herd data from both global store and RTK Query
*
* @param herdId - The herd ID to fetch data for
* @param options - Configuration options for data fetching
* @returns Complete herd data with both structural and paginated content
*
* @example
* ```tsx
* const {
* herd,
* devices,
* events,
* sessions,
* artifacts,
* sessionSummaries
* } = useHerdData(123, {
* supabase,
* eventsLimit: 20,
* enableSessions: true
* });
*
* // Use structural data from global store
* console.log(herd.name, devices.length);
*
* // Use paginated data from RTK Query
* console.log(events.items.length, events.hasMore);
* if (events.hasMore) {
* events.loadMore();
* }
*
* // Use session summaries
* console.log(sessionSummaries?.total_sessions, sessionSummaries?.total_distance_meters);
* ```
*/
export const useHerdData = (herdId, options) => {
const { sessionsLimit = 20, eventsLimit = 20, artifactsLimit = 20, enableSessions = true, enableEvents = true, enableArtifacts = true, supabase, } = options;
// Get structural data from global store
const herdModule = useSelector((state) => state.scout.herd_modules.find((hm) => hm.herd.id === herdId));
// RTK Query infinite data hooks
const sessionsQuery = useInfiniteSessionsByHerd(herdId, {
limit: sessionsLimit,
enabled: enableSessions,
supabase,
});
const eventsQuery = useInfiniteEventsByHerd(herdId, {
limit: eventsLimit,
enabled: enableEvents,
supabase,
});
const artifactsQuery = useInfiniteArtifactsByHerd(herdId, {
limit: artifactsLimit,
enabled: enableArtifacts,
supabase,
});
// Overall loading state - true if any enabled query is loading for the first time
const isInitialLoading = (enableSessions &&
sessionsQuery.isLoading &&
sessionsQuery.items.length === 0) ||
(enableEvents && eventsQuery.isLoading && eventsQuery.items.length === 0) ||
(enableArtifacts &&
artifactsQuery.isLoading &&
artifactsQuery.items.length === 0);
// Overall error state - true if any enabled query has an error
const hasAnyError = (enableSessions && !!sessionsQuery.error) ||
(enableEvents && !!eventsQuery.error) ||
(enableArtifacts && !!artifactsQuery.error);
return {
// Global store structural data
herdModule,
herd: herdModule?.herd,
devices: herdModule?.devices || [],
zones: herdModule?.zones || [],
plans: herdModule?.plans || [],
layers: herdModule?.layers || [],
providers: herdModule?.providers || [],
labels: herdModule?.labels || [],
userRoles: herdModule?.user_roles || null,
sessionSummaries: herdModule?.session_summaries || null,
timestampLastRefreshed: herdModule?.timestamp_last_refreshed || null,
// RTK Query paginated data
sessions: {
items: sessionsQuery.items,
isLoading: sessionsQuery.isLoading,
isLoadingMore: sessionsQuery.isLoadingMore,
hasMore: sessionsQuery.hasMore,
loadMore: sessionsQuery.loadMore,
refetch: sessionsQuery.refetch,
error: sessionsQuery.error,
},
events: {
items: eventsQuery.items,
isLoading: eventsQuery.isLoading,
isLoadingMore: eventsQuery.isLoadingMore,
hasMore: eventsQuery.hasMore,
loadMore: eventsQuery.loadMore,
refetch: eventsQuery.refetch,
error: eventsQuery.error,
},
artifacts: {
items: artifactsQuery.items,
isLoading: artifactsQuery.isLoading,
isLoadingMore: artifactsQuery.isLoadingMore,
hasMore: artifactsQuery.hasMore,
loadMore: artifactsQuery.loadMore,
refetch: artifactsQuery.refetch,
error: artifactsQuery.error,
},
// Overall states
isInitialLoading,
hasAnyError,
};
};
/**
* Hook for getting just the structural herd data from global store
* Useful when you only need basic herd info without paginated content
*/
export const useHerdStructure = (herdId) => {
const herdModule = useSelector((state) => state.scout.herd_modules.find((hm) => hm.herd.id === herdId));
return {
herdModule,
herd: herdModule?.herd,
devices: herdModule?.devices || [],
zones: herdModule?.zones || [],
plans: herdModule?.plans || [],
layers: herdModule?.layers || [],
providers: herdModule?.providers || [],
labels: herdModule?.labels || [],
userRoles: herdModule?.user_roles || null,
sessionSummaries: herdModule?.session_summaries || null,
timestampLastRefreshed: herdModule?.timestamp_last_refreshed || null,
};
};
/**
* Hook for getting all herd structures (without paginated data)
* Useful for dashboard/overview components
*/
export const useAllHerds = () => {
const herdModules = useSelector((state) => state.scout.herd_modules);
return {
herdModules,
herds: herdModules.map((hm) => hm.herd),
totalHerds: herdModules.length,
totalDevices: herdModules.reduce((sum, hm) => sum + hm.devices.length, 0),
sessionSummaries: herdModules.map((hm) => ({
herdId: hm.herd.id,
herdSlug: hm.herd.slug,
summaries: hm.session_summaries,
})),
};
};