@gen3/core 0.12.43 → 0.12.45
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/cjs/index.js +503 -165
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server.js +26 -14
- package/dist/cjs/server.js.map +1 -1
- package/dist/dts/features/cart/cartSelectors.d.ts +12 -0
- package/dist/dts/features/cart/cartSelectors.d.ts.map +1 -1
- package/dist/dts/features/cohort/cohortManagerSelector.d.ts +12 -0
- package/dist/dts/features/cohort/cohortManagerSelector.d.ts.map +1 -1
- package/dist/dts/features/cohort/cohortManagerSlice.d.ts +3 -0
- package/dist/dts/features/cohort/cohortManagerSlice.d.ts.map +1 -1
- package/dist/dts/features/fence/fetchFence.d.ts +1 -1
- package/dist/dts/features/fence/fetchFence.d.ts.map +1 -1
- package/dist/dts/features/fence/index.d.ts +2 -2
- package/dist/dts/features/fence/index.d.ts.map +1 -1
- package/dist/dts/features/fence/jwtApi.d.ts +184 -1
- package/dist/dts/features/fence/jwtApi.d.ts.map +1 -1
- package/dist/dts/features/fence/utils.d.ts.map +1 -1
- package/dist/dts/features/gen3/gen3Api.d.ts.map +1 -1
- package/dist/dts/features/notifications/index.d.ts +2 -0
- package/dist/dts/features/notifications/index.d.ts.map +1 -0
- package/dist/dts/features/notifications/notificationService.d.ts +42 -0
- package/dist/dts/features/notifications/notificationService.d.ts.map +1 -0
- package/dist/dts/features/requestor/remoteSupport/types.d.ts +5 -1
- package/dist/dts/features/requestor/remoteSupport/types.d.ts.map +1 -1
- package/dist/dts/features/requestor/remoteSupport/zenDesk.d.ts.map +1 -1
- package/dist/dts/features/requestor/requestorSlice.d.ts.map +1 -1
- package/dist/dts/features/submission/submissionApi.d.ts +186 -1
- package/dist/dts/features/submission/submissionApi.d.ts.map +1 -1
- package/dist/dts/features/user/userSliceRTK.d.ts +9 -0
- package/dist/dts/features/user/userSliceRTK.d.ts.map +1 -1
- package/dist/dts/features/workspace/index.d.ts +7 -3
- package/dist/dts/features/workspace/index.d.ts.map +1 -1
- package/dist/dts/features/workspace/jegKernelSelector.d.ts +162 -0
- package/dist/dts/features/workspace/jegKernelSelector.d.ts.map +1 -0
- package/dist/dts/features/workspace/jegKernelSlice.d.ts +482 -0
- package/dist/dts/features/workspace/jegKernelSlice.d.ts.map +1 -0
- package/dist/dts/features/workspace/jegWorkspaceSlice.d.ts +16 -0
- package/dist/dts/features/workspace/jegWorkspaceSlice.d.ts.map +1 -0
- package/dist/dts/features/workspace/tieredWorkspaceSlice.d.ts +14 -0
- package/dist/dts/features/workspace/tieredWorkspaceSlice.d.ts.map +1 -0
- package/dist/dts/features/workspace/types.d.ts +11 -1
- package/dist/dts/features/workspace/types.d.ts.map +1 -1
- package/dist/dts/features/workspace/workspaceSlice.d.ts +1 -1
- package/dist/dts/features/workspace/workspaceSlice.d.ts.map +1 -1
- package/dist/dts/hooks.d.ts +6 -0
- package/dist/dts/hooks.d.ts.map +1 -1
- package/dist/dts/index.d.ts +1 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/reducers.d.ts +37 -31
- package/dist/dts/reducers.d.ts.map +1 -1
- package/dist/dts/store.d.ts +12 -0
- package/dist/dts/store.d.ts.map +1 -1
- package/dist/dts/utils/index.d.ts +3 -2
- package/dist/dts/utils/index.d.ts.map +1 -1
- package/dist/dts/utils/normalizeRtkError.d.ts +14 -0
- package/dist/dts/utils/normalizeRtkError.d.ts.map +1 -0
- package/dist/dts/utils/time.d.ts +14 -0
- package/dist/dts/utils/time.d.ts.map +1 -1
- package/dist/esm/index.js +476 -166
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server.js +26 -14
- package/dist/esm/server.js.map +1 -1
- package/dist/index.d.ts +11650 -10940
- package/dist/server.d.ts +1 -1
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -94,12 +94,22 @@ const isFetchError = (obj)=>{
|
|
|
94
94
|
* Template for fence error response dict
|
|
95
95
|
* @returns: An error dict response from a RESTFUL API request
|
|
96
96
|
*/ const buildFetchError = async (res, request)=>{
|
|
97
|
+
let text = '';
|
|
98
|
+
if (!res.bodyUsed) {
|
|
99
|
+
try {
|
|
100
|
+
text = await res.text();
|
|
101
|
+
} catch (err) {
|
|
102
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
103
|
+
console.warn('[buildFetchError] Failed to read response body:', err);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
97
107
|
return {
|
|
98
|
-
url: res.url,
|
|
108
|
+
url: res.url || '(unknown)',
|
|
99
109
|
status: res.status,
|
|
100
110
|
statusText: res.statusText,
|
|
101
|
-
text
|
|
102
|
-
request
|
|
111
|
+
text,
|
|
112
|
+
request
|
|
103
113
|
};
|
|
104
114
|
};
|
|
105
115
|
|
|
@@ -117,13 +127,11 @@ const isFetchError = (obj)=>{
|
|
|
117
127
|
* @returns {Promise<Gen3FenceResponse<T>>} A promise that resolves to the parsed data and response status
|
|
118
128
|
* or rejects with an error if the request fails.
|
|
119
129
|
* @throws {Error} Throws an error if the fetch request fails or the response is not successful.
|
|
120
|
-
*/ const fetchFence = async ({ endpoint, headers, body =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
url = `${GEN3_FENCE_SERVICE}/${endpoint}`;
|
|
124
|
-
}
|
|
130
|
+
*/ const fetchFence = async ({ endpoint, headers, body = undefined, method = 'GET', isJSON = true }, useService = false)=>{
|
|
131
|
+
const base = useService ? GEN3_FENCE_SERVICE : GEN3_FENCE_API;
|
|
132
|
+
const url = `${base.replace(/\/$/, '')}/${endpoint.replace(/^\//, '')}`;
|
|
125
133
|
const res = await fetch(url, {
|
|
126
|
-
method
|
|
134
|
+
method,
|
|
127
135
|
credentials: 'include',
|
|
128
136
|
headers: {
|
|
129
137
|
// Ensure Content-Type is set for JSON POSTs, but allow overrides via 'headers'
|
|
@@ -132,12 +140,16 @@ const isFetchError = (obj)=>{
|
|
|
132
140
|
} : {},
|
|
133
141
|
...headers
|
|
134
142
|
},
|
|
135
|
-
|
|
143
|
+
...method === 'POST' && body ? {
|
|
144
|
+
body: JSON.stringify(body)
|
|
145
|
+
} : {}
|
|
136
146
|
});
|
|
137
|
-
if (res.ok)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
if (res.ok) {
|
|
148
|
+
return {
|
|
149
|
+
data: isJSON ? await res.json() : await res.text(),
|
|
150
|
+
status: res.status
|
|
151
|
+
};
|
|
152
|
+
}
|
|
141
153
|
throw await buildFetchError(res, {
|
|
142
154
|
endpoint,
|
|
143
155
|
method,
|
|
@@ -263,6 +275,13 @@ const selectHeadersWithCSRFToken = toolkit.createSelector([
|
|
|
263
275
|
}
|
|
264
276
|
}));
|
|
265
277
|
|
|
278
|
+
// function readCookie(name: string): string | undefined {
|
|
279
|
+
// const raw = document.cookie
|
|
280
|
+
// .split('; ')
|
|
281
|
+
// .find((c) => c.startsWith(`${name}=`))
|
|
282
|
+
// ?.split('=')[1];
|
|
283
|
+
// return raw ? decodeURIComponent(raw) : undefined;
|
|
284
|
+
// }
|
|
266
285
|
/**
|
|
267
286
|
* Creates a base class core API for building other API endpoints on top of.
|
|
268
287
|
* @param reducerPath - The root key name that the other slices will be derived from
|
|
@@ -279,8 +298,8 @@ const selectHeadersWithCSRFToken = toolkit.createSelector([
|
|
|
279
298
|
if (process.env.NODE_ENV === 'development') {
|
|
280
299
|
// NOTE: This cookie can only be accessed from the client side
|
|
281
300
|
// in development mode. Otherwise, the cookie is set as httpOnly
|
|
282
|
-
const
|
|
283
|
-
if (
|
|
301
|
+
const credentialsToken = cookiesNext.getCookie('credentials_token');
|
|
302
|
+
if (credentialsToken) headers.set('Authorization', `Bearer ${credentialsToken}`);
|
|
284
303
|
}
|
|
285
304
|
if (csrfToken) headers.set('X-CSRF-Token', csrfToken);
|
|
286
305
|
return headers;
|
|
@@ -335,7 +354,7 @@ const useCoreDispatch = reactRedux.useDispatch.withTypes();
|
|
|
335
354
|
});
|
|
336
355
|
const isAuthenticated = (loginStatus)=>loginStatus === 'authenticated';
|
|
337
356
|
const isPending = (loginStatus)=>loginStatus === 'pending';
|
|
338
|
-
const initialState$
|
|
357
|
+
const initialState$d = {
|
|
339
358
|
status: 'uninitialized',
|
|
340
359
|
loginStatus: 'unauthenticated',
|
|
341
360
|
error: undefined
|
|
@@ -344,11 +363,11 @@ const initialState$a = {
|
|
|
344
363
|
* Wraps a slice on top of fetchUserState async thunk to keep track of
|
|
345
364
|
* query state. authenticated/not-authenticated vs. ejected/fulfilled/pending
|
|
346
365
|
* @returns: status messages wrapped around fetchUserState response dict
|
|
347
|
-
*/ const slice$
|
|
366
|
+
*/ const slice$6 = toolkit.createSlice({
|
|
348
367
|
name: 'fence/user',
|
|
349
|
-
initialState: initialState$
|
|
368
|
+
initialState: initialState$d,
|
|
350
369
|
reducers: {
|
|
351
|
-
resetUserState: ()=>initialState$
|
|
370
|
+
resetUserState: ()=>initialState$d
|
|
352
371
|
},
|
|
353
372
|
extraReducers: (builder)=>{
|
|
354
373
|
builder.addCase(fetchUserState.fulfilled, (_, action)=>{
|
|
@@ -379,8 +398,8 @@ const initialState$a = {
|
|
|
379
398
|
});
|
|
380
399
|
}
|
|
381
400
|
});
|
|
382
|
-
const userReducer = slice$
|
|
383
|
-
const { resetUserState } = slice$
|
|
401
|
+
const userReducer = slice$6.reducer;
|
|
402
|
+
const { resetUserState } = slice$6.actions;
|
|
384
403
|
const selectUserData = (state)=>{
|
|
385
404
|
return state.user;
|
|
386
405
|
};
|
|
@@ -431,12 +450,12 @@ const printRegistry = ()=>{
|
|
|
431
450
|
console.log(REGISTRY);
|
|
432
451
|
};
|
|
433
452
|
|
|
434
|
-
const initialState$
|
|
453
|
+
const initialState$c = {
|
|
435
454
|
gen3Apps: {}
|
|
436
455
|
};
|
|
437
|
-
const slice$
|
|
456
|
+
const slice$5 = toolkit.createSlice({
|
|
438
457
|
name: 'gen3Apps',
|
|
439
|
-
initialState: initialState$
|
|
458
|
+
initialState: initialState$c,
|
|
440
459
|
reducers: {
|
|
441
460
|
addGen3AppMetadata: (state, action)=>{
|
|
442
461
|
const { name, requiredEntityTypes } = action.payload;
|
|
@@ -450,24 +469,24 @@ const slice$3 = toolkit.createSlice({
|
|
|
450
469
|
}
|
|
451
470
|
}
|
|
452
471
|
});
|
|
453
|
-
const gen3AppReducer = slice$
|
|
454
|
-
const { addGen3AppMetadata } = slice$
|
|
472
|
+
const gen3AppReducer = slice$5.reducer;
|
|
473
|
+
const { addGen3AppMetadata } = slice$5.actions;
|
|
455
474
|
const selectGen3AppMetadataByName = (state, appName)=>state.gen3Apps.gen3Apps[appName];
|
|
456
475
|
const selectGen3AppByName = (appName)=>lookupGen3App(appName); // TODO: memoize this selector
|
|
457
476
|
|
|
458
|
-
const initialState$
|
|
477
|
+
const initialState$b = {};
|
|
459
478
|
// TODO: document what this does
|
|
460
|
-
const slice$
|
|
479
|
+
const slice$4 = toolkit.createSlice({
|
|
461
480
|
name: 'drsResolver',
|
|
462
|
-
initialState: initialState$
|
|
481
|
+
initialState: initialState$b,
|
|
463
482
|
reducers: {
|
|
464
483
|
setDRSHostnames: (_state, action)=>{
|
|
465
484
|
return action.payload;
|
|
466
485
|
}
|
|
467
486
|
}
|
|
468
487
|
});
|
|
469
|
-
const drsHostnamesReducer = slice$
|
|
470
|
-
const { setDRSHostnames } = slice$
|
|
488
|
+
const drsHostnamesReducer = slice$4.reducer;
|
|
489
|
+
const { setDRSHostnames } = slice$4.actions;
|
|
471
490
|
const drsHostnamesSelector = (id, state)=>state.drsHostnames?.[id];
|
|
472
491
|
|
|
473
492
|
/**
|
|
@@ -482,13 +501,13 @@ const drsHostnamesSelector = (id, state)=>state.drsHostnames?.[id];
|
|
|
482
501
|
Modals["GeneralErrorModal"] = "GeneralErrorModal";
|
|
483
502
|
return Modals;
|
|
484
503
|
}({});
|
|
485
|
-
const initialState$
|
|
504
|
+
const initialState$a = {
|
|
486
505
|
currentModal: null
|
|
487
506
|
};
|
|
488
507
|
//Creates a modal slice for tracking showModal and hideModal state.
|
|
489
|
-
const slice$
|
|
508
|
+
const slice$3 = toolkit.createSlice({
|
|
490
509
|
name: 'modals',
|
|
491
|
-
initialState: initialState$
|
|
510
|
+
initialState: initialState$a,
|
|
492
511
|
reducers: {
|
|
493
512
|
showModal: (state, action)=>{
|
|
494
513
|
state.currentModal = action.payload.modal;
|
|
@@ -501,8 +520,8 @@ const slice$1 = toolkit.createSlice({
|
|
|
501
520
|
}
|
|
502
521
|
}
|
|
503
522
|
});
|
|
504
|
-
const modalReducer = slice$
|
|
505
|
-
const { showModal, hideModal } = slice$
|
|
523
|
+
const modalReducer = slice$3.reducer;
|
|
524
|
+
const { showModal, hideModal } = slice$3.actions;
|
|
506
525
|
const selectCurrentModal = (state)=>state.modals.currentModal;
|
|
507
526
|
const selectCurrentMessage = (state)=>state.modals.message;
|
|
508
527
|
|
|
@@ -516,6 +535,8 @@ const selectCurrentMessage = (state)=>state.modals.message;
|
|
|
516
535
|
WorkspaceStatus["NotFound"] = "Not Found";
|
|
517
536
|
WorkspaceStatus["Errored"] = "Errored";
|
|
518
537
|
WorkspaceStatus["StatusError"] = "Status Error";
|
|
538
|
+
WorkspaceStatus["LaunchError"] = "Launching Error";
|
|
539
|
+
WorkspaceStatus["TerminateError"] = "Terminating Error";
|
|
519
540
|
return WorkspaceStatus;
|
|
520
541
|
}({});
|
|
521
542
|
/**
|
|
@@ -559,17 +580,36 @@ const isTimeGreaterThan = (startTime, minutes)=>{
|
|
|
559
580
|
const getTimestamp = ()=>{
|
|
560
581
|
return new Date(Date.now()).toLocaleString();
|
|
561
582
|
};
|
|
583
|
+
/**
|
|
584
|
+
* Formats a given number of minutes into a human-readable uptime string.
|
|
585
|
+
*
|
|
586
|
+
* @param {number | null | undefined} minutes - The total number of minutes to format.
|
|
587
|
+
* - If `null` or `undefined`, a placeholder string ('—') is returned.
|
|
588
|
+
* - If less than 60, the output is formatted as `{m}m` (e.g., "45m").
|
|
589
|
+
* - If greater than or equal to 60, the output is formatted as:
|
|
590
|
+
* - `{h}h` when there are no remaining minutes (e.g., "2h").
|
|
591
|
+
* - `{h}h {m}m` when there are remaining minutes (e.g., "2h 30m").
|
|
592
|
+
*
|
|
593
|
+
* @returns {string} A formatted string representing the uptime in hours and minutes
|
|
594
|
+
* or a placeholder if the input is null or undefined.
|
|
595
|
+
*/ const formatUptimeInMinutes = (minutes)=>{
|
|
596
|
+
if (minutes == null) return '—';
|
|
597
|
+
const h = Math.floor(minutes / 60);
|
|
598
|
+
const m = minutes % 60;
|
|
599
|
+
if (h === 0) return `${m}m`;
|
|
600
|
+
return m > 0 ? `${h}h ${m}m` : `${h}h`;
|
|
601
|
+
};
|
|
562
602
|
|
|
563
|
-
const NO_WORKSPACE_ID = 'none';
|
|
564
|
-
const initialState$
|
|
565
|
-
id: NO_WORKSPACE_ID,
|
|
603
|
+
const NO_WORKSPACE_ID$2 = 'none';
|
|
604
|
+
const initialState$9 = {
|
|
605
|
+
id: NO_WORKSPACE_ID$2,
|
|
566
606
|
status: WorkspaceStatus.NotFound,
|
|
567
607
|
requestedStatus: RequestedWorkspaceStatus.Unset,
|
|
568
608
|
requestedStatusTimestamp: getCurrentTimestamp()
|
|
569
609
|
};
|
|
570
|
-
const slice = toolkit.createSlice({
|
|
571
|
-
name: '
|
|
572
|
-
initialState: initialState$
|
|
610
|
+
const slice$2 = toolkit.createSlice({
|
|
611
|
+
name: 'activeWorkspace',
|
|
612
|
+
initialState: initialState$9,
|
|
573
613
|
reducers: {
|
|
574
614
|
setActiveWorkspaceId: (state, action)=>{
|
|
575
615
|
state = {
|
|
@@ -581,7 +621,8 @@ const slice = toolkit.createSlice({
|
|
|
581
621
|
clearActiveWorkspaceId: (state)=>{
|
|
582
622
|
return {
|
|
583
623
|
...state,
|
|
584
|
-
id: NO_WORKSPACE_ID
|
|
624
|
+
id: NO_WORKSPACE_ID$2,
|
|
625
|
+
status: WorkspaceStatus.NotFound
|
|
585
626
|
};
|
|
586
627
|
},
|
|
587
628
|
setActiveWorkspaceStatus: (state, action)=>{
|
|
@@ -604,8 +645,8 @@ const slice = toolkit.createSlice({
|
|
|
604
645
|
}
|
|
605
646
|
}
|
|
606
647
|
});
|
|
607
|
-
const activeWorkspaceReducer = slice.reducer;
|
|
608
|
-
const { setActiveWorkspaceId, clearActiveWorkspaceId, setActiveWorkspaceStatus, setRequestedWorkspaceStatus, setActiveWorkspace } = slice.actions;
|
|
648
|
+
const activeWorkspaceReducer = slice$2.reducer;
|
|
649
|
+
const { setActiveWorkspaceId, clearActiveWorkspaceId, setActiveWorkspaceStatus, setRequestedWorkspaceStatus, setActiveWorkspace } = slice$2.actions;
|
|
609
650
|
const selectActiveWorkspaceId = (state)=>state.activeWorkspace.id;
|
|
610
651
|
const selectActiveWorkspaceStatus = (state)=>state.activeWorkspace.status;
|
|
611
652
|
const selectRequestedWorkspaceStatus = (state)=>state.activeWorkspace.requestedStatus;
|
|
@@ -614,10 +655,10 @@ const selectRequestedWorkspaceStatusTimestamp = (state)=>state.activeWorkspace.r
|
|
|
614
655
|
const cartAdapter = toolkit.createEntityAdapter({
|
|
615
656
|
selectId: (item)=>item.id
|
|
616
657
|
});
|
|
617
|
-
const initialState$
|
|
658
|
+
const initialState$8 = cartAdapter.getInitialState({});
|
|
618
659
|
const cartSlice = toolkit.createSlice({
|
|
619
660
|
name: 'cart',
|
|
620
|
-
initialState: initialState$
|
|
661
|
+
initialState: initialState$8,
|
|
621
662
|
reducers: {
|
|
622
663
|
addItemsToCart: cartAdapter.addMany,
|
|
623
664
|
removeItemsFromCart: cartAdapter.removeMany
|
|
@@ -1040,6 +1081,175 @@ const humanify = ({ term = '', capitalize: cap = true, facetTerm = false })=>{
|
|
|
1040
1081
|
* @category Utility
|
|
1041
1082
|
*/ const stringifyJSONParam = (obj, defaults = '{}')=>obj ? JSON.stringify(obj) : defaults;
|
|
1042
1083
|
|
|
1084
|
+
// type guard functions
|
|
1085
|
+
const isHistogramRangeData = (key)=>{
|
|
1086
|
+
return Array.isArray(key) && key.length === 2 && key.every((item)=>typeof item === 'number');
|
|
1087
|
+
};
|
|
1088
|
+
const isJSONObject = (data)=>{
|
|
1089
|
+
return typeof data === 'object' && data !== null && !Array.isArray(data);
|
|
1090
|
+
};
|
|
1091
|
+
const isJSONValue = (data)=>{
|
|
1092
|
+
return typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || Array.isArray(data) && data.every(isJSONValue) || isJSONObject(data);
|
|
1093
|
+
};
|
|
1094
|
+
const isJSONValueArray = (data)=>{
|
|
1095
|
+
return Array.isArray(data) && data.every(isJSONValue);
|
|
1096
|
+
};
|
|
1097
|
+
const isValidObject = (input)=>typeof input === 'object' && input !== null;
|
|
1098
|
+
const isHistogramData = (data)=>{
|
|
1099
|
+
return isValidObject(data) && 'key' in data && 'count' in data;
|
|
1100
|
+
};
|
|
1101
|
+
const isHistogramDataArray = (input)=>{
|
|
1102
|
+
if (!isValidObject(input) || !Array.isArray(input.histogram)) {
|
|
1103
|
+
return false;
|
|
1104
|
+
}
|
|
1105
|
+
return input.histogram.every(isHistogramData);
|
|
1106
|
+
};
|
|
1107
|
+
const isHistogramDataCollection = (obj)=>{
|
|
1108
|
+
return isValidObject(obj) && 'histogram' in obj && isHistogramData(obj.histogram);
|
|
1109
|
+
};
|
|
1110
|
+
// Type guard function for GuppyAggregationData interface
|
|
1111
|
+
const isGuppyAggregationData = (obj)=>{
|
|
1112
|
+
if (!isValidObject(obj)) return false;
|
|
1113
|
+
for(const key in obj){
|
|
1114
|
+
if (!isHistogramDataCollection(obj[key])) {
|
|
1115
|
+
return false;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
return true;
|
|
1119
|
+
};
|
|
1120
|
+
const isHistogramDataAnEnum = (data)=>{
|
|
1121
|
+
return typeof data === 'object' && data !== null && 'key' in data && 'count' in data && typeof data.key === 'string' && typeof data.count === 'number';
|
|
1122
|
+
};
|
|
1123
|
+
const isStatsValue = (item)=>{
|
|
1124
|
+
if (typeof item !== 'object' || item === null) {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
const obj = item;
|
|
1128
|
+
// Check that all present properties have correct types
|
|
1129
|
+
const numericFields = [
|
|
1130
|
+
'count',
|
|
1131
|
+
'min',
|
|
1132
|
+
'max',
|
|
1133
|
+
'avg',
|
|
1134
|
+
'sum',
|
|
1135
|
+
'stddev',
|
|
1136
|
+
'median'
|
|
1137
|
+
];
|
|
1138
|
+
if (!numericFields.some((field)=>field in obj && typeof obj[field] !== 'number')) {
|
|
1139
|
+
return false;
|
|
1140
|
+
}
|
|
1141
|
+
// Check percentiles structure if present
|
|
1142
|
+
if ('percentiles' in obj) {
|
|
1143
|
+
const percentiles = obj.percentiles;
|
|
1144
|
+
if (typeof percentiles !== 'object' || percentiles === null) {
|
|
1145
|
+
return false;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
return true;
|
|
1149
|
+
};
|
|
1150
|
+
const isStatsValuesArray = (data)=>{
|
|
1151
|
+
return Array.isArray(data) && data.every(isStatsValue);
|
|
1152
|
+
};
|
|
1153
|
+
const isHistogramDataAArray = (data)=>{
|
|
1154
|
+
return Array.isArray(data) && data.every(isHistogramData);
|
|
1155
|
+
};
|
|
1156
|
+
const isHistogramDataArrayAnEnum = (data)=>{
|
|
1157
|
+
return Array.isArray(data) && data.every(isHistogramDataAnEnum);
|
|
1158
|
+
};
|
|
1159
|
+
const isHistogramDataArrayARange = (data)=>{
|
|
1160
|
+
return Array.isArray(data) && data.every((item)=>isHistogramRangeData(item.key));
|
|
1161
|
+
};
|
|
1162
|
+
/**
|
|
1163
|
+
* Type predicate to narrow an unknown error to `FetchBaseQueryError`
|
|
1164
|
+
*/ function isFetchBaseQueryError(error) {
|
|
1165
|
+
return typeof error === 'object' && error != null && 'status' in error;
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* Type predicate to narrow an unknown error to an object with a string 'message' property
|
|
1169
|
+
*/ function isErrorWithMessage(error) {
|
|
1170
|
+
return typeof error === 'object' && error != null && 'message' in error && typeof error.message === 'string';
|
|
1171
|
+
}
|
|
1172
|
+
function isHttpStatusError(error) {
|
|
1173
|
+
return typeof error === 'object' && error != null && 'status' in error && typeof error.status === 'number';
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Type predicate to narrow an unknown error to an object with a string 'message' property
|
|
1177
|
+
*/ function isFetchParseError(error) {
|
|
1178
|
+
return typeof error === 'object' && error != null && 'originalStatus' in error && 'status' in error && error['status'] === 'PARSING_ERROR';
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/** Best-effort message extraction from an HTTP error body */ function extractMessage(data) {
|
|
1182
|
+
if (typeof data === 'string') return data;
|
|
1183
|
+
if (typeof data === 'object' && data != null) {
|
|
1184
|
+
const obj = data;
|
|
1185
|
+
// common API error shapes: { message }, { error }, { detail } (FastAPI)
|
|
1186
|
+
for (const key of [
|
|
1187
|
+
'message',
|
|
1188
|
+
'error',
|
|
1189
|
+
'detail'
|
|
1190
|
+
]){
|
|
1191
|
+
const val = obj[key];
|
|
1192
|
+
if (typeof val === 'string') return val;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
return undefined;
|
|
1196
|
+
}
|
|
1197
|
+
function normalizeRtkError(error) {
|
|
1198
|
+
if (!error) {
|
|
1199
|
+
return {
|
|
1200
|
+
type: 'UNKNOWN_ERROR',
|
|
1201
|
+
message: 'Unknown error'
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
if (isFetchBaseQueryError(error)) {
|
|
1205
|
+
// status is number for HTTP errors, string literal for the others
|
|
1206
|
+
if (typeof error.status === 'number') {
|
|
1207
|
+
return {
|
|
1208
|
+
type: 'HTTP_ERROR',
|
|
1209
|
+
status: error.status,
|
|
1210
|
+
message: extractMessage(error.data) ?? `Request failed with status ${error.status}`,
|
|
1211
|
+
data: error.data
|
|
1212
|
+
};
|
|
1213
|
+
}
|
|
1214
|
+
switch(error.status){
|
|
1215
|
+
case 'FETCH_ERROR':
|
|
1216
|
+
return {
|
|
1217
|
+
type: 'FETCH_ERROR',
|
|
1218
|
+
message: error.error
|
|
1219
|
+
};
|
|
1220
|
+
case 'PARSING_ERROR':
|
|
1221
|
+
return {
|
|
1222
|
+
type: 'PARSING_ERROR',
|
|
1223
|
+
status: error.originalStatus,
|
|
1224
|
+
message: error.error,
|
|
1225
|
+
data: error.data
|
|
1226
|
+
};
|
|
1227
|
+
case 'TIMEOUT_ERROR':
|
|
1228
|
+
return {
|
|
1229
|
+
type: 'TIMEOUT_ERROR',
|
|
1230
|
+
message: error.error
|
|
1231
|
+
};
|
|
1232
|
+
case 'CUSTOM_ERROR':
|
|
1233
|
+
return {
|
|
1234
|
+
type: 'CUSTOM_ERROR',
|
|
1235
|
+
message: error.error,
|
|
1236
|
+
data: error.data
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
// SerializedError — a JS error thrown somewhere in the pipeline
|
|
1241
|
+
if ('message' in error || 'name' in error) {
|
|
1242
|
+
return {
|
|
1243
|
+
type: 'SERIALIZED_ERROR',
|
|
1244
|
+
message: error.message ?? 'An error occurred'
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
return {
|
|
1248
|
+
type: 'UNKNOWN_ERROR',
|
|
1249
|
+
message: 'Unknown error'
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1043
1253
|
const queryWTSFederatedLoginStatus = async (signal)=>{
|
|
1044
1254
|
try {
|
|
1045
1255
|
const results = await fetchJSONDataFromURL(`${GEN3_WTS_API}/external_oidc/`, false, HttpMethod.GET, undefined, signal);
|
|
@@ -2229,13 +2439,13 @@ const emptyInitialState = cohortsAdapter.getInitialState({
|
|
|
2229
2439
|
message: undefined
|
|
2230
2440
|
});
|
|
2231
2441
|
// Set the initial cohort in the adapter state
|
|
2232
|
-
const initialState$
|
|
2442
|
+
const initialState$7 = cohortsAdapter.setOne(emptyInitialState, initialCohort);
|
|
2233
2443
|
const getCurrentCohortId = (state)=>state.currentCohortId;
|
|
2234
2444
|
/**
|
|
2235
2445
|
* Redux slice for cohort filters
|
|
2236
2446
|
*/ const cohortManagerSlice = toolkit.createSlice({
|
|
2237
2447
|
name: 'cohort',
|
|
2238
|
-
initialState: initialState$
|
|
2448
|
+
initialState: initialState$7,
|
|
2239
2449
|
reducers: {
|
|
2240
2450
|
createNewCohort: (state, action)=>{
|
|
2241
2451
|
const baseName = action.payload.name || `Cohort`;
|
|
@@ -2476,10 +2686,10 @@ const getCurrentCohortId = (state)=>state.currentCohortId;
|
|
|
2476
2686
|
const { createNewCohort, updateCohortFilter, setCohortFilter, setCohortIndexFilters, duplicateCohort, removeCohortFilter, clearCohortFilters, removeCohort, setCurrentCohortId, updateCohortName, updateCohortCounts, updateCohortIndexCountById, setCohortList } = cohortManagerSlice.actions;
|
|
2477
2687
|
const cohortReducer = cohortManagerSlice.reducer;
|
|
2478
2688
|
|
|
2479
|
-
const initialState$
|
|
2689
|
+
const initialState$6 = {};
|
|
2480
2690
|
const expandSlice$1 = toolkit.createSlice({
|
|
2481
2691
|
name: 'CohortBuilder/filterExpand',
|
|
2482
|
-
initialState: initialState$
|
|
2692
|
+
initialState: initialState$6,
|
|
2483
2693
|
reducers: {
|
|
2484
2694
|
toggleCohortBuilderCategoryFilter: (state, action)=>{
|
|
2485
2695
|
return {
|
|
@@ -2506,10 +2716,10 @@ const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = exp
|
|
|
2506
2716
|
const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
|
|
2507
2717
|
const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
|
|
2508
2718
|
|
|
2509
|
-
const initialState$
|
|
2719
|
+
const initialState$5 = {};
|
|
2510
2720
|
const expandSlice = toolkit.createSlice({
|
|
2511
2721
|
name: 'CohortBuilder/filterCombineMode',
|
|
2512
|
-
initialState: initialState$
|
|
2722
|
+
initialState: initialState$5,
|
|
2513
2723
|
reducers: {
|
|
2514
2724
|
setCohortFilterCombineMode: (state, action)=>{
|
|
2515
2725
|
return {
|
|
@@ -2526,13 +2736,13 @@ const cohortBuilderFiltersCombineModeReducer = expandSlice.reducer;
|
|
|
2526
2736
|
const { setCohortFilterCombineMode } = expandSlice.actions;
|
|
2527
2737
|
const selectCohortFilterCombineMode = (state, index, field)=>state.cohorts.filtersCombineMode?.[index]?.[field] ?? 'or';
|
|
2528
2738
|
|
|
2529
|
-
const initialState$
|
|
2739
|
+
const initialState$4 = {
|
|
2530
2740
|
shouldShareFilters: false,
|
|
2531
2741
|
sharedFiltersMap: {}
|
|
2532
2742
|
};
|
|
2533
2743
|
const cohortSharedFiltersSlice = toolkit.createSlice({
|
|
2534
2744
|
name: 'cohortSharedFilters',
|
|
2535
|
-
initialState: initialState$
|
|
2745
|
+
initialState: initialState$4,
|
|
2536
2746
|
reducers: {
|
|
2537
2747
|
setShouldShareFilters: (state, action)=>{
|
|
2538
2748
|
state.shouldShareFilters = action.payload;
|
|
@@ -2575,12 +2785,12 @@ const createNoopStorage = ()=>{
|
|
|
2575
2785
|
const storage = typeof window !== 'undefined' ? createWebStorage('local') : createNoopStorage();
|
|
2576
2786
|
typeof window !== 'undefined' ? createWebStorage('session') : createNoopStorage();
|
|
2577
2787
|
|
|
2578
|
-
const initialState = {
|
|
2788
|
+
const initialState$3 = {
|
|
2579
2789
|
datatimeCache: {}
|
|
2580
2790
|
};
|
|
2581
2791
|
const sowerJobDatetimeSlice = toolkit.createSlice({
|
|
2582
2792
|
name: 'sowerJobDatetime',
|
|
2583
|
-
initialState,
|
|
2793
|
+
initialState: initialState$3,
|
|
2584
2794
|
reducers: {
|
|
2585
2795
|
setSowerJobDatetime: (state, action)=>{
|
|
2586
2796
|
return {
|
|
@@ -2660,6 +2870,143 @@ const sowerReducer = toolkit.combineReducers({
|
|
|
2660
2870
|
sowerJobDatetime: reduxPersist.persistReducer(sowerJobDatetimePersistConfig, sowerJobDatetimeReducer)
|
|
2661
2871
|
});
|
|
2662
2872
|
|
|
2873
|
+
const workspaceKernelsAdapter = toolkit.createEntityAdapter({
|
|
2874
|
+
selectId: (kernel)=>kernel.id
|
|
2875
|
+
});
|
|
2876
|
+
const initialState$2 = workspaceKernelsAdapter.getInitialState([]);
|
|
2877
|
+
/**
|
|
2878
|
+
* Handles the state of the active kernels in the workspace.
|
|
2879
|
+
*/ const workspaceKernelsSlice = toolkit.createSlice({
|
|
2880
|
+
name: 'workspaceKernels',
|
|
2881
|
+
initialState: initialState$2,
|
|
2882
|
+
reducers: {
|
|
2883
|
+
addJEGActiveKernel: (state, action)=>{
|
|
2884
|
+
workspaceKernelsAdapter.upsertOne(state, {
|
|
2885
|
+
...action.payload,
|
|
2886
|
+
lastUpdate: Date.now()
|
|
2887
|
+
});
|
|
2888
|
+
},
|
|
2889
|
+
upsertManyJEGActiveKernels: (state, action)=>{
|
|
2890
|
+
const now = Date.now();
|
|
2891
|
+
for (const kernel of action.payload){
|
|
2892
|
+
workspaceKernelsAdapter.upsertOne(state, {
|
|
2893
|
+
...kernel,
|
|
2894
|
+
lastUpdate: now
|
|
2895
|
+
});
|
|
2896
|
+
}
|
|
2897
|
+
},
|
|
2898
|
+
removeJEGActiveKernel: workspaceKernelsAdapter.removeOne,
|
|
2899
|
+
removeManyJEGActiveKernels: workspaceKernelsAdapter.removeMany,
|
|
2900
|
+
clearJEGActiveKernels: workspaceKernelsAdapter.removeAll,
|
|
2901
|
+
updateJEGActionKernelStatus: (state, action)=>{
|
|
2902
|
+
const { id, status } = action.payload;
|
|
2903
|
+
workspaceKernelsAdapter.updateOne(state, {
|
|
2904
|
+
id: id,
|
|
2905
|
+
changes: {
|
|
2906
|
+
lastUpdate: Date.now(),
|
|
2907
|
+
executionState: status
|
|
2908
|
+
}
|
|
2909
|
+
});
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2913
|
+
const workspaceKernelReducer = workspaceKernelsSlice.reducer;
|
|
2914
|
+
const { addJEGActiveKernel, upsertManyJEGActiveKernels, removeJEGActiveKernel, removeManyJEGActiveKernels, clearJEGActiveKernels, updateJEGActionKernelStatus } = workspaceKernelsSlice.actions;
|
|
2915
|
+
|
|
2916
|
+
const NO_WORKSPACE_ID$1 = 'none';
|
|
2917
|
+
const initialState$1 = {
|
|
2918
|
+
id: NO_WORKSPACE_ID$1,
|
|
2919
|
+
tier: null,
|
|
2920
|
+
isFullscreen: false
|
|
2921
|
+
};
|
|
2922
|
+
const slice$1 = toolkit.createSlice({
|
|
2923
|
+
name: 'tieredWorkspace',
|
|
2924
|
+
initialState: initialState$1,
|
|
2925
|
+
reducers: {
|
|
2926
|
+
setTieredWorkspaceId: (state, action)=>{
|
|
2927
|
+
state = {
|
|
2928
|
+
...state,
|
|
2929
|
+
id: action.payload.id
|
|
2930
|
+
};
|
|
2931
|
+
return state;
|
|
2932
|
+
},
|
|
2933
|
+
clearTieredWorkspaceId: (state)=>{
|
|
2934
|
+
return {
|
|
2935
|
+
...state,
|
|
2936
|
+
id: NO_WORKSPACE_ID$1
|
|
2937
|
+
};
|
|
2938
|
+
},
|
|
2939
|
+
setWorkspaceTier: (state, action)=>{
|
|
2940
|
+
return {
|
|
2941
|
+
...state,
|
|
2942
|
+
tier: action.payload
|
|
2943
|
+
};
|
|
2944
|
+
},
|
|
2945
|
+
setWorkspaceFullscreen: (state, action)=>{
|
|
2946
|
+
return {
|
|
2947
|
+
...state,
|
|
2948
|
+
isFullscreen: action.payload
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
});
|
|
2953
|
+
const tieredWorkspaceReducer = slice$1.reducer;
|
|
2954
|
+
const { setTieredWorkspaceId, clearTieredWorkspaceId, setWorkspaceTier, setWorkspaceFullscreen } = slice$1.actions;
|
|
2955
|
+
const selectWorkspaceTier = (state)=>state.tieredWorkspace.tier;
|
|
2956
|
+
const selectWorkspaceFullscreen = (state)=>state.tieredWorkspace.isFullscreen;
|
|
2957
|
+
|
|
2958
|
+
const NO_WORKSPACE_ID = 'none';
|
|
2959
|
+
const initialState = {
|
|
2960
|
+
id: NO_WORKSPACE_ID,
|
|
2961
|
+
status: WorkspaceStatus.NotFound,
|
|
2962
|
+
requestedStatus: RequestedWorkspaceStatus.Unset,
|
|
2963
|
+
requestedStatusTimestamp: getCurrentTimestamp()
|
|
2964
|
+
};
|
|
2965
|
+
const slice = toolkit.createSlice({
|
|
2966
|
+
name: 'JEGActiveWorkspace',
|
|
2967
|
+
initialState,
|
|
2968
|
+
reducers: {
|
|
2969
|
+
setJEGActiveWorkspaceId: (state, action)=>{
|
|
2970
|
+
state = {
|
|
2971
|
+
...state,
|
|
2972
|
+
id: action.payload.id
|
|
2973
|
+
};
|
|
2974
|
+
return state;
|
|
2975
|
+
},
|
|
2976
|
+
clearJEGActiveWorkspaceId: (state)=>{
|
|
2977
|
+
return {
|
|
2978
|
+
...state,
|
|
2979
|
+
id: NO_WORKSPACE_ID,
|
|
2980
|
+
status: WorkspaceStatus.NotFound
|
|
2981
|
+
};
|
|
2982
|
+
},
|
|
2983
|
+
setJEGActiveWorkspaceStatus: (state, action)=>{
|
|
2984
|
+
return {
|
|
2985
|
+
...state,
|
|
2986
|
+
status: action.payload
|
|
2987
|
+
};
|
|
2988
|
+
},
|
|
2989
|
+
setJEGRequestedWorkspaceStatus: (state, action)=>{
|
|
2990
|
+
return {
|
|
2991
|
+
...state,
|
|
2992
|
+
requestedStatus: action.payload,
|
|
2993
|
+
requestedStatusTimestamp: getCurrentTimestamp()
|
|
2994
|
+
};
|
|
2995
|
+
},
|
|
2996
|
+
setJEGActiveWorkspace: (_state, action)=>{
|
|
2997
|
+
return {
|
|
2998
|
+
...action.payload
|
|
2999
|
+
};
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
});
|
|
3003
|
+
const jegActiveWorkspaceReducer = slice.reducer;
|
|
3004
|
+
const { setJEGActiveWorkspaceId, clearJEGActiveWorkspaceId, setJEGActiveWorkspaceStatus, setJEGRequestedWorkspaceStatus, setJEGActiveWorkspace } = slice.actions;
|
|
3005
|
+
const selectJEGActiveWorkspaceId = (state)=>state.jegActiveWorkspace.id;
|
|
3006
|
+
const selectJEGActiveWorkspaceStatus = (state)=>state.jegActiveWorkspace.status;
|
|
3007
|
+
const selectJEGRequestedWorkspaceStatus = (state)=>state.jegActiveWorkspace.requestedStatus;
|
|
3008
|
+
const selectJEGRequestedWorkspaceStatusTimestamp = (state)=>state.jegActiveWorkspace.requestedStatusTimestamp;
|
|
3009
|
+
|
|
2663
3010
|
const rootReducer = toolkit.combineReducers({
|
|
2664
3011
|
gen3Services: gen3ServicesReducer,
|
|
2665
3012
|
user: userReducer,
|
|
@@ -2668,6 +3015,9 @@ const rootReducer = toolkit.combineReducers({
|
|
|
2668
3015
|
modals: modalReducer,
|
|
2669
3016
|
cohorts: cohortReducers,
|
|
2670
3017
|
activeWorkspace: activeWorkspaceReducer,
|
|
3018
|
+
tieredWorkspace: tieredWorkspaceReducer,
|
|
3019
|
+
workspaceKernels: workspaceKernelReducer,
|
|
3020
|
+
jegActiveWorkspace: jegActiveWorkspaceReducer,
|
|
2671
3021
|
[guppyApiSliceReducerPath]: guppyApiReducer,
|
|
2672
3022
|
[userAuthApiReducerPath]: userAuthApiReducer,
|
|
2673
3023
|
[cartReducerPath]: cartReducer,
|
|
@@ -2711,103 +3061,6 @@ const rootReducer = toolkit.combineReducers({
|
|
|
2711
3061
|
return json;
|
|
2712
3062
|
}
|
|
2713
3063
|
|
|
2714
|
-
// type guard functions
|
|
2715
|
-
const isHistogramRangeData = (key)=>{
|
|
2716
|
-
return Array.isArray(key) && key.length === 2 && key.every((item)=>typeof item === 'number');
|
|
2717
|
-
};
|
|
2718
|
-
const isJSONObject = (data)=>{
|
|
2719
|
-
return typeof data === 'object' && data !== null && !Array.isArray(data);
|
|
2720
|
-
};
|
|
2721
|
-
const isJSONValue = (data)=>{
|
|
2722
|
-
return typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || Array.isArray(data) && data.every(isJSONValue) || isJSONObject(data);
|
|
2723
|
-
};
|
|
2724
|
-
const isJSONValueArray = (data)=>{
|
|
2725
|
-
return Array.isArray(data) && data.every(isJSONValue);
|
|
2726
|
-
};
|
|
2727
|
-
const isValidObject = (input)=>typeof input === 'object' && input !== null;
|
|
2728
|
-
const isHistogramData = (data)=>{
|
|
2729
|
-
return isValidObject(data) && 'key' in data && 'count' in data;
|
|
2730
|
-
};
|
|
2731
|
-
const isHistogramDataArray = (input)=>{
|
|
2732
|
-
if (!isValidObject(input) || !Array.isArray(input.histogram)) {
|
|
2733
|
-
return false;
|
|
2734
|
-
}
|
|
2735
|
-
return input.histogram.every(isHistogramData);
|
|
2736
|
-
};
|
|
2737
|
-
const isHistogramDataCollection = (obj)=>{
|
|
2738
|
-
return isValidObject(obj) && 'histogram' in obj && isHistogramData(obj.histogram);
|
|
2739
|
-
};
|
|
2740
|
-
// Type guard function for GuppyAggregationData interface
|
|
2741
|
-
const isGuppyAggregationData = (obj)=>{
|
|
2742
|
-
if (!isValidObject(obj)) return false;
|
|
2743
|
-
for(const key in obj){
|
|
2744
|
-
if (!isHistogramDataCollection(obj[key])) {
|
|
2745
|
-
return false;
|
|
2746
|
-
}
|
|
2747
|
-
}
|
|
2748
|
-
return true;
|
|
2749
|
-
};
|
|
2750
|
-
const isHistogramDataAnEnum = (data)=>{
|
|
2751
|
-
return typeof data === 'object' && data !== null && 'key' in data && 'count' in data && typeof data.key === 'string' && typeof data.count === 'number';
|
|
2752
|
-
};
|
|
2753
|
-
const isStatsValue = (item)=>{
|
|
2754
|
-
if (typeof item !== 'object' || item === null) {
|
|
2755
|
-
return false;
|
|
2756
|
-
}
|
|
2757
|
-
const obj = item;
|
|
2758
|
-
// Check that all present properties have correct types
|
|
2759
|
-
const numericFields = [
|
|
2760
|
-
'count',
|
|
2761
|
-
'min',
|
|
2762
|
-
'max',
|
|
2763
|
-
'avg',
|
|
2764
|
-
'sum',
|
|
2765
|
-
'stddev',
|
|
2766
|
-
'median'
|
|
2767
|
-
];
|
|
2768
|
-
if (!numericFields.some((field)=>field in obj && typeof obj[field] !== 'number')) {
|
|
2769
|
-
return false;
|
|
2770
|
-
}
|
|
2771
|
-
// Check percentiles structure if present
|
|
2772
|
-
if ('percentiles' in obj) {
|
|
2773
|
-
const percentiles = obj.percentiles;
|
|
2774
|
-
if (typeof percentiles !== 'object' || percentiles === null) {
|
|
2775
|
-
return false;
|
|
2776
|
-
}
|
|
2777
|
-
}
|
|
2778
|
-
return true;
|
|
2779
|
-
};
|
|
2780
|
-
const isStatsValuesArray = (data)=>{
|
|
2781
|
-
return Array.isArray(data) && data.every(isStatsValue);
|
|
2782
|
-
};
|
|
2783
|
-
const isHistogramDataAArray = (data)=>{
|
|
2784
|
-
return Array.isArray(data) && data.every(isHistogramData);
|
|
2785
|
-
};
|
|
2786
|
-
const isHistogramDataArrayAnEnum = (data)=>{
|
|
2787
|
-
return Array.isArray(data) && data.every(isHistogramDataAnEnum);
|
|
2788
|
-
};
|
|
2789
|
-
const isHistogramDataArrayARange = (data)=>{
|
|
2790
|
-
return Array.isArray(data) && data.every((item)=>isHistogramRangeData(item.key));
|
|
2791
|
-
};
|
|
2792
|
-
/**
|
|
2793
|
-
* Type predicate to narrow an unknown error to `FetchBaseQueryError`
|
|
2794
|
-
*/ function isFetchBaseQueryError(error) {
|
|
2795
|
-
return typeof error === 'object' && error != null && 'status' in error;
|
|
2796
|
-
}
|
|
2797
|
-
/**
|
|
2798
|
-
* Type predicate to narrow an unknown error to an object with a string 'message' property
|
|
2799
|
-
*/ function isErrorWithMessage(error) {
|
|
2800
|
-
return typeof error === 'object' && error != null && 'message' in error && typeof error.message === 'string';
|
|
2801
|
-
}
|
|
2802
|
-
function isHttpStatusError(error) {
|
|
2803
|
-
return typeof error === 'object' && error != null && 'status' in error && typeof error.status === 'number';
|
|
2804
|
-
}
|
|
2805
|
-
/**
|
|
2806
|
-
* Type predicate to narrow an unknown error to an object with a string 'message' property
|
|
2807
|
-
*/ function isFetchParseError(error) {
|
|
2808
|
-
return typeof error === 'object' && error != null && 'originalStatus' in error && 'status' in error && error['status'] === 'PARSING_ERROR';
|
|
2809
|
-
}
|
|
2810
|
-
|
|
2811
3064
|
/**
|
|
2812
3065
|
* Prepares a URL for downloading by appending '/download' to the provided apiUrl.
|
|
2813
3066
|
*
|
|
@@ -3681,7 +3934,9 @@ const persistConfig = {
|
|
|
3681
3934
|
whitelist: [
|
|
3682
3935
|
'cohorts',
|
|
3683
3936
|
'activeWorkspace',
|
|
3684
|
-
'cart'
|
|
3937
|
+
'cart',
|
|
3938
|
+
'workspaceKernels',
|
|
3939
|
+
'tieredWorkspace'
|
|
3685
3940
|
]
|
|
3686
3941
|
};
|
|
3687
3942
|
const persistedReducer = reduxPersist.persistReducer(persistConfig, rootReducer);
|
|
@@ -5424,7 +5679,7 @@ const credentialsWithTags = gen3Api.enhanceEndpoints({
|
|
|
5424
5679
|
})
|
|
5425
5680
|
})
|
|
5426
5681
|
});
|
|
5427
|
-
const { useGetJWKKeysQuery } = jwtApi;
|
|
5682
|
+
const { useGetJWKKeysQuery, useLazyGetJWKKeysQuery } = jwtApi;
|
|
5428
5683
|
|
|
5429
5684
|
// using a random uuid v4 as the namespace
|
|
5430
5685
|
const GEN3_APP_NAMESPACE = '7bfaa818-c69c-457e-8d87-413cf60c25f0';
|
|
@@ -6010,7 +6265,7 @@ function getRemoteSupportServiceRegistry(logger) {
|
|
|
6010
6265
|
const ZENDESK_MAX_SUBJECT_LENGTH = 255;
|
|
6011
6266
|
const ZENDESK_DOMAIN = process.env.NEXT_PUBLIC_GEN3_ZENDESK_API || 'https://<SUBDOMAIN_NAME>.zendesk.com';
|
|
6012
6267
|
const createZendeskTicket = async ({ subject, fullName, email, contents }, configuration)=>{
|
|
6013
|
-
const { zendeskSubdomainName } = configuration;
|
|
6268
|
+
const { zendeskSubdomainName, custom_fields } = configuration;
|
|
6014
6269
|
try {
|
|
6015
6270
|
let zendeskTicketCreationURL = `${ZENDESK_DOMAIN}/api/v2/requests`;
|
|
6016
6271
|
if (zendeskSubdomainName) {
|
|
@@ -6037,7 +6292,8 @@ const createZendeskTicket = async ({ subject, fullName, email, contents }, confi
|
|
|
6037
6292
|
requester: {
|
|
6038
6293
|
name: fullName,
|
|
6039
6294
|
email
|
|
6040
|
-
}
|
|
6295
|
+
},
|
|
6296
|
+
custom_fields
|
|
6041
6297
|
}
|
|
6042
6298
|
})
|
|
6043
6299
|
}).then((response)=>{
|
|
@@ -6121,11 +6377,6 @@ const requestorApi = gen3Api.injectEndpoints({
|
|
|
6121
6377
|
query: (queryBody)=>({
|
|
6122
6378
|
url: `${GEN3_REQUESTOR_API}/request`,
|
|
6123
6379
|
method: 'POST',
|
|
6124
|
-
credentials: 'include',
|
|
6125
|
-
headers: {
|
|
6126
|
-
Accept: 'application/json',
|
|
6127
|
-
'Content-Type': 'application/json'
|
|
6128
|
-
},
|
|
6129
6380
|
body: JSON.stringify(queryBody)
|
|
6130
6381
|
})
|
|
6131
6382
|
})
|
|
@@ -6318,10 +6569,23 @@ const SubmissionGraphqlQuery = `query transactionList {
|
|
|
6318
6569
|
query: ()=>({
|
|
6319
6570
|
url: `${GEN3_SUBMISSION_API}/_dictionary/_all/`
|
|
6320
6571
|
})
|
|
6572
|
+
}),
|
|
6573
|
+
getDictionaryFromUrl: builder.query({
|
|
6574
|
+
query: (url)=>{
|
|
6575
|
+
if (URL.canParse(url)) {
|
|
6576
|
+
return {
|
|
6577
|
+
url: url
|
|
6578
|
+
};
|
|
6579
|
+
} else {
|
|
6580
|
+
return {
|
|
6581
|
+
url: `${GEN3_SUBMISSION_API}/${url}`
|
|
6582
|
+
};
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6321
6585
|
})
|
|
6322
6586
|
})
|
|
6323
6587
|
});
|
|
6324
|
-
const { useGetProjectsQuery, useGetSubmissionGraphQLQuery, useGetProjectsDetailsQuery, useLazyGetProjectsQuery, useLazyGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetDictionaryQuery } = submissionApi;
|
|
6588
|
+
const { useGetProjectsQuery, useGetSubmissionGraphQLQuery, useGetProjectsDetailsQuery, useLazyGetProjectsQuery, useLazyGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetDictionaryQuery, useGetDictionaryFromUrlQuery } = submissionApi;
|
|
6325
6589
|
|
|
6326
6590
|
const WorkspaceWithTags = gen3Api.enhanceEndpoints({
|
|
6327
6591
|
addTagTypes: [
|
|
@@ -6459,6 +6723,8 @@ const selectWorkspaceStatus = toolkit.createSelector(workspaceStatusSelector, (s
|
|
|
6459
6723
|
const paymodelStatusSelector = workspacesApi.endpoints.getWorkspacePayModels.select();
|
|
6460
6724
|
const selectPaymodelStatus = toolkit.createSelector(paymodelStatusSelector, (status)=>status);
|
|
6461
6725
|
|
|
6726
|
+
const { selectAll: selectAllJEGKernels, selectById: selectJEGKernelById, selectIds: selectJEGKernelIds } = workspaceKernelsAdapter.getSelectors((state)=>state.workspaceKernels);
|
|
6727
|
+
|
|
6462
6728
|
const isWorkspaceActive = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Launching || status === WorkspaceStatus.Terminating;
|
|
6463
6729
|
const isWorkspaceRunningOrStopping = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Terminating;
|
|
6464
6730
|
|
|
@@ -6608,6 +6874,50 @@ const indexdApi = gen3Api.injectEndpoints({
|
|
|
6608
6874
|
});
|
|
6609
6875
|
const { useGetIndexdMetdataQuery, useLazyGetIndexdMetdataQuery, useGetIndexObjectQuery, useLazyGetIndexObjectQuery } = indexdApi;
|
|
6610
6876
|
|
|
6877
|
+
/**
|
|
6878
|
+
* Types for the notification service
|
|
6879
|
+
*/ /**
|
|
6880
|
+
* Notification service singleton
|
|
6881
|
+
*/ class NotificationService {
|
|
6882
|
+
constructor(){
|
|
6883
|
+
this.handler = null;
|
|
6884
|
+
}
|
|
6885
|
+
/**
|
|
6886
|
+
* Get the singleton instance
|
|
6887
|
+
*/ static getInstance() {
|
|
6888
|
+
if (!NotificationService.instance) {
|
|
6889
|
+
NotificationService.instance = new NotificationService();
|
|
6890
|
+
}
|
|
6891
|
+
return NotificationService.instance;
|
|
6892
|
+
}
|
|
6893
|
+
/**
|
|
6894
|
+
* Register a notification handler
|
|
6895
|
+
*/ registerHandler(handler) {
|
|
6896
|
+
this.handler = handler;
|
|
6897
|
+
}
|
|
6898
|
+
/**
|
|
6899
|
+
* Unregister the notification handler
|
|
6900
|
+
*/ unregisterHandler() {
|
|
6901
|
+
this.handler = null;
|
|
6902
|
+
}
|
|
6903
|
+
/**
|
|
6904
|
+
* Show a notification using the registered handler
|
|
6905
|
+
*/ showNotification(id, title, message, type, options) {
|
|
6906
|
+
if (this.handler) {
|
|
6907
|
+
this.handler(id, title, message, type, options);
|
|
6908
|
+
} else {
|
|
6909
|
+
// Fallback for when no handler is registered (e.g., log to console)
|
|
6910
|
+
console.log(`Notification [${type}]: ${title} - ${message}`);
|
|
6911
|
+
}
|
|
6912
|
+
}
|
|
6913
|
+
}
|
|
6914
|
+
// Export the singleton instance
|
|
6915
|
+
const notificationService = NotificationService.getInstance();
|
|
6916
|
+
// Export convenience methods
|
|
6917
|
+
const showNotification = (id, title, message, type, options)=>{
|
|
6918
|
+
notificationService.showNotification(id, title, message, type, options);
|
|
6919
|
+
};
|
|
6920
|
+
|
|
6611
6921
|
exports.Accessibility = Accessibility;
|
|
6612
6922
|
exports.CART_LIMIT = CART_LIMIT;
|
|
6613
6923
|
exports.CohortStorage = CohortStorage;
|
|
@@ -6651,6 +6961,7 @@ exports.ToGqlHandler = ToGqlHandler;
|
|
|
6651
6961
|
exports.ValueExtractorHandler = ValueExtractorHandler;
|
|
6652
6962
|
exports.WorkspaceStatus = WorkspaceStatus;
|
|
6653
6963
|
exports.addItemsToCart = addItemsToCart;
|
|
6964
|
+
exports.addJEGActiveKernel = addJEGActiveKernel;
|
|
6654
6965
|
exports.ageDisplay = ageDisplay;
|
|
6655
6966
|
exports.appendFilterToOperation = appendFilterToOperation;
|
|
6656
6967
|
exports.buildCohortGqlOperator = buildCohortGqlOperator;
|
|
@@ -6668,6 +6979,8 @@ exports.cartReducer = cartReducer;
|
|
|
6668
6979
|
exports.cartReducerPath = cartReducerPath;
|
|
6669
6980
|
exports.clearActiveWorkspaceId = clearActiveWorkspaceId;
|
|
6670
6981
|
exports.clearCohortFilters = clearCohortFilters;
|
|
6982
|
+
exports.clearJEGActiveKernels = clearJEGActiveKernels;
|
|
6983
|
+
exports.clearJEGActiveWorkspaceId = clearJEGActiveWorkspaceId;
|
|
6671
6984
|
exports.cohortReducer = cohortReducer;
|
|
6672
6985
|
exports.configRegistry = configRegistry;
|
|
6673
6986
|
exports.conversion = conversion;
|
|
@@ -6711,6 +7024,7 @@ exports.fetchJson = fetchJson;
|
|
|
6711
7024
|
exports.fetchUserState = fetchUserState;
|
|
6712
7025
|
exports.fieldNameToLabel = fieldNameToLabel;
|
|
6713
7026
|
exports.filterSetToOperation = filterSetToOperation;
|
|
7027
|
+
exports.formatUptimeInMinutes = formatUptimeInMinutes;
|
|
6714
7028
|
exports.gen3Api = gen3Api;
|
|
6715
7029
|
exports.generateUniqueName = generateUniqueName;
|
|
6716
7030
|
exports.getCurrentTimestamp = getCurrentTimestamp;
|
|
@@ -6789,6 +7103,8 @@ exports.logoutFence = logoutFence;
|
|
|
6789
7103
|
exports.manifestApi = manifestApi;
|
|
6790
7104
|
exports.manifestTags = manifestTags;
|
|
6791
7105
|
exports.nestedHistogramQueryStrForEachField = nestedHistogramQueryStrForEachField;
|
|
7106
|
+
exports.normalizeRtkError = normalizeRtkError;
|
|
7107
|
+
exports.notificationService = notificationService;
|
|
6792
7108
|
exports.prepareUrl = prepareUrl$1;
|
|
6793
7109
|
exports.prependIndexToFieldName = prependIndexToFieldName;
|
|
6794
7110
|
exports.printRegistry = printRegistry;
|
|
@@ -6800,6 +7116,8 @@ exports.registerDefaultRemoteSupport = registerDefaultRemoteSupport;
|
|
|
6800
7116
|
exports.removeCohort = removeCohort;
|
|
6801
7117
|
exports.removeCohortFilter = removeCohortFilter;
|
|
6802
7118
|
exports.removeItemsFromCart = removeItemsFromCart;
|
|
7119
|
+
exports.removeJEGActiveKernel = removeJEGActiveKernel;
|
|
7120
|
+
exports.removeManyJEGActiveKernels = removeManyJEGActiveKernels;
|
|
6803
7121
|
exports.requestorApi = requestorApi;
|
|
6804
7122
|
exports.resetUserState = resetUserState;
|
|
6805
7123
|
exports.resourcePathFromProjectID = resourcePathFromProjectID;
|
|
@@ -6808,6 +7126,7 @@ exports.selectActiveWorkspaceId = selectActiveWorkspaceId;
|
|
|
6808
7126
|
exports.selectActiveWorkspaceStatus = selectActiveWorkspaceStatus;
|
|
6809
7127
|
exports.selectAllCohortFiltersCollapsed = selectAllCohortFiltersCollapsed;
|
|
6810
7128
|
exports.selectAllCohorts = selectAllCohorts;
|
|
7129
|
+
exports.selectAllJEGKernels = selectAllJEGKernels;
|
|
6811
7130
|
exports.selectAuthzMappingData = selectAuthzMappingData;
|
|
6812
7131
|
exports.selectAvailableCohortByName = selectAvailableCohortByName;
|
|
6813
7132
|
exports.selectAvailableCohorts = selectAvailableCohorts;
|
|
@@ -6835,6 +7154,12 @@ exports.selectGen3AppMetadataByName = selectGen3AppMetadataByName;
|
|
|
6835
7154
|
exports.selectHeadersWithCSRFToken = selectHeadersWithCSRFToken;
|
|
6836
7155
|
exports.selectIndexFilters = selectIndexFilters;
|
|
6837
7156
|
exports.selectIndexedFilterByName = selectIndexedFilterByName;
|
|
7157
|
+
exports.selectJEGActiveWorkspaceId = selectJEGActiveWorkspaceId;
|
|
7158
|
+
exports.selectJEGActiveWorkspaceStatus = selectJEGActiveWorkspaceStatus;
|
|
7159
|
+
exports.selectJEGKernelById = selectJEGKernelById;
|
|
7160
|
+
exports.selectJEGKernelIds = selectJEGKernelIds;
|
|
7161
|
+
exports.selectJEGRequestedWorkspaceStatus = selectJEGRequestedWorkspaceStatus;
|
|
7162
|
+
exports.selectJEGRequestedWorkspaceStatusTimestamp = selectJEGRequestedWorkspaceStatusTimestamp;
|
|
6838
7163
|
exports.selectPaymodelStatus = selectPaymodelStatus;
|
|
6839
7164
|
exports.selectRequestedWorkspaceStatus = selectRequestedWorkspaceStatus;
|
|
6840
7165
|
exports.selectRequestedWorkspaceStatusTimestamp = selectRequestedWorkspaceStatusTimestamp;
|
|
@@ -6848,8 +7173,10 @@ exports.selectUserAuthStatus = selectUserAuthStatus;
|
|
|
6848
7173
|
exports.selectUserData = selectUserData;
|
|
6849
7174
|
exports.selectUserDetails = selectUserDetails;
|
|
6850
7175
|
exports.selectUserLoginStatus = selectUserLoginStatus;
|
|
7176
|
+
exports.selectWorkspaceFullscreen = selectWorkspaceFullscreen;
|
|
6851
7177
|
exports.selectWorkspaceStatus = selectWorkspaceStatus;
|
|
6852
7178
|
exports.selectWorkspaceStatusFromService = selectWorkspaceStatusFromService;
|
|
7179
|
+
exports.selectWorkspaceTier = selectWorkspaceTier;
|
|
6853
7180
|
exports.setActiveWorkspace = setActiveWorkspace;
|
|
6854
7181
|
exports.setActiveWorkspaceId = setActiveWorkspaceId;
|
|
6855
7182
|
exports.setActiveWorkspaceStatus = setActiveWorkspaceStatus;
|
|
@@ -6859,11 +7186,18 @@ exports.setCohortIndexFilters = setCohortIndexFilters;
|
|
|
6859
7186
|
exports.setCohortList = setCohortList;
|
|
6860
7187
|
exports.setCurrentCohortId = setCurrentCohortId;
|
|
6861
7188
|
exports.setDRSHostnames = setDRSHostnames;
|
|
7189
|
+
exports.setJEGActiveWorkspace = setJEGActiveWorkspace;
|
|
7190
|
+
exports.setJEGActiveWorkspaceId = setJEGActiveWorkspaceId;
|
|
7191
|
+
exports.setJEGActiveWorkspaceStatus = setJEGActiveWorkspaceStatus;
|
|
7192
|
+
exports.setJEGRequestedWorkspaceStatus = setJEGRequestedWorkspaceStatus;
|
|
6862
7193
|
exports.setRequestedWorkspaceStatus = setRequestedWorkspaceStatus;
|
|
6863
7194
|
exports.setSharedFilters = setSharedFilters;
|
|
6864
7195
|
exports.setShouldShareFilters = setShouldShareFilters;
|
|
7196
|
+
exports.setWorkspaceFullscreen = setWorkspaceFullscreen;
|
|
7197
|
+
exports.setWorkspaceTier = setWorkspaceTier;
|
|
6865
7198
|
exports.setupCoreStore = setupCoreStore;
|
|
6866
7199
|
exports.showModal = showModal;
|
|
7200
|
+
exports.showNotification = showNotification;
|
|
6867
7201
|
exports.statsQueryStrForEachField = statsQueryStrForEachField;
|
|
6868
7202
|
exports.stringifyJSONParam = stringifyJSONParam;
|
|
6869
7203
|
exports.submissionApi = submissionApi;
|
|
@@ -6872,6 +7206,8 @@ exports.toggleCohortBuilderCategoryFilter = toggleCohortBuilderCategoryFilter;
|
|
|
6872
7206
|
exports.trimFirstfieldNameToLabel = trimFirstfieldNameToLabel;
|
|
6873
7207
|
exports.updateCohortFilter = updateCohortFilter;
|
|
6874
7208
|
exports.updateCohortName = updateCohortName;
|
|
7209
|
+
exports.updateJEGActionKernelStatus = updateJEGActionKernelStatus;
|
|
7210
|
+
exports.upsertManyJEGActiveKernels = upsertManyJEGActiveKernels;
|
|
6875
7211
|
exports.useAddCohortManifestMutation = useAddCohortManifestMutation;
|
|
6876
7212
|
exports.useAddFileManifestMutation = useAddFileManifestMutation;
|
|
6877
7213
|
exports.useAddMetadataManifestMutation = useAddMetadataManifestMutation;
|
|
@@ -6904,6 +7240,7 @@ exports.useGetCountsQuery = useGetCountsQuery;
|
|
|
6904
7240
|
exports.useGetCredentialsQuery = useGetCredentialsQuery;
|
|
6905
7241
|
exports.useGetCrosswalkDataQuery = useGetCrosswalkDataQuery;
|
|
6906
7242
|
exports.useGetDataQuery = useGetDataQuery;
|
|
7243
|
+
exports.useGetDictionaryFromUrlQuery = useGetDictionaryFromUrlQuery;
|
|
6907
7244
|
exports.useGetDictionaryQuery = useGetDictionaryQuery;
|
|
6908
7245
|
exports.useGetDownloadQuery = useGetDownloadQuery;
|
|
6909
7246
|
exports.useGetExternalLoginsQuery = useGetExternalLoginsQuery;
|
|
@@ -6960,6 +7297,7 @@ exports.useLazyGetDownloadQuery = useLazyGetDownloadQuery;
|
|
|
6960
7297
|
exports.useLazyGetExternalLoginsQuery = useLazyGetExternalLoginsQuery;
|
|
6961
7298
|
exports.useLazyGetIndexObjectQuery = useLazyGetIndexObjectQuery;
|
|
6962
7299
|
exports.useLazyGetIndexdMetdataQuery = useLazyGetIndexdMetdataQuery;
|
|
7300
|
+
exports.useLazyGetJWKKeysQuery = useLazyGetJWKKeysQuery;
|
|
6963
7301
|
exports.useLazyGetManifestServiceStatusQuery = useLazyGetManifestServiceStatusQuery;
|
|
6964
7302
|
exports.useLazyGetMultipleSowerJobStatusQuery = useLazyGetMultipleSowerJobStatusQuery;
|
|
6965
7303
|
exports.useLazyGetObjectIdsQuery = useLazyGetObjectIdsQuery;
|