@elevasis/ui 1.2.1 → 1.3.1
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/CoreAuthKitInner-3J4RVQO6.js +43 -0
- package/dist/api/index.d.ts +32 -18
- package/dist/api/index.js +4 -2
- package/dist/auth/context.d.ts +23 -5
- package/dist/auth/index.d.ts +119 -30
- package/dist/auth/index.js +6 -3
- package/dist/chunk-2JBWPFHF.js +108 -0
- package/dist/chunk-4VGWQ5AN.js +91 -0
- package/dist/chunk-72HOBFMP.js +87 -0
- package/dist/{chunk-WNWKOCGJ.js → chunk-A3MCANC6.js} +296 -2
- package/dist/{chunk-JKERRYVS.js → chunk-BLO4SISK.js} +7 -3
- package/dist/chunk-DD3CCMCZ.js +15 -0
- package/dist/chunk-FWZJH3TL.js +13 -0
- package/dist/{chunk-GEFB5YIR.js → chunk-JBFFCZI4.js} +1 -1
- package/dist/chunk-JGJSZ3UE.js +47 -0
- package/dist/{chunk-7AI5ZYJ4.js → chunk-JVAZHVNV.js} +2 -94
- package/dist/{chunk-ZGHDPDTF.js → chunk-JYSYHVLU.js} +3 -3
- package/dist/{chunk-5UWFGBFM.js → chunk-L2CM2CUA.js} +16 -4
- package/dist/chunk-NEK6JKPW.js +75 -0
- package/dist/{chunk-J3FALDQE.js → chunk-NXHL23JW.js} +7 -13
- package/dist/{chunk-OUHGHTE7.js → chunk-O3PY6B6E.js} +3 -2
- package/dist/{chunk-YULUKCS6.js → chunk-PVVQTENF.js} +1 -1
- package/dist/chunk-TIRMFDM4.js +33 -0
- package/dist/{chunk-PYL4XW6H.js → chunk-TMFCNFLW.js} +1 -1
- package/dist/{chunk-S66I2PYB.js → chunk-TN3PU2WK.js} +1 -1
- package/dist/chunk-TYV5NJV2.js +1 -0
- package/dist/{chunk-B64YDSAY.js → chunk-TZPAA4RC.js} +54 -97
- package/dist/chunk-UMXDDEAG.js +148 -0
- package/dist/chunk-XLV6LYN2.js +157 -0
- package/dist/components/command-queue/index.js +6 -4
- package/dist/components/index.js +9 -7
- package/dist/components/notifications/index.js +4 -3
- package/dist/display/index.js +3 -2
- package/dist/hooks/index.d.ts +2630 -3
- package/dist/hooks/index.js +9 -5
- package/dist/hooks/published.d.ts +2630 -3
- package/dist/hooks/published.js +7 -3
- package/dist/index.d.ts +759 -164
- package/dist/index.js +24 -18
- package/dist/initialization/index.d.ts +49 -1
- package/dist/initialization/index.js +5 -2
- package/dist/organization/index.d.ts +61 -2
- package/dist/organization/index.js +5 -2
- package/dist/profile/index.d.ts +30 -2
- package/dist/profile/index.js +2 -1
- package/dist/provider/index.d.ts +116 -43
- package/dist/provider/index.js +10 -6
- package/dist/provider/published.d.ts +88 -28
- package/dist/provider/published.js +9 -4
- package/dist/supabase/index.js +2 -47
- package/dist/utils/index.js +2 -1
- package/package.json +15 -2
- package/dist/CoreAuthKitInner-KM72EYJS.js +0 -19
- package/dist/chunk-GDV44UWF.js +0 -138
- package/dist/chunk-HBRMWW6V.js +0 -43
- package/dist/chunk-NIAVTSMB.js +0 -21
- package/dist/chunk-QSVZP2NU.js +0 -214
- package/dist/chunk-ZQVPUAGR.js +0 -89
- /package/dist/{chunk-Q47SPRY7.js → chunk-RNP5R5I3.js} +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useSupabase } from './chunk-JGJSZ3UE.js';
|
|
2
|
+
import { UuidSchema, ResourceTypeSchema, NonEmptyStringSchema, OriginResourceTypeSchema } from './chunk-BLO4SISK.js';
|
|
3
|
+
import { useNotificationAdapter } from './chunk-TIRMFDM4.js';
|
|
4
|
+
import { useStableAccessToken } from './chunk-FWZJH3TL.js';
|
|
2
5
|
import { useElevasisServices } from './chunk-KA7LO7U5.js';
|
|
3
6
|
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
|
|
4
7
|
import { z } from 'zod';
|
|
8
|
+
import { useCallback, useState, useEffect, useMemo, useId, useRef } from 'react';
|
|
5
9
|
|
|
6
10
|
// src/hooks/executions/queryKeys.ts
|
|
7
11
|
var executionsKeys = {
|
|
@@ -658,6 +662,43 @@ function useExecutionHealth({ timeRange }) {
|
|
|
658
662
|
// 30s monitoring stale time
|
|
659
663
|
});
|
|
660
664
|
}
|
|
665
|
+
function useErrorNotification() {
|
|
666
|
+
const adapter = useNotificationAdapter();
|
|
667
|
+
return useCallback(
|
|
668
|
+
(error) => {
|
|
669
|
+
adapter.apiError(error);
|
|
670
|
+
},
|
|
671
|
+
[adapter]
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
function useSuccessNotification() {
|
|
675
|
+
const adapter = useNotificationAdapter();
|
|
676
|
+
return useCallback((title, message) => adapter.success(title, message), [adapter]);
|
|
677
|
+
}
|
|
678
|
+
function useWarningNotification() {
|
|
679
|
+
const adapter = useNotificationAdapter();
|
|
680
|
+
return useCallback((title, message) => adapter.warning(title, message), [adapter]);
|
|
681
|
+
}
|
|
682
|
+
function useBatchDelete(tableName, invalidateQueryKeys) {
|
|
683
|
+
const supabase = useSupabase();
|
|
684
|
+
const queryClient = useQueryClient();
|
|
685
|
+
const adapter = useNotificationAdapter();
|
|
686
|
+
return useMutation({
|
|
687
|
+
mutationFn: async (ids) => {
|
|
688
|
+
if (ids.length === 0) return;
|
|
689
|
+
const { error } = await supabase.from(tableName).delete().in("id", ids);
|
|
690
|
+
if (error) throw error;
|
|
691
|
+
},
|
|
692
|
+
onSuccess: () => {
|
|
693
|
+
for (const key of invalidateQueryKeys) {
|
|
694
|
+
queryClient.invalidateQueries({ queryKey: key });
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
onError: (err) => {
|
|
698
|
+
adapter.apiError(err);
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
}
|
|
661
702
|
|
|
662
703
|
// src/hooks/observability/queryKeys.ts
|
|
663
704
|
var observabilityKeys = {
|
|
@@ -1063,5 +1104,258 @@ function useDeleteSchedule() {
|
|
|
1063
1104
|
}
|
|
1064
1105
|
});
|
|
1065
1106
|
}
|
|
1107
|
+
function usePaginationState(pageSize, resetDeps, total) {
|
|
1108
|
+
const [page, setPage] = useState(1);
|
|
1109
|
+
useEffect(() => {
|
|
1110
|
+
if (resetDeps) {
|
|
1111
|
+
setPage(1);
|
|
1112
|
+
}
|
|
1113
|
+
}, resetDeps ?? []);
|
|
1114
|
+
useEffect(() => {
|
|
1115
|
+
if (total === void 0) return;
|
|
1116
|
+
const lastPage = Math.max(1, Math.ceil(total / pageSize));
|
|
1117
|
+
if (page > lastPage) {
|
|
1118
|
+
setPage(lastPage);
|
|
1119
|
+
}
|
|
1120
|
+
}, [total, pageSize]);
|
|
1121
|
+
return useMemo(
|
|
1122
|
+
() => ({
|
|
1123
|
+
page,
|
|
1124
|
+
setPage,
|
|
1125
|
+
offset: (page - 1) * pageSize,
|
|
1126
|
+
totalPages: (total2) => Math.ceil(total2 / pageSize)
|
|
1127
|
+
}),
|
|
1128
|
+
[page, pageSize]
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
function useTableSelection(items, allItems) {
|
|
1132
|
+
const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
|
|
1133
|
+
const pageIds = useMemo(() => new Set(items.map((i) => i.id)), [items]);
|
|
1134
|
+
useEffect(() => {
|
|
1135
|
+
setSelectedIds((prev) => {
|
|
1136
|
+
const validIds = allItems ? new Set(allItems.map((i) => i.id)) : pageIds;
|
|
1137
|
+
const next = new Set([...prev].filter((id) => validIds.has(id)));
|
|
1138
|
+
return next.size === prev.size ? prev : next;
|
|
1139
|
+
});
|
|
1140
|
+
}, [allItems, pageIds]);
|
|
1141
|
+
const toggle = useCallback((id) => {
|
|
1142
|
+
setSelectedIds((prev) => {
|
|
1143
|
+
const next = new Set(prev);
|
|
1144
|
+
if (next.has(id)) next.delete(id);
|
|
1145
|
+
else next.add(id);
|
|
1146
|
+
return next;
|
|
1147
|
+
});
|
|
1148
|
+
}, []);
|
|
1149
|
+
const togglePage = useCallback(() => {
|
|
1150
|
+
setSelectedIds((prev) => {
|
|
1151
|
+
const allPageSelected = items.every((i) => prev.has(i.id));
|
|
1152
|
+
const next = new Set(prev);
|
|
1153
|
+
if (allPageSelected) {
|
|
1154
|
+
for (const item of items) next.delete(item.id);
|
|
1155
|
+
} else {
|
|
1156
|
+
for (const item of items) next.add(item.id);
|
|
1157
|
+
}
|
|
1158
|
+
return next;
|
|
1159
|
+
});
|
|
1160
|
+
}, [items]);
|
|
1161
|
+
const clear = useCallback(() => setSelectedIds(/* @__PURE__ */ new Set()), []);
|
|
1162
|
+
const isPageAllSelected = items.length > 0 && items.every((i) => selectedIds.has(i.id));
|
|
1163
|
+
const isPagePartiallySelected = !isPageAllSelected && items.some((i) => selectedIds.has(i.id));
|
|
1164
|
+
return {
|
|
1165
|
+
selectedIds,
|
|
1166
|
+
toggle,
|
|
1167
|
+
togglePage,
|
|
1168
|
+
clear,
|
|
1169
|
+
isPageAllSelected,
|
|
1170
|
+
isPagePartiallySelected,
|
|
1171
|
+
selectedCount: selectedIds.size,
|
|
1172
|
+
isSelected: (id) => selectedIds.has(id)
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
function useTableSort(defaultColumn, defaultDirection = "desc") {
|
|
1176
|
+
const [sort, setSort] = useState({ column: defaultColumn, direction: defaultDirection });
|
|
1177
|
+
const toggleSort = useCallback((column) => {
|
|
1178
|
+
setSort((prev) => {
|
|
1179
|
+
if (prev.column === column) {
|
|
1180
|
+
return { column, direction: prev.direction === "asc" ? "desc" : "asc" };
|
|
1181
|
+
}
|
|
1182
|
+
return { column, direction: "desc" };
|
|
1183
|
+
});
|
|
1184
|
+
}, []);
|
|
1185
|
+
return { sort, toggleSort };
|
|
1186
|
+
}
|
|
1187
|
+
function sortData(data, sort, accessors) {
|
|
1188
|
+
const accessor = accessors[sort.column];
|
|
1189
|
+
if (!accessor) return data;
|
|
1190
|
+
return [...data].sort((a, b) => {
|
|
1191
|
+
const aVal = accessor(a);
|
|
1192
|
+
const bVal = accessor(b);
|
|
1193
|
+
if (aVal == null && bVal == null) return 0;
|
|
1194
|
+
if (aVal == null) return 1;
|
|
1195
|
+
if (bVal == null) return -1;
|
|
1196
|
+
let comparison = 0;
|
|
1197
|
+
if (typeof aVal === "string" && typeof bVal === "string") {
|
|
1198
|
+
comparison = aVal.localeCompare(bVal);
|
|
1199
|
+
} else if (typeof aVal === "number" && typeof bVal === "number") {
|
|
1200
|
+
comparison = aVal - bVal;
|
|
1201
|
+
} else {
|
|
1202
|
+
comparison = String(aVal).localeCompare(String(bVal));
|
|
1203
|
+
}
|
|
1204
|
+
return sort.direction === "asc" ? comparison : -comparison;
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
function useSortedData(data, defaultColumn, accessors, defaultDirection = "desc") {
|
|
1208
|
+
const { sort, toggleSort } = useTableSort(defaultColumn, defaultDirection);
|
|
1209
|
+
const sorted = useMemo(() => sortData(data, sort, accessors), [data, sort, accessors]);
|
|
1210
|
+
return { sorted, sort, toggleSort };
|
|
1211
|
+
}
|
|
1212
|
+
function createUseFeatureAccess({
|
|
1213
|
+
useInitialization,
|
|
1214
|
+
useOrganization,
|
|
1215
|
+
optInFeatures = [],
|
|
1216
|
+
getCoursesByGroup = () => []
|
|
1217
|
+
}) {
|
|
1218
|
+
return function useFeatureAccess() {
|
|
1219
|
+
const { profile, organizationReady } = useInitialization();
|
|
1220
|
+
const { currentMembership } = useOrganization();
|
|
1221
|
+
const { orgConfig, membershipConfig } = useMemo(() => {
|
|
1222
|
+
const organizationConfig = currentMembership?.organization?.config;
|
|
1223
|
+
const memberConfig = currentMembership?.config;
|
|
1224
|
+
return { orgConfig: organizationConfig, membershipConfig: memberConfig };
|
|
1225
|
+
}, [currentMembership]);
|
|
1226
|
+
const userConfig = profile?.config;
|
|
1227
|
+
const checkFeature = useCallback(
|
|
1228
|
+
(featureKey) => {
|
|
1229
|
+
const key = featureKey;
|
|
1230
|
+
const orgValue = orgConfig?.features?.[key];
|
|
1231
|
+
if (!profile?.is_platform_admin) {
|
|
1232
|
+
const membershipValue = membershipConfig?.features?.[key];
|
|
1233
|
+
if (membershipValue === false) return { allowed: false, restrictedBy: "membership" };
|
|
1234
|
+
if (membershipValue === true) return { allowed: true, restrictedBy: null };
|
|
1235
|
+
}
|
|
1236
|
+
if (optInFeatures.includes(featureKey)) {
|
|
1237
|
+
return orgValue === true ? { allowed: true, restrictedBy: null } : { allowed: false, restrictedBy: "org" };
|
|
1238
|
+
}
|
|
1239
|
+
return orgValue === false ? { allowed: false, restrictedBy: "org" } : { allowed: true, restrictedBy: null };
|
|
1240
|
+
},
|
|
1241
|
+
[profile?.is_platform_admin, membershipConfig, orgConfig]
|
|
1242
|
+
);
|
|
1243
|
+
const hasFeature = useCallback((featureKey) => checkFeature(featureKey).allowed, [checkFeature]);
|
|
1244
|
+
const hasTrainingAccess = useCallback(() => {
|
|
1245
|
+
if (profile?.is_platform_admin) return true;
|
|
1246
|
+
return userConfig?.training?.enabled ?? true;
|
|
1247
|
+
}, [profile?.is_platform_admin, userConfig?.training?.enabled]);
|
|
1248
|
+
const getAllowedCourses = useCallback(() => {
|
|
1249
|
+
if (userConfig?.training?.allowed_courses?.length) {
|
|
1250
|
+
return userConfig.training.allowed_courses;
|
|
1251
|
+
}
|
|
1252
|
+
return null;
|
|
1253
|
+
}, [userConfig?.training?.allowed_courses]);
|
|
1254
|
+
const getResolvedCourseAccess = useCallback(() => {
|
|
1255
|
+
if (profile?.is_platform_admin) return null;
|
|
1256
|
+
const orgGroups = orgConfig?.training?.allowed_course_groups ?? [];
|
|
1257
|
+
const userGroups = userConfig?.training?.allowed_course_groups ?? [];
|
|
1258
|
+
const userCourses = userConfig?.training?.allowed_courses ?? [];
|
|
1259
|
+
if (!orgGroups.length && !userGroups.length && !userCourses.length) return null;
|
|
1260
|
+
const foundationCourses = getCoursesByGroup("foundation");
|
|
1261
|
+
const orgCourseSlugs = orgGroups.flatMap(getCoursesByGroup);
|
|
1262
|
+
const userGroupCourseSlugs = userGroups.flatMap(getCoursesByGroup);
|
|
1263
|
+
return [.../* @__PURE__ */ new Set([...foundationCourses, ...orgCourseSlugs, ...userGroupCourseSlugs, ...userCourses])];
|
|
1264
|
+
}, [
|
|
1265
|
+
profile?.is_platform_admin,
|
|
1266
|
+
orgConfig?.training?.allowed_course_groups,
|
|
1267
|
+
userConfig?.training?.allowed_course_groups,
|
|
1268
|
+
userConfig?.training?.allowed_courses
|
|
1269
|
+
]);
|
|
1270
|
+
const hasAccessToCourse = useCallback(
|
|
1271
|
+
(courseSlug) => {
|
|
1272
|
+
const resolved = getResolvedCourseAccess();
|
|
1273
|
+
if (resolved === null) return true;
|
|
1274
|
+
return resolved.includes(courseSlug);
|
|
1275
|
+
},
|
|
1276
|
+
[getResolvedCourseAccess]
|
|
1277
|
+
);
|
|
1278
|
+
const getEnabledGroups = useCallback(() => {
|
|
1279
|
+
const orgGroups = orgConfig?.training?.allowed_course_groups ?? [];
|
|
1280
|
+
const userGroups = userConfig?.training?.allowed_course_groups ?? [];
|
|
1281
|
+
return [.../* @__PURE__ */ new Set(["foundation", ...orgGroups, ...userGroups])];
|
|
1282
|
+
}, [orgConfig?.training?.allowed_course_groups, userConfig?.training?.allowed_course_groups]);
|
|
1283
|
+
return {
|
|
1284
|
+
orgConfig,
|
|
1285
|
+
membershipConfig,
|
|
1286
|
+
userConfig,
|
|
1287
|
+
hasFeature,
|
|
1288
|
+
checkFeature,
|
|
1289
|
+
hasTrainingAccess,
|
|
1290
|
+
getAllowedCourses,
|
|
1291
|
+
getResolvedCourseAccess,
|
|
1292
|
+
hasAccessToCourse,
|
|
1293
|
+
getEnabledGroups,
|
|
1294
|
+
isReady: organizationReady
|
|
1295
|
+
};
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function useSSEConnection({
|
|
1299
|
+
manager,
|
|
1300
|
+
connectionKey,
|
|
1301
|
+
url,
|
|
1302
|
+
enabled = true,
|
|
1303
|
+
headers,
|
|
1304
|
+
onmessage,
|
|
1305
|
+
onopen,
|
|
1306
|
+
onerror,
|
|
1307
|
+
onclose
|
|
1308
|
+
}) {
|
|
1309
|
+
const [connected, setConnected] = useState(false);
|
|
1310
|
+
const [error, setError] = useState(null);
|
|
1311
|
+
const getAccessToken = useStableAccessToken();
|
|
1312
|
+
const subscriberId = useId();
|
|
1313
|
+
const onmessageRef = useRef(onmessage);
|
|
1314
|
+
const onopenRef = useRef(onopen);
|
|
1315
|
+
const onerrorRef = useRef(onerror);
|
|
1316
|
+
const oncloseRef = useRef(onclose);
|
|
1317
|
+
const headersRef = useRef(headers);
|
|
1318
|
+
onmessageRef.current = onmessage;
|
|
1319
|
+
onopenRef.current = onopen;
|
|
1320
|
+
onerrorRef.current = onerror;
|
|
1321
|
+
oncloseRef.current = onclose;
|
|
1322
|
+
headersRef.current = headers;
|
|
1323
|
+
useEffect(() => {
|
|
1324
|
+
if (!enabled) return;
|
|
1325
|
+
const unsubscribe = manager.subscribe(connectionKey, subscriberId, {
|
|
1326
|
+
url,
|
|
1327
|
+
getToken: getAccessToken,
|
|
1328
|
+
headers: headersRef.current ?? {},
|
|
1329
|
+
onopen(response) {
|
|
1330
|
+
if (response.ok) {
|
|
1331
|
+
setConnected(true);
|
|
1332
|
+
setError(null);
|
|
1333
|
+
}
|
|
1334
|
+
const customError = onopenRef.current?.(response);
|
|
1335
|
+
if (customError) setError(customError);
|
|
1336
|
+
},
|
|
1337
|
+
onmessage(event) {
|
|
1338
|
+
if (!event.data || event.data.trim() === "") return;
|
|
1339
|
+
onmessageRef.current(event.data);
|
|
1340
|
+
},
|
|
1341
|
+
onerror(err) {
|
|
1342
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
1343
|
+
setConnected(false);
|
|
1344
|
+
setError(msg);
|
|
1345
|
+
onerrorRef.current?.(err instanceof Error ? err : new Error(msg));
|
|
1346
|
+
},
|
|
1347
|
+
onclose() {
|
|
1348
|
+
setConnected(false);
|
|
1349
|
+
oncloseRef.current?.();
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
return () => {
|
|
1353
|
+
unsubscribe();
|
|
1354
|
+
setConnected(false);
|
|
1355
|
+
setError(null);
|
|
1356
|
+
};
|
|
1357
|
+
}, [enabled, connectionKey, url, subscriberId, getAccessToken, manager]);
|
|
1358
|
+
return { connected, error };
|
|
1359
|
+
}
|
|
1066
1360
|
|
|
1067
|
-
export { OperationsService, executionsKeys, observabilityKeys, scheduleKeys, useActivities, useActivityTrend, useBulkDeleteExecutions, useBusinessImpact, useCancelExecution, useCancelSchedule, useCostBreakdown, useCostByModel, useCostSummary, useCostTrends, useCreateSchedule, useDashboardMetrics, useDeleteExecution, useDeleteSchedule, useErrorAnalysis, useErrorDetail, useErrorDetails, useErrorDistribution, useErrorTrends, useExecuteAsync, useExecution, useExecutionHealth, useExecutionLogs, useExecutions, useGetExecutionHistory, useGetSchedule, useListSchedules, usePauseSchedule, useResolveAllErrors, useResolveError, useResolveErrorsByExecution, useResourceDefinition, useResources, useResumeSchedule, useRetryExecution, useTopFailingResources, useUnresolveError, useUpdateAnchor, useUpdateSchedule };
|
|
1361
|
+
export { OperationsService, createUseFeatureAccess, executionsKeys, observabilityKeys, scheduleKeys, sortData, useActivities, useActivityTrend, useBatchDelete, useBulkDeleteExecutions, useBusinessImpact, useCancelExecution, useCancelSchedule, useCostBreakdown, useCostByModel, useCostSummary, useCostTrends, useCreateSchedule, useDashboardMetrics, useDeleteExecution, useDeleteSchedule, useErrorAnalysis, useErrorDetail, useErrorDetails, useErrorDistribution, useErrorNotification, useErrorTrends, useExecuteAsync, useExecution, useExecutionHealth, useExecutionLogs, useExecutions, useGetExecutionHistory, useGetSchedule, useListSchedules, usePaginationState, usePauseSchedule, useResolveAllErrors, useResolveError, useResolveErrorsByExecution, useResourceDefinition, useResources, useResumeSchedule, useRetryExecution, useSSEConnection, useSortedData, useSuccessNotification, useTableSelection, useTableSort, useTopFailingResources, useUnresolveError, useUpdateAnchor, useUpdateSchedule, useWarningNotification };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { useNotificationAdapter } from './chunk-TIRMFDM4.js';
|
|
1
2
|
import { useElevasisServices } from './chunk-KA7LO7U5.js';
|
|
2
|
-
import { showApiErrorNotification } from './chunk-7AI5ZYJ4.js';
|
|
3
3
|
import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -26,6 +26,8 @@ z.object({
|
|
|
26
26
|
startDate: z.string().datetime(),
|
|
27
27
|
endDate: z.string().datetime()
|
|
28
28
|
});
|
|
29
|
+
|
|
30
|
+
// ../core/src/operations/notifications/api-schemas.ts
|
|
29
31
|
var NotificationCategorySchema = z.enum(["info", "queue", "alert", "error", "system"]);
|
|
30
32
|
var GetNotificationsQuerySchema = z.object({
|
|
31
33
|
limit: z.coerce.number().int().min(1).max(100).default(50),
|
|
@@ -47,6 +49,7 @@ z.object({
|
|
|
47
49
|
function useMarkAsRead() {
|
|
48
50
|
const queryClient = useQueryClient();
|
|
49
51
|
const { apiRequest } = useElevasisServices();
|
|
52
|
+
const notify = useNotificationAdapter();
|
|
50
53
|
return useMutation({
|
|
51
54
|
mutationFn: async (notificationId) => {
|
|
52
55
|
MarkAsReadParamsSchema.parse({ id: notificationId });
|
|
@@ -58,13 +61,14 @@ function useMarkAsRead() {
|
|
|
58
61
|
queryClient.invalidateQueries({ queryKey: ["notifications"] });
|
|
59
62
|
},
|
|
60
63
|
onError: (error) => {
|
|
61
|
-
|
|
64
|
+
notify.apiError(error);
|
|
62
65
|
}
|
|
63
66
|
});
|
|
64
67
|
}
|
|
65
68
|
function useMarkAllAsRead() {
|
|
66
69
|
const queryClient = useQueryClient();
|
|
67
70
|
const { apiRequest } = useElevasisServices();
|
|
71
|
+
const notify = useNotificationAdapter();
|
|
68
72
|
return useMutation({
|
|
69
73
|
mutationFn: async () => {
|
|
70
74
|
await apiRequest("/notifications/mark-all-read", {
|
|
@@ -75,7 +79,7 @@ function useMarkAllAsRead() {
|
|
|
75
79
|
queryClient.invalidateQueries({ queryKey: ["notifications"] });
|
|
76
80
|
},
|
|
77
81
|
onError: (error) => {
|
|
78
|
-
|
|
82
|
+
notify.apiError(error);
|
|
79
83
|
}
|
|
80
84
|
});
|
|
81
85
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/organization/context/OrganizationContext.tsx
|
|
4
|
+
var OrganizationContext = createContext(null);
|
|
5
|
+
function useOrganization() {
|
|
6
|
+
const ctx = useContext(OrganizationContext);
|
|
7
|
+
if (!ctx) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
"useOrganization must be used within an OrganizationProvider. Wrap your app (or the relevant subtree) with <OrganizationProvider>."
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { OrganizationContext, useOrganization };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useAuthContext } from './chunk-7PLEQFHO.js';
|
|
2
|
+
import { useRef, useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
function useStableAccessToken() {
|
|
5
|
+
const { getAccessToken } = useAuthContext();
|
|
6
|
+
const getAccessTokenRef = useRef(getAccessToken);
|
|
7
|
+
getAccessTokenRef.current = getAccessToken;
|
|
8
|
+
return useCallback(() => {
|
|
9
|
+
return getAccessTokenRef.current();
|
|
10
|
+
}, []);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { useStableAccessToken };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useUserProfile } from './chunk-
|
|
1
|
+
import { useUserProfile } from './chunk-L2CM2CUA.js';
|
|
2
2
|
import { useAuthContext } from './chunk-7PLEQFHO.js';
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
4
|
import { Button, Loader, Menu, Text, Badge } from '@mantine/core';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useAuthContext } from './chunk-7PLEQFHO.js';
|
|
2
|
+
import { createClient } from '@supabase/supabase-js';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
|
|
5
|
+
function getSupabaseConfig() {
|
|
6
|
+
const url = import.meta.env?.VITE_SUPABASE_URL;
|
|
7
|
+
const anonKey = import.meta.env?.VITE_SUPABASE_ANON_KEY;
|
|
8
|
+
if (!url || !anonKey) {
|
|
9
|
+
throw new Error("Missing Supabase environment variables (VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY)");
|
|
10
|
+
}
|
|
11
|
+
return { url, anonKey };
|
|
12
|
+
}
|
|
13
|
+
var _supabase = null;
|
|
14
|
+
function getSupabaseClient() {
|
|
15
|
+
if (!_supabase) {
|
|
16
|
+
const { url, anonKey } = getSupabaseConfig();
|
|
17
|
+
_supabase = createClient(url, anonKey);
|
|
18
|
+
}
|
|
19
|
+
return _supabase;
|
|
20
|
+
}
|
|
21
|
+
var useSupabase = () => {
|
|
22
|
+
const { getAccessToken } = useAuthContext();
|
|
23
|
+
const { url, anonKey } = getSupabaseConfig();
|
|
24
|
+
return useMemo(
|
|
25
|
+
() => createClient(url, anonKey, {
|
|
26
|
+
global: {
|
|
27
|
+
headers: {
|
|
28
|
+
// Additional headers if needed
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
accessToken: async () => {
|
|
32
|
+
try {
|
|
33
|
+
const token = await getAccessToken();
|
|
34
|
+
if (!token) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return token;
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
[getAccessToken, url, anonKey]
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { getSupabaseClient, useSupabase };
|
|
@@ -1,99 +1,7 @@
|
|
|
1
|
+
import { getErrorInfo, formatErrorMessage, getErrorTitle } from './chunk-4VGWQ5AN.js';
|
|
1
2
|
import { notifications } from '@mantine/notifications';
|
|
2
3
|
import { IconUser, IconExternalLink, IconPlug, IconBolt, IconGitBranch, IconBrain } from '@tabler/icons-react';
|
|
3
4
|
|
|
4
|
-
// src/utils/notify.tsx
|
|
5
|
-
|
|
6
|
-
// src/utils/error-utils.ts
|
|
7
|
-
var APIClientError = class extends Error {
|
|
8
|
-
statusCode;
|
|
9
|
-
code;
|
|
10
|
-
requestId;
|
|
11
|
-
fields;
|
|
12
|
-
retryAfter;
|
|
13
|
-
constructor(message, code, statusCode, requestId, fields, retryAfter) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.name = "APIClientError";
|
|
16
|
-
this.code = code;
|
|
17
|
-
this.statusCode = statusCode;
|
|
18
|
-
this.requestId = requestId;
|
|
19
|
-
this.fields = fields;
|
|
20
|
-
this.retryAfter = retryAfter;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
function isAPIClientError(error) {
|
|
24
|
-
return error instanceof APIClientError;
|
|
25
|
-
}
|
|
26
|
-
function getErrorInfo(error) {
|
|
27
|
-
if (isAPIClientError(error)) {
|
|
28
|
-
return {
|
|
29
|
-
message: error.message,
|
|
30
|
-
code: error.code,
|
|
31
|
-
requestId: error.requestId,
|
|
32
|
-
statusCode: error.statusCode,
|
|
33
|
-
fields: error.fields,
|
|
34
|
-
retryAfter: error.retryAfter
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
if (error instanceof Error) {
|
|
38
|
-
return {
|
|
39
|
-
message: error.message
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
message: String(error)
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function getErrorTitle(code) {
|
|
47
|
-
if (!code) return "Error";
|
|
48
|
-
switch (code) {
|
|
49
|
-
case "VALIDATION_ERROR":
|
|
50
|
-
return "Validation Error";
|
|
51
|
-
case "AUTHENTICATION_FAILED":
|
|
52
|
-
return "Authentication Required";
|
|
53
|
-
case "FORBIDDEN":
|
|
54
|
-
return "Access Denied";
|
|
55
|
-
case "NOT_FOUND":
|
|
56
|
-
return "Not Found";
|
|
57
|
-
case "CONFLICT":
|
|
58
|
-
return "Conflict";
|
|
59
|
-
case "RATE_LIMIT_EXCEEDED":
|
|
60
|
-
return "Rate Limit Exceeded";
|
|
61
|
-
case "INTERNAL_SERVER_ERROR":
|
|
62
|
-
return "Server Error";
|
|
63
|
-
case "SERVICE_UNAVAILABLE":
|
|
64
|
-
return "Service Temporarily Unavailable";
|
|
65
|
-
default:
|
|
66
|
-
return "Error";
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function formatErrorMessage(message, requestId, fields, retryAfter) {
|
|
70
|
-
let formatted = message;
|
|
71
|
-
if (fields && Object.keys(fields).length > 0) {
|
|
72
|
-
const fieldErrors = [];
|
|
73
|
-
for (const [field, errors] of Object.entries(fields)) {
|
|
74
|
-
const fieldName = field === "root" || field === "_root" ? "Request" : field;
|
|
75
|
-
errors.forEach((error) => {
|
|
76
|
-
fieldErrors.push(`\u2022 ${fieldName}: ${error}`);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
if (fieldErrors.length > 0) {
|
|
80
|
-
formatted = fieldErrors.join("\n");
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (retryAfter) {
|
|
84
|
-
formatted += `
|
|
85
|
-
|
|
86
|
-
Please wait ${retryAfter} seconds before retrying.`;
|
|
87
|
-
}
|
|
88
|
-
if (requestId) {
|
|
89
|
-
formatted += `
|
|
90
|
-
|
|
91
|
-
Request ID: ${requestId}`;
|
|
92
|
-
}
|
|
93
|
-
return formatted;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// src/utils/notify.tsx
|
|
97
5
|
var showInfoNotification = (message) => {
|
|
98
6
|
notifications.show({
|
|
99
7
|
title: "Info",
|
|
@@ -199,4 +107,4 @@ function getResourceIcon(type) {
|
|
|
199
107
|
return iconNameToComponent[iconName];
|
|
200
108
|
}
|
|
201
109
|
|
|
202
|
-
export {
|
|
110
|
+
export { formatDate, getResourceColor, getResourceIcon, showApiErrorNotification, showErrorNotification, showInfoNotification, showSuccessNotification, showWarningNotification, validateEmail };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useSubmitAction, useDeleteTask } from './chunk-
|
|
1
|
+
import { useSubmitAction, useDeleteTask } from './chunk-NXHL23JW.js';
|
|
2
2
|
import { FormFieldRenderer } from './chunk-PSLKGOBZ.js';
|
|
3
|
-
import { ContextViewer, JsonViewer } from './chunk-
|
|
4
|
-
import { getErrorInfo, formatErrorMessage } from './chunk-
|
|
3
|
+
import { ContextViewer, JsonViewer } from './chunk-O3PY6B6E.js';
|
|
4
|
+
import { getErrorInfo, formatErrorMessage } from './chunk-4VGWQ5AN.js';
|
|
5
5
|
import { Modal, Stack, Title, Text, Textarea, Alert, Group, Button, Card, ThemeIcon, Badge, Loader, Menu, ActionIcon, Accordion } from '@mantine/core';
|
|
6
6
|
import { IconMail, IconSend, IconFileText, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconAlertCircle, IconRobot, IconGitBranch, IconDotsVertical, IconTrash, IconPlayerPlay, IconExternalLink } from '@tabler/icons-react';
|
|
7
7
|
import { useState } from 'react';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useElevasisServices } from './chunk-KA7LO7U5.js';
|
|
2
2
|
import { useAuthContext } from './chunk-7PLEQFHO.js';
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
3
|
+
import { createContext, useState, useEffect, useContext, createElement } from 'react';
|
|
4
4
|
|
|
5
5
|
// src/profile/services/UserProfileService.ts
|
|
6
6
|
var UserProfileService = class {
|
|
@@ -65,8 +65,6 @@ var UserProfileService = class {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
|
-
|
|
69
|
-
// src/profile/hooks/useUserProfile.ts
|
|
70
68
|
var useUserProfile = (options) => {
|
|
71
69
|
const { user, isLoading: authLoading } = useAuthContext();
|
|
72
70
|
const { apiRequest } = useElevasisServices();
|
|
@@ -125,5 +123,19 @@ var useUserProfile = (options) => {
|
|
|
125
123
|
refetch
|
|
126
124
|
};
|
|
127
125
|
};
|
|
126
|
+
var ProfileContext = createContext(null);
|
|
127
|
+
function useProfile() {
|
|
128
|
+
const ctx = useContext(ProfileContext);
|
|
129
|
+
if (!ctx) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
"useProfile must be used within a ProfileProvider. Wrap your app (or the relevant subtree) with <ProfileProvider>."
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return ctx;
|
|
135
|
+
}
|
|
136
|
+
function ProfileProvider({ children }) {
|
|
137
|
+
const value = useUserProfile();
|
|
138
|
+
return createElement(ProfileContext.Provider, { value }, children);
|
|
139
|
+
}
|
|
128
140
|
|
|
129
|
-
export { UserProfileService, useUserProfile };
|
|
141
|
+
export { ProfileProvider, UserProfileService, useProfile, useUserProfile };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useProfile } from './chunk-L2CM2CUA.js';
|
|
2
|
+
import { useOrganization } from './chunk-DD3CCMCZ.js';
|
|
3
|
+
import { useAuthContext } from './chunk-7PLEQFHO.js';
|
|
4
|
+
import { createContext, useContext, useMemo, useCallback, createElement } from 'react';
|
|
5
|
+
|
|
6
|
+
var InitializationContext = createContext(null);
|
|
7
|
+
function useInitialization() {
|
|
8
|
+
const ctx = useContext(InitializationContext);
|
|
9
|
+
if (!ctx) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
"useInitialization must be used within an InitializationProvider. Wrap your app (or the relevant subtree) with <InitializationProvider>."
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return ctx;
|
|
15
|
+
}
|
|
16
|
+
function InitializationProvider({ children }) {
|
|
17
|
+
const { user, isLoading: authLoading } = useAuthContext();
|
|
18
|
+
const { profile, loading: profileLoading, error: profileError, refetch } = useProfile();
|
|
19
|
+
const {
|
|
20
|
+
isInitializing: orgInitializing,
|
|
21
|
+
isOrgRefreshing: orgLoading,
|
|
22
|
+
error: orgErrorMsg,
|
|
23
|
+
currentWorkOSOrganizationId,
|
|
24
|
+
memberships,
|
|
25
|
+
retry: orgRetry
|
|
26
|
+
} = useOrganization();
|
|
27
|
+
const isInitializing = authLoading || profileLoading || orgInitializing || orgLoading;
|
|
28
|
+
const userReady = !authLoading && !profileLoading && !!user && !!profile && !profileError;
|
|
29
|
+
const organizationReady = userReady && !orgInitializing && !orgLoading && !!currentWorkOSOrganizationId && !orgErrorMsg;
|
|
30
|
+
const allReady = organizationReady;
|
|
31
|
+
const error = useMemo(() => {
|
|
32
|
+
if (profileError) {
|
|
33
|
+
return {
|
|
34
|
+
layer: "profile",
|
|
35
|
+
message: "Failed to load user profile",
|
|
36
|
+
originalError: profileError
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (orgErrorMsg) {
|
|
40
|
+
return {
|
|
41
|
+
layer: "organization",
|
|
42
|
+
message: orgErrorMsg,
|
|
43
|
+
originalError: new Error(orgErrorMsg)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (userReady && !orgInitializing && !orgLoading && !currentWorkOSOrganizationId && memberships.length > 0) {
|
|
47
|
+
return {
|
|
48
|
+
layer: "organization",
|
|
49
|
+
message: "No organization membership found. Please contact your administrator for an invitation."
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}, [profileError, orgErrorMsg, userReady, orgInitializing, orgLoading, currentWorkOSOrganizationId, memberships]);
|
|
54
|
+
const retry = useCallback(async () => {
|
|
55
|
+
if (profileError && refetch) {
|
|
56
|
+
await refetch();
|
|
57
|
+
}
|
|
58
|
+
await orgRetry();
|
|
59
|
+
}, [profileError, refetch, orgRetry]);
|
|
60
|
+
const value = useMemo(
|
|
61
|
+
() => ({
|
|
62
|
+
userReady,
|
|
63
|
+
organizationReady,
|
|
64
|
+
allReady,
|
|
65
|
+
isInitializing,
|
|
66
|
+
error,
|
|
67
|
+
retry,
|
|
68
|
+
profile
|
|
69
|
+
}),
|
|
70
|
+
[userReady, organizationReady, allReady, isInitializing, error, retry, profile]
|
|
71
|
+
);
|
|
72
|
+
return createElement(InitializationContext.Provider, { value }, children);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { InitializationContext, InitializationProvider, useInitialization };
|