@nimbleflux/fluxbase-sdk-react 2026.3.6 → 2026.3.7-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nvmrc +1 -1
- package/package.json +10 -10
- package/src/index.ts +15 -0
- package/src/use-admin-auth.ts +1 -1
- package/src/use-admin-hooks.ts +122 -113
- package/src/use-auth-config.ts +1 -1
- package/src/use-auth.ts +1 -1
- package/src/use-captcha.ts +2 -2
- package/src/use-client-keys.ts +66 -51
- package/src/use-graphql.ts +14 -9
- package/src/use-query.ts +73 -62
- package/src/use-realtime.ts +6 -2
- package/src/use-saml.ts +1 -1
- package/src/use-storage.ts +4 -2
- package/src/use-table-export.ts +178 -139
- package/src/use-tenant.ts +311 -0
- package/src/use-users.ts +56 -55
- package/tsconfig.json +1 -0
- package/tsup.config.ts +1 -1
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hooks for multi-tenant management
|
|
3
|
+
*
|
|
4
|
+
* @module use-tenant
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useEffect, useCallback } from "react";
|
|
8
|
+
import { useFluxbaseClient } from "./context";
|
|
9
|
+
import type {
|
|
10
|
+
Tenant,
|
|
11
|
+
TenantWithRole,
|
|
12
|
+
CreateTenantOptions,
|
|
13
|
+
UpdateTenantOptions,
|
|
14
|
+
} from "@nimbleflux/fluxbase-sdk";
|
|
15
|
+
|
|
16
|
+
export interface UseTenantsOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Whether to automatically fetch tenants on mount
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
autoFetch?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface UseTenantsReturn {
|
|
25
|
+
/**
|
|
26
|
+
* Array of tenants the user has access to
|
|
27
|
+
*/
|
|
28
|
+
tenants: TenantWithRole[];
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Whether tenants are being fetched
|
|
32
|
+
*/
|
|
33
|
+
isLoading: boolean;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Any error that occurred
|
|
37
|
+
*/
|
|
38
|
+
error: Error | null;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Refetch tenants
|
|
42
|
+
*/
|
|
43
|
+
refetch: () => Promise<void>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a new tenant (instance admin only)
|
|
47
|
+
*/
|
|
48
|
+
createTenant: (options: CreateTenantOptions) => Promise<Tenant>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Update a tenant (tenant admin only)
|
|
52
|
+
*/
|
|
53
|
+
updateTenant: (id: string, options: UpdateTenantOptions) => Promise<Tenant>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Delete a tenant (instance admin only)
|
|
57
|
+
*/
|
|
58
|
+
deleteTenant: (id: string) => Promise<void>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Set the current tenant context
|
|
62
|
+
*/
|
|
63
|
+
setCurrentTenant: (tenantId: string | undefined) => void;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get the current tenant ID
|
|
67
|
+
*/
|
|
68
|
+
currentTenantId: string | undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Hook for managing tenants
|
|
73
|
+
*
|
|
74
|
+
* Provides tenant list and management functions for multi-tenant applications.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* function TenantManager() {
|
|
79
|
+
* const { tenants, isLoading, setCurrentTenant, currentTenantId } = useTenants()
|
|
80
|
+
*
|
|
81
|
+
* if (isLoading) return <div>Loading...</div>
|
|
82
|
+
*
|
|
83
|
+
* return (
|
|
84
|
+
* <select
|
|
85
|
+
* value={currentTenantId || ''}
|
|
86
|
+
* onChange={(e) => setCurrentTenant(e.target.value || undefined)}
|
|
87
|
+
* >
|
|
88
|
+
* {tenants.map(t => (
|
|
89
|
+
* <option key={t.id} value={t.id}>
|
|
90
|
+
* {t.name} ({t.my_role})
|
|
91
|
+
* </option>
|
|
92
|
+
* ))}
|
|
93
|
+
* </select>
|
|
94
|
+
* )
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export function useTenants(options: UseTenantsOptions = {}): UseTenantsReturn {
|
|
99
|
+
const { autoFetch = true } = options;
|
|
100
|
+
const client = useFluxbaseClient();
|
|
101
|
+
|
|
102
|
+
const [tenants, setTenants] = useState<TenantWithRole[]>([]);
|
|
103
|
+
const [isLoading, setIsLoading] = useState(autoFetch);
|
|
104
|
+
const [error, setError] = useState<Error | null>(null);
|
|
105
|
+
const [currentTenantId, setCurrentTenantId] = useState<string | undefined>(
|
|
106
|
+
client.getTenantId(),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const fetchTenants = useCallback(async () => {
|
|
110
|
+
try {
|
|
111
|
+
setIsLoading(true);
|
|
112
|
+
setError(null);
|
|
113
|
+
const { data, error: fetchError } = await client.tenant.listMine();
|
|
114
|
+
if (fetchError) {
|
|
115
|
+
setError(fetchError);
|
|
116
|
+
} else {
|
|
117
|
+
setTenants(data || []);
|
|
118
|
+
}
|
|
119
|
+
} catch (err) {
|
|
120
|
+
setError(err as Error);
|
|
121
|
+
} finally {
|
|
122
|
+
setIsLoading(false);
|
|
123
|
+
}
|
|
124
|
+
}, [client]);
|
|
125
|
+
|
|
126
|
+
const createTenant = useCallback(
|
|
127
|
+
async (opts: CreateTenantOptions): Promise<Tenant> => {
|
|
128
|
+
const { data, error: createError } = await client.tenant.create(opts);
|
|
129
|
+
if (createError) throw createError;
|
|
130
|
+
await fetchTenants();
|
|
131
|
+
return data!;
|
|
132
|
+
},
|
|
133
|
+
[client, fetchTenants],
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const updateTenant = useCallback(
|
|
137
|
+
async (id: string, opts: UpdateTenantOptions): Promise<Tenant> => {
|
|
138
|
+
const { data, error: updateError } = await client.tenant.update(id, opts);
|
|
139
|
+
if (updateError) throw updateError;
|
|
140
|
+
await fetchTenants();
|
|
141
|
+
return data!;
|
|
142
|
+
},
|
|
143
|
+
[client, fetchTenants],
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const deleteTenant = useCallback(
|
|
147
|
+
async (id: string): Promise<void> => {
|
|
148
|
+
const { error: deleteError } = await client.tenant.delete(id);
|
|
149
|
+
if (deleteError) throw deleteError;
|
|
150
|
+
await fetchTenants();
|
|
151
|
+
},
|
|
152
|
+
[client, fetchTenants],
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
const setCurrentTenant = useCallback(
|
|
156
|
+
(tenantId: string | undefined) => {
|
|
157
|
+
client.setTenant(tenantId);
|
|
158
|
+
setCurrentTenantId(tenantId);
|
|
159
|
+
},
|
|
160
|
+
[client],
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
if (autoFetch) {
|
|
165
|
+
fetchTenants();
|
|
166
|
+
}
|
|
167
|
+
}, [autoFetch, fetchTenants]);
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
tenants,
|
|
171
|
+
isLoading,
|
|
172
|
+
error,
|
|
173
|
+
refetch: fetchTenants,
|
|
174
|
+
createTenant,
|
|
175
|
+
updateTenant,
|
|
176
|
+
deleteTenant,
|
|
177
|
+
setCurrentTenant,
|
|
178
|
+
currentTenantId,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface UseTenantOptions {
|
|
183
|
+
/**
|
|
184
|
+
* Tenant ID to fetch
|
|
185
|
+
*/
|
|
186
|
+
tenantId: string;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Whether to automatically fetch tenant on mount
|
|
190
|
+
* @default true
|
|
191
|
+
*/
|
|
192
|
+
autoFetch?: boolean;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface UseTenantReturn {
|
|
196
|
+
/**
|
|
197
|
+
* Tenant data
|
|
198
|
+
*/
|
|
199
|
+
tenant: Tenant | null;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Whether tenant is being fetched
|
|
203
|
+
*/
|
|
204
|
+
isLoading: boolean;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Any error that occurred
|
|
208
|
+
*/
|
|
209
|
+
error: Error | null;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Refetch tenant
|
|
213
|
+
*/
|
|
214
|
+
refetch: () => Promise<void>;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Update the tenant
|
|
218
|
+
*/
|
|
219
|
+
update: (options: UpdateTenantOptions) => Promise<Tenant>;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Delete the tenant
|
|
223
|
+
*/
|
|
224
|
+
remove: () => Promise<void>;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Hook for managing a single tenant
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```tsx
|
|
232
|
+
* function TenantDetails({ tenantId }: { tenantId: string }) {
|
|
233
|
+
* const { tenant, isLoading, update } = useTenant({ tenantId })
|
|
234
|
+
*
|
|
235
|
+
* if (isLoading) return <div>Loading...</div>
|
|
236
|
+
* if (!tenant) return <div>Tenant not found</div>
|
|
237
|
+
*
|
|
238
|
+
* return (
|
|
239
|
+
* <div>
|
|
240
|
+
* <h1>{tenant.name}</h1>
|
|
241
|
+
* <button onClick={() => update({ name: 'New Name' })}>
|
|
242
|
+
* Rename
|
|
243
|
+
* </button>
|
|
244
|
+
* </div>
|
|
245
|
+
* )
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
export function useTenant(options: UseTenantOptions): UseTenantReturn {
|
|
250
|
+
const { tenantId, autoFetch = true } = options;
|
|
251
|
+
const client = useFluxbaseClient();
|
|
252
|
+
|
|
253
|
+
const [tenant, setTenant] = useState<Tenant | null>(null);
|
|
254
|
+
const [isLoading, setIsLoading] = useState(autoFetch);
|
|
255
|
+
const [error, setError] = useState<Error | null>(null);
|
|
256
|
+
|
|
257
|
+
const fetchTenant = useCallback(async () => {
|
|
258
|
+
if (!tenantId) return;
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
setIsLoading(true);
|
|
262
|
+
setError(null);
|
|
263
|
+
const { data, error: fetchError } = await client.tenant.get(tenantId);
|
|
264
|
+
if (fetchError) {
|
|
265
|
+
setError(fetchError);
|
|
266
|
+
setTenant(null);
|
|
267
|
+
} else {
|
|
268
|
+
setTenant(data);
|
|
269
|
+
}
|
|
270
|
+
} catch (err) {
|
|
271
|
+
setError(err as Error);
|
|
272
|
+
setTenant(null);
|
|
273
|
+
} finally {
|
|
274
|
+
setIsLoading(false);
|
|
275
|
+
}
|
|
276
|
+
}, [client, tenantId]);
|
|
277
|
+
|
|
278
|
+
const update = useCallback(
|
|
279
|
+
async (opts: UpdateTenantOptions): Promise<Tenant> => {
|
|
280
|
+
const { data, error: updateError } = await client.tenant.update(
|
|
281
|
+
tenantId,
|
|
282
|
+
opts,
|
|
283
|
+
);
|
|
284
|
+
if (updateError) throw updateError;
|
|
285
|
+
setTenant(data);
|
|
286
|
+
return data!;
|
|
287
|
+
},
|
|
288
|
+
[client, tenantId],
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const remove = useCallback(async (): Promise<void> => {
|
|
292
|
+
const { error: deleteError } = await client.tenant.delete(tenantId);
|
|
293
|
+
if (deleteError) throw deleteError;
|
|
294
|
+
setTenant(null);
|
|
295
|
+
}, [client, tenantId]);
|
|
296
|
+
|
|
297
|
+
useEffect(() => {
|
|
298
|
+
if (autoFetch && tenantId) {
|
|
299
|
+
fetchTenant();
|
|
300
|
+
}
|
|
301
|
+
}, [autoFetch, fetchTenant, tenantId]);
|
|
302
|
+
|
|
303
|
+
return {
|
|
304
|
+
tenant,
|
|
305
|
+
isLoading,
|
|
306
|
+
error,
|
|
307
|
+
refetch: fetchTenant,
|
|
308
|
+
update,
|
|
309
|
+
remove,
|
|
310
|
+
};
|
|
311
|
+
}
|
package/src/use-users.ts
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
import { useState, useEffect, useCallback } from
|
|
2
|
-
import { useFluxbaseClient } from
|
|
3
|
-
import type { EnrichedUser, ListUsersOptions } from
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { useFluxbaseClient } from "./context";
|
|
3
|
+
import type { EnrichedUser, ListUsersOptions } from "@nimbleflux/fluxbase-sdk";
|
|
4
4
|
|
|
5
5
|
export interface UseUsersOptions extends ListUsersOptions {
|
|
6
6
|
/**
|
|
7
7
|
* Whether to automatically fetch users on mount
|
|
8
8
|
* @default true
|
|
9
9
|
*/
|
|
10
|
-
autoFetch?: boolean
|
|
10
|
+
autoFetch?: boolean;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Refetch interval in milliseconds (0 to disable)
|
|
14
14
|
* @default 0
|
|
15
15
|
*/
|
|
16
|
-
refetchInterval?: number
|
|
16
|
+
refetchInterval?: number;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface UseUsersReturn {
|
|
20
20
|
/**
|
|
21
21
|
* Array of users
|
|
22
22
|
*/
|
|
23
|
-
users: EnrichedUser[]
|
|
23
|
+
users: EnrichedUser[];
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Total number of users (for pagination)
|
|
27
27
|
*/
|
|
28
|
-
total: number
|
|
28
|
+
total: number;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Whether users are being fetched
|
|
32
32
|
*/
|
|
33
|
-
isLoading: boolean
|
|
33
|
+
isLoading: boolean;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Any error that occurred
|
|
37
37
|
*/
|
|
38
|
-
error: Error | null
|
|
38
|
+
error: Error | null;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Refetch users
|
|
42
42
|
*/
|
|
43
|
-
refetch: () => Promise<void
|
|
43
|
+
refetch: () => Promise<void>;
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Invite a new user
|
|
47
47
|
*/
|
|
48
|
-
inviteUser: (email: string, role:
|
|
48
|
+
inviteUser: (email: string, role: "user" | "admin") => Promise<void>;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Update user role
|
|
52
52
|
*/
|
|
53
|
-
updateUserRole: (userId: string, role:
|
|
53
|
+
updateUserRole: (userId: string, role: "user" | "admin") => Promise<void>;
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Delete a user
|
|
57
57
|
*/
|
|
58
|
-
deleteUser: (userId: string) => Promise<void
|
|
58
|
+
deleteUser: (userId: string) => Promise<void>;
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* Reset user password
|
|
62
62
|
*/
|
|
63
|
-
resetPassword: (userId: string) => Promise<{ message: string }
|
|
63
|
+
resetPassword: (userId: string) => Promise<{ message: string }>;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -94,95 +94,96 @@ export interface UseUsersReturn {
|
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
96
|
export function useUsers(options: UseUsersOptions = {}): UseUsersReturn {
|
|
97
|
-
const { autoFetch = true, refetchInterval = 0, ...listOptions } = options
|
|
98
|
-
const client = useFluxbaseClient()
|
|
97
|
+
const { autoFetch = true, refetchInterval = 0, ...listOptions } = options;
|
|
98
|
+
const client = useFluxbaseClient();
|
|
99
99
|
|
|
100
|
-
const [users, setUsers] = useState<EnrichedUser[]>([])
|
|
101
|
-
const [total, setTotal] = useState(0)
|
|
102
|
-
const [isLoading, setIsLoading] = useState(autoFetch)
|
|
103
|
-
const [error, setError] = useState<Error | null>(null)
|
|
100
|
+
const [users, setUsers] = useState<EnrichedUser[]>([]);
|
|
101
|
+
const [total, setTotal] = useState(0);
|
|
102
|
+
const [isLoading, setIsLoading] = useState(autoFetch);
|
|
103
|
+
const [error, setError] = useState<Error | null>(null);
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* Fetch users from API
|
|
107
107
|
*/
|
|
108
108
|
const fetchUsers = useCallback(async () => {
|
|
109
109
|
try {
|
|
110
|
-
setIsLoading(true)
|
|
111
|
-
setError(null)
|
|
112
|
-
const { data, error: apiError } =
|
|
110
|
+
setIsLoading(true);
|
|
111
|
+
setError(null);
|
|
112
|
+
const { data, error: apiError } =
|
|
113
|
+
await client.admin.listUsers(listOptions);
|
|
113
114
|
if (apiError) {
|
|
114
|
-
throw apiError
|
|
115
|
+
throw apiError;
|
|
115
116
|
}
|
|
116
|
-
setUsers(data!.users)
|
|
117
|
-
setTotal(data!.total)
|
|
117
|
+
setUsers(data!.users);
|
|
118
|
+
setTotal(data!.total);
|
|
118
119
|
} catch (err) {
|
|
119
|
-
setError(err as Error)
|
|
120
|
+
setError(err as Error);
|
|
120
121
|
} finally {
|
|
121
|
-
setIsLoading(false)
|
|
122
|
+
setIsLoading(false);
|
|
122
123
|
}
|
|
123
|
-
}, [client, JSON.stringify(listOptions)])
|
|
124
|
+
}, [client, JSON.stringify(listOptions)]);
|
|
124
125
|
|
|
125
126
|
/**
|
|
126
127
|
* Invite a new user
|
|
127
128
|
*/
|
|
128
129
|
const inviteUser = useCallback(
|
|
129
|
-
async (email: string, role:
|
|
130
|
-
await client.admin.inviteUser({ email, role })
|
|
131
|
-
await fetchUsers() // Refresh list
|
|
130
|
+
async (email: string, role: "user" | "admin"): Promise<void> => {
|
|
131
|
+
await client.admin.inviteUser({ email, role });
|
|
132
|
+
await fetchUsers(); // Refresh list
|
|
132
133
|
},
|
|
133
|
-
[client, fetchUsers]
|
|
134
|
-
)
|
|
134
|
+
[client, fetchUsers],
|
|
135
|
+
);
|
|
135
136
|
|
|
136
137
|
/**
|
|
137
138
|
* Update user role
|
|
138
139
|
*/
|
|
139
140
|
const updateUserRole = useCallback(
|
|
140
|
-
async (userId: string, role:
|
|
141
|
-
await client.admin.updateUserRole(userId, role)
|
|
142
|
-
await fetchUsers() // Refresh list
|
|
141
|
+
async (userId: string, role: "user" | "admin"): Promise<void> => {
|
|
142
|
+
await client.admin.updateUserRole(userId, role);
|
|
143
|
+
await fetchUsers(); // Refresh list
|
|
143
144
|
},
|
|
144
|
-
[client, fetchUsers]
|
|
145
|
-
)
|
|
145
|
+
[client, fetchUsers],
|
|
146
|
+
);
|
|
146
147
|
|
|
147
148
|
/**
|
|
148
149
|
* Delete a user
|
|
149
150
|
*/
|
|
150
151
|
const deleteUser = useCallback(
|
|
151
152
|
async (userId: string): Promise<void> => {
|
|
152
|
-
await client.admin.deleteUser(userId)
|
|
153
|
-
await fetchUsers() // Refresh list
|
|
153
|
+
await client.admin.deleteUser(userId);
|
|
154
|
+
await fetchUsers(); // Refresh list
|
|
154
155
|
},
|
|
155
|
-
[client, fetchUsers]
|
|
156
|
-
)
|
|
156
|
+
[client, fetchUsers],
|
|
157
|
+
);
|
|
157
158
|
|
|
158
159
|
/**
|
|
159
160
|
* Reset user password
|
|
160
161
|
*/
|
|
161
162
|
const resetPassword = useCallback(
|
|
162
163
|
async (userId: string): Promise<{ message: string }> => {
|
|
163
|
-
const { data, error } = await client.admin.resetUserPassword(userId)
|
|
164
|
+
const { data, error } = await client.admin.resetUserPassword(userId);
|
|
164
165
|
if (error) {
|
|
165
|
-
throw error
|
|
166
|
+
throw error;
|
|
166
167
|
}
|
|
167
|
-
return data
|
|
168
|
+
return data!;
|
|
168
169
|
},
|
|
169
|
-
[client]
|
|
170
|
-
)
|
|
170
|
+
[client],
|
|
171
|
+
);
|
|
171
172
|
|
|
172
173
|
// Auto-fetch on mount
|
|
173
174
|
useEffect(() => {
|
|
174
175
|
if (autoFetch) {
|
|
175
|
-
fetchUsers()
|
|
176
|
+
fetchUsers();
|
|
176
177
|
}
|
|
177
|
-
}, [autoFetch, fetchUsers])
|
|
178
|
+
}, [autoFetch, fetchUsers]);
|
|
178
179
|
|
|
179
180
|
// Set up refetch interval
|
|
180
181
|
useEffect(() => {
|
|
181
182
|
if (refetchInterval > 0) {
|
|
182
|
-
const interval = setInterval(fetchUsers, refetchInterval)
|
|
183
|
-
return () => clearInterval(interval)
|
|
183
|
+
const interval = setInterval(fetchUsers, refetchInterval);
|
|
184
|
+
return () => clearInterval(interval);
|
|
184
185
|
}
|
|
185
|
-
}, [refetchInterval, fetchUsers])
|
|
186
|
+
}, [refetchInterval, fetchUsers]);
|
|
186
187
|
|
|
187
188
|
return {
|
|
188
189
|
users,
|
|
@@ -193,6 +194,6 @@ export function useUsers(options: UseUsersOptions = {}): UseUsersReturn {
|
|
|
193
194
|
inviteUser,
|
|
194
195
|
updateUserRole,
|
|
195
196
|
deleteUser,
|
|
196
|
-
resetPassword
|
|
197
|
-
}
|
|
197
|
+
resetPassword,
|
|
198
|
+
};
|
|
198
199
|
}
|
package/tsconfig.json
CHANGED
package/tsup.config.ts
CHANGED