@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.
Files changed (43) hide show
  1. package/dist/cjs/index.js +782 -710
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/server.js +45 -0
  4. package/dist/cjs/server.js.map +1 -0
  5. package/dist/dts/constants.d.ts +1 -0
  6. package/dist/dts/constants.d.ts.map +1 -1
  7. package/dist/dts/features/cart/cartSelectors.d.ts +129 -0
  8. package/dist/dts/features/cart/cartSelectors.d.ts.map +1 -0
  9. package/dist/dts/features/cart/cartSlice.d.ts +24 -0
  10. package/dist/dts/features/cart/cartSlice.d.ts.map +1 -0
  11. package/dist/dts/features/cart/index.d.ts +5 -0
  12. package/dist/dts/features/cart/index.d.ts.map +1 -0
  13. package/dist/dts/features/cart/test/cartSelector.unit.test.d.ts +2 -0
  14. package/dist/dts/features/cart/test/cartSelector.unit.test.d.ts.map +1 -0
  15. package/dist/dts/features/cohort/cohortManagerSelector.d.ts +4 -0
  16. package/dist/dts/features/cohort/cohortManagerSelector.d.ts.map +1 -1
  17. package/dist/dts/features/cohort/cohortManagerSlice.d.ts +1 -0
  18. package/dist/dts/features/cohort/cohortManagerSlice.d.ts.map +1 -1
  19. package/dist/dts/features/cohort/utils.d.ts +13 -0
  20. package/dist/dts/features/cohort/utils.d.ts.map +1 -1
  21. package/dist/dts/features/filters/types.d.ts +7 -0
  22. package/dist/dts/features/filters/types.d.ts.map +1 -1
  23. package/dist/dts/features/guppy/guppySlice.d.ts +61 -14
  24. package/dist/dts/features/guppy/guppySlice.d.ts.map +1 -1
  25. package/dist/dts/features/user/userSliceRTK.d.ts +3 -0
  26. package/dist/dts/features/user/userSliceRTK.d.ts.map +1 -1
  27. package/dist/dts/hooks.d.ts +2 -0
  28. package/dist/dts/hooks.d.ts.map +1 -1
  29. package/dist/dts/index.d.ts +3 -2
  30. package/dist/dts/index.d.ts.map +1 -1
  31. package/dist/dts/reducers.d.ts +2 -0
  32. package/dist/dts/reducers.d.ts.map +1 -1
  33. package/dist/dts/server.d.ts +4 -0
  34. package/dist/dts/server.d.ts.map +1 -0
  35. package/dist/dts/store.d.ts +4 -0
  36. package/dist/dts/store.d.ts.map +1 -1
  37. package/dist/esm/index.js +771 -711
  38. package/dist/esm/index.js.map +1 -1
  39. package/dist/esm/server.js +29 -0
  40. package/dist/esm/server.js.map +1 -0
  41. package/dist/index.d.ts +433 -209
  42. package/dist/server.d.ts +31 -0
  43. 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$8 = {
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$8,
421
+ initialState: initialState$9,
421
422
  reducers: {
422
- resetUserState: ()=>initialState$8
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$7 = {};
565
+ const initialState$8 = {};
565
566
  // TODO: document what this does
566
567
  const slice$3 = createSlice({
567
568
  name: 'drsResolver',
568
- initialState: initialState$7,
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$6 = {
591
+ const initialState$7 = {
591
592
  gen3Apps: {}
592
593
  };
593
594
  const slice$2 = createSlice({
594
595
  name: 'gen3Apps',
595
- initialState: initialState$6,
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$5 = {
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$5,
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$4 = {
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$4,
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 defaultCohortNameGenerator = ()=>`Custom cohort ${new Date().toLocaleString('en-CA', {
813
- timeZone: 'America/Chicago',
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 generateUniqueName = (entities, baseName)=>{
822
- const trimmedBaseName = baseName.trim();
823
- // If base name is unique, use it
824
- if (isNameUnique(entities, trimmedBaseName)) {
825
- return trimmedBaseName;
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
- * Cohorts in Gen3 are defined as a set of filters for each index in the data.
839
- * This means one cohort id defined for all "tabs" in CohortBuilder (explorer)
840
- * Switching a cohort id means all the cohorts for the index are changed.
841
- */ const DEFAULT_COHORT_NAME = 'Cohort';
842
- const newCohort = ({ filters = {}, customName })=>{
843
- const ts = new Date().toISOString();
844
- const newName = customName ?? defaultCohortNameGenerator();
845
- const newId = createCohortId();
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
- * Redux slice for cohort filters
879
- */ const cohortManagerSlice = createSlice({
880
- name: 'cohort',
881
- initialState: initialState$3,
882
- reducers: {
883
- createNewCohort: (state, action)=>{
884
- const baseName = action.payload.name || `Cohort`;
885
- const uniqueName = generateUniqueName(Object.values(state.entities), baseName);
886
- const cohort = newCohort({
887
- filters: action.payload.filters,
888
- customName: uniqueName
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
- cohortsAdapter.addOne(state, cohort);
891
- state.currentCohortId = cohort.id;
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
- removeCohort: (state, action)=>{
905
- const { id: cohortId } = action.payload;
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
- return;
922
- }
923
- cohortsAdapter.removeOne(state, cohortId);
924
- // deleted the current cohort so set to the most recent cohort
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
- setCohortFilter: (state, action)=>{
961
- const { index, filters } = action.payload;
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
- setCohortIndexFilters: (state, action)=>{
980
- const currentCohortId = getCurrentCohortId(state);
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
- // removes a filter to the cohort filter set at the given index
995
- removeCohortFilter: (state, action)=>{
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
- duplicateCohort: (state)=>{
1024
- const currentCohortId = getCurrentCohortId(state);
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
- state.currentCohortId = duplicatedCohort.id;
1040
- },
1041
- // removes all filters from the cohort filter set at the given index
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
- updateCohortCounts: (state, action)=>{
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
- updateCohortIndexCountById: (state, action)=>{
1082
- const { index, cohortId, counts } = action.payload;
1083
- const cohort = state.entities[cohortId];
1084
- cohortsAdapter.updateOne(state, {
1085
- id: cohortId,
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
- setCurrentCohortId: (state, action)=>{
1097
- state.currentCohortId = action.payload;
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
- toggleCohortBuilderAllFilters: (state, action)=>{
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
- ...state,
1158
- [action.payload.index]: {
1159
- ...state[action.payload.index],
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 cohortBuilderFiltersCombineModeReducer = expandSlice.reducer;
1167
- const { setCohortFilterCombineMode } = expandSlice.actions;
1168
- const selectCohortFilterCombineMode = (state, index, field)=>state.cohorts.filtersCombineMode?.[index]?.[field] ?? 'or';
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 cohortSharedFiltersSlice = createSlice({
1175
- name: 'cohortSharedFilters',
1176
- initialState: initialState,
1177
- reducers: {
1178
- setShouldShareFilters: (state, action)=>{
1179
- state.shouldShareFilters = action.payload;
1180
- return state;
1181
- },
1182
- setSharedFilters: (state, action)=>{
1183
- state.sharedFiltersMap = action.payload;
1184
- }
1185
- }
1186
- });
1187
- const selectShouldShareFilters = (state)=>state.cohorts.sharedFilters.shouldShareFilters;
1188
- const selectSharedFilters = (state)=>state.cohorts.sharedFilters.sharedFiltersMap;
1189
- const selectSharedFiltersForFields = (state, field)=>state.cohorts.sharedFilters.sharedFiltersMap?.[field] ?? [
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
- * Constructs a nested operation object based on the provided field and leaf operand.
1609
- * If the field does not contain a dot '.', it either assigns the field to the leaf operand (if applicable)
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
- * @param {string} field - The hierarchical field path, with segments separated by dots (e.g., "root.child").
1615
- * @param {Operation} leafOperand - The operation to be nested within the specified path.
1616
- * @param parentPath - The parent path of the current field. Guppy nested filters require a parent path.
1617
- * @param depth
1618
- * @returns {Operation} A nested operation object that represents the structured path and operand.
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 isFilterSet = (input)=>{
1639
- if (typeof input !== 'object' || input === null) {
1640
- return false;
1641
- }
1642
- const { root, mode } = input;
1643
- if (typeof root !== 'object' || root === null) {
1644
- return false;
1645
- }
1646
- if (![
1647
- 'and',
1648
- 'or'
1649
- ].includes(mode)) {
1650
- return false;
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
- return true;
1653
- };
1654
- const isUnion = (value)=>{
1655
- return typeof value === 'object' && value !== null && value.operator === 'or' && Array.isArray(value.operands);
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 FieldNameOverrides = {};
1670
- const COMMON_PREPOSITIONS = [
1671
- 'a',
1672
- 'an',
1673
- 'and',
1674
- 'at',
1675
- 'but',
1676
- 'by',
1677
- 'for',
1678
- 'in',
1679
- 'is',
1680
- 'nor',
1681
- 'of',
1682
- 'on',
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
- return fieldNameToTitle(fieldName);
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
- * Converts a filter name to a title,
1701
- * For example files.input.experimental_strategy will get converted to Experimental Strategy
1702
- * if sections == 2 then the output would be Input Experimental Strategy
1703
- * @param fieldName input filter expected to be: string.firstpart_secondpart
1704
- * @param sections number of "sections" string.string.string to got back from the end of the field
1705
- */ const fieldNameToTitle = (fieldName, sections = 1)=>{
1706
- if (fieldName in FieldNameOverrides) {
1707
- return FieldNameOverrides[fieldName];
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
- if (fieldName === undefined) return 'No Title';
1710
- return fieldName.split('.').slice(-sections).map((s)=>s.split('_')).flat().map((word)=>COMMON_PREPOSITIONS.includes(word) ? word : capitalize$1(word)).join(' ');
1711
- };
1712
- /**
1713
- * Extracts the index name from the field name
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: `_aggregation {
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 ? `_${queryId}` : ''} ${gqlFilters ? '($filter: JSON)' : ''}{`;
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._aggregation) {
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._aggregation)) {
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._aggregation[args.type]._totalCount ?? 0;
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['_mapping'];
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(index);
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
- query getAggs${queryId ? `_${queryId}` : ''} {
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