@gen3/core 0.12.44 → 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 +500 -158
- 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/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 +473 -159
- 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 +11159 -10453
- 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';
|
|
@@ -6314,10 +6569,23 @@ const SubmissionGraphqlQuery = `query transactionList {
|
|
|
6314
6569
|
query: ()=>({
|
|
6315
6570
|
url: `${GEN3_SUBMISSION_API}/_dictionary/_all/`
|
|
6316
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
|
+
}
|
|
6317
6585
|
})
|
|
6318
6586
|
})
|
|
6319
6587
|
});
|
|
6320
|
-
const { useGetProjectsQuery, useGetSubmissionGraphQLQuery, useGetProjectsDetailsQuery, useLazyGetProjectsQuery, useLazyGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetDictionaryQuery } = submissionApi;
|
|
6588
|
+
const { useGetProjectsQuery, useGetSubmissionGraphQLQuery, useGetProjectsDetailsQuery, useLazyGetProjectsQuery, useLazyGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetDictionaryQuery, useGetDictionaryFromUrlQuery } = submissionApi;
|
|
6321
6589
|
|
|
6322
6590
|
const WorkspaceWithTags = gen3Api.enhanceEndpoints({
|
|
6323
6591
|
addTagTypes: [
|
|
@@ -6455,6 +6723,8 @@ const selectWorkspaceStatus = toolkit.createSelector(workspaceStatusSelector, (s
|
|
|
6455
6723
|
const paymodelStatusSelector = workspacesApi.endpoints.getWorkspacePayModels.select();
|
|
6456
6724
|
const selectPaymodelStatus = toolkit.createSelector(paymodelStatusSelector, (status)=>status);
|
|
6457
6725
|
|
|
6726
|
+
const { selectAll: selectAllJEGKernels, selectById: selectJEGKernelById, selectIds: selectJEGKernelIds } = workspaceKernelsAdapter.getSelectors((state)=>state.workspaceKernels);
|
|
6727
|
+
|
|
6458
6728
|
const isWorkspaceActive = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Launching || status === WorkspaceStatus.Terminating;
|
|
6459
6729
|
const isWorkspaceRunningOrStopping = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Terminating;
|
|
6460
6730
|
|
|
@@ -6604,6 +6874,50 @@ const indexdApi = gen3Api.injectEndpoints({
|
|
|
6604
6874
|
});
|
|
6605
6875
|
const { useGetIndexdMetdataQuery, useLazyGetIndexdMetdataQuery, useGetIndexObjectQuery, useLazyGetIndexObjectQuery } = indexdApi;
|
|
6606
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
|
+
|
|
6607
6921
|
exports.Accessibility = Accessibility;
|
|
6608
6922
|
exports.CART_LIMIT = CART_LIMIT;
|
|
6609
6923
|
exports.CohortStorage = CohortStorage;
|
|
@@ -6647,6 +6961,7 @@ exports.ToGqlHandler = ToGqlHandler;
|
|
|
6647
6961
|
exports.ValueExtractorHandler = ValueExtractorHandler;
|
|
6648
6962
|
exports.WorkspaceStatus = WorkspaceStatus;
|
|
6649
6963
|
exports.addItemsToCart = addItemsToCart;
|
|
6964
|
+
exports.addJEGActiveKernel = addJEGActiveKernel;
|
|
6650
6965
|
exports.ageDisplay = ageDisplay;
|
|
6651
6966
|
exports.appendFilterToOperation = appendFilterToOperation;
|
|
6652
6967
|
exports.buildCohortGqlOperator = buildCohortGqlOperator;
|
|
@@ -6664,6 +6979,8 @@ exports.cartReducer = cartReducer;
|
|
|
6664
6979
|
exports.cartReducerPath = cartReducerPath;
|
|
6665
6980
|
exports.clearActiveWorkspaceId = clearActiveWorkspaceId;
|
|
6666
6981
|
exports.clearCohortFilters = clearCohortFilters;
|
|
6982
|
+
exports.clearJEGActiveKernels = clearJEGActiveKernels;
|
|
6983
|
+
exports.clearJEGActiveWorkspaceId = clearJEGActiveWorkspaceId;
|
|
6667
6984
|
exports.cohortReducer = cohortReducer;
|
|
6668
6985
|
exports.configRegistry = configRegistry;
|
|
6669
6986
|
exports.conversion = conversion;
|
|
@@ -6707,6 +7024,7 @@ exports.fetchJson = fetchJson;
|
|
|
6707
7024
|
exports.fetchUserState = fetchUserState;
|
|
6708
7025
|
exports.fieldNameToLabel = fieldNameToLabel;
|
|
6709
7026
|
exports.filterSetToOperation = filterSetToOperation;
|
|
7027
|
+
exports.formatUptimeInMinutes = formatUptimeInMinutes;
|
|
6710
7028
|
exports.gen3Api = gen3Api;
|
|
6711
7029
|
exports.generateUniqueName = generateUniqueName;
|
|
6712
7030
|
exports.getCurrentTimestamp = getCurrentTimestamp;
|
|
@@ -6785,6 +7103,8 @@ exports.logoutFence = logoutFence;
|
|
|
6785
7103
|
exports.manifestApi = manifestApi;
|
|
6786
7104
|
exports.manifestTags = manifestTags;
|
|
6787
7105
|
exports.nestedHistogramQueryStrForEachField = nestedHistogramQueryStrForEachField;
|
|
7106
|
+
exports.normalizeRtkError = normalizeRtkError;
|
|
7107
|
+
exports.notificationService = notificationService;
|
|
6788
7108
|
exports.prepareUrl = prepareUrl$1;
|
|
6789
7109
|
exports.prependIndexToFieldName = prependIndexToFieldName;
|
|
6790
7110
|
exports.printRegistry = printRegistry;
|
|
@@ -6796,6 +7116,8 @@ exports.registerDefaultRemoteSupport = registerDefaultRemoteSupport;
|
|
|
6796
7116
|
exports.removeCohort = removeCohort;
|
|
6797
7117
|
exports.removeCohortFilter = removeCohortFilter;
|
|
6798
7118
|
exports.removeItemsFromCart = removeItemsFromCart;
|
|
7119
|
+
exports.removeJEGActiveKernel = removeJEGActiveKernel;
|
|
7120
|
+
exports.removeManyJEGActiveKernels = removeManyJEGActiveKernels;
|
|
6799
7121
|
exports.requestorApi = requestorApi;
|
|
6800
7122
|
exports.resetUserState = resetUserState;
|
|
6801
7123
|
exports.resourcePathFromProjectID = resourcePathFromProjectID;
|
|
@@ -6804,6 +7126,7 @@ exports.selectActiveWorkspaceId = selectActiveWorkspaceId;
|
|
|
6804
7126
|
exports.selectActiveWorkspaceStatus = selectActiveWorkspaceStatus;
|
|
6805
7127
|
exports.selectAllCohortFiltersCollapsed = selectAllCohortFiltersCollapsed;
|
|
6806
7128
|
exports.selectAllCohorts = selectAllCohorts;
|
|
7129
|
+
exports.selectAllJEGKernels = selectAllJEGKernels;
|
|
6807
7130
|
exports.selectAuthzMappingData = selectAuthzMappingData;
|
|
6808
7131
|
exports.selectAvailableCohortByName = selectAvailableCohortByName;
|
|
6809
7132
|
exports.selectAvailableCohorts = selectAvailableCohorts;
|
|
@@ -6831,6 +7154,12 @@ exports.selectGen3AppMetadataByName = selectGen3AppMetadataByName;
|
|
|
6831
7154
|
exports.selectHeadersWithCSRFToken = selectHeadersWithCSRFToken;
|
|
6832
7155
|
exports.selectIndexFilters = selectIndexFilters;
|
|
6833
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;
|
|
6834
7163
|
exports.selectPaymodelStatus = selectPaymodelStatus;
|
|
6835
7164
|
exports.selectRequestedWorkspaceStatus = selectRequestedWorkspaceStatus;
|
|
6836
7165
|
exports.selectRequestedWorkspaceStatusTimestamp = selectRequestedWorkspaceStatusTimestamp;
|
|
@@ -6844,8 +7173,10 @@ exports.selectUserAuthStatus = selectUserAuthStatus;
|
|
|
6844
7173
|
exports.selectUserData = selectUserData;
|
|
6845
7174
|
exports.selectUserDetails = selectUserDetails;
|
|
6846
7175
|
exports.selectUserLoginStatus = selectUserLoginStatus;
|
|
7176
|
+
exports.selectWorkspaceFullscreen = selectWorkspaceFullscreen;
|
|
6847
7177
|
exports.selectWorkspaceStatus = selectWorkspaceStatus;
|
|
6848
7178
|
exports.selectWorkspaceStatusFromService = selectWorkspaceStatusFromService;
|
|
7179
|
+
exports.selectWorkspaceTier = selectWorkspaceTier;
|
|
6849
7180
|
exports.setActiveWorkspace = setActiveWorkspace;
|
|
6850
7181
|
exports.setActiveWorkspaceId = setActiveWorkspaceId;
|
|
6851
7182
|
exports.setActiveWorkspaceStatus = setActiveWorkspaceStatus;
|
|
@@ -6855,11 +7186,18 @@ exports.setCohortIndexFilters = setCohortIndexFilters;
|
|
|
6855
7186
|
exports.setCohortList = setCohortList;
|
|
6856
7187
|
exports.setCurrentCohortId = setCurrentCohortId;
|
|
6857
7188
|
exports.setDRSHostnames = setDRSHostnames;
|
|
7189
|
+
exports.setJEGActiveWorkspace = setJEGActiveWorkspace;
|
|
7190
|
+
exports.setJEGActiveWorkspaceId = setJEGActiveWorkspaceId;
|
|
7191
|
+
exports.setJEGActiveWorkspaceStatus = setJEGActiveWorkspaceStatus;
|
|
7192
|
+
exports.setJEGRequestedWorkspaceStatus = setJEGRequestedWorkspaceStatus;
|
|
6858
7193
|
exports.setRequestedWorkspaceStatus = setRequestedWorkspaceStatus;
|
|
6859
7194
|
exports.setSharedFilters = setSharedFilters;
|
|
6860
7195
|
exports.setShouldShareFilters = setShouldShareFilters;
|
|
7196
|
+
exports.setWorkspaceFullscreen = setWorkspaceFullscreen;
|
|
7197
|
+
exports.setWorkspaceTier = setWorkspaceTier;
|
|
6861
7198
|
exports.setupCoreStore = setupCoreStore;
|
|
6862
7199
|
exports.showModal = showModal;
|
|
7200
|
+
exports.showNotification = showNotification;
|
|
6863
7201
|
exports.statsQueryStrForEachField = statsQueryStrForEachField;
|
|
6864
7202
|
exports.stringifyJSONParam = stringifyJSONParam;
|
|
6865
7203
|
exports.submissionApi = submissionApi;
|
|
@@ -6868,6 +7206,8 @@ exports.toggleCohortBuilderCategoryFilter = toggleCohortBuilderCategoryFilter;
|
|
|
6868
7206
|
exports.trimFirstfieldNameToLabel = trimFirstfieldNameToLabel;
|
|
6869
7207
|
exports.updateCohortFilter = updateCohortFilter;
|
|
6870
7208
|
exports.updateCohortName = updateCohortName;
|
|
7209
|
+
exports.updateJEGActionKernelStatus = updateJEGActionKernelStatus;
|
|
7210
|
+
exports.upsertManyJEGActiveKernels = upsertManyJEGActiveKernels;
|
|
6871
7211
|
exports.useAddCohortManifestMutation = useAddCohortManifestMutation;
|
|
6872
7212
|
exports.useAddFileManifestMutation = useAddFileManifestMutation;
|
|
6873
7213
|
exports.useAddMetadataManifestMutation = useAddMetadataManifestMutation;
|
|
@@ -6900,6 +7240,7 @@ exports.useGetCountsQuery = useGetCountsQuery;
|
|
|
6900
7240
|
exports.useGetCredentialsQuery = useGetCredentialsQuery;
|
|
6901
7241
|
exports.useGetCrosswalkDataQuery = useGetCrosswalkDataQuery;
|
|
6902
7242
|
exports.useGetDataQuery = useGetDataQuery;
|
|
7243
|
+
exports.useGetDictionaryFromUrlQuery = useGetDictionaryFromUrlQuery;
|
|
6903
7244
|
exports.useGetDictionaryQuery = useGetDictionaryQuery;
|
|
6904
7245
|
exports.useGetDownloadQuery = useGetDownloadQuery;
|
|
6905
7246
|
exports.useGetExternalLoginsQuery = useGetExternalLoginsQuery;
|
|
@@ -6956,6 +7297,7 @@ exports.useLazyGetDownloadQuery = useLazyGetDownloadQuery;
|
|
|
6956
7297
|
exports.useLazyGetExternalLoginsQuery = useLazyGetExternalLoginsQuery;
|
|
6957
7298
|
exports.useLazyGetIndexObjectQuery = useLazyGetIndexObjectQuery;
|
|
6958
7299
|
exports.useLazyGetIndexdMetdataQuery = useLazyGetIndexdMetdataQuery;
|
|
7300
|
+
exports.useLazyGetJWKKeysQuery = useLazyGetJWKKeysQuery;
|
|
6959
7301
|
exports.useLazyGetManifestServiceStatusQuery = useLazyGetManifestServiceStatusQuery;
|
|
6960
7302
|
exports.useLazyGetMultipleSowerJobStatusQuery = useLazyGetMultipleSowerJobStatusQuery;
|
|
6961
7303
|
exports.useLazyGetObjectIdsQuery = useLazyGetObjectIdsQuery;
|