@elqnt/admin 2.1.0 → 2.2.0
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/dist/api/index.cjs +303 -32
- package/dist/api/index.cjs.map +1 -1
- package/dist/api/index.d.cts +114 -39
- package/dist/api/index.d.ts +114 -39
- package/dist/api/index.js +276 -30
- package/dist/api/index.js.map +1 -1
- package/dist/hooks/index.cjs +769 -8
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +133 -3
- package/dist/hooks/index.d.ts +133 -3
- package/dist/hooks/index.js +766 -8
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +446 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +383 -33
- package/dist/index.js.map +1 -1
- package/dist/models/index.cjs +143 -4
- package/dist/models/index.cjs.map +1 -1
- package/dist/models/index.d.cts +1258 -12
- package/dist/models/index.d.ts +1258 -12
- package/dist/models/index.js +107 -3
- package/dist/models/index.js.map +1 -1
- package/dist/provisioning-Cfl6wbmV.d.cts +168 -0
- package/dist/provisioning-Il9t2jnH.d.ts +168 -0
- package/package.json +2 -2
- package/dist/admin-Dlsd5IZ0.d.cts +0 -767
- package/dist/admin-Dlsd5IZ0.d.ts +0 -767
package/dist/hooks/index.js
CHANGED
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
import { useState, useCallback } from "react";
|
|
3
3
|
|
|
4
4
|
// api/index.ts
|
|
5
|
-
import { browserApiRequest as
|
|
5
|
+
import { browserApiRequest as browserApiRequest6, clearGatewayTokenCache } from "@elqnt/api-client/browser";
|
|
6
6
|
|
|
7
7
|
// api/orgs.ts
|
|
8
8
|
import { browserApiRequest } from "@elqnt/api-client/browser";
|
|
9
|
-
async function listOrgsApi(options) {
|
|
10
|
-
|
|
9
|
+
async function listOrgsApi(filter, options) {
|
|
10
|
+
const params = new URLSearchParams();
|
|
11
|
+
if (filter?.product) params.set("product", filter.product);
|
|
12
|
+
if (filter?.status) params.set("status", filter.status);
|
|
13
|
+
if (filter?.type) params.set("type", filter.type);
|
|
14
|
+
const queryString = params.toString();
|
|
15
|
+
const url = queryString ? `/api/v1/admin/orgs?${queryString}` : "/api/v1/admin/orgs";
|
|
16
|
+
return browserApiRequest(url, {
|
|
11
17
|
method: "GET",
|
|
12
18
|
...options
|
|
13
19
|
});
|
|
@@ -44,6 +50,13 @@ async function getOrgInfoApi(orgId, options) {
|
|
|
44
50
|
...options
|
|
45
51
|
});
|
|
46
52
|
}
|
|
53
|
+
async function createOrgWithSchemasApi(org, schemas, options) {
|
|
54
|
+
return browserApiRequest("/api/v1/admin/orgs/with-schemas", {
|
|
55
|
+
method: "POST",
|
|
56
|
+
body: { org, schemas },
|
|
57
|
+
...options
|
|
58
|
+
});
|
|
59
|
+
}
|
|
47
60
|
|
|
48
61
|
// api/users.ts
|
|
49
62
|
import { browserApiRequest as browserApiRequest2 } from "@elqnt/api-client/browser";
|
|
@@ -72,6 +85,12 @@ async function getUserByEmailApi(email, options) {
|
|
|
72
85
|
...options
|
|
73
86
|
});
|
|
74
87
|
}
|
|
88
|
+
async function getUserByPhoneApi(phone, options) {
|
|
89
|
+
return browserApiRequest2(`/api/v1/admin/users/by-phone?phone=${encodeURIComponent(phone)}`, {
|
|
90
|
+
method: "GET",
|
|
91
|
+
...options
|
|
92
|
+
});
|
|
93
|
+
}
|
|
75
94
|
async function updateUserApi(userId, updates, options) {
|
|
76
95
|
return browserApiRequest2(`/api/v1/admin/users/${userId}`, {
|
|
77
96
|
method: "PUT",
|
|
@@ -146,22 +165,208 @@ async function acceptInviteApi(inviteId, options) {
|
|
|
146
165
|
});
|
|
147
166
|
}
|
|
148
167
|
|
|
168
|
+
// api/analytics.ts
|
|
169
|
+
import { browserApiRequest as browserApiRequest4 } from "@elqnt/api-client/browser";
|
|
170
|
+
function buildDateFilterParams(filter) {
|
|
171
|
+
if (!filter) return "";
|
|
172
|
+
const params = new URLSearchParams();
|
|
173
|
+
if (filter.from) params.set("from", filter.from);
|
|
174
|
+
if (filter.to) params.set("to", filter.to);
|
|
175
|
+
const queryString = params.toString();
|
|
176
|
+
return queryString ? `?${queryString}` : "";
|
|
177
|
+
}
|
|
178
|
+
async function getAnalyticsSummaryApi(filter, options) {
|
|
179
|
+
const queryString = buildDateFilterParams(filter);
|
|
180
|
+
return browserApiRequest4(`/api/v1/analytics/summary${queryString}`, {
|
|
181
|
+
method: "GET",
|
|
182
|
+
...options
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async function getChatsAnalyticsApi(filter, agentId, options) {
|
|
186
|
+
const params = new URLSearchParams();
|
|
187
|
+
if (filter?.from) params.set("from", filter.from);
|
|
188
|
+
if (filter?.to) params.set("to", filter.to);
|
|
189
|
+
if (agentId) params.set("agent_id", agentId);
|
|
190
|
+
const queryString = params.toString();
|
|
191
|
+
return browserApiRequest4(`/api/v1/analytics/chats${queryString ? `?${queryString}` : ""}`, {
|
|
192
|
+
method: "GET",
|
|
193
|
+
...options
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
async function getAgentsAnalyticsApi(filter, options) {
|
|
197
|
+
const queryString = buildDateFilterParams(filter);
|
|
198
|
+
return browserApiRequest4(`/api/v1/analytics/agents${queryString}`, {
|
|
199
|
+
method: "GET",
|
|
200
|
+
...options
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
async function getUsageAnalyticsApi(filter, options) {
|
|
204
|
+
const queryString = buildDateFilterParams(filter);
|
|
205
|
+
return browserApiRequest4(`/api/v1/analytics/usage${queryString}`, {
|
|
206
|
+
method: "GET",
|
|
207
|
+
...options
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async function getDailyAnalyticsApi(filter, options) {
|
|
211
|
+
const queryString = buildDateFilterParams(filter);
|
|
212
|
+
return browserApiRequest4(`/api/v1/analytics/daily${queryString}`, {
|
|
213
|
+
method: "GET",
|
|
214
|
+
...options
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async function getAnalyticsEventsApi(filter, options) {
|
|
218
|
+
const queryString = buildDateFilterParams(filter);
|
|
219
|
+
return browserApiRequest4(`/api/v1/analytics/events${queryString}`, {
|
|
220
|
+
method: "GET",
|
|
221
|
+
...options
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
async function logAnalyticsEventApi(event, options) {
|
|
225
|
+
return browserApiRequest4("/api/v1/analytics/events", {
|
|
226
|
+
method: "POST",
|
|
227
|
+
body: event,
|
|
228
|
+
...options
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async function getGlobalSummaryApi(filter, options) {
|
|
232
|
+
const queryString = buildDateFilterParams(filter);
|
|
233
|
+
return browserApiRequest4(`/api/v1/analytics/global/summary${queryString}`, {
|
|
234
|
+
method: "GET",
|
|
235
|
+
...options
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
async function getGlobalOrgsAnalyticsApi(filter, options) {
|
|
239
|
+
const queryString = buildDateFilterParams(filter);
|
|
240
|
+
return browserApiRequest4(`/api/v1/analytics/global/orgs${queryString}`, {
|
|
241
|
+
method: "GET",
|
|
242
|
+
...options
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// api/provisioning.ts
|
|
247
|
+
import { browserApiRequest as browserApiRequest5 } from "@elqnt/api-client/browser";
|
|
248
|
+
async function createOrgWithProvisioningApi(request, options) {
|
|
249
|
+
return browserApiRequest5("/api/v1/admin/provisioning/orgs", {
|
|
250
|
+
method: "POST",
|
|
251
|
+
body: request,
|
|
252
|
+
...options
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
async function getProvisioningStatusApi(orgId, options) {
|
|
256
|
+
return browserApiRequest5(`/api/v1/admin/orgs/${orgId}/provisioning`, {
|
|
257
|
+
method: "GET",
|
|
258
|
+
...options
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
async function retryProvisioningApi(orgId, request, options) {
|
|
262
|
+
return browserApiRequest5(`/api/v1/admin/orgs/${orgId}/provisioning/retry`, {
|
|
263
|
+
method: "POST",
|
|
264
|
+
body: request || {},
|
|
265
|
+
...options
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
async function validateProvisioningApi(orgId, options) {
|
|
269
|
+
return browserApiRequest5(
|
|
270
|
+
`/api/v1/admin/orgs/${orgId}/provisioning/validate`,
|
|
271
|
+
{
|
|
272
|
+
method: "POST",
|
|
273
|
+
...options
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
async function cancelProvisioningApi(orgId, options) {
|
|
278
|
+
return browserApiRequest5(
|
|
279
|
+
`/api/v1/admin/orgs/${orgId}/provisioning/cancel`,
|
|
280
|
+
{
|
|
281
|
+
method: "POST",
|
|
282
|
+
...options
|
|
283
|
+
}
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
async function cleanupProvisioningApi(orgId, options) {
|
|
287
|
+
return browserApiRequest5(`/api/v1/admin/orgs/${orgId}/provisioning`, {
|
|
288
|
+
method: "DELETE",
|
|
289
|
+
...options
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
function streamProvisioningProgress(orgId, callbacks, options) {
|
|
293
|
+
const url = new URL(
|
|
294
|
+
`/api/v1/admin/orgs/${orgId}/provisioning/stream`,
|
|
295
|
+
options.baseUrl
|
|
296
|
+
);
|
|
297
|
+
if (options.token) {
|
|
298
|
+
url.searchParams.set("token", options.token);
|
|
299
|
+
}
|
|
300
|
+
const eventSource = new EventSource(url.toString());
|
|
301
|
+
eventSource.addEventListener("connected", (event) => {
|
|
302
|
+
try {
|
|
303
|
+
const data = JSON.parse(event.data);
|
|
304
|
+
callbacks.onConnected?.(data.orgId);
|
|
305
|
+
} catch (e) {
|
|
306
|
+
console.error("Failed to parse connected event", e);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
eventSource.addEventListener("progress", (event) => {
|
|
310
|
+
try {
|
|
311
|
+
const progress = JSON.parse(event.data);
|
|
312
|
+
callbacks.onProgress?.(progress);
|
|
313
|
+
} catch (e) {
|
|
314
|
+
console.error("Failed to parse progress event", e);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
eventSource.addEventListener("done", () => {
|
|
318
|
+
callbacks.onDone?.();
|
|
319
|
+
eventSource.close();
|
|
320
|
+
});
|
|
321
|
+
eventSource.addEventListener("timeout", () => {
|
|
322
|
+
callbacks.onTimeout?.();
|
|
323
|
+
eventSource.close();
|
|
324
|
+
});
|
|
325
|
+
eventSource.onerror = (error) => {
|
|
326
|
+
callbacks.onError?.(new Error("SSE connection error"));
|
|
327
|
+
eventSource.close();
|
|
328
|
+
};
|
|
329
|
+
return () => {
|
|
330
|
+
eventSource.close();
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function calculateProgressPercentage(progress) {
|
|
334
|
+
if (progress.totalArtifacts === 0) return 0;
|
|
335
|
+
return Math.round(
|
|
336
|
+
progress.completedArtifacts / progress.totalArtifacts * 100
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
function isProvisioningComplete(progress) {
|
|
340
|
+
return progress.status === "completed" || progress.status === "failed" || progress.status === "partial";
|
|
341
|
+
}
|
|
342
|
+
function isProvisioningSuccessful(progress) {
|
|
343
|
+
return progress.status === "completed";
|
|
344
|
+
}
|
|
345
|
+
function getFailedArtifacts(progress) {
|
|
346
|
+
return progress.artifacts.filter((a) => a.status === "failed");
|
|
347
|
+
}
|
|
348
|
+
function hasCriticalFailures(progress) {
|
|
349
|
+
return progress.artifacts.some(
|
|
350
|
+
(a) => a.status === "failed" && a.critical
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
149
354
|
// api/index.ts
|
|
150
355
|
async function getOrgSettingsApi(options) {
|
|
151
|
-
return
|
|
356
|
+
return browserApiRequest6("/api/v1/org/settings", {
|
|
152
357
|
method: "GET",
|
|
153
358
|
...options
|
|
154
359
|
});
|
|
155
360
|
}
|
|
156
361
|
async function createOrgSettingsApi(settings, options) {
|
|
157
|
-
return
|
|
362
|
+
return browserApiRequest6("/api/v1/org/settings", {
|
|
158
363
|
method: "POST",
|
|
159
364
|
body: settings,
|
|
160
365
|
...options
|
|
161
366
|
});
|
|
162
367
|
}
|
|
163
368
|
async function updateOrgSettingsApi(settings, options) {
|
|
164
|
-
return
|
|
369
|
+
return browserApiRequest6("/api/v1/org/settings", {
|
|
165
370
|
method: "PUT",
|
|
166
371
|
body: settings,
|
|
167
372
|
...options
|
|
@@ -172,11 +377,11 @@ async function updateOrgSettingsApi(settings, options) {
|
|
|
172
377
|
function useOrgAdmin(options) {
|
|
173
378
|
const [loading, setLoading] = useState(false);
|
|
174
379
|
const [error, setError] = useState(null);
|
|
175
|
-
const listOrgs = useCallback(async () => {
|
|
380
|
+
const listOrgs = useCallback(async (filter) => {
|
|
176
381
|
setLoading(true);
|
|
177
382
|
setError(null);
|
|
178
383
|
try {
|
|
179
|
-
const response = await listOrgsApi(options);
|
|
384
|
+
const response = await listOrgsApi(filter, options);
|
|
180
385
|
if (response.error) {
|
|
181
386
|
setError(response.error);
|
|
182
387
|
return [];
|
|
@@ -253,6 +458,27 @@ function useOrgAdmin(options) {
|
|
|
253
458
|
},
|
|
254
459
|
[options]
|
|
255
460
|
);
|
|
461
|
+
const createOrgWithSchemas = useCallback(
|
|
462
|
+
async (org, schemas) => {
|
|
463
|
+
setLoading(true);
|
|
464
|
+
setError(null);
|
|
465
|
+
try {
|
|
466
|
+
const response = await createOrgWithSchemasApi(org, schemas, options);
|
|
467
|
+
if (response.error) {
|
|
468
|
+
setError(response.error);
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
return response.data || null;
|
|
472
|
+
} catch (err) {
|
|
473
|
+
const message = err instanceof Error ? err.message : "Failed to create organization with schemas";
|
|
474
|
+
setError(message);
|
|
475
|
+
return null;
|
|
476
|
+
} finally {
|
|
477
|
+
setLoading(false);
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
[options]
|
|
481
|
+
);
|
|
256
482
|
const updateOrg = useCallback(
|
|
257
483
|
async (orgId, updates) => {
|
|
258
484
|
setLoading(true);
|
|
@@ -302,6 +528,7 @@ function useOrgAdmin(options) {
|
|
|
302
528
|
getOrg,
|
|
303
529
|
getOrgInfo,
|
|
304
530
|
createOrg,
|
|
531
|
+
createOrgWithSchemas,
|
|
305
532
|
updateOrg,
|
|
306
533
|
deleteOrg
|
|
307
534
|
};
|
|
@@ -372,6 +599,27 @@ function useUsersAdmin(options) {
|
|
|
372
599
|
},
|
|
373
600
|
[options]
|
|
374
601
|
);
|
|
602
|
+
const getUserByPhone = useCallback2(
|
|
603
|
+
async (phone) => {
|
|
604
|
+
setLoading(true);
|
|
605
|
+
setError(null);
|
|
606
|
+
try {
|
|
607
|
+
const response = await getUserByPhoneApi(phone, options);
|
|
608
|
+
if (response.error) {
|
|
609
|
+
setError(response.error);
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
return response.data?.user || null;
|
|
613
|
+
} catch (err) {
|
|
614
|
+
const message = err instanceof Error ? err.message : "Failed to get user by phone";
|
|
615
|
+
setError(message);
|
|
616
|
+
return null;
|
|
617
|
+
} finally {
|
|
618
|
+
setLoading(false);
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
[options]
|
|
622
|
+
);
|
|
375
623
|
const createUser = useCallback2(
|
|
376
624
|
async (user) => {
|
|
377
625
|
setLoading(true);
|
|
@@ -483,6 +731,7 @@ function useUsersAdmin(options) {
|
|
|
483
731
|
listUsers,
|
|
484
732
|
getUser,
|
|
485
733
|
getUserByEmail,
|
|
734
|
+
getUserByPhone,
|
|
486
735
|
createUser,
|
|
487
736
|
updateUser,
|
|
488
737
|
deleteUser,
|
|
@@ -726,10 +975,519 @@ function useOrgSettings(options) {
|
|
|
726
975
|
updateSettings
|
|
727
976
|
};
|
|
728
977
|
}
|
|
978
|
+
|
|
979
|
+
// hooks/use-product-analytics.ts
|
|
980
|
+
import { useState as useState5, useCallback as useCallback5, useRef, useEffect } from "react";
|
|
981
|
+
function useProductAnalytics(options) {
|
|
982
|
+
const [state, setState] = useState5({
|
|
983
|
+
summary: null,
|
|
984
|
+
chats: [],
|
|
985
|
+
agents: [],
|
|
986
|
+
usage: [],
|
|
987
|
+
daily: [],
|
|
988
|
+
events: [],
|
|
989
|
+
loading: false,
|
|
990
|
+
error: null
|
|
991
|
+
});
|
|
992
|
+
const sessionIdRef = useRef("");
|
|
993
|
+
useEffect(() => {
|
|
994
|
+
if (typeof window !== "undefined") {
|
|
995
|
+
let sessionId = sessionStorage.getItem("analytics_session_id");
|
|
996
|
+
if (!sessionId) {
|
|
997
|
+
sessionId = crypto.randomUUID();
|
|
998
|
+
sessionStorage.setItem("analytics_session_id", sessionId);
|
|
999
|
+
}
|
|
1000
|
+
sessionIdRef.current = sessionId;
|
|
1001
|
+
}
|
|
1002
|
+
}, []);
|
|
1003
|
+
const getSummary = useCallback5(
|
|
1004
|
+
async (filter) => {
|
|
1005
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1006
|
+
try {
|
|
1007
|
+
const response = await getAnalyticsSummaryApi(filter, options);
|
|
1008
|
+
if (response.error) {
|
|
1009
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1010
|
+
return null;
|
|
1011
|
+
}
|
|
1012
|
+
const summary = response.data?.data || null;
|
|
1013
|
+
setState((prev) => ({ ...prev, loading: false, summary }));
|
|
1014
|
+
return summary;
|
|
1015
|
+
} catch (err) {
|
|
1016
|
+
const message = err instanceof Error ? err.message : "Failed to get analytics summary";
|
|
1017
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
[options]
|
|
1022
|
+
);
|
|
1023
|
+
const getChats = useCallback5(
|
|
1024
|
+
async (filter, agentId) => {
|
|
1025
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1026
|
+
try {
|
|
1027
|
+
const response = await getChatsAnalyticsApi(filter, agentId, options);
|
|
1028
|
+
if (response.error) {
|
|
1029
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1030
|
+
return [];
|
|
1031
|
+
}
|
|
1032
|
+
const chats = response.data?.data || [];
|
|
1033
|
+
setState((prev) => ({ ...prev, loading: false, chats }));
|
|
1034
|
+
return chats;
|
|
1035
|
+
} catch (err) {
|
|
1036
|
+
const message = err instanceof Error ? err.message : "Failed to get chat analytics";
|
|
1037
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1038
|
+
return [];
|
|
1039
|
+
}
|
|
1040
|
+
},
|
|
1041
|
+
[options]
|
|
1042
|
+
);
|
|
1043
|
+
const getAgents = useCallback5(
|
|
1044
|
+
async (filter) => {
|
|
1045
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1046
|
+
try {
|
|
1047
|
+
const response = await getAgentsAnalyticsApi(filter, options);
|
|
1048
|
+
if (response.error) {
|
|
1049
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1050
|
+
return [];
|
|
1051
|
+
}
|
|
1052
|
+
const agents = response.data?.data || [];
|
|
1053
|
+
setState((prev) => ({ ...prev, loading: false, agents }));
|
|
1054
|
+
return agents;
|
|
1055
|
+
} catch (err) {
|
|
1056
|
+
const message = err instanceof Error ? err.message : "Failed to get agent analytics";
|
|
1057
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1058
|
+
return [];
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
[options]
|
|
1062
|
+
);
|
|
1063
|
+
const getUsage = useCallback5(
|
|
1064
|
+
async (filter) => {
|
|
1065
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1066
|
+
try {
|
|
1067
|
+
const response = await getUsageAnalyticsApi(filter, options);
|
|
1068
|
+
if (response.error) {
|
|
1069
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1070
|
+
return [];
|
|
1071
|
+
}
|
|
1072
|
+
const usage = response.data?.data || [];
|
|
1073
|
+
setState((prev) => ({ ...prev, loading: false, usage }));
|
|
1074
|
+
return usage;
|
|
1075
|
+
} catch (err) {
|
|
1076
|
+
const message = err instanceof Error ? err.message : "Failed to get usage analytics";
|
|
1077
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1078
|
+
return [];
|
|
1079
|
+
}
|
|
1080
|
+
},
|
|
1081
|
+
[options]
|
|
1082
|
+
);
|
|
1083
|
+
const getDaily = useCallback5(
|
|
1084
|
+
async (filter) => {
|
|
1085
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1086
|
+
try {
|
|
1087
|
+
const response = await getDailyAnalyticsApi(filter, options);
|
|
1088
|
+
if (response.error) {
|
|
1089
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1090
|
+
return [];
|
|
1091
|
+
}
|
|
1092
|
+
const daily = response.data?.data || [];
|
|
1093
|
+
setState((prev) => ({ ...prev, loading: false, daily }));
|
|
1094
|
+
return daily;
|
|
1095
|
+
} catch (err) {
|
|
1096
|
+
const message = err instanceof Error ? err.message : "Failed to get daily analytics";
|
|
1097
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1098
|
+
return [];
|
|
1099
|
+
}
|
|
1100
|
+
},
|
|
1101
|
+
[options]
|
|
1102
|
+
);
|
|
1103
|
+
const getEvents = useCallback5(
|
|
1104
|
+
async (filter) => {
|
|
1105
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1106
|
+
try {
|
|
1107
|
+
const response = await getAnalyticsEventsApi(filter, options);
|
|
1108
|
+
if (response.error) {
|
|
1109
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1110
|
+
return [];
|
|
1111
|
+
}
|
|
1112
|
+
const events = response.data?.data || [];
|
|
1113
|
+
setState((prev) => ({ ...prev, loading: false, events }));
|
|
1114
|
+
return events;
|
|
1115
|
+
} catch (err) {
|
|
1116
|
+
const message = err instanceof Error ? err.message : "Failed to get analytics events";
|
|
1117
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1118
|
+
return [];
|
|
1119
|
+
}
|
|
1120
|
+
},
|
|
1121
|
+
[options]
|
|
1122
|
+
);
|
|
1123
|
+
const trackEvent = useCallback5(
|
|
1124
|
+
async (eventType, eventCategory, properties) => {
|
|
1125
|
+
try {
|
|
1126
|
+
const event = {
|
|
1127
|
+
sessionId: sessionIdRef.current,
|
|
1128
|
+
userId: options.userId || "",
|
|
1129
|
+
eventType,
|
|
1130
|
+
eventCategory,
|
|
1131
|
+
pagePath: typeof window !== "undefined" ? window.location.pathname : void 0,
|
|
1132
|
+
properties
|
|
1133
|
+
};
|
|
1134
|
+
await logAnalyticsEventApi(event, options);
|
|
1135
|
+
} catch {
|
|
1136
|
+
console.debug("Failed to track analytics event:", eventType);
|
|
1137
|
+
}
|
|
1138
|
+
},
|
|
1139
|
+
[options]
|
|
1140
|
+
);
|
|
1141
|
+
const trackPageView = useCallback5(
|
|
1142
|
+
async (pageName) => {
|
|
1143
|
+
await trackEvent("page_view", "navigation", {
|
|
1144
|
+
pageName: pageName || (typeof window !== "undefined" ? document.title : "")
|
|
1145
|
+
});
|
|
1146
|
+
},
|
|
1147
|
+
[trackEvent]
|
|
1148
|
+
);
|
|
1149
|
+
const getGlobalSummary = useCallback5(
|
|
1150
|
+
async (filter) => {
|
|
1151
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1152
|
+
try {
|
|
1153
|
+
const response = await getGlobalSummaryApi(filter, options);
|
|
1154
|
+
if (response.error) {
|
|
1155
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1156
|
+
return null;
|
|
1157
|
+
}
|
|
1158
|
+
setState((prev) => ({ ...prev, loading: false }));
|
|
1159
|
+
return response.data?.data || null;
|
|
1160
|
+
} catch (err) {
|
|
1161
|
+
const message = err instanceof Error ? err.message : "Failed to get global summary";
|
|
1162
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1163
|
+
return null;
|
|
1164
|
+
}
|
|
1165
|
+
},
|
|
1166
|
+
[options]
|
|
1167
|
+
);
|
|
1168
|
+
const getGlobalOrgs = useCallback5(
|
|
1169
|
+
async (filter) => {
|
|
1170
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1171
|
+
try {
|
|
1172
|
+
const response = await getGlobalOrgsAnalyticsApi(filter, options);
|
|
1173
|
+
if (response.error) {
|
|
1174
|
+
setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
|
|
1175
|
+
return [];
|
|
1176
|
+
}
|
|
1177
|
+
setState((prev) => ({ ...prev, loading: false }));
|
|
1178
|
+
return response.data?.data || [];
|
|
1179
|
+
} catch (err) {
|
|
1180
|
+
const message = err instanceof Error ? err.message : "Failed to get org analytics";
|
|
1181
|
+
setState((prev) => ({ ...prev, loading: false, error: message }));
|
|
1182
|
+
return [];
|
|
1183
|
+
}
|
|
1184
|
+
},
|
|
1185
|
+
[options]
|
|
1186
|
+
);
|
|
1187
|
+
return {
|
|
1188
|
+
// State
|
|
1189
|
+
...state,
|
|
1190
|
+
// Query functions
|
|
1191
|
+
getSummary,
|
|
1192
|
+
getChats,
|
|
1193
|
+
getAgents,
|
|
1194
|
+
getUsage,
|
|
1195
|
+
getDaily,
|
|
1196
|
+
getEvents,
|
|
1197
|
+
// Event tracking
|
|
1198
|
+
trackEvent,
|
|
1199
|
+
trackPageView,
|
|
1200
|
+
// Global analytics (admin)
|
|
1201
|
+
getGlobalSummary,
|
|
1202
|
+
getGlobalOrgs
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
var useAnalyticsContext = useProductAnalytics;
|
|
1206
|
+
|
|
1207
|
+
// hooks/use-org-provisioning.ts
|
|
1208
|
+
import { useState as useState6, useCallback as useCallback6, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
1209
|
+
function useOrgProvisioning(options) {
|
|
1210
|
+
const [state, setState] = useState6({
|
|
1211
|
+
status: "idle",
|
|
1212
|
+
progress: null,
|
|
1213
|
+
org: null,
|
|
1214
|
+
error: null,
|
|
1215
|
+
percentage: 0
|
|
1216
|
+
});
|
|
1217
|
+
const cleanupRef = useRef2(null);
|
|
1218
|
+
useEffect2(() => {
|
|
1219
|
+
return () => {
|
|
1220
|
+
if (cleanupRef.current) {
|
|
1221
|
+
cleanupRef.current();
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1224
|
+
}, []);
|
|
1225
|
+
const createOrgWithProvisioning = useCallback6(
|
|
1226
|
+
async (request) => {
|
|
1227
|
+
setState((prev) => ({
|
|
1228
|
+
...prev,
|
|
1229
|
+
status: "creating",
|
|
1230
|
+
error: null,
|
|
1231
|
+
progress: null,
|
|
1232
|
+
percentage: 0
|
|
1233
|
+
}));
|
|
1234
|
+
try {
|
|
1235
|
+
const response = await createOrgWithProvisioningApi(request, options);
|
|
1236
|
+
if (response.error) {
|
|
1237
|
+
setState((prev) => ({
|
|
1238
|
+
...prev,
|
|
1239
|
+
status: "failed",
|
|
1240
|
+
error: response.error || "Failed to create organization"
|
|
1241
|
+
}));
|
|
1242
|
+
return null;
|
|
1243
|
+
}
|
|
1244
|
+
const org = response.data?.organization || response.data?.org;
|
|
1245
|
+
if (!org) {
|
|
1246
|
+
setState((prev) => ({
|
|
1247
|
+
...prev,
|
|
1248
|
+
status: "failed",
|
|
1249
|
+
error: "No organization returned"
|
|
1250
|
+
}));
|
|
1251
|
+
return null;
|
|
1252
|
+
}
|
|
1253
|
+
setState((prev) => ({
|
|
1254
|
+
...prev,
|
|
1255
|
+
status: "provisioning",
|
|
1256
|
+
org
|
|
1257
|
+
}));
|
|
1258
|
+
const cleanup = streamProvisioningProgress(
|
|
1259
|
+
org.id,
|
|
1260
|
+
{
|
|
1261
|
+
onProgress: (progress) => {
|
|
1262
|
+
const percentage = calculateProgressPercentage(progress);
|
|
1263
|
+
const status = isProvisioningComplete(progress) ? isProvisioningSuccessful(progress) ? "completed" : progress.status === "partial" ? "partial" : "failed" : "provisioning";
|
|
1264
|
+
setState((prev) => ({
|
|
1265
|
+
...prev,
|
|
1266
|
+
status,
|
|
1267
|
+
progress,
|
|
1268
|
+
percentage,
|
|
1269
|
+
error: progress.error || null
|
|
1270
|
+
}));
|
|
1271
|
+
},
|
|
1272
|
+
onDone: () => {
|
|
1273
|
+
cleanupRef.current = null;
|
|
1274
|
+
},
|
|
1275
|
+
onError: (error) => {
|
|
1276
|
+
setState((prev) => ({
|
|
1277
|
+
...prev,
|
|
1278
|
+
status: "failed",
|
|
1279
|
+
error: error.message
|
|
1280
|
+
}));
|
|
1281
|
+
cleanupRef.current = null;
|
|
1282
|
+
},
|
|
1283
|
+
onTimeout: () => {
|
|
1284
|
+
setState((prev) => ({
|
|
1285
|
+
...prev,
|
|
1286
|
+
error: "Provisioning timed out"
|
|
1287
|
+
}));
|
|
1288
|
+
cleanupRef.current = null;
|
|
1289
|
+
}
|
|
1290
|
+
},
|
|
1291
|
+
{ baseUrl: options.baseUrl }
|
|
1292
|
+
);
|
|
1293
|
+
cleanupRef.current = cleanup;
|
|
1294
|
+
return org;
|
|
1295
|
+
} catch (err) {
|
|
1296
|
+
const message = err instanceof Error ? err.message : "Failed to create organization";
|
|
1297
|
+
setState((prev) => ({
|
|
1298
|
+
...prev,
|
|
1299
|
+
status: "failed",
|
|
1300
|
+
error: message
|
|
1301
|
+
}));
|
|
1302
|
+
return null;
|
|
1303
|
+
}
|
|
1304
|
+
},
|
|
1305
|
+
[options]
|
|
1306
|
+
);
|
|
1307
|
+
const getProvisioningStatus = useCallback6(
|
|
1308
|
+
async (orgId) => {
|
|
1309
|
+
try {
|
|
1310
|
+
const response = await getProvisioningStatusApi(orgId, options);
|
|
1311
|
+
if (response.error) {
|
|
1312
|
+
setState((prev) => ({ ...prev, error: response.error || null }));
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
const progress = response.data?.progress || null;
|
|
1316
|
+
if (progress) {
|
|
1317
|
+
setState((prev) => ({
|
|
1318
|
+
...prev,
|
|
1319
|
+
progress,
|
|
1320
|
+
percentage: calculateProgressPercentage(progress),
|
|
1321
|
+
status: isProvisioningComplete(progress) ? isProvisioningSuccessful(progress) ? "completed" : progress.status === "partial" ? "partial" : "failed" : "provisioning"
|
|
1322
|
+
}));
|
|
1323
|
+
}
|
|
1324
|
+
return progress;
|
|
1325
|
+
} catch (err) {
|
|
1326
|
+
const message = err instanceof Error ? err.message : "Failed to get provisioning status";
|
|
1327
|
+
setState((prev) => ({ ...prev, error: message }));
|
|
1328
|
+
return null;
|
|
1329
|
+
}
|
|
1330
|
+
},
|
|
1331
|
+
[options]
|
|
1332
|
+
);
|
|
1333
|
+
const retryProvisioning = useCallback6(
|
|
1334
|
+
async (orgId, artifacts) => {
|
|
1335
|
+
setState((prev) => ({
|
|
1336
|
+
...prev,
|
|
1337
|
+
status: "provisioning",
|
|
1338
|
+
error: null
|
|
1339
|
+
}));
|
|
1340
|
+
try {
|
|
1341
|
+
const request = artifacts ? { artifacts } : void 0;
|
|
1342
|
+
const response = await retryProvisioningApi(orgId, request, options);
|
|
1343
|
+
if (response.error) {
|
|
1344
|
+
setState((prev) => ({
|
|
1345
|
+
...prev,
|
|
1346
|
+
status: "failed",
|
|
1347
|
+
error: response.error || "Failed to retry provisioning"
|
|
1348
|
+
}));
|
|
1349
|
+
return false;
|
|
1350
|
+
}
|
|
1351
|
+
const cleanup = streamProvisioningProgress(
|
|
1352
|
+
orgId,
|
|
1353
|
+
{
|
|
1354
|
+
onProgress: (progress) => {
|
|
1355
|
+
const percentage = calculateProgressPercentage(progress);
|
|
1356
|
+
const status = isProvisioningComplete(progress) ? isProvisioningSuccessful(progress) ? "completed" : progress.status === "partial" ? "partial" : "failed" : "provisioning";
|
|
1357
|
+
setState((prev) => ({
|
|
1358
|
+
...prev,
|
|
1359
|
+
status,
|
|
1360
|
+
progress,
|
|
1361
|
+
percentage,
|
|
1362
|
+
error: progress.error || null
|
|
1363
|
+
}));
|
|
1364
|
+
},
|
|
1365
|
+
onDone: () => {
|
|
1366
|
+
cleanupRef.current = null;
|
|
1367
|
+
},
|
|
1368
|
+
onError: (error) => {
|
|
1369
|
+
setState((prev) => ({
|
|
1370
|
+
...prev,
|
|
1371
|
+
status: "failed",
|
|
1372
|
+
error: error.message
|
|
1373
|
+
}));
|
|
1374
|
+
cleanupRef.current = null;
|
|
1375
|
+
}
|
|
1376
|
+
},
|
|
1377
|
+
{ baseUrl: options.baseUrl }
|
|
1378
|
+
);
|
|
1379
|
+
cleanupRef.current = cleanup;
|
|
1380
|
+
return true;
|
|
1381
|
+
} catch (err) {
|
|
1382
|
+
const message = err instanceof Error ? err.message : "Failed to retry provisioning";
|
|
1383
|
+
setState((prev) => ({
|
|
1384
|
+
...prev,
|
|
1385
|
+
status: "failed",
|
|
1386
|
+
error: message
|
|
1387
|
+
}));
|
|
1388
|
+
return false;
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
[options]
|
|
1392
|
+
);
|
|
1393
|
+
const validateProvisioning = useCallback6(
|
|
1394
|
+
async (orgId) => {
|
|
1395
|
+
try {
|
|
1396
|
+
const response = await validateProvisioningApi(orgId, options);
|
|
1397
|
+
if (response.error) {
|
|
1398
|
+
setState((prev) => ({ ...prev, error: response.error || null }));
|
|
1399
|
+
return null;
|
|
1400
|
+
}
|
|
1401
|
+
return response.data || null;
|
|
1402
|
+
} catch (err) {
|
|
1403
|
+
const message = err instanceof Error ? err.message : "Failed to validate provisioning";
|
|
1404
|
+
setState((prev) => ({ ...prev, error: message }));
|
|
1405
|
+
return null;
|
|
1406
|
+
}
|
|
1407
|
+
},
|
|
1408
|
+
[options]
|
|
1409
|
+
);
|
|
1410
|
+
const cancelProvisioning = useCallback6(
|
|
1411
|
+
async (orgId) => {
|
|
1412
|
+
try {
|
|
1413
|
+
if (cleanupRef.current) {
|
|
1414
|
+
cleanupRef.current();
|
|
1415
|
+
cleanupRef.current = null;
|
|
1416
|
+
}
|
|
1417
|
+
const response = await cancelProvisioningApi(orgId, options);
|
|
1418
|
+
if (response.error) {
|
|
1419
|
+
setState((prev) => ({ ...prev, error: response.error || null }));
|
|
1420
|
+
return false;
|
|
1421
|
+
}
|
|
1422
|
+
setState((prev) => ({
|
|
1423
|
+
...prev,
|
|
1424
|
+
status: "failed",
|
|
1425
|
+
error: "Provisioning cancelled"
|
|
1426
|
+
}));
|
|
1427
|
+
return true;
|
|
1428
|
+
} catch (err) {
|
|
1429
|
+
const message = err instanceof Error ? err.message : "Failed to cancel provisioning";
|
|
1430
|
+
setState((prev) => ({ ...prev, error: message }));
|
|
1431
|
+
return false;
|
|
1432
|
+
}
|
|
1433
|
+
},
|
|
1434
|
+
[options]
|
|
1435
|
+
);
|
|
1436
|
+
const cleanupOrg = useCallback6(
|
|
1437
|
+
async (orgId) => {
|
|
1438
|
+
try {
|
|
1439
|
+
const response = await cleanupProvisioningApi(orgId, options);
|
|
1440
|
+
if (response.error) {
|
|
1441
|
+
setState((prev) => ({ ...prev, error: response.error || null }));
|
|
1442
|
+
return false;
|
|
1443
|
+
}
|
|
1444
|
+
return true;
|
|
1445
|
+
} catch (err) {
|
|
1446
|
+
const message = err instanceof Error ? err.message : "Failed to cleanup organization";
|
|
1447
|
+
setState((prev) => ({ ...prev, error: message }));
|
|
1448
|
+
return false;
|
|
1449
|
+
}
|
|
1450
|
+
},
|
|
1451
|
+
[options]
|
|
1452
|
+
);
|
|
1453
|
+
const reset = useCallback6(() => {
|
|
1454
|
+
if (cleanupRef.current) {
|
|
1455
|
+
cleanupRef.current();
|
|
1456
|
+
cleanupRef.current = null;
|
|
1457
|
+
}
|
|
1458
|
+
setState({
|
|
1459
|
+
status: "idle",
|
|
1460
|
+
progress: null,
|
|
1461
|
+
org: null,
|
|
1462
|
+
error: null,
|
|
1463
|
+
percentage: 0
|
|
1464
|
+
});
|
|
1465
|
+
}, []);
|
|
1466
|
+
return {
|
|
1467
|
+
state,
|
|
1468
|
+
createOrgWithProvisioning,
|
|
1469
|
+
getProvisioningStatus,
|
|
1470
|
+
retryProvisioning,
|
|
1471
|
+
validateProvisioning,
|
|
1472
|
+
cancelProvisioning,
|
|
1473
|
+
cleanupOrg,
|
|
1474
|
+
reset,
|
|
1475
|
+
// Helper functions
|
|
1476
|
+
isComplete: state.status === "completed",
|
|
1477
|
+
isFailed: state.status === "failed",
|
|
1478
|
+
isPartial: state.status === "partial",
|
|
1479
|
+
isProvisioning: state.status === "provisioning" || state.status === "creating",
|
|
1480
|
+
failedArtifacts: state.progress ? getFailedArtifacts(state.progress) : [],
|
|
1481
|
+
hasCriticalFailures: state.progress ? hasCriticalFailures(state.progress) : false
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
729
1484
|
export {
|
|
1485
|
+
useAnalyticsContext,
|
|
730
1486
|
useInvitesAdmin,
|
|
731
1487
|
useOrgAdmin,
|
|
1488
|
+
useOrgProvisioning,
|
|
732
1489
|
useOrgSettings,
|
|
1490
|
+
useProductAnalytics,
|
|
733
1491
|
useUsersAdmin
|
|
734
1492
|
};
|
|
735
1493
|
//# sourceMappingURL=index.js.map
|