@gen3/core 0.11.33 → 0.11.34
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 +624 -554
- 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/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 +613 -555
- 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 +385 -208
- package/dist/server.d.ts +31 -0
- package/package.json +7 -2
package/dist/cjs/index.js
CHANGED
|
@@ -8,9 +8,9 @@ var reactRedux = require('react-redux');
|
|
|
8
8
|
var React = require('react');
|
|
9
9
|
var graphql = require('graphql');
|
|
10
10
|
var jsonpathPlus = require('jsonpath-plus');
|
|
11
|
+
var lodash = require('lodash');
|
|
11
12
|
var nanoid$1 = require('nanoid');
|
|
12
13
|
var useSWR = require('swr');
|
|
13
|
-
var lodash = require('lodash');
|
|
14
14
|
var flat = require('flat');
|
|
15
15
|
var Papa = require('papaparse');
|
|
16
16
|
var reduxPersist = require('redux-persist');
|
|
@@ -72,6 +72,7 @@ const FILE_DELIMITERS = {
|
|
|
72
72
|
tsv: '\t',
|
|
73
73
|
csv: ','
|
|
74
74
|
};
|
|
75
|
+
const CART_LIMIT = 10000;
|
|
75
76
|
|
|
76
77
|
const isFetchError = (obj)=>{
|
|
77
78
|
if (typeof obj !== 'object' || obj === null) {
|
|
@@ -426,7 +427,7 @@ const useCoreDispatch = reactRedux.useDispatch.withTypes();
|
|
|
426
427
|
});
|
|
427
428
|
const isAuthenticated = (loginStatus)=>loginStatus === 'authenticated';
|
|
428
429
|
const isPending = (loginStatus)=>loginStatus === 'pending';
|
|
429
|
-
const initialState$
|
|
430
|
+
const initialState$9 = {
|
|
430
431
|
status: 'uninitialized',
|
|
431
432
|
loginStatus: 'unauthenticated',
|
|
432
433
|
error: undefined
|
|
@@ -437,9 +438,9 @@ const initialState$8 = {
|
|
|
437
438
|
* @returns: status messages wrapped around fetchUserState response dict
|
|
438
439
|
*/ const slice$4 = toolkit.createSlice({
|
|
439
440
|
name: 'fence/user',
|
|
440
|
-
initialState: initialState$
|
|
441
|
+
initialState: initialState$9,
|
|
441
442
|
reducers: {
|
|
442
|
-
resetUserState: ()=>initialState$
|
|
443
|
+
resetUserState: ()=>initialState$9
|
|
443
444
|
},
|
|
444
445
|
extraReducers: (builder)=>{
|
|
445
446
|
builder.addCase(fetchUserState.fulfilled, (_, action)=>{
|
|
@@ -581,11 +582,11 @@ const { useGetExternalLoginsQuery, useLazyGetExternalLoginsQuery, useLazyIsExter
|
|
|
581
582
|
}
|
|
582
583
|
};
|
|
583
584
|
|
|
584
|
-
const initialState$
|
|
585
|
+
const initialState$8 = {};
|
|
585
586
|
// TODO: document what this does
|
|
586
587
|
const slice$3 = toolkit.createSlice({
|
|
587
588
|
name: 'drsResolver',
|
|
588
|
-
initialState: initialState$
|
|
589
|
+
initialState: initialState$8,
|
|
589
590
|
reducers: {
|
|
590
591
|
setDRSHostnames: (_state, action)=>{
|
|
591
592
|
return action.payload;
|
|
@@ -607,12 +608,12 @@ const lookupGen3App = (id)=>{
|
|
|
607
608
|
else return null;
|
|
608
609
|
};
|
|
609
610
|
|
|
610
|
-
const initialState$
|
|
611
|
+
const initialState$7 = {
|
|
611
612
|
gen3Apps: {}
|
|
612
613
|
};
|
|
613
614
|
const slice$2 = toolkit.createSlice({
|
|
614
615
|
name: 'gen3Apps',
|
|
615
|
-
initialState: initialState$
|
|
616
|
+
initialState: initialState$7,
|
|
616
617
|
reducers: {
|
|
617
618
|
addGen3AppMetadata: (state, action)=>{
|
|
618
619
|
const { name, requiredEntityTypes } = action.payload;
|
|
@@ -643,13 +644,13 @@ const selectGen3AppByName = (appName)=>lookupGen3App(appName); // TODO: memoize
|
|
|
643
644
|
Modals["GeneralErrorModal"] = "GeneralErrorModal";
|
|
644
645
|
return Modals;
|
|
645
646
|
}({});
|
|
646
|
-
const initialState$
|
|
647
|
+
const initialState$6 = {
|
|
647
648
|
currentModal: null
|
|
648
649
|
};
|
|
649
650
|
//Creates a modal slice for tracking showModal and hideModal state.
|
|
650
651
|
const slice$1 = toolkit.createSlice({
|
|
651
652
|
name: 'modals',
|
|
652
|
-
initialState: initialState$
|
|
653
|
+
initialState: initialState$6,
|
|
653
654
|
reducers: {
|
|
654
655
|
showModal: (state, action)=>{
|
|
655
656
|
state.currentModal = action.payload.modal;
|
|
@@ -722,7 +723,7 @@ const getTimestamp = ()=>{
|
|
|
722
723
|
};
|
|
723
724
|
|
|
724
725
|
const NO_WORKSPACE_ID = 'none';
|
|
725
|
-
const initialState$
|
|
726
|
+
const initialState$5 = {
|
|
726
727
|
id: NO_WORKSPACE_ID,
|
|
727
728
|
status: WorkspaceStatus.NotFound,
|
|
728
729
|
requestedStatus: RequestedWorkspaceStatus.Unset,
|
|
@@ -730,7 +731,7 @@ const initialState$4 = {
|
|
|
730
731
|
};
|
|
731
732
|
const slice = toolkit.createSlice({
|
|
732
733
|
name: 'ActiveWorkspace',
|
|
733
|
-
initialState: initialState$
|
|
734
|
+
initialState: initialState$5,
|
|
734
735
|
reducers: {
|
|
735
736
|
setActiveWorkspaceId: (state, action)=>{
|
|
736
737
|
state = {
|
|
@@ -772,6 +773,25 @@ const selectActiveWorkspaceStatus = (state)=>state.activeWorkspace.status;
|
|
|
772
773
|
const selectRequestedWorkspaceStatus = (state)=>state.activeWorkspace.requestedStatus;
|
|
773
774
|
const selectRequestedWorkspaceStatusTimestamp = (state)=>state.activeWorkspace.requestedStatusTimestamp;
|
|
774
775
|
|
|
776
|
+
const cartAdapter = toolkit.createEntityAdapter({
|
|
777
|
+
selectId: (item)=>item.id
|
|
778
|
+
});
|
|
779
|
+
const initialState$4 = cartAdapter.getInitialState({});
|
|
780
|
+
const cartSlice = toolkit.createSlice({
|
|
781
|
+
name: 'cart',
|
|
782
|
+
initialState: initialState$4,
|
|
783
|
+
reducers: {
|
|
784
|
+
addItemsToCart: cartAdapter.addMany,
|
|
785
|
+
removeItemsFromCart: cartAdapter.removeMany
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
const cartReducer = cartSlice.reducer;
|
|
789
|
+
const { addItemsToCart, removeItemsFromCart } = cartSlice.actions;
|
|
790
|
+
|
|
791
|
+
const { selectById: selectCartItem, selectIds: selectCartItems, selectAll: selectCart, selectTotal: selectCartCount } = cartAdapter.getSelectors((state)=>state.cart);
|
|
792
|
+
|
|
793
|
+
const cartReducerPath = 'cart';
|
|
794
|
+
|
|
775
795
|
/**
|
|
776
796
|
* Creates a base class core API for guppy API calls.
|
|
777
797
|
* @returns: guppy core API with guppyAPIFetch base query
|
|
@@ -829,578 +849,176 @@ const guppyAPISliceMiddleware = guppyApi.middleware;
|
|
|
829
849
|
const guppyApiSliceReducerPath = guppyApi.reducerPath;
|
|
830
850
|
const guppyApiReducer = guppyApi.reducer;
|
|
831
851
|
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
hour12: false
|
|
835
|
-
}).replace(',', '')}`;
|
|
836
|
-
const isNameUnique = (entities, name, excludeId)=>{
|
|
837
|
-
const trimmedName = name.trim();
|
|
838
|
-
if (!trimmedName) return false;
|
|
839
|
-
return !entities.some((cohort)=>cohort && cohort.id !== excludeId && cohort.name.trim().toLowerCase() === trimmedName.toLowerCase());
|
|
852
|
+
const isOperationWithField = (operation)=>{
|
|
853
|
+
return operation?.field !== undefined;
|
|
840
854
|
};
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
return
|
|
855
|
+
const isOperatorWithFieldAndArrayOfOperands = (operation)=>{
|
|
856
|
+
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
|
|
857
|
+
) {
|
|
858
|
+
const { operator } = operation.operator;
|
|
859
|
+
return operator === 'in' || operator === 'exclude' || operator === 'excludeifany';
|
|
860
|
+
}
|
|
861
|
+
return false;
|
|
862
|
+
};
|
|
863
|
+
const extractFilterValue = (op)=>{
|
|
864
|
+
const valueExtractorHandler = new ValueExtractorHandler();
|
|
865
|
+
return handleOperation(valueExtractorHandler, op);
|
|
866
|
+
};
|
|
867
|
+
const extractEnumFilterValue = (op)=>{
|
|
868
|
+
const enumValueExtractorHandler = new EnumValueExtractorHandler();
|
|
869
|
+
const results = handleOperation(enumValueExtractorHandler, op);
|
|
870
|
+
return results ?? [];
|
|
871
|
+
};
|
|
872
|
+
const assertNever = (x)=>{
|
|
873
|
+
throw Error(`Exhaustive comparison did not handle: ${x}`);
|
|
874
|
+
};
|
|
875
|
+
const handleOperation = (handler, op)=>{
|
|
876
|
+
switch(op.operator){
|
|
877
|
+
case '=':
|
|
878
|
+
return handler.handleEquals(op);
|
|
879
|
+
case '!=':
|
|
880
|
+
return handler.handleNotEquals(op);
|
|
881
|
+
case '<':
|
|
882
|
+
return handler.handleLessThan(op);
|
|
883
|
+
case '<=':
|
|
884
|
+
return handler.handleLessThanOrEquals(op);
|
|
885
|
+
case '>':
|
|
886
|
+
return handler.handleGreaterThan(op);
|
|
887
|
+
case '>=':
|
|
888
|
+
return handler.handleGreaterThanOrEquals(op);
|
|
889
|
+
case 'and':
|
|
890
|
+
return handler.handleIntersection(op);
|
|
891
|
+
case 'or':
|
|
892
|
+
return handler.handleUnion(op);
|
|
893
|
+
case 'nested':
|
|
894
|
+
return handler.handleNestedFilter(op);
|
|
895
|
+
case 'in':
|
|
896
|
+
case 'includes':
|
|
897
|
+
return handler.handleIncludes(op);
|
|
898
|
+
case 'excludeifany':
|
|
899
|
+
return handler.handleExcludeIfAny(op);
|
|
900
|
+
case 'excludes':
|
|
901
|
+
return handler.handleExcludes(op);
|
|
902
|
+
case 'exists':
|
|
903
|
+
return handler.handleExists(op);
|
|
904
|
+
case 'missing':
|
|
905
|
+
return handler.handleMissing(op);
|
|
906
|
+
default:
|
|
907
|
+
return assertNever(op);
|
|
846
908
|
}
|
|
847
|
-
// Find a unique name by appending numbers
|
|
848
|
-
let counter = 1;
|
|
849
|
-
let uniqueName;
|
|
850
|
-
do {
|
|
851
|
-
uniqueName = `${trimmedBaseName} (${counter})`;
|
|
852
|
-
counter++;
|
|
853
|
-
}while (!isNameUnique(entities, uniqueName))
|
|
854
|
-
return uniqueName;
|
|
855
909
|
};
|
|
856
|
-
|
|
857
910
|
/**
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return
|
|
867
|
-
name: newName,
|
|
868
|
-
id: newId,
|
|
869
|
-
filters: filters ?? {},
|
|
870
|
-
modified: false,
|
|
871
|
-
saved: false,
|
|
872
|
-
createdDatetime: ts,
|
|
873
|
-
modifiedDatetime: ts,
|
|
874
|
-
counts: {}
|
|
875
|
-
};
|
|
911
|
+
* Return true if a FilterSet's root value is an empty object
|
|
912
|
+
* @param fs - FilterSet to test
|
|
913
|
+
*/ const isFilterEmpty = (fs)=>lodash.isEqual({}, fs);
|
|
914
|
+
/**
|
|
915
|
+
* Type guard to check if an object is a GQLIntersection
|
|
916
|
+
* @param value - The value to check
|
|
917
|
+
* @returns True if the value is a GQLIntersection
|
|
918
|
+
*/ const isGQLIntersection = (value)=>{
|
|
919
|
+
return typeof value === 'object' && value !== null && 'and' in value && Array.isArray(value.and);
|
|
876
920
|
};
|
|
877
|
-
const nanoid = nanoid$1.customAlphabet('1234567890abcdef', 16);
|
|
878
|
-
const createCohortId = ()=>nanoid();
|
|
879
|
-
const cohortsAdapter = toolkit.createEntityAdapter({
|
|
880
|
-
sortComparer: (a, b)=>{
|
|
881
|
-
if (a.modifiedDatetime <= b.modifiedDatetime) return 1;
|
|
882
|
-
else return -1;
|
|
883
|
-
},
|
|
884
|
-
selectId: (cohort)=>cohort.id
|
|
885
|
-
});
|
|
886
|
-
// Create an initial unsaved cohort
|
|
887
|
-
const initialCohort = newCohort({
|
|
888
|
-
customName: DEFAULT_COHORT_NAME
|
|
889
|
-
});
|
|
890
|
-
const emptyInitialState = cohortsAdapter.getInitialState({
|
|
891
|
-
currentCohortId: initialCohort.id,
|
|
892
|
-
message: undefined
|
|
893
|
-
});
|
|
894
|
-
// Set the initial cohort in the adapter state
|
|
895
|
-
const initialState$3 = cohortsAdapter.setOne(emptyInitialState, initialCohort);
|
|
896
|
-
const getCurrentCohortId = (state)=>state.currentCohortId;
|
|
897
921
|
/**
|
|
898
|
-
*
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
922
|
+
* Type guard to check if an object is a GQLIntersection
|
|
923
|
+
* @param value - The value to check
|
|
924
|
+
* @returns True if the value is a GQLIntersection
|
|
925
|
+
*/ const isGQLUnion = (value)=>{
|
|
926
|
+
return typeof value === 'object' && value !== null && 'or' in value && Array.isArray(value.or);
|
|
927
|
+
};
|
|
928
|
+
class ToGqlHandler {
|
|
929
|
+
constructor(){
|
|
930
|
+
this.handleEquals = (op)=>({
|
|
931
|
+
'=': {
|
|
932
|
+
[op.field]: op.operand
|
|
933
|
+
}
|
|
909
934
|
});
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
updateCohortName: (state, action)=>{
|
|
914
|
-
const { id, name } = action.payload;
|
|
915
|
-
cohortsAdapter.updateOne(state, {
|
|
916
|
-
id: id,
|
|
917
|
-
changes: {
|
|
918
|
-
name: name,
|
|
919
|
-
modified: true,
|
|
920
|
-
modifiedDatetime: new Date().toISOString()
|
|
935
|
+
this.handleNotEquals = (op)=>({
|
|
936
|
+
'!=': {
|
|
937
|
+
[op.field]: op.operand
|
|
921
938
|
}
|
|
922
939
|
});
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
const removedCohortName = state.entities[cohortId].name;
|
|
927
|
-
const totalCohorts = Object.keys(state.entities).length;
|
|
928
|
-
if (totalCohorts <= 1) {
|
|
929
|
-
cohortsAdapter.removeAll(state);
|
|
930
|
-
const defaultCohort = newCohort({
|
|
931
|
-
filters: {},
|
|
932
|
-
customName: DEFAULT_COHORT_NAME
|
|
933
|
-
});
|
|
934
|
-
cohortsAdapter.addOne(state, defaultCohort);
|
|
935
|
-
state.currentCohortId = defaultCohort.id;
|
|
936
|
-
if (action?.payload.shouldShowMessage) {
|
|
937
|
-
state.message = [
|
|
938
|
-
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
939
|
-
];
|
|
940
|
+
this.handleLessThan = (op)=>({
|
|
941
|
+
'<': {
|
|
942
|
+
[op.field]: op.operand
|
|
940
943
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
if (state.currentCohortId === cohortId) {
|
|
946
|
-
const remainingIds = Object.keys(state.entities);
|
|
947
|
-
state.currentCohortId = remainingIds[0];
|
|
948
|
-
}
|
|
949
|
-
if (action?.payload.shouldShowMessage) {
|
|
950
|
-
state.message = [
|
|
951
|
-
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
952
|
-
];
|
|
953
|
-
}
|
|
954
|
-
},
|
|
955
|
-
// adds a filter to the cohort filter set at the given index
|
|
956
|
-
updateCohortFilter: (state, action)=>{
|
|
957
|
-
const { index, field, filter } = action.payload;
|
|
958
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
959
|
-
if (!state.entities[currentCohortId]) {
|
|
960
|
-
return;
|
|
961
|
-
}
|
|
962
|
-
cohortsAdapter.updateOne(state, {
|
|
963
|
-
id: currentCohortId,
|
|
964
|
-
changes: {
|
|
965
|
-
filters: {
|
|
966
|
-
...state.entities[currentCohortId].filters,
|
|
967
|
-
[index]: {
|
|
968
|
-
mode: state.entities[currentCohortId]?.filters[index]?.mode ?? 'and',
|
|
969
|
-
root: {
|
|
970
|
-
...state.entities[currentCohortId]?.filters[index]?.root ?? {},
|
|
971
|
-
[field]: filter
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
},
|
|
975
|
-
modified: true,
|
|
976
|
-
modifiedDatetime: new Date().toISOString()
|
|
944
|
+
});
|
|
945
|
+
this.handleLessThanOrEquals = (op)=>({
|
|
946
|
+
'<=': {
|
|
947
|
+
[op.field]: op.operand
|
|
977
948
|
}
|
|
978
949
|
});
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
983
|
-
if (!state.entities[currentCohortId]) {
|
|
984
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
985
|
-
return;
|
|
986
|
-
}
|
|
987
|
-
cohortsAdapter.updateOne(state, {
|
|
988
|
-
id: currentCohortId,
|
|
989
|
-
changes: {
|
|
990
|
-
filters: {
|
|
991
|
-
...state.entities[currentCohortId].filters,
|
|
992
|
-
[index]: filters
|
|
993
|
-
},
|
|
994
|
-
modified: true,
|
|
995
|
-
modifiedDatetime: new Date().toISOString()
|
|
950
|
+
this.handleGreaterThan = (op)=>({
|
|
951
|
+
'>': {
|
|
952
|
+
[op.field]: op.operand
|
|
996
953
|
}
|
|
997
954
|
});
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
if (!state.entities[currentCohortId]) {
|
|
1002
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
cohortsAdapter.updateOne(state, {
|
|
1006
|
-
id: currentCohortId,
|
|
1007
|
-
changes: {
|
|
1008
|
-
filters: action.payload.filters,
|
|
1009
|
-
modified: true,
|
|
1010
|
-
modifiedDatetime: new Date().toISOString()
|
|
955
|
+
this.handleGreaterThanOrEquals = (op)=>({
|
|
956
|
+
'>=': {
|
|
957
|
+
[op.field]: op.operand
|
|
1011
958
|
}
|
|
1012
959
|
});
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const { index, field } = action.payload;
|
|
1017
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
1018
|
-
if (!state.entities[currentCohortId]) {
|
|
1019
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1020
|
-
return;
|
|
1021
|
-
}
|
|
1022
|
-
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1023
|
-
if (!filters) {
|
|
1024
|
-
return;
|
|
1025
|
-
}
|
|
1026
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1027
|
-
const { [field]: _a, ...updated } = filters;
|
|
1028
|
-
cohortsAdapter.updateOne(state, {
|
|
1029
|
-
id: currentCohortId,
|
|
1030
|
-
changes: {
|
|
1031
|
-
filters: {
|
|
1032
|
-
...state.entities[currentCohortId]?.filters,
|
|
1033
|
-
[index]: {
|
|
1034
|
-
mode: state.entities[currentCohortId].filters[index].mode,
|
|
1035
|
-
root: updated
|
|
1036
|
-
}
|
|
1037
|
-
},
|
|
1038
|
-
modified: true,
|
|
1039
|
-
modifiedDatetime: new Date().toISOString()
|
|
960
|
+
this.handleIncludes = (op)=>({
|
|
961
|
+
in: {
|
|
962
|
+
[op.field]: op.operands
|
|
1040
963
|
}
|
|
1041
964
|
});
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
const currentCohort = state.entities[currentCohortId];
|
|
1046
|
-
const newName = generateUniqueName(Object.values(state.entities), currentCohort.name);
|
|
1047
|
-
const duplicatedCohort = newCohort({
|
|
1048
|
-
filters: {
|
|
1049
|
-
...currentCohort.filters
|
|
1050
|
-
},
|
|
1051
|
-
customName: newName
|
|
1052
|
-
});
|
|
1053
|
-
cohortsAdapter.addOne(state, {
|
|
1054
|
-
...duplicatedCohort,
|
|
1055
|
-
counts: {
|
|
1056
|
-
...currentCohort.counts
|
|
965
|
+
this.handleExcludes = (op)=>({
|
|
966
|
+
exclude: {
|
|
967
|
+
[op.field]: op.operands
|
|
1057
968
|
}
|
|
1058
969
|
});
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
clearCohortFilters: (state, action)=>{
|
|
1063
|
-
const { index } = action.payload;
|
|
1064
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
1065
|
-
if (!state.entities[currentCohortId]) {
|
|
1066
|
-
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1067
|
-
return;
|
|
1068
|
-
}
|
|
1069
|
-
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1070
|
-
if (!filters) {
|
|
1071
|
-
return;
|
|
1072
|
-
}
|
|
1073
|
-
cohortsAdapter.updateOne(state, {
|
|
1074
|
-
id: currentCohortId,
|
|
1075
|
-
changes: {
|
|
1076
|
-
filters: {
|
|
1077
|
-
...state.entities[currentCohortId]?.filters,
|
|
1078
|
-
[index]: {
|
|
1079
|
-
mode: 'and',
|
|
1080
|
-
root: {}
|
|
1081
|
-
}
|
|
1082
|
-
},
|
|
1083
|
-
modified: true,
|
|
1084
|
-
modifiedDatetime: new Date().toISOString()
|
|
970
|
+
this.handleExcludeIfAny = (op)=>({
|
|
971
|
+
excludeifany: {
|
|
972
|
+
[op.field]: op.operands
|
|
1085
973
|
}
|
|
1086
974
|
});
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
const currentCohortId = getCurrentCohortId(state);
|
|
1090
|
-
const currentCohort = state.entities[currentCohortId];
|
|
1091
|
-
cohortsAdapter.updateOne(state, {
|
|
1092
|
-
id: currentCohortId,
|
|
1093
|
-
changes: {
|
|
1094
|
-
counts: {
|
|
1095
|
-
...currentCohort.counts,
|
|
1096
|
-
...action.payload
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
975
|
+
this.handleIntersection = (op)=>({
|
|
976
|
+
and: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
1099
977
|
});
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
changes: {
|
|
1107
|
-
counts: {
|
|
1108
|
-
...cohort.counts,
|
|
1109
|
-
...{
|
|
1110
|
-
[index]: counts
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
978
|
+
this.handleUnion = (op)=>({
|
|
979
|
+
or: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
980
|
+
});
|
|
981
|
+
this.handleMissing = (op)=>({
|
|
982
|
+
is: {
|
|
983
|
+
[op.field]: 'MISSING'
|
|
1113
984
|
}
|
|
1114
985
|
});
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
},
|
|
1119
|
-
/** @hidden */ setCohortList: (state, action)=>{
|
|
1120
|
-
if (!action.payload) {
|
|
1121
|
-
cohortsAdapter.removeMany(state, state.ids);
|
|
1122
|
-
} else {
|
|
1123
|
-
cohortsAdapter.upsertMany(state, [
|
|
1124
|
-
...action.payload
|
|
1125
|
-
]);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
});
|
|
1130
|
-
/**
|
|
1131
|
-
* Returns the selectors for the cohorts EntityAdapter
|
|
1132
|
-
* @param state - the CoreState
|
|
1133
|
-
*
|
|
1134
|
-
* @hidden
|
|
1135
|
-
*/ const cohortSelectors = cohortsAdapter.getSelectors((state)=>state.cohorts.cohortManager);
|
|
1136
|
-
// Filter actions: addFilter, removeFilter, updateFilter
|
|
1137
|
-
const { createNewCohort, updateCohortFilter, setCohortFilter, setCohortIndexFilters, duplicateCohort, removeCohortFilter, clearCohortFilters, removeCohort, setCurrentCohortId, updateCohortName, updateCohortCounts, updateCohortIndexCountById, setCohortList } = cohortManagerSlice.actions;
|
|
1138
|
-
const cohortReducer = cohortManagerSlice.reducer;
|
|
1139
|
-
|
|
1140
|
-
const initialState$2 = {};
|
|
1141
|
-
const expandSlice$1 = toolkit.createSlice({
|
|
1142
|
-
name: 'CohortBuilder/filterExpand',
|
|
1143
|
-
initialState: initialState$2,
|
|
1144
|
-
reducers: {
|
|
1145
|
-
toggleCohortBuilderCategoryFilter: (state, action)=>{
|
|
1146
|
-
return {
|
|
1147
|
-
...state,
|
|
1148
|
-
[action.payload.index]: {
|
|
1149
|
-
...state[action.payload.index],
|
|
1150
|
-
[action.payload.field]: action.payload.expanded
|
|
986
|
+
this.handleExists = (op)=>({
|
|
987
|
+
not: {
|
|
988
|
+
[op.field]: op?.operand ?? null
|
|
1151
989
|
}
|
|
1152
|
-
};
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
return {
|
|
1156
|
-
...state,
|
|
1157
|
-
[action.payload.index]: Object.keys(state[action.payload.index]).reduce((acc, k)=>{
|
|
1158
|
-
acc[k] = action.payload.expand;
|
|
1159
|
-
return acc;
|
|
1160
|
-
}, {})
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
});
|
|
1165
|
-
const cohortBuilderFiltersExpandedReducer = expandSlice$1.reducer;
|
|
1166
|
-
const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = expandSlice$1.actions;
|
|
1167
|
-
const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
|
|
1168
|
-
const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
|
|
1169
|
-
|
|
1170
|
-
const initialState$1 = {};
|
|
1171
|
-
const expandSlice = toolkit.createSlice({
|
|
1172
|
-
name: 'CohortBuilder/filterCombineMode',
|
|
1173
|
-
initialState: initialState$1,
|
|
1174
|
-
reducers: {
|
|
1175
|
-
setCohortFilterCombineMode: (state, action)=>{
|
|
990
|
+
});
|
|
991
|
+
this.handleNestedFilter = (op)=>{
|
|
992
|
+
const child = convertFilterToGqlFilter(op.operand);
|
|
1176
993
|
return {
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
...
|
|
1180
|
-
[action.payload.field]: action.payload.mode
|
|
994
|
+
nested: {
|
|
995
|
+
path: op.path,
|
|
996
|
+
...child
|
|
1181
997
|
}
|
|
1182
998
|
};
|
|
1183
|
-
}
|
|
999
|
+
};
|
|
1184
1000
|
}
|
|
1185
|
-
}
|
|
1186
|
-
const
|
|
1187
|
-
const
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
const initialState = {
|
|
1191
|
-
shouldShareFilters: false,
|
|
1192
|
-
sharedFiltersMap: {}
|
|
1001
|
+
}
|
|
1002
|
+
const convertFilterToGqlFilter = (filter)=>{
|
|
1003
|
+
const handler = new ToGqlHandler();
|
|
1004
|
+
return handleOperation(handler, filter);
|
|
1193
1005
|
};
|
|
1194
|
-
const
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
field
|
|
1211
|
-
];
|
|
1212
|
-
const { setShouldShareFilters, setSharedFilters } = cohortSharedFiltersSlice.actions;
|
|
1213
|
-
const cohortSharedFiltersReducer = cohortSharedFiltersSlice.reducer;
|
|
1214
|
-
|
|
1215
|
-
const cohortReducers = toolkit.combineReducers({
|
|
1216
|
-
filtersExpanded: cohortBuilderFiltersExpandedReducer,
|
|
1217
|
-
filtersCombineMode: cohortBuilderFiltersCombineModeReducer,
|
|
1218
|
-
sharedFilters: cohortSharedFiltersReducer,
|
|
1219
|
-
cohortManager: cohortReducer
|
|
1220
|
-
});
|
|
1221
|
-
|
|
1222
|
-
const rootReducer = toolkit.combineReducers({
|
|
1223
|
-
gen3Services: gen3ServicesReducer,
|
|
1224
|
-
user: userReducer,
|
|
1225
|
-
gen3Apps: gen3AppReducer,
|
|
1226
|
-
drsHostnames: drsHostnamesReducer,
|
|
1227
|
-
modals: modalReducer,
|
|
1228
|
-
cohorts: cohortReducers,
|
|
1229
|
-
activeWorkspace: activeWorkspaceReducer,
|
|
1230
|
-
[guppyApiSliceReducerPath]: guppyApiReducer,
|
|
1231
|
-
[userAuthApiReducerPath]: userAuthApiReducer
|
|
1232
|
-
});
|
|
1233
|
-
|
|
1234
|
-
const isOperationWithField = (operation)=>{
|
|
1235
|
-
return operation?.field !== undefined;
|
|
1236
|
-
};
|
|
1237
|
-
const isOperatorWithFieldAndArrayOfOperands = (operation)=>{
|
|
1238
|
-
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
|
|
1239
|
-
) {
|
|
1240
|
-
const { operator } = operation.operator;
|
|
1241
|
-
return operator === 'in' || operator === 'exclude' || operator === 'excludeifany';
|
|
1242
|
-
}
|
|
1243
|
-
return false;
|
|
1244
|
-
};
|
|
1245
|
-
const extractFilterValue = (op)=>{
|
|
1246
|
-
const valueExtractorHandler = new ValueExtractorHandler();
|
|
1247
|
-
return handleOperation(valueExtractorHandler, op);
|
|
1248
|
-
};
|
|
1249
|
-
const extractEnumFilterValue = (op)=>{
|
|
1250
|
-
const enumValueExtractorHandler = new EnumValueExtractorHandler();
|
|
1251
|
-
const results = handleOperation(enumValueExtractorHandler, op);
|
|
1252
|
-
return results ?? [];
|
|
1253
|
-
};
|
|
1254
|
-
const assertNever = (x)=>{
|
|
1255
|
-
throw Error(`Exhaustive comparison did not handle: ${x}`);
|
|
1256
|
-
};
|
|
1257
|
-
const handleOperation = (handler, op)=>{
|
|
1258
|
-
switch(op.operator){
|
|
1259
|
-
case '=':
|
|
1260
|
-
return handler.handleEquals(op);
|
|
1261
|
-
case '!=':
|
|
1262
|
-
return handler.handleNotEquals(op);
|
|
1263
|
-
case '<':
|
|
1264
|
-
return handler.handleLessThan(op);
|
|
1265
|
-
case '<=':
|
|
1266
|
-
return handler.handleLessThanOrEquals(op);
|
|
1267
|
-
case '>':
|
|
1268
|
-
return handler.handleGreaterThan(op);
|
|
1269
|
-
case '>=':
|
|
1270
|
-
return handler.handleGreaterThanOrEquals(op);
|
|
1271
|
-
case 'and':
|
|
1272
|
-
return handler.handleIntersection(op);
|
|
1273
|
-
case 'or':
|
|
1274
|
-
return handler.handleUnion(op);
|
|
1275
|
-
case 'nested':
|
|
1276
|
-
return handler.handleNestedFilter(op);
|
|
1277
|
-
case 'in':
|
|
1278
|
-
case 'includes':
|
|
1279
|
-
return handler.handleIncludes(op);
|
|
1280
|
-
case 'excludeifany':
|
|
1281
|
-
return handler.handleExcludeIfAny(op);
|
|
1282
|
-
case 'excludes':
|
|
1283
|
-
return handler.handleExcludes(op);
|
|
1284
|
-
case 'exists':
|
|
1285
|
-
return handler.handleExists(op);
|
|
1286
|
-
case 'missing':
|
|
1287
|
-
return handler.handleMissing(op);
|
|
1288
|
-
default:
|
|
1289
|
-
return assertNever(op);
|
|
1290
|
-
}
|
|
1291
|
-
};
|
|
1292
|
-
/**
|
|
1293
|
-
* Return true if a FilterSet's root value is an empty object
|
|
1294
|
-
* @param fs - FilterSet to test
|
|
1295
|
-
*/ const isFilterEmpty = (fs)=>lodash.isEqual({}, fs);
|
|
1296
|
-
/**
|
|
1297
|
-
* Type guard to check if an object is a GQLIntersection
|
|
1298
|
-
* @param value - The value to check
|
|
1299
|
-
* @returns True if the value is a GQLIntersection
|
|
1300
|
-
*/ const isGQLIntersection = (value)=>{
|
|
1301
|
-
return typeof value === 'object' && value !== null && 'and' in value && Array.isArray(value.and);
|
|
1302
|
-
};
|
|
1303
|
-
/**
|
|
1304
|
-
* Type guard to check if an object is a GQLIntersection
|
|
1305
|
-
* @param value - The value to check
|
|
1306
|
-
* @returns True if the value is a GQLIntersection
|
|
1307
|
-
*/ const isGQLUnion = (value)=>{
|
|
1308
|
-
return typeof value === 'object' && value !== null && 'or' in value && Array.isArray(value.or);
|
|
1309
|
-
};
|
|
1310
|
-
class ToGqlHandler {
|
|
1311
|
-
constructor(){
|
|
1312
|
-
this.handleEquals = (op)=>({
|
|
1313
|
-
'=': {
|
|
1314
|
-
[op.field]: op.operand
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1317
|
-
this.handleNotEquals = (op)=>({
|
|
1318
|
-
'!=': {
|
|
1319
|
-
[op.field]: op.operand
|
|
1320
|
-
}
|
|
1321
|
-
});
|
|
1322
|
-
this.handleLessThan = (op)=>({
|
|
1323
|
-
'<': {
|
|
1324
|
-
[op.field]: op.operand
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
this.handleLessThanOrEquals = (op)=>({
|
|
1328
|
-
'<=': {
|
|
1329
|
-
[op.field]: op.operand
|
|
1330
|
-
}
|
|
1331
|
-
});
|
|
1332
|
-
this.handleGreaterThan = (op)=>({
|
|
1333
|
-
'>': {
|
|
1334
|
-
[op.field]: op.operand
|
|
1335
|
-
}
|
|
1336
|
-
});
|
|
1337
|
-
this.handleGreaterThanOrEquals = (op)=>({
|
|
1338
|
-
'>=': {
|
|
1339
|
-
[op.field]: op.operand
|
|
1340
|
-
}
|
|
1341
|
-
});
|
|
1342
|
-
this.handleIncludes = (op)=>({
|
|
1343
|
-
in: {
|
|
1344
|
-
[op.field]: op.operands
|
|
1345
|
-
}
|
|
1346
|
-
});
|
|
1347
|
-
this.handleExcludes = (op)=>({
|
|
1348
|
-
exclude: {
|
|
1349
|
-
[op.field]: op.operands
|
|
1350
|
-
}
|
|
1351
|
-
});
|
|
1352
|
-
this.handleExcludeIfAny = (op)=>({
|
|
1353
|
-
excludeifany: {
|
|
1354
|
-
[op.field]: op.operands
|
|
1355
|
-
}
|
|
1356
|
-
});
|
|
1357
|
-
this.handleIntersection = (op)=>({
|
|
1358
|
-
and: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
1359
|
-
});
|
|
1360
|
-
this.handleUnion = (op)=>({
|
|
1361
|
-
or: op.operands.map((x)=>convertFilterToGqlFilter(x))
|
|
1362
|
-
});
|
|
1363
|
-
this.handleMissing = (op)=>({
|
|
1364
|
-
is: {
|
|
1365
|
-
[op.field]: 'MISSING'
|
|
1366
|
-
}
|
|
1367
|
-
});
|
|
1368
|
-
this.handleExists = (op)=>({
|
|
1369
|
-
not: {
|
|
1370
|
-
[op.field]: op?.operand ?? null
|
|
1371
|
-
}
|
|
1372
|
-
});
|
|
1373
|
-
this.handleNestedFilter = (op)=>{
|
|
1374
|
-
const child = convertFilterToGqlFilter(op.operand);
|
|
1375
|
-
return {
|
|
1376
|
-
nested: {
|
|
1377
|
-
path: op.path,
|
|
1378
|
-
...child
|
|
1379
|
-
}
|
|
1380
|
-
};
|
|
1381
|
-
};
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
const convertFilterToGqlFilter = (filter)=>{
|
|
1385
|
-
const handler = new ToGqlHandler();
|
|
1386
|
-
return handleOperation(handler, filter);
|
|
1387
|
-
};
|
|
1388
|
-
const convertFilterSetToGqlFilter = (fs, toplevelOp = 'and')=>{
|
|
1389
|
-
const fsKeys = Object.keys(fs.root);
|
|
1390
|
-
// if no keys return undefined
|
|
1391
|
-
if (fsKeys.length === 0) return {
|
|
1392
|
-
and: []
|
|
1393
|
-
};
|
|
1394
|
-
return toplevelOp === 'and' ? {
|
|
1395
|
-
and: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
1396
|
-
} : {
|
|
1397
|
-
or: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
1398
|
-
};
|
|
1399
|
-
};
|
|
1400
|
-
const handleGqlOperation = (handler, op)=>{
|
|
1401
|
-
const operationKeys = Object.keys(op);
|
|
1402
|
-
if (operationKeys.includes('=')) {
|
|
1403
|
-
return handler.handleEquals(op);
|
|
1006
|
+
const convertFilterSetToGqlFilter = (fs, toplevelOp = 'and')=>{
|
|
1007
|
+
const fsKeys = Object.keys(fs.root);
|
|
1008
|
+
// if no keys return undefined
|
|
1009
|
+
if (fsKeys.length === 0) return {
|
|
1010
|
+
and: []
|
|
1011
|
+
};
|
|
1012
|
+
return toplevelOp === 'and' ? {
|
|
1013
|
+
and: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
1014
|
+
} : {
|
|
1015
|
+
or: fsKeys.map((key)=>convertFilterToGqlFilter(fs.root[key]))
|
|
1016
|
+
};
|
|
1017
|
+
};
|
|
1018
|
+
const handleGqlOperation = (handler, op)=>{
|
|
1019
|
+
const operationKeys = Object.keys(op);
|
|
1020
|
+
if (operationKeys.includes('=')) {
|
|
1021
|
+
return handler.handleEquals(op);
|
|
1404
1022
|
}
|
|
1405
1023
|
if (operationKeys.includes('!=')) {
|
|
1406
1024
|
return handler.handleNotEquals(op);
|
|
@@ -1677,9 +1295,17 @@ const isUnion = (value)=>{
|
|
|
1677
1295
|
const isIntersection = (value)=>{
|
|
1678
1296
|
return typeof value === 'object' && value !== null && value.operator === 'and' && Array.isArray(value.operands);
|
|
1679
1297
|
};
|
|
1298
|
+
/**
|
|
1299
|
+
* Type guard for Union or Intersection
|
|
1300
|
+
* @param o - operator to check
|
|
1301
|
+
* @category Filters
|
|
1302
|
+
*/ const isIntersectionOrUnion = (o)=>o.operator === 'and' || o.operator === 'or';
|
|
1680
1303
|
const isOperandsType = (operation)=>{
|
|
1681
1304
|
return operation?.operands !== undefined;
|
|
1682
1305
|
};
|
|
1306
|
+
const isNestedFilter = (operation)=>{
|
|
1307
|
+
return operation.operator === 'nested';
|
|
1308
|
+
};
|
|
1683
1309
|
const isIndexedFilterSetEmpty = (filters)=>Object.values(filters).every((filterSet)=>Object.keys(filterSet).length === 0);
|
|
1684
1310
|
const EmptyFilterSet = {
|
|
1685
1311
|
mode: 'and',
|
|
@@ -1749,6 +1375,437 @@ const trimFirstFieldNameToTitle = (fieldName, trim = false)=>{
|
|
|
1749
1375
|
];
|
|
1750
1376
|
};
|
|
1751
1377
|
|
|
1378
|
+
const defaultCohortNameGenerator = ()=>`Custom cohort ${new Date().toLocaleString('en-CA', {
|
|
1379
|
+
timeZone: 'America/Chicago',
|
|
1380
|
+
hour12: false
|
|
1381
|
+
}).replace(',', '')}`;
|
|
1382
|
+
const isNameUnique = (entities, name, excludeId)=>{
|
|
1383
|
+
const trimmedName = name.trim();
|
|
1384
|
+
if (!trimmedName) return false;
|
|
1385
|
+
return !entities.some((cohort)=>cohort && cohort.id !== excludeId && cohort.name.trim().toLowerCase() === trimmedName.toLowerCase());
|
|
1386
|
+
};
|
|
1387
|
+
const generateUniqueName = (entities, baseName)=>{
|
|
1388
|
+
const trimmedBaseName = baseName.trim();
|
|
1389
|
+
// If base name is unique, use it
|
|
1390
|
+
if (isNameUnique(entities, trimmedBaseName)) {
|
|
1391
|
+
return trimmedBaseName;
|
|
1392
|
+
}
|
|
1393
|
+
// Find a unique name by appending numbers
|
|
1394
|
+
let counter = 1;
|
|
1395
|
+
let uniqueName;
|
|
1396
|
+
do {
|
|
1397
|
+
uniqueName = `${trimmedBaseName} (${counter})`;
|
|
1398
|
+
counter++;
|
|
1399
|
+
}while (!isNameUnique(entities, uniqueName))
|
|
1400
|
+
return uniqueName;
|
|
1401
|
+
};
|
|
1402
|
+
/**
|
|
1403
|
+
* This function takes a FilterSet object and a prefix string as input.
|
|
1404
|
+
* It filters the root property of the FilterSet object and returns a
|
|
1405
|
+
* new FilterSet object that only contains filters with field names
|
|
1406
|
+
* that start with the specified prefix.
|
|
1407
|
+
*
|
|
1408
|
+
* @param fs - The FilterSet object to filter
|
|
1409
|
+
* @param prefix - The prefix to filter by
|
|
1410
|
+
* @returns - A new FilterSet object that only contains filters with field names that start with the specified prefix
|
|
1411
|
+
* @category Filters
|
|
1412
|
+
*/ const extractFiltersWithPrefixFromFilterSet = (fs, prefix)=>{
|
|
1413
|
+
if (fs === undefined || fs.root === undefined) {
|
|
1414
|
+
return {
|
|
1415
|
+
mode: 'and',
|
|
1416
|
+
root: {}
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
return Object.values(fs.root).reduce((acc, filter)=>{
|
|
1420
|
+
if (isIntersectionOrUnion(filter) || isNestedFilter(filter)) return acc;
|
|
1421
|
+
if (filter.field.startsWith(prefix)) {
|
|
1422
|
+
acc.root[filter.field] = filter;
|
|
1423
|
+
}
|
|
1424
|
+
return acc;
|
|
1425
|
+
}, {
|
|
1426
|
+
mode: 'and',
|
|
1427
|
+
root: {}
|
|
1428
|
+
});
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* Cohorts in Gen3 are defined as a set of filters for each index in the data.
|
|
1433
|
+
* This means one cohort id defined for all "tabs" in CohortBuilder (explorer)
|
|
1434
|
+
* Switching a cohort id means all the cohorts for the index are changed.
|
|
1435
|
+
*/ const DEFAULT_COHORT_NAME = 'Cohort';
|
|
1436
|
+
const newCohort = ({ filters = {}, customName })=>{
|
|
1437
|
+
const ts = new Date().toISOString();
|
|
1438
|
+
const newName = customName ?? defaultCohortNameGenerator();
|
|
1439
|
+
const newId = createCohortId();
|
|
1440
|
+
return {
|
|
1441
|
+
name: newName,
|
|
1442
|
+
id: newId,
|
|
1443
|
+
filters: filters ?? {},
|
|
1444
|
+
modified: false,
|
|
1445
|
+
saved: false,
|
|
1446
|
+
createdDatetime: ts,
|
|
1447
|
+
modifiedDatetime: ts,
|
|
1448
|
+
counts: {}
|
|
1449
|
+
};
|
|
1450
|
+
};
|
|
1451
|
+
const nanoid = nanoid$1.customAlphabet('1234567890abcdef', 16);
|
|
1452
|
+
const createCohortId = ()=>nanoid();
|
|
1453
|
+
const cohortsAdapter = toolkit.createEntityAdapter({
|
|
1454
|
+
sortComparer: (a, b)=>{
|
|
1455
|
+
if (a.modifiedDatetime <= b.modifiedDatetime) return 1;
|
|
1456
|
+
else return -1;
|
|
1457
|
+
},
|
|
1458
|
+
selectId: (cohort)=>cohort.id
|
|
1459
|
+
});
|
|
1460
|
+
// Create an initial unsaved cohort
|
|
1461
|
+
const initialCohort = newCohort({
|
|
1462
|
+
customName: DEFAULT_COHORT_NAME
|
|
1463
|
+
});
|
|
1464
|
+
const emptyInitialState = cohortsAdapter.getInitialState({
|
|
1465
|
+
currentCohortId: initialCohort.id,
|
|
1466
|
+
message: undefined
|
|
1467
|
+
});
|
|
1468
|
+
// Set the initial cohort in the adapter state
|
|
1469
|
+
const initialState$3 = cohortsAdapter.setOne(emptyInitialState, initialCohort);
|
|
1470
|
+
const getCurrentCohortId = (state)=>state.currentCohortId;
|
|
1471
|
+
/**
|
|
1472
|
+
* Redux slice for cohort filters
|
|
1473
|
+
*/ const cohortManagerSlice = toolkit.createSlice({
|
|
1474
|
+
name: 'cohort',
|
|
1475
|
+
initialState: initialState$3,
|
|
1476
|
+
reducers: {
|
|
1477
|
+
createNewCohort: (state, action)=>{
|
|
1478
|
+
const baseName = action.payload.name || `Cohort`;
|
|
1479
|
+
const uniqueName = generateUniqueName(Object.values(state.entities), baseName);
|
|
1480
|
+
const cohort = newCohort({
|
|
1481
|
+
filters: action.payload.filters,
|
|
1482
|
+
customName: uniqueName
|
|
1483
|
+
});
|
|
1484
|
+
cohortsAdapter.addOne(state, cohort);
|
|
1485
|
+
state.currentCohortId = cohort.id;
|
|
1486
|
+
},
|
|
1487
|
+
updateCohortName: (state, action)=>{
|
|
1488
|
+
const { id, name } = action.payload;
|
|
1489
|
+
cohortsAdapter.updateOne(state, {
|
|
1490
|
+
id: id,
|
|
1491
|
+
changes: {
|
|
1492
|
+
name: name,
|
|
1493
|
+
modified: true,
|
|
1494
|
+
modifiedDatetime: new Date().toISOString()
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
},
|
|
1498
|
+
removeCohort: (state, action)=>{
|
|
1499
|
+
const { id: cohortId } = action.payload;
|
|
1500
|
+
const removedCohortName = state.entities[cohortId].name;
|
|
1501
|
+
const totalCohorts = Object.keys(state.entities).length;
|
|
1502
|
+
if (totalCohorts <= 1) {
|
|
1503
|
+
cohortsAdapter.removeAll(state);
|
|
1504
|
+
const defaultCohort = newCohort({
|
|
1505
|
+
filters: {},
|
|
1506
|
+
customName: DEFAULT_COHORT_NAME
|
|
1507
|
+
});
|
|
1508
|
+
cohortsAdapter.addOne(state, defaultCohort);
|
|
1509
|
+
state.currentCohortId = defaultCohort.id;
|
|
1510
|
+
if (action?.payload.shouldShowMessage) {
|
|
1511
|
+
state.message = [
|
|
1512
|
+
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
1513
|
+
];
|
|
1514
|
+
}
|
|
1515
|
+
return;
|
|
1516
|
+
}
|
|
1517
|
+
cohortsAdapter.removeOne(state, cohortId);
|
|
1518
|
+
// deleted the current cohort so set to the most recent cohort
|
|
1519
|
+
if (state.currentCohortId === cohortId) {
|
|
1520
|
+
const remainingIds = Object.keys(state.entities);
|
|
1521
|
+
state.currentCohortId = remainingIds[0];
|
|
1522
|
+
}
|
|
1523
|
+
if (action?.payload.shouldShowMessage) {
|
|
1524
|
+
state.message = [
|
|
1525
|
+
`deleteCohort|${removedCohortName}|${state.currentCohortId}`
|
|
1526
|
+
];
|
|
1527
|
+
}
|
|
1528
|
+
},
|
|
1529
|
+
// adds a filter to the cohort filter set at the given index
|
|
1530
|
+
updateCohortFilter: (state, action)=>{
|
|
1531
|
+
const { index, field, filter } = action.payload;
|
|
1532
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1533
|
+
if (!state.entities[currentCohortId]) {
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
cohortsAdapter.updateOne(state, {
|
|
1537
|
+
id: currentCohortId,
|
|
1538
|
+
changes: {
|
|
1539
|
+
filters: {
|
|
1540
|
+
...state.entities[currentCohortId].filters,
|
|
1541
|
+
[index]: {
|
|
1542
|
+
mode: state.entities[currentCohortId]?.filters[index]?.mode ?? 'and',
|
|
1543
|
+
root: {
|
|
1544
|
+
...state.entities[currentCohortId]?.filters[index]?.root ?? {},
|
|
1545
|
+
[field]: filter
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
},
|
|
1549
|
+
modified: true,
|
|
1550
|
+
modifiedDatetime: new Date().toISOString()
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
},
|
|
1554
|
+
setCohortFilter: (state, action)=>{
|
|
1555
|
+
const { index, filters } = action.payload;
|
|
1556
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1557
|
+
if (!state.entities[currentCohortId]) {
|
|
1558
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1561
|
+
cohortsAdapter.updateOne(state, {
|
|
1562
|
+
id: currentCohortId,
|
|
1563
|
+
changes: {
|
|
1564
|
+
filters: {
|
|
1565
|
+
...state.entities[currentCohortId].filters,
|
|
1566
|
+
[index]: filters
|
|
1567
|
+
},
|
|
1568
|
+
modified: true,
|
|
1569
|
+
modifiedDatetime: new Date().toISOString()
|
|
1570
|
+
}
|
|
1571
|
+
});
|
|
1572
|
+
},
|
|
1573
|
+
setCohortIndexFilters: (state, action)=>{
|
|
1574
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1575
|
+
if (!state.entities[currentCohortId]) {
|
|
1576
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1579
|
+
cohortsAdapter.updateOne(state, {
|
|
1580
|
+
id: currentCohortId,
|
|
1581
|
+
changes: {
|
|
1582
|
+
filters: action.payload.filters,
|
|
1583
|
+
modified: true,
|
|
1584
|
+
modifiedDatetime: new Date().toISOString()
|
|
1585
|
+
}
|
|
1586
|
+
});
|
|
1587
|
+
},
|
|
1588
|
+
// removes a filter to the cohort filter set at the given index
|
|
1589
|
+
removeCohortFilter: (state, action)=>{
|
|
1590
|
+
const { index, field } = action.payload;
|
|
1591
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1592
|
+
if (!state.entities[currentCohortId]) {
|
|
1593
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1597
|
+
if (!filters) {
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1601
|
+
const { [field]: _a, ...updated } = filters;
|
|
1602
|
+
cohortsAdapter.updateOne(state, {
|
|
1603
|
+
id: currentCohortId,
|
|
1604
|
+
changes: {
|
|
1605
|
+
filters: {
|
|
1606
|
+
...state.entities[currentCohortId]?.filters,
|
|
1607
|
+
[index]: {
|
|
1608
|
+
mode: state.entities[currentCohortId].filters[index].mode,
|
|
1609
|
+
root: updated
|
|
1610
|
+
}
|
|
1611
|
+
},
|
|
1612
|
+
modified: true,
|
|
1613
|
+
modifiedDatetime: new Date().toISOString()
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
},
|
|
1617
|
+
duplicateCohort: (state)=>{
|
|
1618
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1619
|
+
const currentCohort = state.entities[currentCohortId];
|
|
1620
|
+
const newName = generateUniqueName(Object.values(state.entities), currentCohort.name);
|
|
1621
|
+
const duplicatedCohort = newCohort({
|
|
1622
|
+
filters: {
|
|
1623
|
+
...currentCohort.filters
|
|
1624
|
+
},
|
|
1625
|
+
customName: newName
|
|
1626
|
+
});
|
|
1627
|
+
cohortsAdapter.addOne(state, {
|
|
1628
|
+
...duplicatedCohort,
|
|
1629
|
+
counts: {
|
|
1630
|
+
...currentCohort.counts
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
state.currentCohortId = duplicatedCohort.id;
|
|
1634
|
+
},
|
|
1635
|
+
// removes all filters from the cohort filter set at the given index
|
|
1636
|
+
clearCohortFilters: (state, action)=>{
|
|
1637
|
+
const { index } = action.payload;
|
|
1638
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1639
|
+
if (!state.entities[currentCohortId]) {
|
|
1640
|
+
console.error(`no cohort with id=${currentCohortId} defined`);
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
const filters = state.entities[currentCohortId]?.filters[index]?.root;
|
|
1644
|
+
if (!filters) {
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
cohortsAdapter.updateOne(state, {
|
|
1648
|
+
id: currentCohortId,
|
|
1649
|
+
changes: {
|
|
1650
|
+
filters: {
|
|
1651
|
+
...state.entities[currentCohortId]?.filters,
|
|
1652
|
+
[index]: {
|
|
1653
|
+
mode: 'and',
|
|
1654
|
+
root: {}
|
|
1655
|
+
}
|
|
1656
|
+
},
|
|
1657
|
+
modified: true,
|
|
1658
|
+
modifiedDatetime: new Date().toISOString()
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
},
|
|
1662
|
+
updateCohortCounts: (state, action)=>{
|
|
1663
|
+
const currentCohortId = getCurrentCohortId(state);
|
|
1664
|
+
const currentCohort = state.entities[currentCohortId];
|
|
1665
|
+
cohortsAdapter.updateOne(state, {
|
|
1666
|
+
id: currentCohortId,
|
|
1667
|
+
changes: {
|
|
1668
|
+
counts: {
|
|
1669
|
+
...currentCohort.counts,
|
|
1670
|
+
...action.payload
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
});
|
|
1674
|
+
},
|
|
1675
|
+
updateCohortIndexCountById: (state, action)=>{
|
|
1676
|
+
const { index, cohortId, counts } = action.payload;
|
|
1677
|
+
const cohort = state.entities[cohortId];
|
|
1678
|
+
cohortsAdapter.updateOne(state, {
|
|
1679
|
+
id: cohortId,
|
|
1680
|
+
changes: {
|
|
1681
|
+
counts: {
|
|
1682
|
+
...cohort.counts,
|
|
1683
|
+
...{
|
|
1684
|
+
[index]: counts
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
});
|
|
1689
|
+
},
|
|
1690
|
+
setCurrentCohortId: (state, action)=>{
|
|
1691
|
+
state.currentCohortId = action.payload;
|
|
1692
|
+
},
|
|
1693
|
+
/** @hidden */ setCohortList: (state, action)=>{
|
|
1694
|
+
if (!action.payload) {
|
|
1695
|
+
cohortsAdapter.removeMany(state, state.ids);
|
|
1696
|
+
} else {
|
|
1697
|
+
cohortsAdapter.upsertMany(state, [
|
|
1698
|
+
...action.payload
|
|
1699
|
+
]);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
});
|
|
1704
|
+
/**
|
|
1705
|
+
* Returns the selectors for the cohorts EntityAdapter
|
|
1706
|
+
* @param state - the CoreState
|
|
1707
|
+
*
|
|
1708
|
+
* @hidden
|
|
1709
|
+
*/ const cohortSelectors = cohortsAdapter.getSelectors((state)=>state.cohorts.cohortManager);
|
|
1710
|
+
// Filter actions: addFilter, removeFilter, updateFilter
|
|
1711
|
+
const { createNewCohort, updateCohortFilter, setCohortFilter, setCohortIndexFilters, duplicateCohort, removeCohortFilter, clearCohortFilters, removeCohort, setCurrentCohortId, updateCohortName, updateCohortCounts, updateCohortIndexCountById, setCohortList } = cohortManagerSlice.actions;
|
|
1712
|
+
const cohortReducer = cohortManagerSlice.reducer;
|
|
1713
|
+
|
|
1714
|
+
const initialState$2 = {};
|
|
1715
|
+
const expandSlice$1 = toolkit.createSlice({
|
|
1716
|
+
name: 'CohortBuilder/filterExpand',
|
|
1717
|
+
initialState: initialState$2,
|
|
1718
|
+
reducers: {
|
|
1719
|
+
toggleCohortBuilderCategoryFilter: (state, action)=>{
|
|
1720
|
+
return {
|
|
1721
|
+
...state,
|
|
1722
|
+
[action.payload.index]: {
|
|
1723
|
+
...state[action.payload.index],
|
|
1724
|
+
[action.payload.field]: action.payload.expanded
|
|
1725
|
+
}
|
|
1726
|
+
};
|
|
1727
|
+
},
|
|
1728
|
+
toggleCohortBuilderAllFilters: (state, action)=>{
|
|
1729
|
+
return {
|
|
1730
|
+
...state,
|
|
1731
|
+
[action.payload.index]: Object.keys(state[action.payload.index]).reduce((acc, k)=>{
|
|
1732
|
+
acc[k] = action.payload.expand;
|
|
1733
|
+
return acc;
|
|
1734
|
+
}, {})
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1739
|
+
const cohortBuilderFiltersExpandedReducer = expandSlice$1.reducer;
|
|
1740
|
+
const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = expandSlice$1.actions;
|
|
1741
|
+
const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
|
|
1742
|
+
const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
|
|
1743
|
+
|
|
1744
|
+
const initialState$1 = {};
|
|
1745
|
+
const expandSlice = toolkit.createSlice({
|
|
1746
|
+
name: 'CohortBuilder/filterCombineMode',
|
|
1747
|
+
initialState: initialState$1,
|
|
1748
|
+
reducers: {
|
|
1749
|
+
setCohortFilterCombineMode: (state, action)=>{
|
|
1750
|
+
return {
|
|
1751
|
+
...state,
|
|
1752
|
+
[action.payload.index]: {
|
|
1753
|
+
...state[action.payload.index],
|
|
1754
|
+
[action.payload.field]: action.payload.mode
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
});
|
|
1760
|
+
const cohortBuilderFiltersCombineModeReducer = expandSlice.reducer;
|
|
1761
|
+
const { setCohortFilterCombineMode } = expandSlice.actions;
|
|
1762
|
+
const selectCohortFilterCombineMode = (state, index, field)=>state.cohorts.filtersCombineMode?.[index]?.[field] ?? 'or';
|
|
1763
|
+
|
|
1764
|
+
const initialState = {
|
|
1765
|
+
shouldShareFilters: false,
|
|
1766
|
+
sharedFiltersMap: {}
|
|
1767
|
+
};
|
|
1768
|
+
const cohortSharedFiltersSlice = toolkit.createSlice({
|
|
1769
|
+
name: 'cohortSharedFilters',
|
|
1770
|
+
initialState: initialState,
|
|
1771
|
+
reducers: {
|
|
1772
|
+
setShouldShareFilters: (state, action)=>{
|
|
1773
|
+
state.shouldShareFilters = action.payload;
|
|
1774
|
+
return state;
|
|
1775
|
+
},
|
|
1776
|
+
setSharedFilters: (state, action)=>{
|
|
1777
|
+
state.sharedFiltersMap = action.payload;
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1781
|
+
const selectShouldShareFilters = (state)=>state.cohorts.sharedFilters.shouldShareFilters;
|
|
1782
|
+
const selectSharedFilters = (state)=>state.cohorts.sharedFilters.sharedFiltersMap;
|
|
1783
|
+
const selectSharedFiltersForFields = (state, field)=>state.cohorts.sharedFilters.sharedFiltersMap?.[field] ?? [
|
|
1784
|
+
field
|
|
1785
|
+
];
|
|
1786
|
+
const { setShouldShareFilters, setSharedFilters } = cohortSharedFiltersSlice.actions;
|
|
1787
|
+
const cohortSharedFiltersReducer = cohortSharedFiltersSlice.reducer;
|
|
1788
|
+
|
|
1789
|
+
const cohortReducers = toolkit.combineReducers({
|
|
1790
|
+
filtersExpanded: cohortBuilderFiltersExpandedReducer,
|
|
1791
|
+
filtersCombineMode: cohortBuilderFiltersCombineModeReducer,
|
|
1792
|
+
sharedFilters: cohortSharedFiltersReducer,
|
|
1793
|
+
cohortManager: cohortReducer
|
|
1794
|
+
});
|
|
1795
|
+
|
|
1796
|
+
const rootReducer = toolkit.combineReducers({
|
|
1797
|
+
gen3Services: gen3ServicesReducer,
|
|
1798
|
+
user: userReducer,
|
|
1799
|
+
gen3Apps: gen3AppReducer,
|
|
1800
|
+
drsHostnames: drsHostnamesReducer,
|
|
1801
|
+
modals: modalReducer,
|
|
1802
|
+
cohorts: cohortReducers,
|
|
1803
|
+
activeWorkspace: activeWorkspaceReducer,
|
|
1804
|
+
[guppyApiSliceReducerPath]: guppyApiReducer,
|
|
1805
|
+
[userAuthApiReducerPath]: userAuthApiReducer,
|
|
1806
|
+
[cartReducerPath]: cartReducer
|
|
1807
|
+
});
|
|
1808
|
+
|
|
1752
1809
|
/**
|
|
1753
1810
|
* Flattens a deep nested JSON object skipping
|
|
1754
1811
|
* the first level to avoid potentially flattening
|
|
@@ -2574,7 +2631,8 @@ const persistConfig = {
|
|
|
2574
2631
|
storage,
|
|
2575
2632
|
whitelist: [
|
|
2576
2633
|
'cohorts',
|
|
2577
|
-
'activeWorkspace'
|
|
2634
|
+
'activeWorkspace',
|
|
2635
|
+
'cart'
|
|
2578
2636
|
]
|
|
2579
2637
|
};
|
|
2580
2638
|
const persistedReducer = reduxPersist.persistReducer(persistConfig, rootReducer);
|
|
@@ -5759,6 +5817,7 @@ const isWorkspaceActive = (status)=>status === WorkspaceStatus.Running || status
|
|
|
5759
5817
|
const isWorkspaceRunningOrStopping = (status)=>status === WorkspaceStatus.Running || status === WorkspaceStatus.Terminating;
|
|
5760
5818
|
|
|
5761
5819
|
exports.Accessibility = Accessibility;
|
|
5820
|
+
exports.CART_LIMIT = CART_LIMIT;
|
|
5762
5821
|
exports.CohortStorage = CohortStorage;
|
|
5763
5822
|
exports.CoreProvider = CoreProvider;
|
|
5764
5823
|
exports.DAYS_IN_YEAR = DAYS_IN_YEAR;
|
|
@@ -5792,6 +5851,7 @@ exports.RequestedWorkspaceStatus = RequestedWorkspaceStatus;
|
|
|
5792
5851
|
exports.ToGqlHandler = ToGqlHandler;
|
|
5793
5852
|
exports.ValueExtractorHandler = ValueExtractorHandler;
|
|
5794
5853
|
exports.WorkspaceStatus = WorkspaceStatus;
|
|
5854
|
+
exports.addItemsToCart = addItemsToCart;
|
|
5795
5855
|
exports.ageDisplay = ageDisplay;
|
|
5796
5856
|
exports.appendFilterToOperation = appendFilterToOperation;
|
|
5797
5857
|
exports.buildGetAggregationQuery = buildGetAggregationQuery;
|
|
@@ -5801,6 +5861,8 @@ exports.buildNestedGQLFilter = buildNestedGQLFilter;
|
|
|
5801
5861
|
exports.calculatePercentageAsNumber = calculatePercentageAsNumber;
|
|
5802
5862
|
exports.calculatePercentageAsString = calculatePercentageAsString;
|
|
5803
5863
|
exports.capitalize = capitalize;
|
|
5864
|
+
exports.cartReducer = cartReducer;
|
|
5865
|
+
exports.cartReducerPath = cartReducerPath;
|
|
5804
5866
|
exports.clearActiveWorkspaceId = clearActiveWorkspaceId;
|
|
5805
5867
|
exports.clearCohortFilters = clearCohortFilters;
|
|
5806
5868
|
exports.cohortReducer = cohortReducer;
|
|
@@ -5828,6 +5890,7 @@ exports.extractEnumFilterValue = extractEnumFilterValue;
|
|
|
5828
5890
|
exports.extractFieldNameFromFullFieldName = extractFieldNameFromFullFieldName;
|
|
5829
5891
|
exports.extractFileDatasetsInRecords = extractFileDatasetsInRecords;
|
|
5830
5892
|
exports.extractFilterValue = extractFilterValue;
|
|
5893
|
+
exports.extractFiltersWithPrefixFromFilterSet = extractFiltersWithPrefixFromFilterSet;
|
|
5831
5894
|
exports.extractIndexAndFieldNameFromFullFieldName = extractIndexAndFieldNameFromFullFieldName;
|
|
5832
5895
|
exports.extractIndexFromDataLibraryCohort = extractIndexFromDataLibraryCohort;
|
|
5833
5896
|
exports.extractIndexFromFullFieldName = extractIndexFromFullFieldName;
|
|
@@ -5885,10 +5948,12 @@ exports.isHistogramRangeData = isHistogramRangeData;
|
|
|
5885
5948
|
exports.isHttpStatusError = isHttpStatusError;
|
|
5886
5949
|
exports.isIndexedFilterSetEmpty = isIndexedFilterSetEmpty;
|
|
5887
5950
|
exports.isIntersection = isIntersection;
|
|
5951
|
+
exports.isIntersectionOrUnion = isIntersectionOrUnion;
|
|
5888
5952
|
exports.isJSONObject = isJSONObject;
|
|
5889
5953
|
exports.isJSONValue = isJSONValue;
|
|
5890
5954
|
exports.isJSONValueArray = isJSONValueArray;
|
|
5891
5955
|
exports.isNameUnique = isNameUnique;
|
|
5956
|
+
exports.isNestedFilter = isNestedFilter;
|
|
5892
5957
|
exports.isNotDefined = isNotDefined;
|
|
5893
5958
|
exports.isObject = isObject;
|
|
5894
5959
|
exports.isOperandsType = isOperandsType;
|
|
@@ -5918,6 +5983,7 @@ exports.rawDataQueryStrForEachField = rawDataQueryStrForEachField;
|
|
|
5918
5983
|
exports.registerDefaultRemoteSupport = registerDefaultRemoteSupport;
|
|
5919
5984
|
exports.removeCohort = removeCohort;
|
|
5920
5985
|
exports.removeCohortFilter = removeCohortFilter;
|
|
5986
|
+
exports.removeItemsFromCart = removeItemsFromCart;
|
|
5921
5987
|
exports.requestorApi = requestorApi;
|
|
5922
5988
|
exports.resetUserState = resetUserState;
|
|
5923
5989
|
exports.resourcePathFromProjectID = resourcePathFromProjectID;
|
|
@@ -5931,6 +5997,10 @@ exports.selectAvailableCohortByName = selectAvailableCohortByName;
|
|
|
5931
5997
|
exports.selectAvailableCohorts = selectAvailableCohorts;
|
|
5932
5998
|
exports.selectCSRFToken = selectCSRFToken;
|
|
5933
5999
|
exports.selectCSRFTokenData = selectCSRFTokenData;
|
|
6000
|
+
exports.selectCart = selectCart;
|
|
6001
|
+
exports.selectCartCount = selectCartCount;
|
|
6002
|
+
exports.selectCartItem = selectCartItem;
|
|
6003
|
+
exports.selectCartItems = selectCartItems;
|
|
5934
6004
|
exports.selectCohortById = selectCohortById;
|
|
5935
6005
|
exports.selectCohortFilterCombineMode = selectCohortFilterCombineMode;
|
|
5936
6006
|
exports.selectCohortFilterExpanded = selectCohortFilterExpanded;
|