@gen3/core 0.11.33 → 0.11.35
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 +782 -710
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server.js +45 -0
- package/dist/cjs/server.js.map +1 -0
- package/dist/dts/constants.d.ts +1 -0
- package/dist/dts/constants.d.ts.map +1 -1
- package/dist/dts/features/cart/cartSelectors.d.ts +129 -0
- package/dist/dts/features/cart/cartSelectors.d.ts.map +1 -0
- package/dist/dts/features/cart/cartSlice.d.ts +24 -0
- package/dist/dts/features/cart/cartSlice.d.ts.map +1 -0
- package/dist/dts/features/cart/index.d.ts +5 -0
- package/dist/dts/features/cart/index.d.ts.map +1 -0
- package/dist/dts/features/cart/test/cartSelector.unit.test.d.ts +2 -0
- package/dist/dts/features/cart/test/cartSelector.unit.test.d.ts.map +1 -0
- package/dist/dts/features/cohort/cohortManagerSelector.d.ts +4 -0
- package/dist/dts/features/cohort/cohortManagerSelector.d.ts.map +1 -1
- package/dist/dts/features/cohort/cohortManagerSlice.d.ts +1 -0
- package/dist/dts/features/cohort/cohortManagerSlice.d.ts.map +1 -1
- package/dist/dts/features/cohort/utils.d.ts +13 -0
- package/dist/dts/features/cohort/utils.d.ts.map +1 -1
- package/dist/dts/features/filters/types.d.ts +7 -0
- package/dist/dts/features/filters/types.d.ts.map +1 -1
- package/dist/dts/features/guppy/guppySlice.d.ts +61 -14
- package/dist/dts/features/guppy/guppySlice.d.ts.map +1 -1
- package/dist/dts/features/user/userSliceRTK.d.ts +3 -0
- package/dist/dts/features/user/userSliceRTK.d.ts.map +1 -1
- package/dist/dts/hooks.d.ts +2 -0
- package/dist/dts/hooks.d.ts.map +1 -1
- package/dist/dts/index.d.ts +3 -2
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/reducers.d.ts +2 -0
- package/dist/dts/reducers.d.ts.map +1 -1
- package/dist/dts/server.d.ts +4 -0
- package/dist/dts/server.d.ts.map +1 -0
- package/dist/dts/store.d.ts +4 -0
- package/dist/dts/store.d.ts.map +1 -1
- package/dist/esm/index.js +771 -711
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server.js +29 -0
- package/dist/esm/server.js.map +1 -0
- package/dist/index.d.ts +433 -209
- package/dist/server.d.ts +31 -0
- package/package.json +7 -2
package/dist/esm/index.js
CHANGED
|
@@ -7,9 +7,9 @@ import * as React from 'react';
|
|
|
7
7
|
import React__default, { useEffect, useState, useRef, useCallback } from 'react';
|
|
8
8
|
import { GraphQLError, parse } from 'graphql';
|
|
9
9
|
import { JSONPath } from 'jsonpath-plus';
|
|
10
|
+
import { isEqual } from 'lodash';
|
|
10
11
|
import { customAlphabet } from 'nanoid';
|
|
11
12
|
import useSWR from 'swr';
|
|
12
|
-
import { isEqual } from 'lodash';
|
|
13
13
|
import { flatten } from 'flat';
|
|
14
14
|
import Papa from 'papaparse';
|
|
15
15
|
import { persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, persistStore } from 'redux-persist';
|
|
@@ -52,6 +52,7 @@ const FILE_DELIMITERS = {
|
|
|
52
52
|
tsv: '\t',
|
|
53
53
|
csv: ','
|
|
54
54
|
};
|
|
55
|
+
const CART_LIMIT = 10000;
|
|
55
56
|
|
|
56
57
|
const isFetchError = (obj)=>{
|
|
57
58
|
if (typeof obj !== 'object' || obj === null) {
|
|
@@ -406,7 +407,7 @@ const useCoreDispatch = useDispatch.withTypes();
|
|
|
406
407
|
});
|
|
407
408
|
const isAuthenticated = (loginStatus)=>loginStatus === 'authenticated';
|
|
408
409
|
const isPending = (loginStatus)=>loginStatus === 'pending';
|
|
409
|
-
const initialState$
|
|
410
|
+
const initialState$9 = {
|
|
410
411
|
status: 'uninitialized',
|
|
411
412
|
loginStatus: 'unauthenticated',
|
|
412
413
|
error: undefined
|
|
@@ -417,9 +418,9 @@ const initialState$8 = {
|
|
|
417
418
|
* @returns: status messages wrapped around fetchUserState response dict
|
|
418
419
|
*/ const slice$4 = createSlice({
|
|
419
420
|
name: 'fence/user',
|
|
420
|
-
initialState: initialState$
|
|
421
|
+
initialState: initialState$9,
|
|
421
422
|
reducers: {
|
|
422
|
-
resetUserState: ()=>initialState$
|
|
423
|
+
resetUserState: ()=>initialState$9
|
|
423
424
|
},
|
|
424
425
|
extraReducers: (builder)=>{
|
|
425
426
|
builder.addCase(fetchUserState.fulfilled, (_, action)=>{
|
|
@@ -561,11 +562,11 @@ const { useGetExternalLoginsQuery, useLazyGetExternalLoginsQuery, useLazyIsExter
|
|
|
561
562
|
}
|
|
562
563
|
};
|
|
563
564
|
|
|
564
|
-
const initialState$
|
|
565
|
+
const initialState$8 = {};
|
|
565
566
|
// TODO: document what this does
|
|
566
567
|
const slice$3 = createSlice({
|
|
567
568
|
name: 'drsResolver',
|
|
568
|
-
initialState: initialState$
|
|
569
|
+
initialState: initialState$8,
|
|
569
570
|
reducers: {
|
|
570
571
|
setDRSHostnames: (_state, action)=>{
|
|
571
572
|
return action.payload;
|
|
@@ -587,12 +588,12 @@ const lookupGen3App = (id)=>{
|
|
|
587
588
|
else return null;
|
|
588
589
|
};
|
|
589
590
|
|
|
590
|
-
const initialState$
|
|
591
|
+
const initialState$7 = {
|
|
591
592
|
gen3Apps: {}
|
|
592
593
|
};
|
|
593
594
|
const slice$2 = createSlice({
|
|
594
595
|
name: 'gen3Apps',
|
|
595
|
-
initialState: initialState$
|
|
596
|
+
initialState: initialState$7,
|
|
596
597
|
reducers: {
|
|
597
598
|
addGen3AppMetadata: (state, action)=>{
|
|
598
599
|
const { name, requiredEntityTypes } = action.payload;
|
|
@@ -623,13 +624,13 @@ const selectGen3AppByName = (appName)=>lookupGen3App(appName); // TODO: memoize
|
|
|
623
624
|
Modals["GeneralErrorModal"] = "GeneralErrorModal";
|
|
624
625
|
return Modals;
|
|
625
626
|
}({});
|
|
626
|
-
const initialState$
|
|
627
|
+
const initialState$6 = {
|
|
627
628
|
currentModal: null
|
|
628
629
|
};
|
|
629
630
|
//Creates a modal slice for tracking showModal and hideModal state.
|
|
630
631
|
const slice$1 = createSlice({
|
|
631
632
|
name: 'modals',
|
|
632
|
-
initialState: initialState$
|
|
633
|
+
initialState: initialState$6,
|
|
633
634
|
reducers: {
|
|
634
635
|
showModal: (state, action)=>{
|
|
635
636
|
state.currentModal = action.payload.modal;
|
|
@@ -702,7 +703,7 @@ const getTimestamp = ()=>{
|
|
|
702
703
|
};
|
|
703
704
|
|
|
704
705
|
const NO_WORKSPACE_ID = 'none';
|
|
705
|
-
const initialState$
|
|
706
|
+
const initialState$5 = {
|
|
706
707
|
id: NO_WORKSPACE_ID,
|
|
707
708
|
status: WorkspaceStatus.NotFound,
|
|
708
709
|
requestedStatus: RequestedWorkspaceStatus.Unset,
|
|
@@ -710,7 +711,7 @@ const initialState$4 = {
|
|
|
710
711
|
};
|
|
711
712
|
const slice = createSlice({
|
|
712
713
|
name: 'ActiveWorkspace',
|
|
713
|
-
initialState: initialState$
|
|
714
|
+
initialState: initialState$5,
|
|
714
715
|
reducers: {
|
|
715
716
|
setActiveWorkspaceId: (state, action)=>{
|
|
716
717
|
state = {
|
|
@@ -752,6 +753,25 @@ const selectActiveWorkspaceStatus = (state)=>state.activeWorkspace.status;
|
|
|
752
753
|
const selectRequestedWorkspaceStatus = (state)=>state.activeWorkspace.requestedStatus;
|
|
753
754
|
const selectRequestedWorkspaceStatusTimestamp = (state)=>state.activeWorkspace.requestedStatusTimestamp;
|
|
754
755
|
|
|
756
|
+
const cartAdapter = createEntityAdapter({
|
|
757
|
+
selectId: (item)=>item.id
|
|
758
|
+
});
|
|
759
|
+
const initialState$4 = cartAdapter.getInitialState({});
|
|
760
|
+
const cartSlice = createSlice({
|
|
761
|
+
name: 'cart',
|
|
762
|
+
initialState: initialState$4,
|
|
763
|
+
reducers: {
|
|
764
|
+
addItemsToCart: cartAdapter.addMany,
|
|
765
|
+
removeItemsFromCart: cartAdapter.removeMany
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
const cartReducer = cartSlice.reducer;
|
|
769
|
+
const { addItemsToCart, removeItemsFromCart } = cartSlice.actions;
|
|
770
|
+
|
|
771
|
+
const { selectById: selectCartItem, selectIds: selectCartItems, selectAll: selectCart, selectTotal: selectCartCount } = cartAdapter.getSelectors((state)=>state.cart);
|
|
772
|
+
|
|
773
|
+
const cartReducerPath = 'cart';
|
|
774
|
+
|
|
755
775
|
/**
|
|
756
776
|
* Creates a base class core API for guppy API calls.
|
|
757
777
|
* @returns: guppy core API with guppyAPIFetch base query
|
|
@@ -809,578 +829,176 @@ const guppyAPISliceMiddleware = guppyApi.middleware;
|
|
|
809
829
|
const guppyApiSliceReducerPath = guppyApi.reducerPath;
|
|
810
830
|
const guppyApiReducer = guppyApi.reducer;
|
|
811
831
|
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
hour12: false
|
|
815
|
-
}).replace(',', '')}`;
|
|
816
|
-
const isNameUnique = (entities, name, excludeId)=>{
|
|
817
|
-
const trimmedName = name.trim();
|
|
818
|
-
if (!trimmedName) return false;
|
|
819
|
-
return !entities.some((cohort)=>cohort && cohort.id !== excludeId && cohort.name.trim().toLowerCase() === trimmedName.toLowerCase());
|
|
832
|
+
const isOperationWithField = (operation)=>{
|
|
833
|
+
return operation?.field !== undefined;
|
|
820
834
|
};
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
return
|
|
835
|
+
const isOperatorWithFieldAndArrayOfOperands = (operation)=>{
|
|
836
|
+
if (typeof operation === 'object' && operation !== null && 'operands' in operation && Array.isArray(operation.operands) && 'field' in operation && typeof operation.field === 'string' // Assuming `field` should be a string
|
|
837
|
+
) {
|
|
838
|
+
const { operator } = operation.operator;
|
|
839
|
+
return operator === 'in' || operator === 'exclude' || operator === 'excludeifany';
|
|
840
|
+
}
|
|
841
|
+
return false;
|
|
842
|
+
};
|
|
843
|
+
const extractFilterValue = (op)=>{
|
|
844
|
+
const valueExtractorHandler = new ValueExtractorHandler();
|
|
845
|
+
return handleOperation(valueExtractorHandler, op);
|
|
846
|
+
};
|
|
847
|
+
const extractEnumFilterValue = (op)=>{
|
|
848
|
+
const enumValueExtractorHandler = new EnumValueExtractorHandler();
|
|
849
|
+
const results = handleOperation(enumValueExtractorHandler, op);
|
|
850
|
+
return results ?? [];
|
|
851
|
+
};
|
|
852
|
+
const assertNever = (x)=>{
|
|
853
|
+
throw Error(`Exhaustive comparison did not handle: ${x}`);
|
|
854
|
+
};
|
|
855
|
+
const handleOperation = (handler, op)=>{
|
|
856
|
+
switch(op.operator){
|
|
857
|
+
case '=':
|
|
858
|
+
return handler.handleEquals(op);
|
|
859
|
+
case '!=':
|
|
860
|
+
return handler.handleNotEquals(op);
|
|
861
|
+
case '<':
|
|
862
|
+
return handler.handleLessThan(op);
|
|
863
|
+
case '<=':
|
|
864
|
+
return handler.handleLessThanOrEquals(op);
|
|
865
|
+
case '>':
|
|
866
|
+
return handler.handleGreaterThan(op);
|
|
867
|
+
case '>=':
|
|
868
|
+
return handler.handleGreaterThanOrEquals(op);
|
|
869
|
+
case 'and':
|
|
870
|
+
return handler.handleIntersection(op);
|
|
871
|
+
case 'or':
|
|
872
|
+
return handler.handleUnion(op);
|
|
873
|
+
case 'nested':
|
|
874
|
+
return handler.handleNestedFilter(op);
|
|
875
|
+
case 'in':
|
|
876
|
+
case 'includes':
|
|
877
|
+
return handler.handleIncludes(op);
|
|
878
|
+
case 'excludeifany':
|
|
879
|
+
return handler.handleExcludeIfAny(op);
|
|
880
|
+
case 'excludes':
|
|
881
|
+
return handler.handleExcludes(op);
|
|
882
|
+
case 'exists':
|
|
883
|
+
return handler.handleExists(op);
|
|
884
|
+
case 'missing':
|
|
885
|
+
return handler.handleMissing(op);
|
|
886
|
+
default:
|
|
887
|
+
return assertNever(op);
|
|
826
888
|
}
|
|
827
|
-
// Find a unique name by appending numbers
|
|
828
|
-
let counter = 1;
|
|
829
|
-
let uniqueName;
|
|
830
|
-
do {
|
|
831
|
-
uniqueName = `${trimmedBaseName} (${counter})`;
|
|
832
|
-
counter++;
|
|
833
|
-
}while (!isNameUnique(entities, uniqueName))
|
|
834
|
-
return uniqueName;
|
|
835
889
|
};
|
|
836
|
-
|
|
837
890
|
/**
|
|
838
|
-
*
|
|
839
|
-
*
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
return
|
|
847
|
-
name: newName,
|
|
848
|
-
id: newId,
|
|
849
|
-
filters: filters ?? {},
|
|
850
|
-
modified: false,
|
|
851
|
-
saved: false,
|
|
852
|
-
createdDatetime: ts,
|
|
853
|
-
modifiedDatetime: ts,
|
|
854
|
-
counts: {}
|
|
855
|
-
};
|
|
891
|
+
* Return true if a FilterSet's root value is an empty object
|
|
892
|
+
* @param fs - FilterSet to test
|
|
893
|
+
*/ const isFilterEmpty = (fs)=>isEqual({}, fs);
|
|
894
|
+
/**
|
|
895
|
+
* Type guard to check if an object is a GQLIntersection
|
|
896
|
+
* @param value - The value to check
|
|
897
|
+
* @returns True if the value is a GQLIntersection
|
|
898
|
+
*/ const isGQLIntersection = (value)=>{
|
|
899
|
+
return typeof value === 'object' && value !== null && 'and' in value && Array.isArray(value.and);
|
|
856
900
|
};
|
|
857
|
-
const nanoid = customAlphabet('1234567890abcdef', 16);
|
|
858
|
-
const createCohortId = ()=>nanoid();
|
|
859
|
-
const cohortsAdapter = createEntityAdapter({
|
|
860
|
-
sortComparer: (a, b)=>{
|
|
861
|
-
if (a.modifiedDatetime <= b.modifiedDatetime) return 1;
|
|
862
|
-
else return -1;
|
|
863
|
-
},
|
|
864
|
-
selectId: (cohort)=>cohort.id
|
|
865
|
-
});
|
|
866
|
-
// Create an initial unsaved cohort
|
|
867
|
-
const initialCohort = newCohort({
|
|
868
|
-
customName: DEFAULT_COHORT_NAME
|
|
869
|
-
});
|
|
870
|
-
const emptyInitialState = cohortsAdapter.getInitialState({
|
|
871
|
-
currentCohortId: initialCohort.id,
|
|
872
|
-
message: undefined
|
|
873
|
-
});
|
|
874
|
-
// Set the initial cohort in the adapter state
|
|
875
|
-
const initialState$3 = cohortsAdapter.setOne(emptyInitialState, initialCohort);
|
|
876
|
-
const getCurrentCohortId = (state)=>state.currentCohortId;
|
|
877
901
|
/**
|
|
878
|
-
*
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
902
|
+
* Type guard to check if an object is a GQLIntersection
|
|
903
|
+
* @param value - The value to check
|
|
904
|
+
* @returns True if the value is a GQLIntersection
|
|
905
|
+
*/ const isGQLUnion = (value)=>{
|
|
906
|
+
return typeof value === 'object' && value !== null && 'or' in value && Array.isArray(value.or);
|
|
907
|
+
};
|
|
908
|
+
class ToGqlHandler {
|
|
909
|
+
constructor(){
|
|
910
|
+
this.handleEquals = (op)=>({
|
|
911
|
+
'=': {
|
|
912
|
+
[op.field]: op.operand
|
|
913
|
+
}
|
|
889
914
|
});
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
updateCohortName: (state, action)=>{
|
|
894
|
-
const { id, name } = action.payload;
|
|
895
|
-
cohortsAdapter.updateOne(state, {
|
|
896
|
-
id: id,
|
|
897
|
-
changes: {
|
|
898
|
-
name: name,
|
|
899
|
-
modified: true,
|
|
900
|
-
modifiedDatetime: new Date().toISOString()
|
|
915
|
+
this.handleNotEquals = (op)=>({
|
|
916
|
+
'!=': {
|
|
917
|
+
[op.field]: op.operand
|
|
901
918
|
}
|
|
902
919
|
});
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const removedCohortName = state.entities[cohortId].name;
|
|
907
|
-
const totalCohorts = Object.keys(state.entities).length;
|
|
908
|
-
if (totalCohorts <= 1) {
|
|
909
|
-
cohortsAdapter.removeAll(state);
|
|
910
|
-
const defaultCohort = newCohort({
|
|
911
|
-
filters: {},
|
|
912
|
-
customName: DEFAULT_COHORT_NAME
|
|
913
|
-
});
|
|
914
|
-
cohortsAdapter.addOne(state, defaultCohort);
|
|
915
|
-
state.currentCohortId = defaultCohort.id;
|
|
916
|
-
if (action?.payload.shouldShowMessage) {
|
|
917
|
-
state.message = [
|
|
918
|
-
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
919
|
-
];
|
|
920
|
+
this.handleLessThan = (op)=>({
|
|
921
|
+
'<': {
|
|
922
|
+
[op.field]: op.operand
|
|
920
923
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
if (state.currentCohortId === cohortId) {
|
|
926
|
-
const remainingIds = Object.keys(state.entities);
|
|
927
|
-
state.currentCohortId = remainingIds[0];
|
|
928
|
-
}
|
|
929
|
-
if (action?.payload.shouldShowMessage) {
|
|
930
|
-
state.message = [
|
|
931
|
-
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
932
|
-
];
|
|
933
|
-
}
|
|
934
|
-
},
|
|
935
|
-
// adds a filter to the cohort filter set at the given index
|
|
936
|
-
updateCohortFilter: (state, action)=>{
|
|
937
|
-
const { index, field, filter } = action.payload;
|
|
938
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
939
|
-
if (!state.entities[currentCohortId]) {
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
cohortsAdapter.updateOne(state, {
|
|
943
|
-
id: currentCohortId,
|
|
944
|
-
changes: {
|
|
945
|
-
filters: {
|
|
946
|
-
...state.entities[currentCohortId].filters,
|
|
947
|
-
[index]: {
|
|
948
|
-
mode: state.entities[currentCohortId]?.filters[index]?.mode ?? 'and',
|
|
949
|
-
root: {
|
|
950
|
-
...state.entities[currentCohortId]?.filters[index]?.root ?? {},
|
|
951
|
-
[field]: filter
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
},
|
|
955
|
-
modified: true,
|
|
956
|
-
modifiedDatetime: new Date().toISOString()
|
|
924
|
+
});
|
|
925
|
+
this.handleLessThanOrEquals = (op)=>({
|
|
926
|
+
'<=': {
|
|
927
|
+
[op.field]: op.operand
|
|
957
928
|
}
|
|
958
929
|
});
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
963
|
-
if (!state.entities[currentCohortId]) {
|
|
964
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
965
|
-
return;
|
|
966
|
-
}
|
|
967
|
-
cohortsAdapter.updateOne(state, {
|
|
968
|
-
id: currentCohortId,
|
|
969
|
-
changes: {
|
|
970
|
-
filters: {
|
|
971
|
-
...state.entities[currentCohortId].filters,
|
|
972
|
-
[index]: filters
|
|
973
|
-
},
|
|
974
|
-
modified: true,
|
|
975
|
-
modifiedDatetime: new Date().toISOString()
|
|
930
|
+
this.handleGreaterThan = (op)=>({
|
|
931
|
+
'>': {
|
|
932
|
+
[op.field]: op.operand
|
|
976
933
|
}
|
|
977
934
|
});
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
if (!state.entities[currentCohortId]) {
|
|
982
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
cohortsAdapter.updateOne(state, {
|
|
986
|
-
id: currentCohortId,
|
|
987
|
-
changes: {
|
|
988
|
-
filters: action.payload.filters,
|
|
989
|
-
modified: true,
|
|
990
|
-
modifiedDatetime: new Date().toISOString()
|
|
935
|
+
this.handleGreaterThanOrEquals = (op)=>({
|
|
936
|
+
'>=': {
|
|
937
|
+
[op.field]: op.operand
|
|
991
938
|
}
|
|
992
939
|
});
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
const { index, field } = action.payload;
|
|
997
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
998
|
-
if (!state.entities[currentCohortId]) {
|
|
999
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1000
|
-
return;
|
|
1001
|
-
}
|
|
1002
|
-
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1003
|
-
if (!filters) {
|
|
1004
|
-
return;
|
|
1005
|
-
}
|
|
1006
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1007
|
-
const { [field]: _a, ...updated } = filters;
|
|
1008
|
-
cohortsAdapter.updateOne(state, {
|
|
1009
|
-
id: currentCohortId,
|
|
1010
|
-
changes: {
|
|
1011
|
-
filters: {
|
|
1012
|
-
...state.entities[currentCohortId]?.filters,
|
|
1013
|
-
[index]: {
|
|
1014
|
-
mode: state.entities[currentCohortId].filters[index].mode,
|
|
1015
|
-
root: updated
|
|
1016
|
-
}
|
|
1017
|
-
},
|
|
1018
|
-
modified: true,
|
|
1019
|
-
modifiedDatetime: new Date().toISOString()
|
|
940
|
+
this.handleIncludes = (op)=>({
|
|
941
|
+
in: {
|
|
942
|
+
[op.field]: op.operands
|
|
1020
943
|
}
|
|
1021
944
|
});
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
const currentCohort = state.entities[currentCohortId];
|
|
1026
|
-
const newName = generateUniqueName(Object.values(state.entities), currentCohort.name);
|
|
1027
|
-
const duplicatedCohort = newCohort({
|
|
1028
|
-
filters: {
|
|
1029
|
-
...currentCohort.filters
|
|
1030
|
-
},
|
|
1031
|
-
customName: newName
|
|
1032
|
-
});
|
|
1033
|
-
cohortsAdapter.addOne(state, {
|
|
1034
|
-
...duplicatedCohort,
|
|
1035
|
-
counts: {
|
|
1036
|
-
...currentCohort.counts
|
|
945
|
+
this.handleExcludes = (op)=>({
|
|
946
|
+
exclude: {
|
|
947
|
+
[op.field]: op.operands
|
|
1037
948
|
}
|
|
1038
949
|
});
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
clearCohortFilters: (state, action)=>{
|
|
1043
|
-
const { index } = action.payload;
|
|
1044
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
1045
|
-
if (!state.entities[currentCohortId]) {
|
|
1046
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1047
|
-
return;
|
|
1048
|
-
}
|
|
1049
|
-
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1050
|
-
if (!filters) {
|
|
1051
|
-
return;
|
|
1052
|
-
}
|
|
1053
|
-
cohortsAdapter.updateOne(state, {
|
|
1054
|
-
id: currentCohortId,
|
|
1055
|
-
changes: {
|
|
1056
|
-
filters: {
|
|
1057
|
-
...state.entities[currentCohortId]?.filters,
|
|
1058
|
-
[index]: {
|
|
1059
|
-
mode: 'and',
|
|
1060
|
-
root: {}
|
|
1061
|
-
}
|
|
1062
|
-
},
|
|
1063
|
-
modified: true,
|
|
1064
|
-
modifiedDatetime: new Date().toISOString()
|
|
950
|
+
this.handleExcludeIfAny = (op)=>({
|
|
951
|
+
excludeifany: {
|
|
952
|
+
[op.field]: op.operands
|
|
1065
953
|
}
|
|
1066
954
|
});
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
1070
|
-
const currentCohort = state.entities[currentCohortId];
|
|
1071
|
-
cohortsAdapter.updateOne(state, {
|
|
1072
|
-
id: currentCohortId,
|
|
1073
|
-
changes: {
|
|
1074
|
-
counts: {
|
|
1075
|
-
...currentCohort.counts,
|
|
1076
|
-
...action.payload
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
955
|
+
this.handleIntersection = (op)=>({
|
|
956
|
+
and: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
1079
957
|
});
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
changes: {
|
|
1087
|
-
counts: {
|
|
1088
|
-
...cohort.counts,
|
|
1089
|
-
...{
|
|
1090
|
-
[index]: counts
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
958
|
+
this.handleUnion = (op)=>({
|
|
959
|
+
or: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
960
|
+
});
|
|
961
|
+
this.handleMissing = (op)=>({
|
|
962
|
+
is: {
|
|
963
|
+
[op.field]: 'MISSING'
|
|
1093
964
|
}
|
|
1094
965
|
});
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
},
|
|
1099
|
-
/** @hidden */ setCohortList: (state, action)=>{
|
|
1100
|
-
if (!action.payload) {
|
|
1101
|
-
cohortsAdapter.removeMany(state, state.ids);
|
|
1102
|
-
} else {
|
|
1103
|
-
cohortsAdapter.upsertMany(state, [
|
|
1104
|
-
...action.payload
|
|
1105
|
-
]);
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
});
|
|
1110
|
-
/**
|
|
1111
|
-
* Returns the selectors for the cohorts EntityAdapter
|
|
1112
|
-
* @param state - the CoreState
|
|
1113
|
-
*
|
|
1114
|
-
* @hidden
|
|
1115
|
-
*/ const cohortSelectors = cohortsAdapter.getSelectors((state)=>state.cohorts.cohortManager);
|
|
1116
|
-
// Filter actions: addFilter, removeFilter, updateFilter
|
|
1117
|
-
const { createNewCohort, updateCohortFilter, setCohortFilter, setCohortIndexFilters, duplicateCohort, removeCohortFilter, clearCohortFilters, removeCohort, setCurrentCohortId, updateCohortName, updateCohortCounts, updateCohortIndexCountById, setCohortList } = cohortManagerSlice.actions;
|
|
1118
|
-
const cohortReducer = cohortManagerSlice.reducer;
|
|
1119
|
-
|
|
1120
|
-
const initialState$2 = {};
|
|
1121
|
-
const expandSlice$1 = createSlice({
|
|
1122
|
-
name: 'CohortBuilder/filterExpand',
|
|
1123
|
-
initialState: initialState$2,
|
|
1124
|
-
reducers: {
|
|
1125
|
-
toggleCohortBuilderCategoryFilter: (state, action)=>{
|
|
1126
|
-
return {
|
|
1127
|
-
...state,
|
|
1128
|
-
[action.payload.index]: {
|
|
1129
|
-
...state[action.payload.index],
|
|
1130
|
-
[action.payload.field]: action.payload.expanded
|
|
966
|
+
this.handleExists = (op)=>({
|
|
967
|
+
not: {
|
|
968
|
+
[op.field]: op?.operand ?? null
|
|
1131
969
|
}
|
|
1132
|
-
};
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
return {
|
|
1136
|
-
...state,
|
|
1137
|
-
[action.payload.index]: Object.keys(state[action.payload.index]).reduce((acc, k)=>{
|
|
1138
|
-
acc[k] = action.payload.expand;
|
|
1139
|
-
return acc;
|
|
1140
|
-
}, {})
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
});
|
|
1145
|
-
const cohortBuilderFiltersExpandedReducer = expandSlice$1.reducer;
|
|
1146
|
-
const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = expandSlice$1.actions;
|
|
1147
|
-
const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
|
|
1148
|
-
const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
|
|
1149
|
-
|
|
1150
|
-
const initialState$1 = {};
|
|
1151
|
-
const expandSlice = createSlice({
|
|
1152
|
-
name: 'CohortBuilder/filterCombineMode',
|
|
1153
|
-
initialState: initialState$1,
|
|
1154
|
-
reducers: {
|
|
1155
|
-
setCohortFilterCombineMode: (state, action)=>{
|
|
970
|
+
});
|
|
971
|
+
this.handleNestedFilter = (op)=>{
|
|
972
|
+
const child = convertFilterToGqlFilter(op.operand);
|
|
1156
973
|
return {
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
...
|
|
1160
|
-
[action.payload.field]: action.payload.mode
|
|
974
|
+
nested: {
|
|
975
|
+
path: op.path,
|
|
976
|
+
...child
|
|
1161
977
|
}
|
|
1162
978
|
};
|
|
1163
|
-
}
|
|
979
|
+
};
|
|
1164
980
|
}
|
|
1165
|
-
}
|
|
1166
|
-
const
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
const initialState = {
|
|
1171
|
-
shouldShareFilters: false,
|
|
1172
|
-
sharedFiltersMap: {}
|
|
981
|
+
}
|
|
982
|
+
const convertFilterToGqlFilter = (filter)=>{
|
|
983
|
+
const handler = new ToGqlHandler();
|
|
984
|
+
return handleOperation(handler, filter);
|
|
1173
985
|
};
|
|
1174
|
-
const
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
const
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
field
|
|
1191
|
-
];
|
|
1192
|
-
const { setShouldShareFilters, setSharedFilters } = cohortSharedFiltersSlice.actions;
|
|
1193
|
-
const cohortSharedFiltersReducer = cohortSharedFiltersSlice.reducer;
|
|
1194
|
-
|
|
1195
|
-
const cohortReducers = combineReducers({
|
|
1196
|
-
filtersExpanded: cohortBuilderFiltersExpandedReducer,
|
|
1197
|
-
filtersCombineMode: cohortBuilderFiltersCombineModeReducer,
|
|
1198
|
-
sharedFilters: cohortSharedFiltersReducer,
|
|
1199
|
-
cohortManager: cohortReducer
|
|
1200
|
-
});
|
|
1201
|
-
|
|
1202
|
-
const rootReducer = combineReducers({
|
|
1203
|
-
gen3Services: gen3ServicesReducer,
|
|
1204
|
-
user: userReducer,
|
|
1205
|
-
gen3Apps: gen3AppReducer,
|
|
1206
|
-
drsHostnames: drsHostnamesReducer,
|
|
1207
|
-
modals: modalReducer,
|
|
1208
|
-
cohorts: cohortReducers,
|
|
1209
|
-
activeWorkspace: activeWorkspaceReducer,
|
|
1210
|
-
[guppyApiSliceReducerPath]: guppyApiReducer,
|
|
1211
|
-
[userAuthApiReducerPath]: userAuthApiReducer
|
|
1212
|
-
});
|
|
1213
|
-
|
|
1214
|
-
const isOperationWithField = (operation)=>{
|
|
1215
|
-
return operation?.field !== undefined;
|
|
1216
|
-
};
|
|
1217
|
-
const isOperatorWithFieldAndArrayOfOperands = (operation)=>{
|
|
1218
|
-
if (typeof operation === 'object' && operation !== null && 'operands' in operation && Array.isArray(operation.operands) && 'field' in operation && typeof operation.field === 'string' // Assuming `field` should be a string
|
|
1219
|
-
) {
|
|
1220
|
-
const { operator } = operation.operator;
|
|
1221
|
-
return operator === 'in' || operator === 'exclude' || operator === 'excludeifany';
|
|
1222
|
-
}
|
|
1223
|
-
return false;
|
|
1224
|
-
};
|
|
1225
|
-
const extractFilterValue = (op)=>{
|
|
1226
|
-
const valueExtractorHandler = new ValueExtractorHandler();
|
|
1227
|
-
return handleOperation(valueExtractorHandler, op);
|
|
1228
|
-
};
|
|
1229
|
-
const extractEnumFilterValue = (op)=>{
|
|
1230
|
-
const enumValueExtractorHandler = new EnumValueExtractorHandler();
|
|
1231
|
-
const results = handleOperation(enumValueExtractorHandler, op);
|
|
1232
|
-
return results ?? [];
|
|
1233
|
-
};
|
|
1234
|
-
const assertNever = (x)=>{
|
|
1235
|
-
throw Error(`Exhaustive comparison did not handle: ${x}`);
|
|
1236
|
-
};
|
|
1237
|
-
const handleOperation = (handler, op)=>{
|
|
1238
|
-
switch(op.operator){
|
|
1239
|
-
case '=':
|
|
1240
|
-
return handler.handleEquals(op);
|
|
1241
|
-
case '!=':
|
|
1242
|
-
return handler.handleNotEquals(op);
|
|
1243
|
-
case '<':
|
|
1244
|
-
return handler.handleLessThan(op);
|
|
1245
|
-
case '<=':
|
|
1246
|
-
return handler.handleLessThanOrEquals(op);
|
|
1247
|
-
case '>':
|
|
1248
|
-
return handler.handleGreaterThan(op);
|
|
1249
|
-
case '>=':
|
|
1250
|
-
return handler.handleGreaterThanOrEquals(op);
|
|
1251
|
-
case 'and':
|
|
1252
|
-
return handler.handleIntersection(op);
|
|
1253
|
-
case 'or':
|
|
1254
|
-
return handler.handleUnion(op);
|
|
1255
|
-
case 'nested':
|
|
1256
|
-
return handler.handleNestedFilter(op);
|
|
1257
|
-
case 'in':
|
|
1258
|
-
case 'includes':
|
|
1259
|
-
return handler.handleIncludes(op);
|
|
1260
|
-
case 'excludeifany':
|
|
1261
|
-
return handler.handleExcludeIfAny(op);
|
|
1262
|
-
case 'excludes':
|
|
1263
|
-
return handler.handleExcludes(op);
|
|
1264
|
-
case 'exists':
|
|
1265
|
-
return handler.handleExists(op);
|
|
1266
|
-
case 'missing':
|
|
1267
|
-
return handler.handleMissing(op);
|
|
1268
|
-
default:
|
|
1269
|
-
return assertNever(op);
|
|
1270
|
-
}
|
|
1271
|
-
};
|
|
1272
|
-
/**
|
|
1273
|
-
* Return true if a FilterSet's root value is an empty object
|
|
1274
|
-
* @param fs - FilterSet to test
|
|
1275
|
-
*/ const isFilterEmpty = (fs)=>isEqual({}, fs);
|
|
1276
|
-
/**
|
|
1277
|
-
* Type guard to check if an object is a GQLIntersection
|
|
1278
|
-
* @param value - The value to check
|
|
1279
|
-
* @returns True if the value is a GQLIntersection
|
|
1280
|
-
*/ const isGQLIntersection = (value)=>{
|
|
1281
|
-
return typeof value === 'object' && value !== null && 'and' in value && Array.isArray(value.and);
|
|
1282
|
-
};
|
|
1283
|
-
/**
|
|
1284
|
-
* Type guard to check if an object is a GQLIntersection
|
|
1285
|
-
* @param value - The value to check
|
|
1286
|
-
* @returns True if the value is a GQLIntersection
|
|
1287
|
-
*/ const isGQLUnion = (value)=>{
|
|
1288
|
-
return typeof value === 'object' && value !== null && 'or' in value && Array.isArray(value.or);
|
|
1289
|
-
};
|
|
1290
|
-
class ToGqlHandler {
|
|
1291
|
-
constructor(){
|
|
1292
|
-
this.handleEquals = (op)=>({
|
|
1293
|
-
'=': {
|
|
1294
|
-
[op.field]: op.operand
|
|
1295
|
-
}
|
|
1296
|
-
});
|
|
1297
|
-
this.handleNotEquals = (op)=>({
|
|
1298
|
-
'!=': {
|
|
1299
|
-
[op.field]: op.operand
|
|
1300
|
-
}
|
|
1301
|
-
});
|
|
1302
|
-
this.handleLessThan = (op)=>({
|
|
1303
|
-
'<': {
|
|
1304
|
-
[op.field]: op.operand
|
|
1305
|
-
}
|
|
1306
|
-
});
|
|
1307
|
-
this.handleLessThanOrEquals = (op)=>({
|
|
1308
|
-
'<=': {
|
|
1309
|
-
[op.field]: op.operand
|
|
1310
|
-
}
|
|
1311
|
-
});
|
|
1312
|
-
this.handleGreaterThan = (op)=>({
|
|
1313
|
-
'>': {
|
|
1314
|
-
[op.field]: op.operand
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1317
|
-
this.handleGreaterThanOrEquals = (op)=>({
|
|
1318
|
-
'>=': {
|
|
1319
|
-
[op.field]: op.operand
|
|
1320
|
-
}
|
|
1321
|
-
});
|
|
1322
|
-
this.handleIncludes = (op)=>({
|
|
1323
|
-
in: {
|
|
1324
|
-
[op.field]: op.operands
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
this.handleExcludes = (op)=>({
|
|
1328
|
-
exclude: {
|
|
1329
|
-
[op.field]: op.operands
|
|
1330
|
-
}
|
|
1331
|
-
});
|
|
1332
|
-
this.handleExcludeIfAny = (op)=>({
|
|
1333
|
-
excludeifany: {
|
|
1334
|
-
[op.field]: op.operands
|
|
1335
|
-
}
|
|
1336
|
-
});
|
|
1337
|
-
this.handleIntersection = (op)=>({
|
|
1338
|
-
and: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
1339
|
-
});
|
|
1340
|
-
this.handleUnion = (op)=>({
|
|
1341
|
-
or: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
1342
|
-
});
|
|
1343
|
-
this.handleMissing = (op)=>({
|
|
1344
|
-
is: {
|
|
1345
|
-
[op.field]: 'MISSING'
|
|
1346
|
-
}
|
|
1347
|
-
});
|
|
1348
|
-
this.handleExists = (op)=>({
|
|
1349
|
-
not: {
|
|
1350
|
-
[op.field]: op?.operand ?? null
|
|
1351
|
-
}
|
|
1352
|
-
});
|
|
1353
|
-
this.handleNestedFilter = (op)=>{
|
|
1354
|
-
const child = convertFilterToGqlFilter(op.operand);
|
|
1355
|
-
return {
|
|
1356
|
-
nested: {
|
|
1357
|
-
path: op.path,
|
|
1358
|
-
...child
|
|
1359
|
-
}
|
|
1360
|
-
};
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
const convertFilterToGqlFilter = (filter)=>{
|
|
1365
|
-
const handler = new ToGqlHandler();
|
|
1366
|
-
return handleOperation(handler, filter);
|
|
1367
|
-
};
|
|
1368
|
-
const convertFilterSetToGqlFilter = (fs, toplevelOp = 'and')=>{
|
|
1369
|
-
const fsKeys = Object.keys(fs.root);
|
|
1370
|
-
// if no keys return undefined
|
|
1371
|
-
if (fsKeys.length === 0) return {
|
|
1372
|
-
and: []
|
|
1373
|
-
};
|
|
1374
|
-
return toplevelOp === 'and' ? {
|
|
1375
|
-
and: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
1376
|
-
} : {
|
|
1377
|
-
or: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
1378
|
-
};
|
|
1379
|
-
};
|
|
1380
|
-
const handleGqlOperation = (handler, op)=>{
|
|
1381
|
-
const operationKeys = Object.keys(op);
|
|
1382
|
-
if (operationKeys.includes('=')) {
|
|
1383
|
-
return handler.handleEquals(op);
|
|
986
|
+
const convertFilterSetToGqlFilter = (fs, toplevelOp = 'and')=>{
|
|
987
|
+
const fsKeys = Object.keys(fs.root);
|
|
988
|
+
// if no keys return undefined
|
|
989
|
+
if (fsKeys.length === 0) return {
|
|
990
|
+
and: []
|
|
991
|
+
};
|
|
992
|
+
return toplevelOp === 'and' ? {
|
|
993
|
+
and: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
994
|
+
} : {
|
|
995
|
+
or: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
996
|
+
};
|
|
997
|
+
};
|
|
998
|
+
const handleGqlOperation = (handler, op)=>{
|
|
999
|
+
const operationKeys = Object.keys(op);
|
|
1000
|
+
if (operationKeys.includes('=')) {
|
|
1001
|
+
return handler.handleEquals(op);
|
|
1384
1002
|
}
|
|
1385
1003
|
if (operationKeys.includes('!=')) {
|
|
1386
1004
|
return handler.handleNotEquals(op);
|
|
@@ -1602,132 +1220,571 @@ const filterSetToOperation = (fs)=>{
|
|
|
1602
1220
|
})
|
|
1603
1221
|
};
|
|
1604
1222
|
}
|
|
1605
|
-
return undefined;
|
|
1606
|
-
};
|
|
1223
|
+
return undefined;
|
|
1224
|
+
};
|
|
1225
|
+
/**
|
|
1226
|
+
* Constructs a nested operation object based on the provided field and leaf operand.
|
|
1227
|
+
* If the field does not contain a dot '.', it either assigns the field to the leaf operand (if applicable)
|
|
1228
|
+
* or returns the leaf operand as is. When the field contains dots, it splits the field into parts,
|
|
1229
|
+
* creates a "nested" operation for the root field, and recursively constructs the nested structure
|
|
1230
|
+
* for the remaining portion of the field.
|
|
1231
|
+
*
|
|
1232
|
+
* @param {string} field - The hierarchical field path, with segments separated by dots (e.g., "root.child").
|
|
1233
|
+
* @param {Operation} leafOperand - The operation to be nested within the specified path.
|
|
1234
|
+
* @param parentPath - The parent path of the current field. Guppy nested filters require a parent path.
|
|
1235
|
+
* @param depth
|
|
1236
|
+
* @returns {Operation} A nested operation object that represents the structured path and operand.
|
|
1237
|
+
*/ const buildNestedGQLFilter = (field, leafOperand, parentPath = undefined)=>{
|
|
1238
|
+
if (!field.includes('.')) {
|
|
1239
|
+
return leafOperand;
|
|
1240
|
+
}
|
|
1241
|
+
const splitFieldArray = field.split('.');
|
|
1242
|
+
const nextField = splitFieldArray.shift();
|
|
1243
|
+
if (!nextField) {
|
|
1244
|
+
console.warn('Invalid field path:', field);
|
|
1245
|
+
return leafOperand;
|
|
1246
|
+
}
|
|
1247
|
+
const currentPath = parentPath ? `${parentPath}.${nextField}` : nextField;
|
|
1248
|
+
return {
|
|
1249
|
+
nested: {
|
|
1250
|
+
path: currentPath,
|
|
1251
|
+
...buildNestedGQLFilter(splitFieldArray.join('.'), leafOperand, currentPath)
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
};
|
|
1255
|
+
|
|
1256
|
+
const isFilterSet = (input)=>{
|
|
1257
|
+
if (typeof input !== 'object' || input === null) {
|
|
1258
|
+
return false;
|
|
1259
|
+
}
|
|
1260
|
+
const { root, mode } = input;
|
|
1261
|
+
if (typeof root !== 'object' || root === null) {
|
|
1262
|
+
return false;
|
|
1263
|
+
}
|
|
1264
|
+
if (![
|
|
1265
|
+
'and',
|
|
1266
|
+
'or'
|
|
1267
|
+
].includes(mode)) {
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
return true;
|
|
1271
|
+
};
|
|
1272
|
+
const isUnion = (value)=>{
|
|
1273
|
+
return typeof value === 'object' && value !== null && value.operator === 'or' && Array.isArray(value.operands);
|
|
1274
|
+
};
|
|
1275
|
+
const isIntersection = (value)=>{
|
|
1276
|
+
return typeof value === 'object' && value !== null && value.operator === 'and' && Array.isArray(value.operands);
|
|
1277
|
+
};
|
|
1278
|
+
/**
|
|
1279
|
+
* Type guard for Union or Intersection
|
|
1280
|
+
* @param o - operator to check
|
|
1281
|
+
* @category Filters
|
|
1282
|
+
*/ const isIntersectionOrUnion = (o)=>o.operator === 'and' || o.operator === 'or';
|
|
1283
|
+
const isOperandsType = (operation)=>{
|
|
1284
|
+
return operation?.operands !== undefined;
|
|
1285
|
+
};
|
|
1286
|
+
const isNestedFilter = (operation)=>{
|
|
1287
|
+
return operation.operator === 'nested';
|
|
1288
|
+
};
|
|
1289
|
+
const isIndexedFilterSetEmpty = (filters)=>Object.values(filters).every((filterSet)=>Object.keys(filterSet).length === 0);
|
|
1290
|
+
const EmptyFilterSet = {
|
|
1291
|
+
mode: 'and',
|
|
1292
|
+
root: {}
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
const FieldNameOverrides = {};
|
|
1296
|
+
const COMMON_PREPOSITIONS = [
|
|
1297
|
+
'a',
|
|
1298
|
+
'an',
|
|
1299
|
+
'and',
|
|
1300
|
+
'at',
|
|
1301
|
+
'but',
|
|
1302
|
+
'by',
|
|
1303
|
+
'for',
|
|
1304
|
+
'in',
|
|
1305
|
+
'is',
|
|
1306
|
+
'nor',
|
|
1307
|
+
'of',
|
|
1308
|
+
'on',
|
|
1309
|
+
'or',
|
|
1310
|
+
'out',
|
|
1311
|
+
'so',
|
|
1312
|
+
'the',
|
|
1313
|
+
'to',
|
|
1314
|
+
'up',
|
|
1315
|
+
'yet'
|
|
1316
|
+
];
|
|
1317
|
+
const capitalize$1 = (s)=>s.length > 0 ? s[0].toUpperCase() + s.slice(1) : '';
|
|
1318
|
+
const trimFirstFieldNameToTitle = (fieldName, trim = false)=>{
|
|
1319
|
+
if (trim) {
|
|
1320
|
+
const source = fieldName.slice(fieldName.indexOf('.') + 1);
|
|
1321
|
+
return fieldNameToTitle(source ? source : fieldName, 0);
|
|
1322
|
+
}
|
|
1323
|
+
return fieldNameToTitle(fieldName);
|
|
1324
|
+
};
|
|
1325
|
+
/**
|
|
1326
|
+
* Converts a filter name to a title,
|
|
1327
|
+
* For example files.input.experimental_strategy will get converted to Experimental Strategy
|
|
1328
|
+
* if sections == 2 then the output would be Input Experimental Strategy
|
|
1329
|
+
* @param fieldName input filter expected to be: string.firstpart_secondpart
|
|
1330
|
+
* @param sections number of "sections" string.string.string to got back from the end of the field
|
|
1331
|
+
*/ const fieldNameToTitle = (fieldName, sections = 1)=>{
|
|
1332
|
+
if (fieldName in FieldNameOverrides) {
|
|
1333
|
+
return FieldNameOverrides[fieldName];
|
|
1334
|
+
}
|
|
1335
|
+
if (fieldName === undefined) return 'No Title';
|
|
1336
|
+
return fieldName.split('.').slice(-sections).map((s)=>s.split('_')).flat().map((word)=>COMMON_PREPOSITIONS.includes(word) ? word : capitalize$1(word)).join(' ');
|
|
1337
|
+
};
|
|
1338
|
+
/**
|
|
1339
|
+
* Extracts the index name from the field name
|
|
1340
|
+
* @param fieldName
|
|
1341
|
+
*/ const extractIndexFromFullFieldName = (fieldName)=>fieldName.split('.')[0];
|
|
1342
|
+
/**
|
|
1343
|
+
* prepend the index name to the field name
|
|
1344
|
+
*/ const prependIndexToFieldName = (fieldName, index)=>`${index}.${fieldName}`;
|
|
1345
|
+
/**
|
|
1346
|
+
* extract the field name from the index.field name
|
|
1347
|
+
*/ const extractFieldNameFromFullFieldName = (fieldName)=>fieldName.split('.').slice(1).join('.');
|
|
1348
|
+
/**
|
|
1349
|
+
* extract the field name and the index from the index.field name returning as a tuple
|
|
1350
|
+
*/ const extractIndexAndFieldNameFromFullFieldName = (fieldName)=>{
|
|
1351
|
+
const [index, ...rest] = fieldName.split('.');
|
|
1352
|
+
return [
|
|
1353
|
+
index,
|
|
1354
|
+
rest.join('.')
|
|
1355
|
+
];
|
|
1356
|
+
};
|
|
1357
|
+
|
|
1358
|
+
const defaultCohortNameGenerator = ()=>`Custom cohort ${new Date().toLocaleString('en-CA', {
|
|
1359
|
+
timeZone: 'America/Chicago',
|
|
1360
|
+
hour12: false
|
|
1361
|
+
}).replace(',', '')}`;
|
|
1362
|
+
const isNameUnique = (entities, name, excludeId)=>{
|
|
1363
|
+
const trimmedName = name.trim();
|
|
1364
|
+
if (!trimmedName) return false;
|
|
1365
|
+
return !entities.some((cohort)=>cohort && cohort.id !== excludeId && cohort.name.trim().toLowerCase() === trimmedName.toLowerCase());
|
|
1366
|
+
};
|
|
1367
|
+
const generateUniqueName = (entities, baseName)=>{
|
|
1368
|
+
const trimmedBaseName = baseName.trim();
|
|
1369
|
+
// If base name is unique, use it
|
|
1370
|
+
if (isNameUnique(entities, trimmedBaseName)) {
|
|
1371
|
+
return trimmedBaseName;
|
|
1372
|
+
}
|
|
1373
|
+
// Find a unique name by appending numbers
|
|
1374
|
+
let counter = 1;
|
|
1375
|
+
let uniqueName;
|
|
1376
|
+
do {
|
|
1377
|
+
uniqueName = `${trimmedBaseName} (${counter})`;
|
|
1378
|
+
counter++;
|
|
1379
|
+
}while (!isNameUnique(entities, uniqueName))
|
|
1380
|
+
return uniqueName;
|
|
1381
|
+
};
|
|
1382
|
+
/**
|
|
1383
|
+
* This function takes a FilterSet object and a prefix string as input.
|
|
1384
|
+
* It filters the root property of the FilterSet object and returns a
|
|
1385
|
+
* new FilterSet object that only contains filters with field names
|
|
1386
|
+
* that start with the specified prefix.
|
|
1387
|
+
*
|
|
1388
|
+
* @param fs - The FilterSet object to filter
|
|
1389
|
+
* @param prefix - The prefix to filter by
|
|
1390
|
+
* @returns - A new FilterSet object that only contains filters with field names that start with the specified prefix
|
|
1391
|
+
* @category Filters
|
|
1392
|
+
*/ const extractFiltersWithPrefixFromFilterSet = (fs, prefix)=>{
|
|
1393
|
+
if (fs === undefined || fs.root === undefined) {
|
|
1394
|
+
return {
|
|
1395
|
+
mode: 'and',
|
|
1396
|
+
root: {}
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
return Object.values(fs.root).reduce((acc, filter)=>{
|
|
1400
|
+
if (isIntersectionOrUnion(filter) || isNestedFilter(filter)) return acc;
|
|
1401
|
+
if (filter.field.startsWith(prefix)) {
|
|
1402
|
+
acc.root[filter.field] = filter;
|
|
1403
|
+
}
|
|
1404
|
+
return acc;
|
|
1405
|
+
}, {
|
|
1406
|
+
mode: 'and',
|
|
1407
|
+
root: {}
|
|
1408
|
+
});
|
|
1409
|
+
};
|
|
1410
|
+
|
|
1411
|
+
/**
|
|
1412
|
+
* Cohorts in Gen3 are defined as a set of filters for each index in the data.
|
|
1413
|
+
* This means one cohort id defined for all "tabs" in CohortBuilder (explorer)
|
|
1414
|
+
* Switching a cohort id means all the cohorts for the index are changed.
|
|
1415
|
+
*/ const DEFAULT_COHORT_NAME = 'Cohort';
|
|
1416
|
+
const newCohort = ({ filters = {}, customName })=>{
|
|
1417
|
+
const ts = new Date().toISOString();
|
|
1418
|
+
const newName = customName ?? defaultCohortNameGenerator();
|
|
1419
|
+
const newId = createCohortId();
|
|
1420
|
+
return {
|
|
1421
|
+
name: newName,
|
|
1422
|
+
id: newId,
|
|
1423
|
+
filters: filters ?? {},
|
|
1424
|
+
modified: false,
|
|
1425
|
+
saved: false,
|
|
1426
|
+
createdDatetime: ts,
|
|
1427
|
+
modifiedDatetime: ts,
|
|
1428
|
+
counts: {}
|
|
1429
|
+
};
|
|
1430
|
+
};
|
|
1431
|
+
const nanoid = customAlphabet('1234567890abcdef', 16);
|
|
1432
|
+
const createCohortId = ()=>nanoid();
|
|
1433
|
+
const cohortsAdapter = createEntityAdapter({
|
|
1434
|
+
sortComparer: (a, b)=>{
|
|
1435
|
+
if (a.modifiedDatetime <= b.modifiedDatetime) return 1;
|
|
1436
|
+
else return -1;
|
|
1437
|
+
},
|
|
1438
|
+
selectId: (cohort)=>cohort.id
|
|
1439
|
+
});
|
|
1440
|
+
// Create an initial unsaved cohort
|
|
1441
|
+
const initialCohort = newCohort({
|
|
1442
|
+
customName: DEFAULT_COHORT_NAME
|
|
1443
|
+
});
|
|
1444
|
+
const emptyInitialState = cohortsAdapter.getInitialState({
|
|
1445
|
+
currentCohortId: initialCohort.id,
|
|
1446
|
+
message: undefined
|
|
1447
|
+
});
|
|
1448
|
+
// Set the initial cohort in the adapter state
|
|
1449
|
+
const initialState$3 = cohortsAdapter.setOne(emptyInitialState, initialCohort);
|
|
1450
|
+
const getCurrentCohortId = (state)=>state.currentCohortId;
|
|
1451
|
+
/**
|
|
1452
|
+
* Redux slice for cohort filters
|
|
1453
|
+
*/ const cohortManagerSlice = createSlice({
|
|
1454
|
+
name: 'cohort',
|
|
1455
|
+
initialState: initialState$3,
|
|
1456
|
+
reducers: {
|
|
1457
|
+
createNewCohort: (state, action)=>{
|
|
1458
|
+
const baseName = action.payload.name || `Cohort`;
|
|
1459
|
+
const uniqueName = generateUniqueName(Object.values(state.entities), baseName);
|
|
1460
|
+
const cohort = newCohort({
|
|
1461
|
+
filters: action.payload.filters,
|
|
1462
|
+
customName: uniqueName
|
|
1463
|
+
});
|
|
1464
|
+
cohortsAdapter.addOne(state, cohort);
|
|
1465
|
+
state.currentCohortId = cohort.id;
|
|
1466
|
+
},
|
|
1467
|
+
updateCohortName: (state, action)=>{
|
|
1468
|
+
const { id, name } = action.payload;
|
|
1469
|
+
cohortsAdapter.updateOne(state, {
|
|
1470
|
+
id: id,
|
|
1471
|
+
changes: {
|
|
1472
|
+
name: name,
|
|
1473
|
+
modified: true,
|
|
1474
|
+
modifiedDatetime: new Date().toISOString()
|
|
1475
|
+
}
|
|
1476
|
+
});
|
|
1477
|
+
},
|
|
1478
|
+
removeCohort: (state, action)=>{
|
|
1479
|
+
const { id: cohortId } = action.payload;
|
|
1480
|
+
const removedCohortName = state.entities[cohortId].name;
|
|
1481
|
+
const totalCohorts = Object.keys(state.entities).length;
|
|
1482
|
+
if (totalCohorts <= 1) {
|
|
1483
|
+
cohortsAdapter.removeAll(state);
|
|
1484
|
+
const defaultCohort = newCohort({
|
|
1485
|
+
filters: {},
|
|
1486
|
+
customName: DEFAULT_COHORT_NAME
|
|
1487
|
+
});
|
|
1488
|
+
cohortsAdapter.addOne(state, defaultCohort);
|
|
1489
|
+
state.currentCohortId = defaultCohort.id;
|
|
1490
|
+
if (action?.payload.shouldShowMessage) {
|
|
1491
|
+
state.message = [
|
|
1492
|
+
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
1493
|
+
];
|
|
1494
|
+
}
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
cohortsAdapter.removeOne(state, cohortId);
|
|
1498
|
+
// deleted the current cohort so set to the most recent cohort
|
|
1499
|
+
if (state.currentCohortId === cohortId) {
|
|
1500
|
+
const remainingIds = Object.keys(state.entities);
|
|
1501
|
+
state.currentCohortId = remainingIds[0];
|
|
1502
|
+
}
|
|
1503
|
+
if (action?.payload.shouldShowMessage) {
|
|
1504
|
+
state.message = [
|
|
1505
|
+
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
1506
|
+
];
|
|
1507
|
+
}
|
|
1508
|
+
},
|
|
1509
|
+
// adds a filter to the cohort filter set at the given index
|
|
1510
|
+
updateCohortFilter: (state, action)=>{
|
|
1511
|
+
const { index, field, filter } = action.payload;
|
|
1512
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1513
|
+
if (!state.entities[currentCohortId]) {
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
cohortsAdapter.updateOne(state, {
|
|
1517
|
+
id: currentCohortId,
|
|
1518
|
+
changes: {
|
|
1519
|
+
filters: {
|
|
1520
|
+
...state.entities[currentCohortId].filters,
|
|
1521
|
+
[index]: {
|
|
1522
|
+
mode: state.entities[currentCohortId]?.filters[index]?.mode ?? 'and',
|
|
1523
|
+
root: {
|
|
1524
|
+
...state.entities[currentCohortId]?.filters[index]?.root ?? {},
|
|
1525
|
+
[field]: filter
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
},
|
|
1529
|
+
modified: true,
|
|
1530
|
+
modifiedDatetime: new Date().toISOString()
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
},
|
|
1534
|
+
setCohortFilter: (state, action)=>{
|
|
1535
|
+
const { index, filters } = action.payload;
|
|
1536
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1537
|
+
if (!state.entities[currentCohortId]) {
|
|
1538
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1541
|
+
cohortsAdapter.updateOne(state, {
|
|
1542
|
+
id: currentCohortId,
|
|
1543
|
+
changes: {
|
|
1544
|
+
filters: {
|
|
1545
|
+
...state.entities[currentCohortId].filters,
|
|
1546
|
+
[index]: filters
|
|
1547
|
+
},
|
|
1548
|
+
modified: true,
|
|
1549
|
+
modifiedDatetime: new Date().toISOString()
|
|
1550
|
+
}
|
|
1551
|
+
});
|
|
1552
|
+
},
|
|
1553
|
+
setCohortIndexFilters: (state, action)=>{
|
|
1554
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1555
|
+
if (!state.entities[currentCohortId]) {
|
|
1556
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1557
|
+
return;
|
|
1558
|
+
}
|
|
1559
|
+
cohortsAdapter.updateOne(state, {
|
|
1560
|
+
id: currentCohortId,
|
|
1561
|
+
changes: {
|
|
1562
|
+
filters: action.payload.filters,
|
|
1563
|
+
modified: true,
|
|
1564
|
+
modifiedDatetime: new Date().toISOString()
|
|
1565
|
+
}
|
|
1566
|
+
});
|
|
1567
|
+
},
|
|
1568
|
+
// removes a filter to the cohort filter set at the given index
|
|
1569
|
+
removeCohortFilter: (state, action)=>{
|
|
1570
|
+
const { index, field } = action.payload;
|
|
1571
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1572
|
+
if (!state.entities[currentCohortId]) {
|
|
1573
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1577
|
+
if (!filters) {
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1581
|
+
const { [field]: _a, ...updated } = filters;
|
|
1582
|
+
cohortsAdapter.updateOne(state, {
|
|
1583
|
+
id: currentCohortId,
|
|
1584
|
+
changes: {
|
|
1585
|
+
filters: {
|
|
1586
|
+
...state.entities[currentCohortId]?.filters,
|
|
1587
|
+
[index]: {
|
|
1588
|
+
mode: state.entities[currentCohortId].filters[index].mode,
|
|
1589
|
+
root: updated
|
|
1590
|
+
}
|
|
1591
|
+
},
|
|
1592
|
+
modified: true,
|
|
1593
|
+
modifiedDatetime: new Date().toISOString()
|
|
1594
|
+
}
|
|
1595
|
+
});
|
|
1596
|
+
},
|
|
1597
|
+
duplicateCohort: (state)=>{
|
|
1598
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1599
|
+
const currentCohort = state.entities[currentCohortId];
|
|
1600
|
+
const newName = generateUniqueName(Object.values(state.entities), currentCohort.name);
|
|
1601
|
+
const duplicatedCohort = newCohort({
|
|
1602
|
+
filters: {
|
|
1603
|
+
...currentCohort.filters
|
|
1604
|
+
},
|
|
1605
|
+
customName: newName
|
|
1606
|
+
});
|
|
1607
|
+
cohortsAdapter.addOne(state, {
|
|
1608
|
+
...duplicatedCohort,
|
|
1609
|
+
counts: {
|
|
1610
|
+
...currentCohort.counts
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
state.currentCohortId = duplicatedCohort.id;
|
|
1614
|
+
},
|
|
1615
|
+
// removes all filters from the cohort filter set at the given index
|
|
1616
|
+
clearCohortFilters: (state, action)=>{
|
|
1617
|
+
const { index } = action.payload;
|
|
1618
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1619
|
+
if (!state.entities[currentCohortId]) {
|
|
1620
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1621
|
+
return;
|
|
1622
|
+
}
|
|
1623
|
+
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1624
|
+
if (!filters) {
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1627
|
+
cohortsAdapter.updateOne(state, {
|
|
1628
|
+
id: currentCohortId,
|
|
1629
|
+
changes: {
|
|
1630
|
+
filters: {
|
|
1631
|
+
...state.entities[currentCohortId]?.filters,
|
|
1632
|
+
[index]: {
|
|
1633
|
+
mode: 'and',
|
|
1634
|
+
root: {}
|
|
1635
|
+
}
|
|
1636
|
+
},
|
|
1637
|
+
modified: true,
|
|
1638
|
+
modifiedDatetime: new Date().toISOString()
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
},
|
|
1642
|
+
updateCohortCounts: (state, action)=>{
|
|
1643
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1644
|
+
const currentCohort = state.entities[currentCohortId];
|
|
1645
|
+
cohortsAdapter.updateOne(state, {
|
|
1646
|
+
id: currentCohortId,
|
|
1647
|
+
changes: {
|
|
1648
|
+
counts: {
|
|
1649
|
+
...currentCohort.counts,
|
|
1650
|
+
...action.payload
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
});
|
|
1654
|
+
},
|
|
1655
|
+
updateCohortIndexCountById: (state, action)=>{
|
|
1656
|
+
const { index, cohortId, counts } = action.payload;
|
|
1657
|
+
const cohort = state.entities[cohortId];
|
|
1658
|
+
cohortsAdapter.updateOne(state, {
|
|
1659
|
+
id: cohortId,
|
|
1660
|
+
changes: {
|
|
1661
|
+
counts: {
|
|
1662
|
+
...cohort.counts,
|
|
1663
|
+
...{
|
|
1664
|
+
[index]: counts
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
},
|
|
1670
|
+
setCurrentCohortId: (state, action)=>{
|
|
1671
|
+
state.currentCohortId = action.payload;
|
|
1672
|
+
},
|
|
1673
|
+
/** @hidden */ setCohortList: (state, action)=>{
|
|
1674
|
+
if (!action.payload) {
|
|
1675
|
+
cohortsAdapter.removeMany(state, state.ids);
|
|
1676
|
+
} else {
|
|
1677
|
+
cohortsAdapter.upsertMany(state, [
|
|
1678
|
+
...action.payload
|
|
1679
|
+
]);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
});
|
|
1607
1684
|
/**
|
|
1608
|
-
*
|
|
1609
|
-
*
|
|
1610
|
-
* or returns the leaf operand as is. When the field contains dots, it splits the field into parts,
|
|
1611
|
-
* creates a "nested" operation for the root field, and recursively constructs the nested structure
|
|
1612
|
-
* for the remaining portion of the field.
|
|
1685
|
+
* Returns the selectors for the cohorts EntityAdapter
|
|
1686
|
+
* @param state - the CoreState
|
|
1613
1687
|
*
|
|
1614
|
-
* @
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
*/ const buildNestedGQLFilter = (field, leafOperand, parentPath = undefined)=>{
|
|
1620
|
-
if (!field.includes('.')) {
|
|
1621
|
-
return leafOperand;
|
|
1622
|
-
}
|
|
1623
|
-
const splitFieldArray = field.split('.');
|
|
1624
|
-
const nextField = splitFieldArray.shift();
|
|
1625
|
-
if (!nextField) {
|
|
1626
|
-
console.warn('Invalid field path:', field);
|
|
1627
|
-
return leafOperand;
|
|
1628
|
-
}
|
|
1629
|
-
const currentPath = parentPath ? `${parentPath}.${nextField}` : nextField;
|
|
1630
|
-
return {
|
|
1631
|
-
nested: {
|
|
1632
|
-
path: currentPath,
|
|
1633
|
-
...buildNestedGQLFilter(splitFieldArray.join('.'), leafOperand, currentPath)
|
|
1634
|
-
}
|
|
1635
|
-
};
|
|
1636
|
-
};
|
|
1688
|
+
* @hidden
|
|
1689
|
+
*/ const cohortSelectors = cohortsAdapter.getSelectors((state)=>state.cohorts.cohortManager);
|
|
1690
|
+
// Filter actions: addFilter, removeFilter, updateFilter
|
|
1691
|
+
const { createNewCohort, updateCohortFilter, setCohortFilter, setCohortIndexFilters, duplicateCohort, removeCohortFilter, clearCohortFilters, removeCohort, setCurrentCohortId, updateCohortName, updateCohortCounts, updateCohortIndexCountById, setCohortList } = cohortManagerSlice.actions;
|
|
1692
|
+
const cohortReducer = cohortManagerSlice.reducer;
|
|
1637
1693
|
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1694
|
+
const initialState$2 = {};
|
|
1695
|
+
const expandSlice$1 = createSlice({
|
|
1696
|
+
name: 'CohortBuilder/filterExpand',
|
|
1697
|
+
initialState: initialState$2,
|
|
1698
|
+
reducers: {
|
|
1699
|
+
toggleCohortBuilderCategoryFilter: (state, action)=>{
|
|
1700
|
+
return {
|
|
1701
|
+
...state,
|
|
1702
|
+
[action.payload.index]: {
|
|
1703
|
+
...state[action.payload.index],
|
|
1704
|
+
[action.payload.field]: action.payload.expanded
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
},
|
|
1708
|
+
toggleCohortBuilderAllFilters: (state, action)=>{
|
|
1709
|
+
return {
|
|
1710
|
+
...state,
|
|
1711
|
+
[action.payload.index]: Object.keys(state[action.payload.index]).reduce((acc, k)=>{
|
|
1712
|
+
acc[k] = action.payload.expand;
|
|
1713
|
+
return acc;
|
|
1714
|
+
}, {})
|
|
1715
|
+
};
|
|
1716
|
+
}
|
|
1651
1717
|
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
const
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
const isIntersection = (value)=>{
|
|
1658
|
-
return typeof value === 'object' && value !== null && value.operator === 'and' && Array.isArray(value.operands);
|
|
1659
|
-
};
|
|
1660
|
-
const isOperandsType = (operation)=>{
|
|
1661
|
-
return operation?.operands !== undefined;
|
|
1662
|
-
};
|
|
1663
|
-
const isIndexedFilterSetEmpty = (filters)=>Object.values(filters).every((filterSet)=>Object.keys(filterSet).length === 0);
|
|
1664
|
-
const EmptyFilterSet = {
|
|
1665
|
-
mode: 'and',
|
|
1666
|
-
root: {}
|
|
1667
|
-
};
|
|
1718
|
+
});
|
|
1719
|
+
const cohortBuilderFiltersExpandedReducer = expandSlice$1.reducer;
|
|
1720
|
+
const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = expandSlice$1.actions;
|
|
1721
|
+
const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
|
|
1722
|
+
const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
|
|
1668
1723
|
|
|
1669
|
-
const
|
|
1670
|
-
const
|
|
1671
|
-
'
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
'or',
|
|
1684
|
-
'out',
|
|
1685
|
-
'so',
|
|
1686
|
-
'the',
|
|
1687
|
-
'to',
|
|
1688
|
-
'up',
|
|
1689
|
-
'yet'
|
|
1690
|
-
];
|
|
1691
|
-
const capitalize$1 = (s)=>s.length > 0 ? s[0].toUpperCase() + s.slice(1) : '';
|
|
1692
|
-
const trimFirstFieldNameToTitle = (fieldName, trim = false)=>{
|
|
1693
|
-
if (trim) {
|
|
1694
|
-
const source = fieldName.slice(fieldName.indexOf('.') + 1);
|
|
1695
|
-
return fieldNameToTitle(source ? source : fieldName, 0);
|
|
1724
|
+
const initialState$1 = {};
|
|
1725
|
+
const expandSlice = createSlice({
|
|
1726
|
+
name: 'CohortBuilder/filterCombineMode',
|
|
1727
|
+
initialState: initialState$1,
|
|
1728
|
+
reducers: {
|
|
1729
|
+
setCohortFilterCombineMode: (state, action)=>{
|
|
1730
|
+
return {
|
|
1731
|
+
...state,
|
|
1732
|
+
[action.payload.index]: {
|
|
1733
|
+
...state[action.payload.index],
|
|
1734
|
+
[action.payload.field]: action.payload.mode
|
|
1735
|
+
}
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1696
1738
|
}
|
|
1697
|
-
|
|
1739
|
+
});
|
|
1740
|
+
const cohortBuilderFiltersCombineModeReducer = expandSlice.reducer;
|
|
1741
|
+
const { setCohortFilterCombineMode } = expandSlice.actions;
|
|
1742
|
+
const selectCohortFilterCombineMode = (state, index, field)=>state.cohorts.filtersCombineMode?.[index]?.[field] ?? 'or';
|
|
1743
|
+
|
|
1744
|
+
const initialState = {
|
|
1745
|
+
shouldShareFilters: false,
|
|
1746
|
+
sharedFiltersMap: {}
|
|
1698
1747
|
};
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1748
|
+
const cohortSharedFiltersSlice = createSlice({
|
|
1749
|
+
name: 'cohortSharedFilters',
|
|
1750
|
+
initialState: initialState,
|
|
1751
|
+
reducers: {
|
|
1752
|
+
setShouldShareFilters: (state, action)=>{
|
|
1753
|
+
state.shouldShareFilters = action.payload;
|
|
1754
|
+
return state;
|
|
1755
|
+
},
|
|
1756
|
+
setSharedFilters: (state, action)=>{
|
|
1757
|
+
state.sharedFiltersMap = action.payload;
|
|
1758
|
+
}
|
|
1708
1759
|
}
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
* @param fieldName
|
|
1715
|
-
*/ const extractIndexFromFullFieldName = (fieldName)=>fieldName.split('.')[0];
|
|
1716
|
-
/**
|
|
1717
|
-
* prepend the index name to the field name
|
|
1718
|
-
*/ const prependIndexToFieldName = (fieldName, index)=>`${index}.${fieldName}`;
|
|
1719
|
-
/**
|
|
1720
|
-
* extract the field name from the index.field name
|
|
1721
|
-
*/ const extractFieldNameFromFullFieldName = (fieldName)=>fieldName.split('.').slice(1).join('.');
|
|
1722
|
-
/**
|
|
1723
|
-
* extract the field name and the index from the index.field name returning as a tuple
|
|
1724
|
-
*/ const extractIndexAndFieldNameFromFullFieldName = (fieldName)=>{
|
|
1725
|
-
const [index, ...rest] = fieldName.split('.');
|
|
1726
|
-
return [
|
|
1727
|
-
index,
|
|
1728
|
-
rest.join('.')
|
|
1760
|
+
});
|
|
1761
|
+
const selectShouldShareFilters = (state)=>state.cohorts.sharedFilters.shouldShareFilters;
|
|
1762
|
+
const selectSharedFilters = (state)=>state.cohorts.sharedFilters.sharedFiltersMap;
|
|
1763
|
+
const selectSharedFiltersForFields = (state, field)=>state.cohorts.sharedFilters.sharedFiltersMap?.[field] ?? [
|
|
1764
|
+
field
|
|
1729
1765
|
];
|
|
1730
|
-
};
|
|
1766
|
+
const { setShouldShareFilters, setSharedFilters } = cohortSharedFiltersSlice.actions;
|
|
1767
|
+
const cohortSharedFiltersReducer = cohortSharedFiltersSlice.reducer;
|
|
1768
|
+
|
|
1769
|
+
const cohortReducers = combineReducers({
|
|
1770
|
+
filtersExpanded: cohortBuilderFiltersExpandedReducer,
|
|
1771
|
+
filtersCombineMode: cohortBuilderFiltersCombineModeReducer,
|
|
1772
|
+
sharedFilters: cohortSharedFiltersReducer,
|
|
1773
|
+
cohortManager: cohortReducer
|
|
1774
|
+
});
|
|
1775
|
+
|
|
1776
|
+
const rootReducer = combineReducers({
|
|
1777
|
+
gen3Services: gen3ServicesReducer,
|
|
1778
|
+
user: userReducer,
|
|
1779
|
+
gen3Apps: gen3AppReducer,
|
|
1780
|
+
drsHostnames: drsHostnamesReducer,
|
|
1781
|
+
modals: modalReducer,
|
|
1782
|
+
cohorts: cohortReducers,
|
|
1783
|
+
activeWorkspace: activeWorkspaceReducer,
|
|
1784
|
+
[guppyApiSliceReducerPath]: guppyApiReducer,
|
|
1785
|
+
[userAuthApiReducerPath]: userAuthApiReducer,
|
|
1786
|
+
[cartReducerPath]: cartReducer
|
|
1787
|
+
});
|
|
1731
1788
|
|
|
1732
1789
|
/**
|
|
1733
1790
|
* Flattens a deep nested JSON object skipping
|
|
@@ -2215,18 +2272,18 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2215
2272
|
*/ const explorerApi = explorerTags.injectEndpoints({
|
|
2216
2273
|
endpoints: (builder)=>({
|
|
2217
2274
|
getAllFieldsForType: builder.query({
|
|
2218
|
-
query: (type)=>({
|
|
2219
|
-
query: `{ _mapping ${type} } }`
|
|
2275
|
+
query: ({ type, indexPrefix = '' })=>({
|
|
2276
|
+
query: `{ ${indexPrefix}_mapping ${type} } }`
|
|
2220
2277
|
}),
|
|
2221
2278
|
transformResponse: (response, _meta, params)=>{
|
|
2222
2279
|
return response[params.type];
|
|
2223
2280
|
}
|
|
2224
2281
|
}),
|
|
2225
2282
|
getAccessibleData: builder.query({
|
|
2226
|
-
query: ({ type, fields, accessibility })=>{
|
|
2283
|
+
query: ({ type, fields, accessibility, indexPrefix = '' })=>{
|
|
2227
2284
|
const fieldParts = fields.map((field)=>`${field} { histogram { key count } }`);
|
|
2228
2285
|
return {
|
|
2229
|
-
query:
|
|
2286
|
+
query: `${indexPrefix}_aggregation {
|
|
2230
2287
|
${type} (accessibility: ${accessibility}) {
|
|
2231
2288
|
${fieldParts.join(',')}
|
|
2232
2289
|
}
|
|
@@ -2235,7 +2292,7 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2235
2292
|
}
|
|
2236
2293
|
}),
|
|
2237
2294
|
getRawDataAndTotalCounts: builder.query({
|
|
2238
|
-
query: ({ type, fields, filters, sort, offset = 0, size = 20, accessibility = Accessibility.ALL, format = undefined })=>{
|
|
2295
|
+
query: ({ type, fields, filters, sort, offset = 0, size = 20, accessibility = Accessibility.ALL, format = undefined, indexPrefix = '' })=>{
|
|
2239
2296
|
const gqlFilter = convertFilterSetToGqlFilter(filters);
|
|
2240
2297
|
const params = [
|
|
2241
2298
|
...sort ? [
|
|
@@ -2260,7 +2317,7 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2260
2317
|
'filter: $filter'
|
|
2261
2318
|
] : []
|
|
2262
2319
|
].join(',');
|
|
2263
|
-
const dataTypeLine = `${type} (accessibility: ${accessibility}, offset: ${offset}, first: ${size},
|
|
2320
|
+
const dataTypeLine = `${indexPrefix}${type} (accessibility: ${accessibility}, offset: ${offset}, first: ${size},
|
|
2264
2321
|
${dataParams}) {`;
|
|
2265
2322
|
const typeAggsLine = `${type} (${gqlFilter && 'filter: $filter,'} accessibility: ${accessibility}) {`;
|
|
2266
2323
|
const processedFields = fields.map((field)=>rawDataQueryStrForEachField(field));
|
|
@@ -2268,7 +2325,7 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2268
2325
|
${dataTypeLine}
|
|
2269
2326
|
${processedFields.join(' ')}
|
|
2270
2327
|
}
|
|
2271
|
-
_aggregation {
|
|
2328
|
+
${indexPrefix}_aggregation {
|
|
2272
2329
|
${typeAggsLine}
|
|
2273
2330
|
_totalCount
|
|
2274
2331
|
}
|
|
@@ -2296,13 +2353,13 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2296
2353
|
]
|
|
2297
2354
|
}),
|
|
2298
2355
|
getAggs: builder.query({
|
|
2299
|
-
query: ({ type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false })=>{
|
|
2300
|
-
return buildGetAggregationQuery(type, fields, filters, accessibility, filterSelf);
|
|
2356
|
+
query: ({ type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, indexPrefix = '' })=>{
|
|
2357
|
+
return buildGetAggregationQuery(type, fields, filters, accessibility, filterSelf, undefined, indexPrefix);
|
|
2301
2358
|
},
|
|
2302
2359
|
transformResponse: (response, _meta, args)=>{
|
|
2303
|
-
const buckets = processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
|
|
2360
|
+
const buckets = processHistogramResponse(response?.data?.[`${args?.indexPrefix ?? ''}_aggregation`][args.type] ?? {});
|
|
2304
2361
|
// check for totals
|
|
2305
|
-
const count = response?.data?._aggregation[args.type]?._totalCount ?? null;
|
|
2362
|
+
const count = response?.data?.[`${args?.indexPrefix ?? ''}_aggregation`][args.type]?._totalCount ?? null;
|
|
2306
2363
|
return {
|
|
2307
2364
|
_totalCount: [
|
|
2308
2365
|
{
|
|
@@ -2318,24 +2375,24 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2318
2375
|
]
|
|
2319
2376
|
}),
|
|
2320
2377
|
getStatsAggregations: builder.query({
|
|
2321
|
-
query: ({ type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, queryId = undefined })=>{
|
|
2322
|
-
return buildGetStatsAggregationQuery(type, fields, filters, accessibility, filterSelf, queryId);
|
|
2378
|
+
query: ({ type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, queryId = undefined, indexPrefix = '' })=>{
|
|
2379
|
+
return buildGetStatsAggregationQuery(type, fields, filters, accessibility, filterSelf, queryId, indexPrefix);
|
|
2323
2380
|
},
|
|
2324
2381
|
transformResponse: (response, _meta, args)=>{
|
|
2325
|
-
return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
|
|
2382
|
+
return processHistogramResponse(response?.data?.[`${args?.indexPrefix ?? ''}_aggregation`][args.type] ?? {});
|
|
2326
2383
|
},
|
|
2327
2384
|
providesTags: [
|
|
2328
2385
|
'STATS'
|
|
2329
2386
|
]
|
|
2330
2387
|
}),
|
|
2331
2388
|
getSubAggs: builder.query({
|
|
2332
|
-
query: ({ type, mainField, termsFields = undefined, missingFields = undefined, numericAggAsText = false, filters = undefined, accessibility = Accessibility.ALL })=>{
|
|
2389
|
+
query: ({ type, mainField, termsFields = undefined, missingFields = undefined, numericAggAsText = false, filters = undefined, accessibility = Accessibility.ALL, indexPrefix = '' })=>{
|
|
2333
2390
|
const nestedAggFields = {
|
|
2334
2391
|
termsFields: termsFields,
|
|
2335
2392
|
missingFields: missingFields
|
|
2336
2393
|
};
|
|
2337
2394
|
const query = `query getSubAggs ( ${filters ?? '$filter: JSON,'} $nestedAggFields: JSON) {
|
|
2338
|
-
_aggregation {
|
|
2395
|
+
${indexPrefix}_aggregation {
|
|
2339
2396
|
${type} ( ${filters ?? 'filter: $filter, filterSelf: false,'} nestedAggFields: $nestedAggFields, accessibility: ${accessibility}) {
|
|
2340
2397
|
_totalCounts
|
|
2341
2398
|
${nestedHistogramQueryStrForEachField(mainField, numericAggAsText)}
|
|
@@ -2351,18 +2408,18 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2351
2408
|
};
|
|
2352
2409
|
},
|
|
2353
2410
|
transformResponse: (response, _meta, args)=>{
|
|
2354
|
-
return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
|
|
2411
|
+
return processHistogramResponse(response?.data?.[`${args?.indexPrefix ?? ''}_aggregation`][args.type] ?? {});
|
|
2355
2412
|
},
|
|
2356
2413
|
providesTags: [
|
|
2357
2414
|
'AGGS'
|
|
2358
2415
|
]
|
|
2359
2416
|
}),
|
|
2360
2417
|
getCounts: builder.query({
|
|
2361
|
-
query: ({ type, filters, accessibility = Accessibility.ALL, queryId = undefined })=>{
|
|
2418
|
+
query: ({ type, filters, accessibility = Accessibility.ALL, queryId = undefined, indexPrefix = '' })=>{
|
|
2362
2419
|
const gqlFilters = convertFilterSetToGqlFilter(filters);
|
|
2363
|
-
const queryLine = `query totalCounts${queryId ?
|
|
2420
|
+
const queryLine = `query totalCounts${queryId ? `${indexPrefix}_${queryId}` : ''} ${gqlFilters ? '($filter: JSON)' : ''}{`;
|
|
2364
2421
|
const typeAggsLine = `${type} ${gqlFilters ? '(filter: $filter, ' : '('} accessibility: ${accessibility}) {`;
|
|
2365
|
-
const query = `${queryLine} _aggregation {
|
|
2422
|
+
const query = `${queryLine} ${indexPrefix}_aggregation {
|
|
2366
2423
|
${typeAggsLine}
|
|
2367
2424
|
_totalCount
|
|
2368
2425
|
}
|
|
@@ -2378,23 +2435,23 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2378
2435
|
};
|
|
2379
2436
|
},
|
|
2380
2437
|
transformResponse: (response, _meta, args)=>{
|
|
2381
|
-
if (!response.data || !response.data
|
|
2438
|
+
if (!response.data || !response.data[`${args?.indexPrefix ?? ''}_aggregation`]) {
|
|
2382
2439
|
throw new Error('Invalid response: Missing data or _aggregation field');
|
|
2383
2440
|
}
|
|
2384
|
-
if (!(args.type in response.data
|
|
2441
|
+
if (!(args.type in response.data[`${args?.indexPrefix ?? ''}_aggregation`])) {
|
|
2385
2442
|
throw new Error(`Invalid response: Missing expected key '${args.type}' in _aggregation`);
|
|
2386
2443
|
}
|
|
2387
|
-
return response.data
|
|
2444
|
+
return response.data[`${args?.indexPrefix ?? ''}_aggregation`][args.type]._totalCount ?? 0;
|
|
2388
2445
|
},
|
|
2389
2446
|
providesTags: [
|
|
2390
2447
|
'COUNTS'
|
|
2391
2448
|
]
|
|
2392
2449
|
}),
|
|
2393
2450
|
getFieldCountSummary: builder.query({
|
|
2394
|
-
query: ({ type, field, filters, accessibility = Accessibility.ALL })=>{
|
|
2451
|
+
query: ({ type, field, filters, accessibility = Accessibility.ALL, indexPrefix = '' })=>{
|
|
2395
2452
|
const gqlFilters = convertFilterSetToGqlFilter(filters);
|
|
2396
2453
|
const query = `query summary ($filter: JSON) {
|
|
2397
|
-
_aggregation {
|
|
2454
|
+
${indexPrefix}_aggregation {
|
|
2398
2455
|
${type} (filter: $filter, accessibility: ${accessibility}) {
|
|
2399
2456
|
${field} {
|
|
2400
2457
|
histogram {
|
|
@@ -2415,15 +2472,15 @@ const explorerTags = guppyApi.enhanceEndpoints({
|
|
|
2415
2472
|
}
|
|
2416
2473
|
}),
|
|
2417
2474
|
getFieldsForIndex: builder.query({
|
|
2418
|
-
query: (index)=>{
|
|
2475
|
+
query: ({ index, indexPrefix = '' })=>{
|
|
2419
2476
|
return {
|
|
2420
2477
|
query: `{
|
|
2421
|
-
_mapping { ${index} }
|
|
2478
|
+
${indexPrefix}_mapping { ${index} }
|
|
2422
2479
|
}`
|
|
2423
2480
|
};
|
|
2424
2481
|
},
|
|
2425
|
-
transformResponse: (response)=>{
|
|
2426
|
-
return response[
|
|
2482
|
+
transformResponse: (response, _meta, args)=>{
|
|
2483
|
+
return response[`${args.indexPrefix}_mapping`];
|
|
2427
2484
|
}
|
|
2428
2485
|
}),
|
|
2429
2486
|
getSharedFieldsForIndex: builder.query({
|
|
@@ -2460,16 +2517,18 @@ const useGetArrayTypes = ()=>{
|
|
|
2460
2517
|
return data ? data['indices'] : {};
|
|
2461
2518
|
}
|
|
2462
2519
|
};
|
|
2463
|
-
const useGetIndexFields = (index)=>{
|
|
2464
|
-
const { data } = useGetFieldsForIndexQuery(
|
|
2520
|
+
const useGetIndexFields = (index, indexPrefix = '')=>{
|
|
2521
|
+
const { data } = useGetFieldsForIndexQuery({
|
|
2522
|
+
index: index,
|
|
2523
|
+
indexPrefix: indexPrefix
|
|
2524
|
+
});
|
|
2465
2525
|
return data ?? [];
|
|
2466
2526
|
};
|
|
2467
|
-
const buildGetAggregationQuery = (type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, queryId = undefined)=>{
|
|
2468
|
-
const queryStart = isFilterEmpty(filters) ? `
|
|
2469
|
-
|
|
2470
|
-
_aggregation {
|
|
2527
|
+
const buildGetAggregationQuery = (type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, queryId = undefined, indexPrefix = '')=>{
|
|
2528
|
+
const queryStart = isFilterEmpty(filters) ? `query getAggs${queryId ? `_${queryId}` : ''} {
|
|
2529
|
+
${indexPrefix}_aggregation {
|
|
2471
2530
|
${type} (accessibility: ${accessibility}) {` : `query getAggs ($filter: JSON) {
|
|
2472
|
-
_aggregation {
|
|
2531
|
+
${indexPrefix}_aggregation {
|
|
2473
2532
|
|
|
2474
2533
|
${type} (filter: $filter, filterSelf: ${filterSelf ? 'true' : 'false'}, accessibility: ${accessibility}) { _totalCount`;
|
|
2475
2534
|
const query = `${queryStart}
|
|
@@ -2485,12 +2544,12 @@ const buildGetAggregationQuery = (type, fields, filters, accessibility = Accessi
|
|
|
2485
2544
|
};
|
|
2486
2545
|
return queryBody;
|
|
2487
2546
|
};
|
|
2488
|
-
const buildGetStatsAggregationQuery = (type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, queryId = undefined)=>{
|
|
2547
|
+
const buildGetStatsAggregationQuery = (type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false, queryId = undefined, indexPrefix = '')=>{
|
|
2489
2548
|
const queryStart = isFilterEmpty(filters) ? `
|
|
2490
2549
|
query getStatsAggs${queryId ? `_${queryId}` : ''} {
|
|
2491
|
-
_aggregation {
|
|
2550
|
+
${indexPrefix}_aggregation {
|
|
2492
2551
|
${type} (accessibility: ${accessibility}) {` : `query getStatsAggs${queryId ? `_${queryId}` : ''} ($filter: JSON) {
|
|
2493
|
-
_aggregation {
|
|
2552
|
+
${indexPrefix}_aggregation {
|
|
2494
2553
|
${type} (filter: $filter, filterSelf: ${filterSelf ? 'true' : 'false'}, accessibility: ${accessibility}) { _totalCount`;
|
|
2495
2554
|
const query = `${queryStart}
|
|
2496
2555
|
${fields.map((field)=>statsQueryStrForEachField(field))}
|
|
@@ -2554,7 +2613,8 @@ const persistConfig = {
|
|
|
2554
2613
|
storage,
|
|
2555
2614
|
whitelist: [
|
|
2556
2615
|
'cohorts',
|
|
2557
|
-
'activeWorkspace'
|
|
2616
|
+
'activeWorkspace',
|
|
2617
|
+
'cart'
|
|
2558
2618
|
]
|
|
2559
2619
|
};
|
|
2560
2620
|
const persistedReducer = persistReducer(persistConfig, rootReducer);
|
|
@@ -5738,5 +5798,5 @@ const selectPaymodelStatus = createSelector(paymodelStatusSelector, (status)=>st
|
|
|
5738
5798
|
const isWorkspaceActive = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Launching || status === WorkspaceStatus.Terminating;
|
|
5739
5799
|
const isWorkspaceRunningOrStopping = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Terminating;
|
|
5740
5800
|
|
|
5741
|
-
export { Accessibility, CohortStorage, CoreProvider, DAYS_IN_YEAR, DataLibraryStoreMode, EmptyFilterSet, EmptyWorkspaceStatusResponse, EnumValueExtractorHandler, ExtractValueFromObject, GEN3_API, GEN3_AUTHZ_API, GEN3_COMMONS_NAME, GEN3_CROSSWALK_API, GEN3_DOMAIN, GEN3_DOWNLOADS_ENDPOINT, GEN3_FENCE_API, GEN3_GUPPY_API, GEN3_MANIFEST_API, GEN3_MDS_API, GEN3_REDIRECT_URL, GEN3_SOWER_API, GEN3_SUBMISSION_API, GEN3_WORKSPACE_API, HTTPError, HTTPErrorMessages, HttpMethod, MissingServiceConfigurationError, Modals, PodConditionType, PodStatus, RequestedWorkspaceStatus, ToGqlHandler, ValueExtractorHandler, WorkspaceStatus, ageDisplay, appendFilterToOperation, buildGetAggregationQuery, buildGetStatsAggregationQuery, buildListItemsGroupedByDataset, buildNestedGQLFilter, calculatePercentageAsNumber, calculatePercentageAsString, capitalize, clearActiveWorkspaceId, clearCohortFilters, cohortReducer, convertFilterSetToGqlFilter, convertFilterToGqlFilter, convertGqlFilterToFilter, convertToHistogramDataAsStringKey, convertToQueryString, coreStore, createAppApiForRTKQ, createAppStore, createGen3App, createGen3AppWithOwnStore, createNewCohort, createUseCoreDataHook, customQueryStrForField, defaultCohortNameGenerator, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, drsHostnamesReducer, duplicateCohort, explorerApi, explorerTags, extractEnumFilterValue, extractFieldNameFromFullFieldName, extractFileDatasetsInRecords, extractFilterValue, extractIndexAndFieldNameFromFullFieldName, extractIndexFromDataLibraryCohort, extractIndexFromFullFieldName, fetchFence, fetchFencePresignedURL, fetchJSONDataFromURL, fetchJson, fetchUserState, fieldNameToTitle, filterSetToOperation, gen3Api, generateUniqueName, getCurrentTimestamp, getFederatedLoginStatus, getGen3AppId, getNumberOfItemsInDatalist, getRemoteSupportServiceRegistry, getTimestamp, graphQLAPI, graphQLWithTags, groupSharedFields, guppyAPISliceMiddleware, guppyApi, guppyApiReducer, guppyApiSliceReducerPath, handleGqlOperation, handleOperation, hideModal, histogramQueryStrForEachField, humanify, isAdditionalDataItem, isArray, isAuthenticated, isCohortItem, isDataLibraryAPIResponse, isDatalistAPI, isErrorWithMessage, isFetchBaseQueryError, isFetchError, isFetchParseError, isFileItem, isFilterEmpty, isFilterSet, isGQLIntersection, isGQLUnion, isGuppyAggregationData, isHistogramData, isHistogramDataAArray, isHistogramDataAnEnum, isHistogramDataArray, isHistogramDataArrayARange, isHistogramDataArrayAnEnum, isHistogramDataCollection, isHistogramRangeData, isHttpStatusError, isIndexedFilterSetEmpty, isIntersection, isJSONObject, isJSONValue, isJSONValueArray, isNameUnique, isNotDefined, isObject, isOperandsType, isOperationWithField, isOperatorWithFieldAndArrayOfOperands, isPending, isProgramUrl, isRootUrl, isStatsValue, isStatsValuesArray, isString, isTimeGreaterThan, isUnion, isWorkspaceActive, isWorkspaceRunningOrStopping, listifyMethodsFromMapping, logoutFence, manifestApi, manifestTags, nestedHistogramQueryStrForEachField, prepareUrl, prependIndexToFieldName, processHistogramResponse, projectCodeFromResourcePath, queryMultipleMDSRecords, rawDataQueryStrForEachField, registerDefaultRemoteSupport, removeCohort, removeCohortFilter, requestorApi, resetUserState, resourcePathFromProjectID, roundHistogramResponse, selectActiveWorkspaceId, selectActiveWorkspaceStatus, selectAllCohortFiltersCollapsed, selectAllCohorts, selectAuthzMappingData, selectAvailableCohortByName, selectAvailableCohorts, selectCSRFToken, selectCSRFTokenData, selectCohortById, selectCohortFilterCombineMode, selectCohortFilterExpanded, selectCohortFilters, selectCohortIds, selectCurrentCohort, selectCurrentCohortFilters, selectCurrentCohortId, selectCurrentCohortModified, selectCurrentCohortName, selectCurrentCohortSaved, selectCurrentMessage, selectCurrentModal, selectGen3AppByName, selectGen3AppMetadataByName, selectHeadersWithCSRFToken, selectIndexFilters, selectIndexedFilterByName, selectPaymodelStatus, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, selectSharedFilters, selectSharedFiltersForFields, selectShouldShareFilters, selectTotalCohorts, selectUser, selectUserAuthStatus, selectUserData, selectUserDetails, selectUserLoginStatus, selectWorkspaceStatus, selectWorkspaceStatusFromService, setActiveWorkspace, setActiveWorkspaceId, setActiveWorkspaceStatus, setCohortFilter, setCohortFilterCombineMode, setCohortIndexFilters, setCohortList, setCurrentCohortId, setDRSHostnames, setRequestedWorkspaceStatus, setSharedFilters, setShouldShareFilters, setupCoreStore, showModal, statsQueryStrForEachField, stringifyJSONParam, submissionApi, toggleCohortBuilderAllFilters, toggleCohortBuilderCategoryFilter, trimFirstFieldNameToTitle, updateCohortFilter, updateCohortName, useAddCohortManifestMutation, useAddFileManifestMutation, useAddMetadataManifestMutation, useAddNewCredentialMutation, useAskQuestionMutation, useAuthorizeFromCredentialsMutation, useCoreDispatch, useCoreSelector, useCreateAuthzResourceMutation, useCreateRequestMutation, useDataLibrary, useDownloadFromGuppyMutation, useFetchUserDetailsQuery, useGeneralGQLQuery, useGetAISearchStatusQuery, useGetAISearchVersionQuery, useGetAccessibleDataQuery, useGetActivePayModelQuery, useGetAggMDSQuery, useGetAggsQuery, useGetAllFieldsForTypeQuery, useGetArrayTypes, useGetAuthzMappingsQuery, useGetAuthzResourcesQuery, useGetCSRFQuery, useGetCohortManifestQuery, useGetCountsQuery, useGetCredentialsQuery, useGetCrosswalkDataQuery, useGetDataQuery, useGetDictionaryQuery, useGetDownloadQuery, useGetExternalLoginsQuery, useGetFederatedLoginStatus, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetFileFromManifestQuery, useGetFileManifestQuery, useGetIndexAggMDSQuery, useGetIndexFields, useGetJWKKeysQuery, useGetLoginProvidersQuery, useGetMDSQuery, useGetManifestServiceStatusQuery, useGetMetadataByIdQuery, useGetMetadataFromManifestQuery, useGetMetadataManifestQuery, useGetProjectsDetailsQuery, useGetProjectsQuery, useGetRawDataAndTotalCountsQuery, useGetSharedFieldsForIndexQuery, useGetSowerJobListQuery, useGetSowerJobStatusQuery, useGetSowerOutputQuery, useGetSowerServiceStatusQuery, useGetStatsAggregationsQuery, useGetStatus, useGetSubAggsQuery, useGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetTagsQuery, useGetWorkspaceOptionsQuery, useGetWorkspacePayModelsQuery, useGetWorkspaceStatusQuery, useGraphQLQuery, useIsExternalConnectedQuery, useIsUserLoggedIn, useLaunchWorkspaceMutation, useLazyFetchUserDetailsQuery, useLazyGeneralGQLQuery, useLazyGetAggsQuery, useLazyGetAuthzMappingsQuery, useLazyGetAuthzResourcesQuery, useLazyGetCSRFQuery, useLazyGetCountsQuery, useLazyGetCrosswalkDataQuery, useLazyGetDownloadQuery, useLazyGetExternalLoginsQuery, useLazyGetManifestServiceStatusQuery, useLazyGetProjectsQuery, useLazyGetSowerJobListQuery, useLazyGetStatsAggregationsQuery, useLazyGetSubmissionGraphQLQuery, useLazyIsExternalConnectedQuery, useLazyRequestQuery, usePrevious, useRemoveCredentialMutation, useRequestByIdQuery, useRequestQuery, useRequestorStatusQuery, useSetCurrentPayModelMutation, useSubmitSowerJobMutation, useTerminateWorkspaceMutation, useUserAuth, useUserRequestQuery, userHasCreateOrUpdateOnAnyProject, userHasDataUpload, userHasMethodForServiceOnProject, userHasMethodForServiceOnResource, userHasMethodOnAnyProject, userHasSheepdogProgramAdmin, userHasSheepdogProjectAdmin };
|
|
5801
|
+
export { Accessibility, CART_LIMIT, CohortStorage, CoreProvider, DAYS_IN_YEAR, DataLibraryStoreMode, EmptyFilterSet, EmptyWorkspaceStatusResponse, EnumValueExtractorHandler, ExtractValueFromObject, GEN3_API, GEN3_AUTHZ_API, GEN3_COMMONS_NAME, GEN3_CROSSWALK_API, GEN3_DOMAIN, GEN3_DOWNLOADS_ENDPOINT, GEN3_FENCE_API, GEN3_GUPPY_API, GEN3_MANIFEST_API, GEN3_MDS_API, GEN3_REDIRECT_URL, GEN3_SOWER_API, GEN3_SUBMISSION_API, GEN3_WORKSPACE_API, HTTPError, HTTPErrorMessages, HttpMethod, MissingServiceConfigurationError, Modals, PodConditionType, PodStatus, RequestedWorkspaceStatus, ToGqlHandler, ValueExtractorHandler, WorkspaceStatus, addItemsToCart, ageDisplay, appendFilterToOperation, buildGetAggregationQuery, buildGetStatsAggregationQuery, buildListItemsGroupedByDataset, buildNestedGQLFilter, calculatePercentageAsNumber, calculatePercentageAsString, capitalize, cartReducer, cartReducerPath, clearActiveWorkspaceId, clearCohortFilters, cohortReducer, convertFilterSetToGqlFilter, convertFilterToGqlFilter, convertGqlFilterToFilter, convertToHistogramDataAsStringKey, convertToQueryString, coreStore, createAppApiForRTKQ, createAppStore, createGen3App, createGen3AppWithOwnStore, createNewCohort, createUseCoreDataHook, customQueryStrForField, defaultCohortNameGenerator, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, drsHostnamesReducer, duplicateCohort, explorerApi, explorerTags, extractEnumFilterValue, extractFieldNameFromFullFieldName, extractFileDatasetsInRecords, extractFilterValue, extractFiltersWithPrefixFromFilterSet, extractIndexAndFieldNameFromFullFieldName, extractIndexFromDataLibraryCohort, extractIndexFromFullFieldName, fetchFence, fetchFencePresignedURL, fetchJSONDataFromURL, fetchJson, fetchUserState, fieldNameToTitle, filterSetToOperation, gen3Api, generateUniqueName, getCurrentTimestamp, getFederatedLoginStatus, getGen3AppId, getNumberOfItemsInDatalist, getRemoteSupportServiceRegistry, getTimestamp, graphQLAPI, graphQLWithTags, groupSharedFields, guppyAPISliceMiddleware, guppyApi, guppyApiReducer, guppyApiSliceReducerPath, handleGqlOperation, handleOperation, hideModal, histogramQueryStrForEachField, humanify, isAdditionalDataItem, isArray, isAuthenticated, isCohortItem, isDataLibraryAPIResponse, isDatalistAPI, isErrorWithMessage, isFetchBaseQueryError, isFetchError, isFetchParseError, isFileItem, isFilterEmpty, isFilterSet, isGQLIntersection, isGQLUnion, isGuppyAggregationData, isHistogramData, isHistogramDataAArray, isHistogramDataAnEnum, isHistogramDataArray, isHistogramDataArrayARange, isHistogramDataArrayAnEnum, isHistogramDataCollection, isHistogramRangeData, isHttpStatusError, isIndexedFilterSetEmpty, isIntersection, isIntersectionOrUnion, isJSONObject, isJSONValue, isJSONValueArray, isNameUnique, isNestedFilter, isNotDefined, isObject, isOperandsType, isOperationWithField, isOperatorWithFieldAndArrayOfOperands, isPending, isProgramUrl, isRootUrl, isStatsValue, isStatsValuesArray, isString, isTimeGreaterThan, isUnion, isWorkspaceActive, isWorkspaceRunningOrStopping, listifyMethodsFromMapping, logoutFence, manifestApi, manifestTags, nestedHistogramQueryStrForEachField, prepareUrl, prependIndexToFieldName, processHistogramResponse, projectCodeFromResourcePath, queryMultipleMDSRecords, rawDataQueryStrForEachField, registerDefaultRemoteSupport, removeCohort, removeCohortFilter, removeItemsFromCart, requestorApi, resetUserState, resourcePathFromProjectID, roundHistogramResponse, selectActiveWorkspaceId, selectActiveWorkspaceStatus, selectAllCohortFiltersCollapsed, selectAllCohorts, selectAuthzMappingData, selectAvailableCohortByName, selectAvailableCohorts, selectCSRFToken, selectCSRFTokenData, selectCart, selectCartCount, selectCartItem, selectCartItems, selectCohortById, selectCohortFilterCombineMode, selectCohortFilterExpanded, selectCohortFilters, selectCohortIds, selectCurrentCohort, selectCurrentCohortFilters, selectCurrentCohortId, selectCurrentCohortModified, selectCurrentCohortName, selectCurrentCohortSaved, selectCurrentMessage, selectCurrentModal, selectGen3AppByName, selectGen3AppMetadataByName, selectHeadersWithCSRFToken, selectIndexFilters, selectIndexedFilterByName, selectPaymodelStatus, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, selectSharedFilters, selectSharedFiltersForFields, selectShouldShareFilters, selectTotalCohorts, selectUser, selectUserAuthStatus, selectUserData, selectUserDetails, selectUserLoginStatus, selectWorkspaceStatus, selectWorkspaceStatusFromService, setActiveWorkspace, setActiveWorkspaceId, setActiveWorkspaceStatus, setCohortFilter, setCohortFilterCombineMode, setCohortIndexFilters, setCohortList, setCurrentCohortId, setDRSHostnames, setRequestedWorkspaceStatus, setSharedFilters, setShouldShareFilters, setupCoreStore, showModal, statsQueryStrForEachField, stringifyJSONParam, submissionApi, toggleCohortBuilderAllFilters, toggleCohortBuilderCategoryFilter, trimFirstFieldNameToTitle, updateCohortFilter, updateCohortName, useAddCohortManifestMutation, useAddFileManifestMutation, useAddMetadataManifestMutation, useAddNewCredentialMutation, useAskQuestionMutation, useAuthorizeFromCredentialsMutation, useCoreDispatch, useCoreSelector, useCreateAuthzResourceMutation, useCreateRequestMutation, useDataLibrary, useDownloadFromGuppyMutation, useFetchUserDetailsQuery, useGeneralGQLQuery, useGetAISearchStatusQuery, useGetAISearchVersionQuery, useGetAccessibleDataQuery, useGetActivePayModelQuery, useGetAggMDSQuery, useGetAggsQuery, useGetAllFieldsForTypeQuery, useGetArrayTypes, useGetAuthzMappingsQuery, useGetAuthzResourcesQuery, useGetCSRFQuery, useGetCohortManifestQuery, useGetCountsQuery, useGetCredentialsQuery, useGetCrosswalkDataQuery, useGetDataQuery, useGetDictionaryQuery, useGetDownloadQuery, useGetExternalLoginsQuery, useGetFederatedLoginStatus, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetFileFromManifestQuery, useGetFileManifestQuery, useGetIndexAggMDSQuery, useGetIndexFields, useGetJWKKeysQuery, useGetLoginProvidersQuery, useGetMDSQuery, useGetManifestServiceStatusQuery, useGetMetadataByIdQuery, useGetMetadataFromManifestQuery, useGetMetadataManifestQuery, useGetProjectsDetailsQuery, useGetProjectsQuery, useGetRawDataAndTotalCountsQuery, useGetSharedFieldsForIndexQuery, useGetSowerJobListQuery, useGetSowerJobStatusQuery, useGetSowerOutputQuery, useGetSowerServiceStatusQuery, useGetStatsAggregationsQuery, useGetStatus, useGetSubAggsQuery, useGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetTagsQuery, useGetWorkspaceOptionsQuery, useGetWorkspacePayModelsQuery, useGetWorkspaceStatusQuery, useGraphQLQuery, useIsExternalConnectedQuery, useIsUserLoggedIn, useLaunchWorkspaceMutation, useLazyFetchUserDetailsQuery, useLazyGeneralGQLQuery, useLazyGetAggsQuery, useLazyGetAuthzMappingsQuery, useLazyGetAuthzResourcesQuery, useLazyGetCSRFQuery, useLazyGetCountsQuery, useLazyGetCrosswalkDataQuery, useLazyGetDownloadQuery, useLazyGetExternalLoginsQuery, useLazyGetManifestServiceStatusQuery, useLazyGetProjectsQuery, useLazyGetSowerJobListQuery, useLazyGetStatsAggregationsQuery, useLazyGetSubmissionGraphQLQuery, useLazyIsExternalConnectedQuery, useLazyRequestQuery, usePrevious, useRemoveCredentialMutation, useRequestByIdQuery, useRequestQuery, useRequestorStatusQuery, useSetCurrentPayModelMutation, useSubmitSowerJobMutation, useTerminateWorkspaceMutation, useUserAuth, useUserRequestQuery, userHasCreateOrUpdateOnAnyProject, userHasDataUpload, userHasMethodForServiceOnProject, userHasMethodForServiceOnResource, userHasMethodOnAnyProject, userHasSheepdogProgramAdmin, userHasSheepdogProjectAdmin };
|
|
5742
5802
|
//# sourceMappingURL=index.js.map
|