Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { useCallback } from "react";
import { useInfiniteQuery } from "@tanstack/react-query";
import { queryClient } from "@humansignal/core/lib/utils/query-client";
import { isActive, FF_DM_FILTER_MEMBERS } from "@humansignal/core/lib/utils/feature-flags";
 
// Extend Window interface to include DataManager properties
declare global {
  interface Window {
    DM?: {
      store?: {
        apiCall: (method: string, params: any) => Promise<any>;
      };
      apiCall?: (method: string, params: any) => Promise<any>;
    };
  }
}
 
interface APIUser {
  id: number;
  username: string;
  first_name: string;
  last_name: string;
  email: string;
}
 
interface UsersResponse {
  results: APIUser[];
  count: number;
}
 
// DataManager-style user fetching with pagination using React Query
export const useDataManagerUsers = (
  projectId: string,
  pageSize = 20,
  isDeleted = false,
  role = null,
  search = null,
  selectedValue = null,
) => {
  if (!isActive(FF_DM_FILTER_MEMBERS)) return null;
 
  const queryKey = ["users", projectId, pageSize, isDeleted, role, search, selectedValue];
 
  const { data, isLoading, isError, error, refetch, hasNextPage, fetchNextPage, isFetchingNextPage } = useInfiniteQuery(
    {
      queryKey,
      queryFn: async ({ pageParam = 1 }) => {
        // Use the correct DataManager API pattern - window.DM is the AppStore
        const store = window?.DM?.store || window?.DM;
 
        if (!store) {
          throw new Error("DataManager store not available");
        }
 
        const params: any = {
          page: pageParam,
          page_size: pageSize,
          project: projectId,
          is_deleted: isDeleted,
        };
 
        if (role) params.role = role;
        if (search) params.search = search;
        if (selectedValue) params.selected_value = selectedValue;
        const response = await store.apiCall?.("users", params);
 
        if (!response) {
          throw new Error("No users found in response or response is invalid");
        }
        if (search && selectedValue && response.count) {
          const users: any = queryClient.getQueryData([
            "users",
            projectId,
            pageSize,
            isDeleted,
            role,
            null,
            selectedValue,
          ])?.pages?.[0];
          if (users) {
            const selectedUser = users.find((user: any) => user.id === selectedValue);
            const results = [...response.filter((user: any) => user.id !== selectedValue), selectedUser];
            results.count = results.length;
            return results;
          }
        }
 
        return response as UsersResponse;
      },
      getNextPageParam: (lastPage, allPages) => {
        const totalCount = lastPage.count || 0;
        const currentPage = allPages.length;
        const hasMore = currentPage * pageSize < totalCount;
        return hasMore ? currentPage + 1 : undefined;
      },
      enabled: !!projectId,
      staleTime: 5 * 60 * 1000, // 5 minutes
      cacheTime: 10 * 60 * 1000, // 10 minutes
    },
  );
 
  // Flatten all pages into a single array
  const users = data?.pages.flatMap((page) => page.results ?? page) ?? [];
  const total = data?.pages[0]?.count ?? 0;
 
  const loadMore = useCallback(() => {
    if (!isFetchingNextPage && hasNextPage) {
      fetchNextPage();
    }
  }, [fetchNextPage, isFetchingNextPage, hasNextPage]);
 
  return {
    users,
    isLoading,
    isError,
    error,
    hasMore: hasNextPage,
    total,
    loadMore,
    refetch,
    isFetchingNextPage,
  };
};