@gen3/core 0.10.94 → 0.10.97

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 (82) hide show
  1. package/dist/cjs/index.js +631 -126
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/constants.d.ts +1 -0
  4. package/dist/dts/constants.d.ts.map +1 -1
  5. package/dist/dts/features/authz/authzMappingSlice.d.ts +463 -31
  6. package/dist/dts/features/authz/authzMappingSlice.d.ts.map +1 -1
  7. package/dist/dts/features/authz/index.d.ts +2 -2
  8. package/dist/dts/features/authz/index.d.ts.map +1 -1
  9. package/dist/dts/features/authz/types.d.ts +17 -0
  10. package/dist/dts/features/authz/types.d.ts.map +1 -1
  11. package/dist/dts/features/cohort/cohortSlice.d.ts +152 -77
  12. package/dist/dts/features/cohort/cohortSlice.d.ts.map +1 -1
  13. package/dist/dts/features/cohort/index.d.ts +2 -2
  14. package/dist/dts/features/cohort/index.d.ts.map +1 -1
  15. package/dist/dts/features/cohort/reducers.d.ts +2 -2
  16. package/dist/dts/features/cohort/utils.d.ts +2 -0
  17. package/dist/dts/features/cohort/utils.d.ts.map +1 -0
  18. package/dist/dts/features/dataLibrary/index.d.ts +1 -1
  19. package/dist/dts/features/dataLibrary/index.d.ts.map +1 -1
  20. package/dist/dts/features/dataLibrary/storage/types.d.ts +1 -5
  21. package/dist/dts/features/dataLibrary/storage/types.d.ts.map +1 -1
  22. package/dist/dts/features/dataLibrary/useDataLibrary.d.ts +1 -1
  23. package/dist/dts/features/dataLibrary/useDataLibrary.d.ts.map +1 -1
  24. package/dist/dts/features/fence/utils.d.ts.map +1 -1
  25. package/dist/dts/features/filters/filters.d.ts +17 -0
  26. package/dist/dts/features/filters/filters.d.ts.map +1 -1
  27. package/dist/dts/features/filters/index.d.ts +2 -2
  28. package/dist/dts/features/filters/index.d.ts.map +1 -1
  29. package/dist/dts/features/filters/tests/filters.unit.test.d.ts +2 -0
  30. package/dist/dts/features/filters/tests/filters.unit.test.d.ts.map +1 -0
  31. package/dist/dts/features/filters/types.d.ts +4 -1
  32. package/dist/dts/features/filters/types.d.ts.map +1 -1
  33. package/dist/dts/features/gen3/gen3Api.d.ts.map +1 -1
  34. package/dist/dts/features/gen3Apps/Gen3AppRTKQ.d.ts +4 -8
  35. package/dist/dts/features/gen3Apps/Gen3AppRTKQ.d.ts.map +1 -1
  36. package/dist/dts/features/guppy/guppySlice.d.ts +189 -2
  37. package/dist/dts/features/guppy/guppySlice.d.ts.map +1 -1
  38. package/dist/dts/features/guppy/index.d.ts +2 -0
  39. package/dist/dts/features/guppy/index.d.ts.map +1 -1
  40. package/dist/dts/features/guppy/processing.d.ts +20 -0
  41. package/dist/dts/features/guppy/processing.d.ts.map +1 -0
  42. package/dist/dts/features/guppy/tests/processing.unit.test.d.ts +2 -0
  43. package/dist/dts/features/guppy/tests/processing.unit.test.d.ts.map +1 -0
  44. package/dist/dts/features/requestor/index.d.ts +5 -0
  45. package/dist/dts/features/requestor/index.d.ts.map +1 -0
  46. package/dist/dts/features/requestor/remoteSupport/index.d.ts +5 -0
  47. package/dist/dts/features/requestor/remoteSupport/index.d.ts.map +1 -0
  48. package/dist/dts/features/requestor/remoteSupport/registerDefaultRemoteSupport.d.ts +2 -0
  49. package/dist/dts/features/requestor/remoteSupport/registerDefaultRemoteSupport.d.ts.map +1 -0
  50. package/dist/dts/features/requestor/remoteSupport/registeredRemoteSupportServices.d.ts +48 -0
  51. package/dist/dts/features/requestor/remoteSupport/registeredRemoteSupportServices.d.ts.map +1 -0
  52. package/dist/dts/features/requestor/remoteSupport/types.d.ts +12 -0
  53. package/dist/dts/features/requestor/remoteSupport/types.d.ts.map +1 -0
  54. package/dist/dts/features/requestor/remoteSupport/zenDesk.d.ts +5 -0
  55. package/dist/dts/features/requestor/remoteSupport/zenDesk.d.ts.map +1 -0
  56. package/dist/dts/features/requestor/requestorSlice.d.ts +870 -0
  57. package/dist/dts/features/requestor/requestorSlice.d.ts.map +1 -0
  58. package/dist/dts/features/user/index.d.ts +2 -2
  59. package/dist/dts/features/user/index.d.ts.map +1 -1
  60. package/dist/dts/features/user/userSliceRTK.d.ts +171 -4
  61. package/dist/dts/features/user/userSliceRTK.d.ts.map +1 -1
  62. package/dist/dts/hooks.d.ts +2 -2
  63. package/dist/dts/index.d.ts +1 -0
  64. package/dist/dts/index.d.ts.map +1 -1
  65. package/dist/dts/reducers.d.ts +3 -3
  66. package/dist/dts/store.d.ts +4 -4
  67. package/dist/dts/types/index.d.ts +17 -6
  68. package/dist/dts/types/index.d.ts.map +1 -1
  69. package/dist/dts/utils/caseConversion.d.ts +3 -0
  70. package/dist/dts/utils/caseConversion.d.ts.map +1 -0
  71. package/dist/dts/utils/extractvalues.d.ts +1 -4
  72. package/dist/dts/utils/extractvalues.d.ts.map +1 -1
  73. package/dist/dts/utils/fetch.d.ts +1 -1
  74. package/dist/dts/utils/fetch.d.ts.map +1 -1
  75. package/dist/dts/utils/logger.d.ts +6 -0
  76. package/dist/dts/utils/logger.d.ts.map +1 -0
  77. package/dist/dts/utils/test/caseConversion.unit.test.d.ts +2 -0
  78. package/dist/dts/utils/test/caseConversion.unit.test.d.ts.map +1 -0
  79. package/dist/esm/index.js +603 -128
  80. package/dist/esm/index.js.map +1 -1
  81. package/dist/index.d.ts +8359 -6542
  82. package/package.json +2 -2
package/dist/cjs/index.js CHANGED
@@ -16,9 +16,9 @@ var idb = require('idb');
16
16
  var uuid = require('uuid');
17
17
  var reactCookie = require('react-cookie');
18
18
  var useSWR = require('swr');
19
- var jsonpathPlus = require('jsonpath-plus');
20
19
  var flat = require('flat');
21
20
  var Papa = require('papaparse');
21
+ var jsonpathPlus = require('jsonpath-plus');
22
22
  var Queue = require('queue');
23
23
 
24
24
  function _interopNamespaceDefault(e) {
@@ -60,6 +60,7 @@ const GEN3_DATA_LIBRARY_API = process.env.NEXT_PUBLIC_GEN3_DATA_LIBRARY_API || `
60
60
  const GEN3_CROSSWALK_API = process.env.NEXT_PUBLIC_GEN3_CROSSWALK_API || `${GEN3_API}/mds`;
61
61
  const GEN3_SOWER_API = process.env.NEXT_PUBLIC_GEN3_SOWER_API || `${GEN3_API}/jobs`;
62
62
  const GEN3_MANIFEST_API = process.env.NEXT_PUBLIC_GEN3_MANIFEST_API || `${GEN3_API}/manifests`;
63
+ const GEN3_REQUESTOR_API = process.env.NEXT_PUBLIC_GEN3_REQUESTOR_API || `${GEN3_API}/requestor`;
63
64
  var Accessibility = /*#__PURE__*/ function(Accessibility) {
64
65
  Accessibility["ACCESSIBLE"] = "accessible";
65
66
  Accessibility["UNACCESSIBLE"] = "unaccessible";
@@ -96,6 +97,7 @@ const isFetchError = (obj)=>{
96
97
  */ const fetchFence = async ({ endpoint, headers, body = {}, method = 'GET', isJSON = true })=>{
97
98
  const res = await fetch(`${GEN3_FENCE_API}${endpoint}`, {
98
99
  method: method,
100
+ credentials: 'include',
99
101
  headers: headers,
100
102
  body: 'POST' === method ? JSON.stringify(body) : null
101
103
  });
@@ -188,6 +190,10 @@ const userAuthApi = react.createApi({
188
190
  return {
189
191
  error: error
190
192
  };
193
+ } else {
194
+ return {
195
+ error: 'Unknown Error'
196
+ };
191
197
  }
192
198
  }
193
199
  return {
@@ -200,7 +206,7 @@ const userAuthApi = react.createApi({
200
206
  const EMPTY_USER = {
201
207
  username: undefined
202
208
  };
203
- const { useFetchUserDetailsQuery, useLazyFetchUserDetailsQuery, useGetCSRFQuery } = userAuthApi;
209
+ const { useFetchUserDetailsQuery, useLazyFetchUserDetailsQuery, useGetCSRFQuery, useLazyGetCSRFQuery } = userAuthApi;
204
210
  const userAuthApiMiddleware = userAuthApi.middleware;
205
211
  const userAuthApiReducerPath = userAuthApi.reducerPath;
206
212
  const userAuthApiReducer = userAuthApi.reducer;
@@ -245,6 +251,9 @@ const selectHeadersWithCSRFToken = toolkit.createSelector([
245
251
  }
246
252
  if (csrfToken) headers.set('X-CSRF-Token', csrfToken);
247
253
  return headers;
254
+ },
255
+ validateStatus: (response)=>{
256
+ return response.status >= 200 && response.status < 300;
248
257
  }
249
258
  }),
250
259
  endpoints: ()=>({})
@@ -416,7 +425,7 @@ const useCoreDispatch = reactRedux.useDispatch.withTypes();
416
425
  });
417
426
  const isAuthenticated = (loginStatus)=>loginStatus === 'authenticated';
418
427
  const isPending = (loginStatus)=>loginStatus === 'pending';
419
- const initialState$7 = {
428
+ const initialState$8 = {
420
429
  status: 'uninitialized',
421
430
  loginStatus: 'unauthenticated',
422
431
  error: undefined
@@ -427,9 +436,9 @@ const initialState$7 = {
427
436
  * @returns: status messages wrapped around fetchUserState response dict
428
437
  */ const slice$4 = toolkit.createSlice({
429
438
  name: 'fence/user',
430
- initialState: initialState$7,
439
+ initialState: initialState$8,
431
440
  reducers: {
432
- resetUserState: ()=>initialState$7
441
+ resetUserState: ()=>initialState$8
433
442
  },
434
443
  extraReducers: (builder)=>{
435
444
  builder.addCase(fetchUserState.fulfilled, (_, action)=>{
@@ -571,11 +580,11 @@ const { useGetExternalLoginsQuery, useLazyGetExternalLoginsQuery, useLazyIsExter
571
580
  }
572
581
  };
573
582
 
574
- const initialState$6 = {};
583
+ const initialState$7 = {};
575
584
  // TODO: document what this does
576
585
  const slice$3 = toolkit.createSlice({
577
586
  name: 'drsResolver',
578
- initialState: initialState$6,
587
+ initialState: initialState$7,
579
588
  reducers: {
580
589
  setDRSHostnames: (_state, action)=>{
581
590
  return action.payload;
@@ -596,12 +605,12 @@ const lookupGen3App = (id)=>{
596
605
  return REGISTRY[id];
597
606
  };
598
607
 
599
- const initialState$5 = {
608
+ const initialState$6 = {
600
609
  gen3Apps: {}
601
610
  };
602
611
  const slice$2 = toolkit.createSlice({
603
612
  name: 'gen3Apps',
604
- initialState: initialState$5,
613
+ initialState: initialState$6,
605
614
  reducers: {
606
615
  addGen3AppMetadata: (state, action)=>{
607
616
  const { name, requiredEntityTypes } = action.payload;
@@ -632,13 +641,13 @@ const selectGen3AppByName = (appName)=>lookupGen3App(appName); // TODO: memoize
632
641
  Modals["GeneralErrorModal"] = "GeneralErrorModal";
633
642
  return Modals;
634
643
  }({});
635
- const initialState$4 = {
644
+ const initialState$5 = {
636
645
  currentModal: null
637
646
  };
638
647
  //Creates a modal slice for tracking showModal and hideModal state.
639
648
  const slice$1 = toolkit.createSlice({
640
649
  name: 'modals',
641
- initialState: initialState$4,
650
+ initialState: initialState$5,
642
651
  reducers: {
643
652
  showModal: (state, action)=>{
644
653
  state.currentModal = action.payload.modal;
@@ -708,7 +717,7 @@ const isTimeGreaterThan = (startTime, minutes)=>{
708
717
  };
709
718
 
710
719
  const NO_WORKSPACE_ID = 'none';
711
- const initialState$3 = {
720
+ const initialState$4 = {
712
721
  id: NO_WORKSPACE_ID,
713
722
  status: WorkspaceStatus.NotFound,
714
723
  requestedStatus: RequestedWorkspaceStatus.Unset,
@@ -716,7 +725,7 @@ const initialState$3 = {
716
725
  };
717
726
  const slice = toolkit.createSlice({
718
727
  name: 'ActiveWorkspace',
719
- initialState: initialState$3,
728
+ initialState: initialState$4,
720
729
  reducers: {
721
730
  setActiveWorkspaceId: (state, action)=>{
722
731
  state = {
@@ -806,119 +815,260 @@ const guppyAPISliceMiddleware = guppyApi.middleware;
806
815
  const guppyApiSliceReducerPath = guppyApi.reducerPath;
807
816
  const guppyApiReducer = guppyApi.reducer;
808
817
 
809
- const EmptyCohort = {
810
- id: 'default',
811
- name: 'Filters',
812
- filters: {},
813
- modified_datetime: new Date().toISOString()
814
- };
815
- const initialCohortState = {
816
- cohort: {
817
- ...EmptyCohort
818
- }
818
+ /**
819
+ * Cohorts in Gen3 are defined as a set of filters for each index in the data.
820
+ * This means one cohort id defined for all "tabs" in CohortBuilder (explorer)
821
+ * Switching a cohort is means that all the cohorts for the index changes.
822
+ */ const UNSAVED_COHORT_NAME = 'Unsaved_Cohort';
823
+ const NULL_COHORT_ID = 'null_cohort_id';
824
+ const newCohort = ({ filters = {}, customName })=>{
825
+ const ts = new Date();
826
+ const newName = customName;
827
+ const newId = createCohortId();
828
+ return {
829
+ name: newName,
830
+ id: newId,
831
+ filters: filters ?? {},
832
+ modified: false,
833
+ saved: false,
834
+ modified_datetime: ts.toISOString()
835
+ };
819
836
  };
820
- // TODO: start using this adapter
821
- /*
822
- const cohortsAdapter = createEntityAdapter<Cohort>({
823
- sortComparer: (a, b) => {
824
- if (a.modified_datetime <= b.modified_datetime) return 1;
825
- else return -1;
826
- },
837
+ const createCohortId = ()=>toolkit.nanoid();
838
+ const cohortsAdapter = toolkit.createEntityAdapter({
839
+ sortComparer: (a, b)=>{
840
+ if (a.modified_datetime <= b.modified_datetime) return 1;
841
+ else return -1;
842
+ },
843
+ selectId: (cohort)=>cohort.id
844
+ });
845
+ // Create an initial unsaved cohort
846
+ const initialCohort = newCohort({
847
+ customName: UNSAVED_COHORT_NAME
827
848
  });
828
- */ /**
849
+ const emptyInitialState = cohortsAdapter.getInitialState({
850
+ currentCohort: initialCohort.id,
851
+ message: undefined
852
+ });
853
+ // Set the initial cohort in the adapter state
854
+ const initialState$3 = cohortsAdapter.setOne(emptyInitialState, initialCohort);
855
+ const getCurrentCohort = (state)=>{
856
+ if (state.currentCohort) {
857
+ return state.currentCohort;
858
+ }
859
+ return NULL_COHORT_ID;
860
+ };
861
+ /**
829
862
  * Redux slice for cohort filters
830
863
  */ const cohortSlice = toolkit.createSlice({
831
864
  name: 'cohort',
832
- initialState: initialCohortState,
865
+ initialState: initialState$3,
833
866
  reducers: {
867
+ addNewDefaultUnsavedCohort: (state)=>{
868
+ const cohort = newCohort({
869
+ customName: UNSAVED_COHORT_NAME
870
+ });
871
+ cohortsAdapter.addOne(state, cohort);
872
+ state.currentCohort = cohort.id;
873
+ state.message = [
874
+ `newCohort|${cohort.name}|${cohort.id}`
875
+ ];
876
+ },
877
+ updateCohortName: (state, action)=>{
878
+ cohortsAdapter.updateOne(state, {
879
+ id: getCurrentCohort(state),
880
+ changes: {
881
+ name: action.payload,
882
+ modified: true,
883
+ modified_datetime: new Date().toISOString()
884
+ }
885
+ });
886
+ },
887
+ removeCohort: (state, action)=>{
888
+ const removedCohort = state.entities[action?.payload?.id || getCurrentCohort(state)];
889
+ cohortsAdapter.removeOne(state, action?.payload?.id || getCurrentCohort(state));
890
+ if (action?.payload.shouldShowMessage) {
891
+ state.message = [
892
+ `deleteCohort|${removedCohort?.name}|${state.currentCohort}`
893
+ ];
894
+ }
895
+ },
834
896
  // adds a filter to the cohort filter set at the given index
835
897
  updateCohortFilter: (state, action)=>{
836
898
  const { index, field, filter } = action.payload;
837
- return {
838
- cohort: {
839
- ...state.cohort,
899
+ const currentCohortId = getCurrentCohort(state);
900
+ if (!state.entities[currentCohortId]) {
901
+ return;
902
+ }
903
+ cohortsAdapter.updateOne(state, {
904
+ id: currentCohortId,
905
+ changes: {
840
906
  filters: {
841
- ...state.cohort.filters,
907
+ ...state.entities[currentCohortId].filters,
842
908
  [index]: {
843
- mode: state.cohort.filters?.[index]?.mode ?? 'and',
909
+ mode: state.entities[currentCohortId]?.filters[index]?.mode ?? 'and',
844
910
  root: {
845
- ...state.cohort.filters?.[index]?.root ?? {},
911
+ ...state.entities[currentCohortId]?.filters[index]?.root ?? {},
846
912
  [field]: filter
847
913
  }
848
914
  }
849
- }
915
+ },
916
+ modified: true,
917
+ modified_datetime: new Date().toISOString()
850
918
  }
851
- };
919
+ });
852
920
  },
853
921
  setCohortFilter: (state, action)=>{
854
922
  const { index, filters } = action.payload;
855
- return {
856
- cohort: {
857
- ...state.cohort,
923
+ const currentCohortId = getCurrentCohort(state);
924
+ if (!state.entities[currentCohortId]) {
925
+ console.error(`no cohort with id=${currentCohortId} defined`);
926
+ return;
927
+ }
928
+ cohortsAdapter.updateOne(state, {
929
+ id: currentCohortId,
930
+ changes: {
858
931
  filters: {
859
- ...state.cohort.filters,
932
+ ...state.entities[currentCohortId].filters,
860
933
  [index]: filters
861
- }
934
+ },
935
+ modified: true,
936
+ modified_datetime: new Date().toISOString()
862
937
  }
863
- };
938
+ });
864
939
  },
865
940
  setCohortIndexFilters: (state, action)=>{
866
- return {
867
- cohort: {
868
- ...state.cohort,
869
- filters: {
870
- ...action.payload.filters
871
- }
941
+ const currentCohortId = getCurrentCohort(state);
942
+ if (!state.entities[currentCohortId]) {
943
+ console.error(`no cohort with id=${currentCohortId} defined`);
944
+ return;
945
+ }
946
+ cohortsAdapter.updateOne(state, {
947
+ id: currentCohortId,
948
+ changes: {
949
+ filters: action.payload.filters,
950
+ modified: true,
951
+ modified_datetime: new Date().toISOString()
872
952
  }
873
- };
953
+ });
874
954
  },
875
955
  // removes a filter to the cohort filter set at the given index
876
956
  removeCohortFilter: (state, action)=>{
877
957
  const { index, field } = action.payload;
878
- const filters = state.cohort?.filters?.[index]?.root;
958
+ const currentCohortId = getCurrentCohort(state);
959
+ if (!state.entities[currentCohortId]) {
960
+ console.error(`no cohort with id=${currentCohortId} defined`);
961
+ return;
962
+ }
963
+ const filters = state.entities[currentCohortId]?.filters[index]?.root;
879
964
  if (!filters) {
880
965
  return;
881
966
  }
882
967
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
883
968
  const { [field]: _a, ...updated } = filters;
884
- return {
885
- cohort: {
886
- ...state.cohort,
969
+ cohortsAdapter.updateOne(state, {
970
+ id: currentCohortId,
971
+ changes: {
887
972
  filters: {
888
- ...state.cohort.filters,
973
+ ...state.entities[currentCohortId]?.filters,
889
974
  [index]: {
890
- mode: state.cohort.filters[index].mode,
975
+ mode: state.entities[currentCohortId].filters[index].mode,
891
976
  root: updated
892
977
  }
893
- }
978
+ },
979
+ modified: true,
980
+ modified_datetime: new Date().toISOString()
894
981
  }
895
- };
982
+ });
896
983
  },
897
984
  // removes all filters from the cohort filter set at the given index
898
985
  clearCohortFilters: (state, action)=>{
899
986
  const { index } = action.payload;
900
- return {
901
- cohort: {
902
- ...state.cohort,
987
+ const currentCohortId = getCurrentCohort(state);
988
+ if (!state.entities[currentCohortId]) {
989
+ console.error(`no cohort with id=${currentCohortId} defined`);
990
+ return;
991
+ }
992
+ const filters = state.entities[currentCohortId]?.filters[index]?.root;
993
+ if (!filters) {
994
+ return;
995
+ }
996
+ cohortsAdapter.updateOne(state, {
997
+ id: currentCohortId,
998
+ changes: {
903
999
  filters: {
904
- ...state.cohort.filters,
1000
+ ...state.entities[currentCohortId]?.filters,
905
1001
  [index]: {
906
- // empty filter set
907
1002
  mode: 'and',
908
1003
  root: {}
909
1004
  }
910
- }
1005
+ },
1006
+ modified: true,
1007
+ modified_datetime: new Date().toISOString()
911
1008
  }
912
- };
1009
+ });
1010
+ },
1011
+ discardCohortChanges: (state, action)=>{
1012
+ const { index, id, filters } = action.payload;
1013
+ const cohortId = id ?? getCurrentCohort(state);
1014
+ cohortsAdapter.updateOne(state, {
1015
+ id: cohortId,
1016
+ changes: {
1017
+ filters: {
1018
+ ...state.entities[cohortId].filters,
1019
+ [index]: filters || {
1020
+ mode: 'and',
1021
+ root: {}
1022
+ }
1023
+ },
1024
+ modified: false,
1025
+ modified_datetime: new Date().toISOString()
1026
+ }
1027
+ });
1028
+ },
1029
+ setCurrentCohortId: (state, action)=>{
1030
+ state.currentCohort = action.payload;
1031
+ },
1032
+ /** @hidden */ setCohortList: (state, action)=>{
1033
+ if (!action.payload) {
1034
+ cohortsAdapter.removeMany(state, state.ids);
1035
+ } else {
1036
+ cohortsAdapter.upsertMany(state, [
1037
+ ...action.payload
1038
+ ]);
1039
+ }
913
1040
  }
914
1041
  }
915
1042
  });
1043
+ /**
1044
+ * Returns the selectors for the cohorts EntityAdapter
1045
+ * @param state - the CoreState
1046
+ *
1047
+ * @hidden
1048
+ */ const cohortSelectors = cohortsAdapter.getSelectors((state)=>state.cohorts.cohort);
1049
+ /**
1050
+ * Returns an array of all the cohorts
1051
+ * @param state - the CoreState
1052
+ * @category Cohort
1053
+ * @category Selectors
1054
+ */ const selectAllCohorts = (state)=>cohortSelectors.selectEntities(state);
1055
+ const getCurrentCohortFromCoreState = (state)=>{
1056
+ if (state.cohorts.cohort.currentCohort) {
1057
+ return state.cohorts.cohort.currentCohort;
1058
+ }
1059
+ return NULL_COHORT_ID;
1060
+ };
916
1061
  // Filter actions: addFilter, removeFilter, updateFilter
917
- const { updateCohortFilter, setCohortFilter, setCohortIndexFilters, removeCohortFilter, clearCohortFilters } = cohortSlice.actions;
918
- const selectCohortFilters = (state)=>state.cohorts.cohort.cohort.filters;
919
- const selectCurrentCohortId = (state)=>state.cohorts.cohort.cohort.id;
920
- const selectCurrentCohort = (state)=>state.cohorts.cohort.cohort;
921
- const selectCurrentCohortName = (state)=>state.cohorts.cohort.cohort.name;
1062
+ const { updateCohortFilter, setCohortFilter, setCohortIndexFilters, removeCohortFilter, clearCohortFilters, removeCohort, discardCohortChanges, addNewDefaultUnsavedCohort, setCurrentCohortId, setCohortList } = cohortSlice.actions;
1063
+ const selectCohortFilters = (state)=>{
1064
+ const currentCohortId = getCurrentCohortFromCoreState(state);
1065
+ return state.cohorts.cohort.entities[currentCohortId]?.filters;
1066
+ };
1067
+ const selectCurrentCohortId = (state)=>{
1068
+ return getCurrentCohort(state.cohorts.cohort);
1069
+ };
1070
+ const selectCurrentCohort = (state)=>cohortSelectors.selectById(state, getCurrentCohortFromCoreState(state));
1071
+ const selectCurrentCohortName = (state)=>cohortSelectors.selectById(state, getCurrentCohortFromCoreState(state)).name;
922
1072
  /**
923
1073
  * Select a filter by its name from the current cohort. If the filter is not found
924
1074
  * returns undefined.
@@ -926,7 +1076,40 @@ const selectCurrentCohortName = (state)=>state.cohorts.cohort.cohort.name;
926
1076
  * @param index which cohort index to select from
927
1077
  * @param name name of the filter to select
928
1078
  */ const selectIndexedFilterByName = (state, index, name)=>{
929
- return state.cohorts.cohort.cohort.filters[index]?.root[name];
1079
+ return cohortSelectors.selectById(state, getCurrentCohortFromCoreState(state)).filters[index]?.root[name];
1080
+ };
1081
+ /**
1082
+ * a thunk to optionally create a caseSet when switching cohorts.
1083
+ * Note the assumption if the caseset member has ids then the caseset has previously been created.
1084
+ */ const setActiveCohort = (cohortId)=>async (dispatch /* getState */ )=>{
1085
+ dispatch(setCurrentCohortId(cohortId));
1086
+ };
1087
+ /**
1088
+ * Returns all the cohorts in the state
1089
+ * @param state - the CoreState
1090
+ *
1091
+ * @category Cohort
1092
+ * @category Selectors
1093
+ */ const selectAvailableCohorts = (state)=>cohortSelectors.selectAll(state);
1094
+ /**
1095
+ * Returns if the current cohort is modified
1096
+ * @param state - the CoreState
1097
+ * @category Cohort
1098
+ * @category Selectors
1099
+ * @hidden
1100
+ */ const selectCurrentCohortModified = (state)=>{
1101
+ const cohort = cohortSelectors.selectById(state, getCurrentCohortFromCoreState(state));
1102
+ return cohort?.modified;
1103
+ };
1104
+ /**
1105
+ * Returns if the current cohort has been saved
1106
+ * @param state - the CoreState
1107
+ * @category Cohort
1108
+ * @category Selectors
1109
+ * @hidden
1110
+ */ const selectCurrentCohortSaved = (state)=>{
1111
+ const cohort = cohortSelectors.selectById(state, getCurrentCohortFromCoreState(state));
1112
+ return cohort?.saved;
930
1113
  };
931
1114
  const EmptyFilterSet = {
932
1115
  mode: 'and',
@@ -938,8 +1121,23 @@ const EmptyFilterSet = {
938
1121
  * @param state - Core
939
1122
  * @param index which cohort index to select from
940
1123
  */ const selectIndexFilters = (state, index)=>{
941
- return state.cohorts.cohort.cohort.filters?.[index] ?? EmptyFilterSet; // TODO: check if this is undefined
1124
+ const cohort = cohortSelectors.selectById(state, getCurrentCohortFromCoreState(state));
1125
+ if (!cohort) {
1126
+ console.error('No Cohort Defined');
1127
+ }
1128
+ return cohort?.filters?.[index] ?? EmptyFilterSet;
942
1129
  };
1130
+ const setActiveCohortList = (cohorts)=>async (dispatch, getState)=>{
1131
+ // set the list of all cohorts
1132
+ if (cohorts) {
1133
+ dispatch(setCohortList(cohorts));
1134
+ return;
1135
+ }
1136
+ const availableCohorts = selectAllCohorts(getState());
1137
+ if (Object.keys(availableCohorts).length === 0) {
1138
+ dispatch(addNewDefaultUnsavedCohort());
1139
+ }
1140
+ };
943
1141
  const cohortReducer = cohortSlice.reducer;
944
1142
 
945
1143
  const initialState$2 = {};
@@ -1058,7 +1256,7 @@ const persistConfig = {
1058
1256
  version: 1,
1059
1257
  storage,
1060
1258
  whitelist: [
1061
- 'cohort',
1259
+ 'cohorts',
1062
1260
  'activeWorkspace'
1063
1261
  ]
1064
1262
  };
@@ -1298,13 +1496,13 @@ const fetchFencePresignedURL = async ({ guid, method = 'GET', onAbort = ()=>null
1298
1496
  } : {}
1299
1497
  });
1300
1498
  if (!response.ok) {
1301
- throw new HTTPError(response.status, response.statusText);
1499
+ throw new HTTPError(response.status, response.statusText, response.text());
1302
1500
  }
1303
1501
  if (response.status === 204) {
1304
1502
  // no content so return null
1305
1503
  return null;
1306
1504
  }
1307
- return response.json();
1505
+ return await response.json();
1308
1506
  };
1309
1507
 
1310
1508
  const queryWTSFederatedLoginStatus = async (signal)=>{
@@ -1617,19 +1815,42 @@ const CoreProvider = ({ children })=>{
1617
1815
  // Add more endpoints here
1618
1816
  const { useAskQuestionMutation, useGetAISearchStatusQuery, useGetAISearchVersionQuery } = aiSearchApi;
1619
1817
 
1818
+ const TAGS$1 = 'authz';
1819
+ const authzTags = gen3Api.enhanceEndpoints({
1820
+ addTagTypes: [
1821
+ TAGS$1
1822
+ ]
1823
+ });
1620
1824
  /**
1621
1825
  * Creates the authzApi for checking arborist permissions for a selected user
1622
1826
  * @see https://petstore.swagger.io/?url=https://raw.githubusercontent.com/uc-cdis/arborist/master/docs/openapi.yaml#/auth/get_auth_mapping
1623
1827
  * @see https://github.com/uc-cdis/arborist/blob/master/docs/relationships.simplified.png
1624
1828
  * @returns: An arborist response dict of user permissions {method, service} for each resource path.
1625
- */ const authzApi = gen3Api.injectEndpoints({
1829
+ */ const authzApi = authzTags.injectEndpoints({
1626
1830
  endpoints: (builder)=>({
1627
1831
  getAuthzMappings: builder.query({
1628
1832
  query: ()=>`${GEN3_AUTHZ_API}/mapping`
1833
+ }),
1834
+ getAuthzResources: builder.query({
1835
+ query: ()=>({
1836
+ url: `${GEN3_AUTHZ_API}/resources`,
1837
+ method: 'GET'
1838
+ })
1839
+ }),
1840
+ createAuthzResource: builder.mutation({
1841
+ query: (request)=>({
1842
+ // url: `${GEN3_AUTHZ_API}/resources/${request.resourcePath}${request?.path ? `&p=${request.path}` : ''}`,
1843
+ url: `${GEN3_AUTHZ_API}/resources`,
1844
+ method: 'POST',
1845
+ body: request.data
1846
+ }),
1847
+ invalidatesTags: [
1848
+ TAGS$1
1849
+ ]
1629
1850
  })
1630
1851
  })
1631
1852
  });
1632
- const { useGetAuthzMappingsQuery, useLazyGetAuthzMappingsQuery } = authzApi;
1853
+ const { useGetAuthzMappingsQuery, useLazyGetAuthzMappingsQuery, useGetAuthzResourcesQuery, useLazyGetAuthzResourcesQuery, useCreateAuthzResourceMutation } = authzApi;
1633
1854
  const selectAuthzMapping = authzApi.endpoints.getAuthzMappings.select();
1634
1855
  const selectAuthzMappingData = toolkit.createSelector(selectAuthzMapping, (authzMapping)=>authzMapping?.data ?? {
1635
1856
  mappings: []
@@ -2747,6 +2968,7 @@ const handleOperation = (handler, op)=>{
2747
2968
  case 'nested':
2748
2969
  return handler.handleNestedFilter(op);
2749
2970
  case 'in':
2971
+ case 'includes':
2750
2972
  return handler.handleIncludes(op);
2751
2973
  case 'excludeifany':
2752
2974
  return handler.handleExcludeIfAny(op);
@@ -2901,6 +3123,9 @@ function isUnion(value) {
2901
3123
  function isIntersection(value) {
2902
3124
  return typeof value === 'object' && value !== null && value.operator === 'and' && Array.isArray(value.operands);
2903
3125
  }
3126
+ const isOperandsType = (operation)=>{
3127
+ return operation?.operands !== undefined;
3128
+ };
2904
3129
 
2905
3130
  const FieldNameOverrides = {};
2906
3131
  const COMMON_PREPOSITIONS = [
@@ -3086,9 +3311,11 @@ const createGen3AppWithOwnStore = (options)=>{
3086
3311
  return Gen3AppWrapper;
3087
3312
  };
3088
3313
 
3089
- const createAppApiForRTKQ = (reducerPath, baseQuery)=>{
3314
+ const createAppApiForRTKQ = (reducerPath, name, version, additionalReducers, baseQuery)=>{
3315
+ const nameVersion = `${name}::${version}`;
3316
+ const id = uuid.v5(nameVersion, GEN3_APP_NAMESPACE);
3090
3317
  const appContext = React__namespace.createContext(null);
3091
- const useAppSelector = reactRedux.useSelector.withTypes();
3318
+ const useAppSelector = reactRedux.createSelectorHook(appContext);
3092
3319
  const useAppDispatch = reactRedux.createDispatchHook(appContext);
3093
3320
  const useAppStore = reactRedux.createStoreHook(appContext);
3094
3321
  const appCreateApi = react.buildCreateApi(react.coreModule(), react.reactHooksModule({
@@ -3104,13 +3331,12 @@ const createAppApiForRTKQ = (reducerPath, baseQuery)=>{
3104
3331
  baseUrl: `${GEN3_API}`,
3105
3332
  prepareHeaders: (headers)=>{
3106
3333
  headers.set('Content-Type', 'application/json');
3107
- let accessToken = undefined;
3108
3334
  if (process.env.NODE_ENV === 'development') {
3109
3335
  // NOTE: This cookie can only be accessed from the client side
3110
3336
  // in development mode. Otherwise, the cookie is set as httpOnly
3111
- accessToken = cookiesNext.getCookie('credentials_token');
3337
+ const accessToken = cookiesNext.getCookie('credentials_token');
3338
+ if (accessToken) headers.set('Authorization', `Bearer ${accessToken}`);
3112
3339
  }
3113
- if (accessToken) headers.set('Authorization', `Bearer ${accessToken}`);
3114
3340
  return headers;
3115
3341
  }
3116
3342
  }),
@@ -3118,8 +3344,12 @@ const createAppApiForRTKQ = (reducerPath, baseQuery)=>{
3118
3344
  });
3119
3345
  const appMiddleware = appRTKQApi.middleware;
3120
3346
  const appStore = toolkit.configureStore({
3347
+ devTools: {
3348
+ name: `${nameVersion}::${id}`
3349
+ },
3121
3350
  reducer: {
3122
- [appRTKQApi.reducerPath]: appRTKQApi.reducer
3351
+ [appRTKQApi.reducerPath]: appRTKQApi.reducer,
3352
+ ...additionalReducers
3123
3353
  },
3124
3354
  middleware: (getDefaultMiddleware)=>getDefaultMiddleware({
3125
3355
  serializableCheck: {
@@ -3348,8 +3578,12 @@ const groupSharedFields = (data)=>{
3348
3578
  }, {});
3349
3579
  };
3350
3580
 
3351
- const statusEndpoint = '/_status';
3352
- const processHistogramResponse = (data)=>{
3581
+ /**
3582
+ * Processes the histogram data from the given input object and returns an aggregated data object.
3583
+ *
3584
+ * @param {Record<string, unknown>} data - The input data object containing histogram information.
3585
+ * @returns {AggregationsData} An object containing the processed histogram data, structured as key-value pairs.
3586
+ */ const processHistogramResponse = (data)=>{
3353
3587
  const valueData = jsonpathPlus.JSONPath({
3354
3588
  json: data,
3355
3589
  path: '$..histogram',
@@ -3369,6 +3603,42 @@ const processHistogramResponse = (data)=>{
3369
3603
  }, {});
3370
3604
  return results;
3371
3605
  };
3606
+ /**
3607
+ * Adjusts histogram data in the provided object by rounding counts below a specified minimum value.
3608
+ *
3609
+ * This function traverses the input object for histogram data and updates it such that all count values
3610
+ * falling below the defined `minValue` are set to `-1`. By default, the `minValue` is set to `100`.
3611
+ *
3612
+ * @param {Record<string, unknown>} origData - The original input data containing histogram structures to modify.
3613
+ * @param {number} [minValue=100] - The minimum value of histogram counts. Counts below this value are replaced with `-1`.
3614
+ * @returns {Record<string, unknown>} - A new object containing the modified histogram data while preserving other properties.
3615
+ */ const roundHistogramResponse = (origData, minValue = 100)=>{
3616
+ const data = {
3617
+ ...origData
3618
+ };
3619
+ const pointerData = jsonpathPlus.JSONPath({
3620
+ json: data,
3621
+ path: '$..histogram',
3622
+ resultType: 'pointer'
3623
+ });
3624
+ if (pointerData.length === 0) {
3625
+ return {};
3626
+ }
3627
+ pointerData.forEach((element)=>{
3628
+ const key = element.slice(1).replace(/\//g, '.');
3629
+ const histogramData = jsonpathPlus.JSONPath({
3630
+ json: data,
3631
+ path: key,
3632
+ resultType: 'value'
3633
+ });
3634
+ histogramData[0].forEach((x)=>{
3635
+ x.count = x.count < minValue ? -1 : x.count;
3636
+ });
3637
+ });
3638
+ return data;
3639
+ };
3640
+
3641
+ const statusEndpoint = '/_status';
3372
3642
  const fetchJson = async (url)=>{
3373
3643
  const res = await fetch(url, {
3374
3644
  method: 'GET',
@@ -3481,24 +3751,7 @@ const useGetStatus = ()=>{
3481
3751
  }),
3482
3752
  getAggs: builder.query({
3483
3753
  query: ({ type, fields, filters, accessibility = Accessibility.ALL })=>{
3484
- const queryStart = isFilterEmpty(filters) ? `
3485
- query getAggs {
3486
- _aggregation {
3487
- ${type} (accessibility: ${accessibility}) {` : `query getAggs ($filter: JSON) {
3488
- _aggregation {
3489
- ${type} (filter: $filter, filterSelf: false, accessibility: ${accessibility}) {`;
3490
- const query = `${queryStart}
3491
- ${fields.map((field)=>histogramQueryStrForEachField(field))}
3492
- }
3493
- }
3494
- }`;
3495
- const queryBody = {
3496
- query: query,
3497
- variables: {
3498
- filter: convertFilterSetToGqlFilter(filters)
3499
- }
3500
- };
3501
- return queryBody;
3754
+ return buildGetAggregationQuery(type, fields, filters, accessibility, false);
3502
3755
  },
3503
3756
  transformResponse: (response, _meta, args)=>{
3504
3757
  return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
@@ -3506,24 +3759,7 @@ const useGetStatus = ()=>{
3506
3759
  }),
3507
3760
  getAggsNoFilterSelf: builder.query({
3508
3761
  query: ({ type, fields, filters, accessibility = Accessibility.ALL })=>{
3509
- const queryStart = isFilterEmpty(filters) ? `
3510
- query getAggs {
3511
- _aggregation {
3512
- ${type} (accessibility: ${accessibility}) {` : `query getAggs ($filter: JSON) {
3513
- _aggregation {
3514
- ${type} (filter: $filter, filterSelf: true, accessibility: ${accessibility}) {`;
3515
- const query = `${queryStart}
3516
- ${fields.map((field)=>histogramQueryStrForEachField(field))}
3517
- }
3518
- }
3519
- }`;
3520
- const queryBody = {
3521
- query: query,
3522
- variables: {
3523
- filter: convertFilterSetToGqlFilter(filters)
3524
- }
3525
- };
3526
- return queryBody;
3762
+ return buildGetAggregationQuery(type, fields, filters, accessibility, true);
3527
3763
  },
3528
3764
  transformResponse: (response, _meta, args)=>{
3529
3765
  return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
@@ -3709,7 +3945,27 @@ const useGetIndexFields = (index)=>{
3709
3945
  const { data } = useGetFieldsForIndexQuery(index);
3710
3946
  return data ?? [];
3711
3947
  };
3712
- const { useGetRawDataAndTotalCountsQuery, useGetAccessibleDataQuery, useGetAllFieldsForTypeQuery, useGetAggsQuery, useGetAggsNoFilterSelfQuery, useLazyGetAggsQuery, useGetSubAggsQuery, useGetCountsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetSharedFieldsForIndexQuery, useGeneralGQLQuery, useLazyGeneralGQLQuery } = explorerApi;
3948
+ const buildGetAggregationQuery = (type, fields, filters, accessibility = Accessibility.ALL, filterSelf = false)=>{
3949
+ const queryStart = isFilterEmpty(filters) ? `
3950
+ query getAggs {
3951
+ _aggregation {
3952
+ ${type} (accessibility: ${accessibility}) {` : `query getAggs ($filter: JSON) {
3953
+ _aggregation {
3954
+ ${type} (filter: $filter, filterSelf: ${filterSelf ? 'true' : 'false'}, accessibility: ${accessibility}) {`;
3955
+ const query = `${queryStart}
3956
+ ${fields.map((field)=>histogramQueryStrForEachField(field))}
3957
+ }
3958
+ }
3959
+ }`;
3960
+ const queryBody = {
3961
+ query: query,
3962
+ variables: {
3963
+ filter: convertFilterSetToGqlFilter(filters)
3964
+ }
3965
+ };
3966
+ return queryBody;
3967
+ };
3968
+ const { useGetRawDataAndTotalCountsQuery, useGetAccessibleDataQuery, useGetAllFieldsForTypeQuery, useGetAggsQuery, useGetAggsNoFilterSelfQuery, useLazyGetAggsQuery, useLazyGetAggsNoFilterSelfQuery, useGetSubAggsQuery, useGetCountsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetSharedFieldsForIndexQuery, useGeneralGQLQuery, useLazyGeneralGQLQuery } = explorerApi;
3713
3969
 
3714
3970
  /**
3715
3971
  * Creates a Guppy API for fetching bulk (> 10K rows) elasticsearch data
@@ -3989,6 +4245,225 @@ const queryMultipleMDSRecords = async (guids, useAggMDS = false, signal)=>{
3989
4245
  });
3990
4246
  };
3991
4247
 
4248
+ class MissingServiceConfigurationError extends Error {
4249
+ constructor(serviceName){
4250
+ super(`Missing service configuration for ${serviceName}`);
4251
+ this.name = 'MissingServiceConfigurationError';
4252
+ }
4253
+ }
4254
+
4255
+ // Default console logger
4256
+ const defaultLogger = {
4257
+ warn: (message)=>console.warn(message),
4258
+ error: (message)=>console.error(message)
4259
+ };
4260
+
4261
+ const DefaultRemoteSupportAction = async ()=>{
4262
+ throw new Error('No remote support service registered for this service name');
4263
+ };
4264
+ class RemoteSupportServiceRegistry {
4265
+ constructor(logger = defaultLogger){
4266
+ this.services = new Map();
4267
+ this.logger = logger;
4268
+ }
4269
+ /**
4270
+ * Register a remote support service
4271
+ * @param serviceName - Unique identifier for the service
4272
+ * @param action - The action function to execute for this service
4273
+ * @throws Error if serviceName or action is invalid
4274
+ */ registerService(serviceName, action) {
4275
+ if (!serviceName?.trim()) {
4276
+ throw new Error('Service name cannot be empty or null');
4277
+ }
4278
+ if (typeof action !== 'function') {
4279
+ throw new Error('Action must be a function');
4280
+ }
4281
+ if (this.services.has(serviceName)) {
4282
+ this.logger.warn(`Service '${serviceName}' is already registered and will be overwritten.`);
4283
+ }
4284
+ this.services.set(serviceName, action);
4285
+ }
4286
+ /**
4287
+ * Get a registered service action
4288
+ * @param serviceName - The service identifier
4289
+ * @returns The registered action or default action if not found
4290
+ */ getSupportService(serviceName) {
4291
+ if (!serviceName?.trim()) {
4292
+ this.logger.error('Service name cannot be empty or null');
4293
+ return DefaultRemoteSupportAction;
4294
+ }
4295
+ const service = this.services.get(serviceName);
4296
+ if (!service) {
4297
+ this.logger.warn(`Service '${serviceName}' not registered. Using default action.`);
4298
+ throw new MissingServiceConfigurationError(serviceName);
4299
+ }
4300
+ return service;
4301
+ }
4302
+ /**
4303
+ * Check if a service is registered
4304
+ * @param serviceName - The service identifier
4305
+ * @returns true if service is registered
4306
+ */ hasService(serviceName) {
4307
+ return this.services.has(serviceName);
4308
+ }
4309
+ /**
4310
+ * Get all registered service names
4311
+ * @returns Array of registered service names
4312
+ */ getRegisteredServices() {
4313
+ return Array.from(this.services.keys());
4314
+ }
4315
+ /**
4316
+ * Unregister a service
4317
+ * @param serviceName - The service identifier
4318
+ * @returns true if service was removed, false if it wasn't registered
4319
+ */ unregisterService(serviceName) {
4320
+ return this.services.delete(serviceName);
4321
+ }
4322
+ /**
4323
+ * Clear all registered services
4324
+ */ clear() {
4325
+ this.services.clear();
4326
+ }
4327
+ /**
4328
+ * Get the number of registered services
4329
+ */ size() {
4330
+ return this.services.size;
4331
+ }
4332
+ }
4333
+ let defaultRegistryInstance = null;
4334
+ function getRemoteSupportServiceRegistry(logger) {
4335
+ if (!defaultRegistryInstance) {
4336
+ defaultRegistryInstance = new RemoteSupportServiceRegistry(logger);
4337
+ }
4338
+ return defaultRegistryInstance;
4339
+ }
4340
+
4341
+ const ZENDESK_MAX_SUBJECT_LENGTH = 255;
4342
+ const ZENDESK_DOMAIN = process.env.NEXT_PUBLIC_GEN3_ZENDESK_API || 'https://<SUBDOMAIN_NAME>.zendesk.com';
4343
+ const createZendeskTicket = async ({ subject, fullName, email, contents }, configuration)=>{
4344
+ const { zendeskSubdomainName } = configuration;
4345
+ try {
4346
+ let zendeskTicketCreationURL = `${ZENDESK_DOMAIN}/api/v2/requests`;
4347
+ if (zendeskSubdomainName) {
4348
+ zendeskTicketCreationURL = zendeskTicketCreationURL.replace('<SUBDOMAIN_NAME>', zendeskSubdomainName);
4349
+ } else {
4350
+ // This is the default Gen3 helpdesk subdomain
4351
+ zendeskTicketCreationURL = zendeskTicketCreationURL.replace('<SUBDOMAIN_NAME>', 'gen3support');
4352
+ }
4353
+ let ticketSubject = subject;
4354
+ if (subject.length > ZENDESK_MAX_SUBJECT_LENGTH) {
4355
+ ticketSubject = `${subject.substring(0, ZENDESK_MAX_SUBJECT_LENGTH - 3)}...`;
4356
+ }
4357
+ await fetch(zendeskTicketCreationURL, {
4358
+ method: 'POST',
4359
+ headers: {
4360
+ 'Content-Type': 'application/json'
4361
+ },
4362
+ body: JSON.stringify({
4363
+ request: {
4364
+ subject: ticketSubject,
4365
+ comment: {
4366
+ body: contents
4367
+ },
4368
+ requester: {
4369
+ name: fullName,
4370
+ email
4371
+ }
4372
+ }
4373
+ })
4374
+ }).then((response)=>{
4375
+ if (response.status !== 201) {
4376
+ throw new Error(`Request for create Zendesk ticket failed with status ${response.status}`);
4377
+ }
4378
+ return response;
4379
+ });
4380
+ } catch (err) {
4381
+ throw new Error(`Request for create Zendesk ticket failed: ${err}`);
4382
+ }
4383
+ };
4384
+
4385
+ const registerDefaultRemoteSupport = ()=>{
4386
+ const registry = getRemoteSupportServiceRegistry();
4387
+ registry.registerService('zenDesk', createZendeskTicket);
4388
+ };
4389
+
4390
+ /**
4391
+ * Converts a Partial<RequestListQuery> object to a URL query string
4392
+ * @param params - The parameters to convert
4393
+ * @returns A formatted query string (including the leading '?')
4394
+ */ const convertToQueryString = (params)=>{
4395
+ if (!params || Object.keys(params).length === 0) {
4396
+ return '';
4397
+ }
4398
+ const queryParts = [];
4399
+ // Handle policy_ids array
4400
+ if (params.policy_ids && params.policy_ids.length > 0) {
4401
+ params.policy_ids.forEach((id)=>{
4402
+ queryParts.push(`policy_id=${encodeURIComponent(id)}`);
4403
+ });
4404
+ }
4405
+ if (params.resource_ids && params.resource_ids.length > 0) {
4406
+ params.resource_ids.forEach((id)=>{
4407
+ queryParts.push(`resource_id=${encodeURIComponent(id)}`);
4408
+ });
4409
+ }
4410
+ // Handle status
4411
+ if (params.status !== undefined) {
4412
+ queryParts.push(`status=${encodeURIComponent(params.status)}`);
4413
+ }
4414
+ // Handle revoke
4415
+ if (params.revoke !== undefined) {
4416
+ queryParts.push(`revoke=${params.revoke}`);
4417
+ }
4418
+ return queryParts.length > 0 ? `?${queryParts.join('&')}` : undefined;
4419
+ };
4420
+ /**
4421
+ * Defines requester service using a base URL and expected endpoints. Derived from gen3Api core API.
4422
+ *
4423
+ * @param endpoints - Defines endpoints used in discovery page
4424
+ * @param request - Queries Requestor service
4425
+ * @see https://github.com/uc-cdis/requestor?tab=readme-ov-file#requestor
4426
+ * @see https://petstore.swagger.io/?url=https://raw.githubusercontent.com/uc-cdis/requestor/master/docs/openapi.yaml#/Query/list_requests_request_get
4427
+ * @returns: Object of request made
4428
+ */ //TODO convert snakeCase yTpes o camelCase by adding transform respomse
4429
+ const requestorApi = gen3Api.injectEndpoints({
4430
+ endpoints: (builder)=>({
4431
+ status: builder.query({
4432
+ // get status of requestor service
4433
+ query: ()=>`${GEN3_REQUESTOR_API}/_status`
4434
+ }),
4435
+ request: builder.query({
4436
+ query: (params)=>{
4437
+ const strParams = params ? convertToQueryString(params) : undefined;
4438
+ return `${GEN3_REQUESTOR_API}/request${strParams ?? ''}`;
4439
+ }
4440
+ }),
4441
+ userRequest: builder.query({
4442
+ // get a list of requests
4443
+ query: (params)=>{
4444
+ const strParams = params ? convertToQueryString(params) : undefined;
4445
+ return `${GEN3_REQUESTOR_API}/request/user${strParams ?? ''}`;
4446
+ }
4447
+ }),
4448
+ requestById: builder.query({
4449
+ query: (requestId)=>`${GEN3_REQUESTOR_API}/request/${requestId}`
4450
+ }),
4451
+ createRequest: builder.mutation({
4452
+ query: (queryBody)=>({
4453
+ url: `${GEN3_REQUESTOR_API}/request`,
4454
+ method: 'POST',
4455
+ credentials: 'include',
4456
+ headers: {
4457
+ Accept: 'application/json',
4458
+ 'Content-Type': 'application/json'
4459
+ },
4460
+ body: JSON.stringify(queryBody)
4461
+ })
4462
+ })
4463
+ })
4464
+ });
4465
+ const { useCreateRequestMutation, useRequestQuery, useLazyRequestQuery, useStatusQuery: useRequestorStatusQuery, useRequestByIdQuery, useUserRequestQuery } = requestorApi;
4466
+
3992
4467
  /**
3993
4468
  * Creates a loadingStatusApi for checking the status of a sower data download job
3994
4469
  * @param getJobList Shows the list of jobs currently running
@@ -4078,7 +4553,7 @@ const extractValuesFromObject = (jsonPathMappings, obj)=>{
4078
4553
  };
4079
4554
  for(const key in jsonPathMappings){
4080
4555
  if (key in Object.keys(jsonPathMappings)) {
4081
- // Extract value from object and store it in the result.
4556
+ // Extract value from an object and store it in the result.
4082
4557
  result[key] = extractObjectValue(jsonPathMappings[key], obj);
4083
4558
  }
4084
4559
  }
@@ -4388,15 +4863,21 @@ exports.GEN3_WORKSPACE_API = GEN3_WORKSPACE_API;
4388
4863
  exports.HTTPError = HTTPError;
4389
4864
  exports.HTTPErrorMessages = HTTPErrorMessages;
4390
4865
  exports.HttpMethod = HttpMethod;
4866
+ exports.MissingServiceConfigurationError = MissingServiceConfigurationError;
4391
4867
  exports.Modals = Modals;
4392
4868
  exports.PodConditionType = PodConditionType;
4393
4869
  exports.PodStatus = PodStatus;
4394
4870
  exports.RequestedWorkspaceStatus = RequestedWorkspaceStatus;
4395
4871
  exports.WorkspaceStatus = WorkspaceStatus;
4872
+ exports.addNewDefaultUnsavedCohort = addNewDefaultUnsavedCohort;
4873
+ exports.buildGetAggregationQuery = buildGetAggregationQuery;
4396
4874
  exports.buildListItemsGroupedByDataset = buildListItemsGroupedByDataset;
4397
4875
  exports.clearActiveWorkspaceId = clearActiveWorkspaceId;
4398
4876
  exports.clearCohortFilters = clearCohortFilters;
4877
+ exports.cohortReducer = cohortReducer;
4399
4878
  exports.convertFilterSetToGqlFilter = convertFilterSetToGqlFilter;
4879
+ exports.convertFilterToGqlFilter = convertFilterToGqlFilter;
4880
+ exports.convertToQueryString = convertToQueryString;
4400
4881
  exports.coreStore = coreStore;
4401
4882
  exports.createAppApiForRTKQ = createAppApiForRTKQ;
4402
4883
  exports.createAppStore = createAppStore;
@@ -4424,6 +4905,7 @@ exports.getCurrentTimestamp = getCurrentTimestamp;
4424
4905
  exports.getFederatedLoginStatus = getFederatedLoginStatus;
4425
4906
  exports.getGen3AppId = getGen3AppId;
4426
4907
  exports.getNumberOfItemsInDatalist = getNumberOfItemsInDatalist;
4908
+ exports.getRemoteSupportServiceRegistry = getRemoteSupportServiceRegistry;
4427
4909
  exports.getTimestamp = getTimestamp;
4428
4910
  exports.graphQLAPI = graphQLAPI;
4429
4911
  exports.graphQLWithTags = graphQLWithTags;
@@ -4434,6 +4916,7 @@ exports.guppyApiReducer = guppyApiReducer;
4434
4916
  exports.guppyApiSliceReducerPath = guppyApiSliceReducerPath;
4435
4917
  exports.handleOperation = handleOperation;
4436
4918
  exports.hideModal = hideModal;
4919
+ exports.histogramQueryStrForEachField = histogramQueryStrForEachField;
4437
4920
  exports.isAdditionalDataItem = isAdditionalDataItem;
4438
4921
  exports.isArray = isArray;
4439
4922
  exports.isAuthenticated = isAuthenticated;
@@ -4463,6 +4946,7 @@ exports.isJSONValue = isJSONValue;
4463
4946
  exports.isJSONValueArray = isJSONValueArray;
4464
4947
  exports.isNotDefined = isNotDefined;
4465
4948
  exports.isObject = isObject;
4949
+ exports.isOperandsType = isOperandsType;
4466
4950
  exports.isOperationWithField = isOperationWithField;
4467
4951
  exports.isOperatorWithFieldAndArrayOfOperands = isOperatorWithFieldAndArrayOfOperands;
4468
4952
  exports.isPending = isPending;
@@ -4477,19 +4961,25 @@ exports.listifyMethodsFromMapping = listifyMethodsFromMapping;
4477
4961
  exports.logoutFence = logoutFence;
4478
4962
  exports.manifestApi = manifestApi;
4479
4963
  exports.manifestTags = manifestTags;
4964
+ exports.nestedHistogramQueryStrForEachField = nestedHistogramQueryStrForEachField;
4480
4965
  exports.prepareUrl = prepareUrl$1;
4481
4966
  exports.prependIndexToFieldName = prependIndexToFieldName;
4482
4967
  exports.processHistogramResponse = processHistogramResponse;
4483
4968
  exports.projectCodeFromResourcePath = projectCodeFromResourcePath;
4484
4969
  exports.queryMultipleMDSRecords = queryMultipleMDSRecords;
4485
4970
  exports.rawDataQueryStrForEachField = rawDataQueryStrForEachField;
4971
+ exports.registerDefaultRemoteSupport = registerDefaultRemoteSupport;
4972
+ exports.removeCohort = removeCohort;
4486
4973
  exports.removeCohortFilter = removeCohortFilter;
4974
+ exports.requestorApi = requestorApi;
4487
4975
  exports.resetUserState = resetUserState;
4488
4976
  exports.resourcePathFromProjectID = resourcePathFromProjectID;
4977
+ exports.roundHistogramResponse = roundHistogramResponse;
4489
4978
  exports.selectActiveWorkspaceId = selectActiveWorkspaceId;
4490
4979
  exports.selectActiveWorkspaceStatus = selectActiveWorkspaceStatus;
4491
4980
  exports.selectAllCohortFiltersCollapsed = selectAllCohortFiltersCollapsed;
4492
4981
  exports.selectAuthzMappingData = selectAuthzMappingData;
4982
+ exports.selectAvailableCohorts = selectAvailableCohorts;
4493
4983
  exports.selectCSRFToken = selectCSRFToken;
4494
4984
  exports.selectCSRFTokenData = selectCSRFTokenData;
4495
4985
  exports.selectCohortFilterCombineMode = selectCohortFilterCombineMode;
@@ -4497,7 +4987,9 @@ exports.selectCohortFilterExpanded = selectCohortFilterExpanded;
4497
4987
  exports.selectCohortFilters = selectCohortFilters;
4498
4988
  exports.selectCurrentCohort = selectCurrentCohort;
4499
4989
  exports.selectCurrentCohortId = selectCurrentCohortId;
4990
+ exports.selectCurrentCohortModified = selectCurrentCohortModified;
4500
4991
  exports.selectCurrentCohortName = selectCurrentCohortName;
4992
+ exports.selectCurrentCohortSaved = selectCurrentCohortSaved;
4501
4993
  exports.selectCurrentMessage = selectCurrentMessage;
4502
4994
  exports.selectCurrentModal = selectCurrentModal;
4503
4995
  exports.selectGen3AppByName = selectGen3AppByName;
@@ -4518,6 +5010,8 @@ exports.selectUserDetails = selectUserDetails;
4518
5010
  exports.selectUserLoginStatus = selectUserLoginStatus;
4519
5011
  exports.selectWorkspaceStatus = selectWorkspaceStatus;
4520
5012
  exports.selectWorkspaceStatusFromService = selectWorkspaceStatusFromService;
5013
+ exports.setActiveCohort = setActiveCohort;
5014
+ exports.setActiveCohortList = setActiveCohortList;
4521
5015
  exports.setActiveWorkspace = setActiveWorkspace;
4522
5016
  exports.setActiveWorkspaceId = setActiveWorkspaceId;
4523
5017
  exports.setActiveWorkspaceStatus = setActiveWorkspaceStatus;
@@ -4543,6 +5037,8 @@ exports.useAskQuestionMutation = useAskQuestionMutation;
4543
5037
  exports.useAuthorizeFromCredentialsMutation = useAuthorizeFromCredentialsMutation;
4544
5038
  exports.useCoreDispatch = useCoreDispatch;
4545
5039
  exports.useCoreSelector = useCoreSelector;
5040
+ exports.useCreateAuthzResourceMutation = useCreateAuthzResourceMutation;
5041
+ exports.useCreateRequestMutation = useCreateRequestMutation;
4546
5042
  exports.useDataLibrary = useDataLibrary;
4547
5043
  exports.useDownloadFromGuppyMutation = useDownloadFromGuppyMutation;
4548
5044
  exports.useFetchUserDetailsQuery = useFetchUserDetailsQuery;
@@ -4557,6 +5053,7 @@ exports.useGetAggsQuery = useGetAggsQuery;
4557
5053
  exports.useGetAllFieldsForTypeQuery = useGetAllFieldsForTypeQuery;
4558
5054
  exports.useGetArrayTypes = useGetArrayTypes;
4559
5055
  exports.useGetAuthzMappingsQuery = useGetAuthzMappingsQuery;
5056
+ exports.useGetAuthzResourcesQuery = useGetAuthzResourcesQuery;
4560
5057
  exports.useGetCSRFQuery = useGetCSRFQuery;
4561
5058
  exports.useGetCohortManifestQuery = useGetCohortManifestQuery;
4562
5059
  exports.useGetCountsQuery = useGetCountsQuery;
@@ -4602,8 +5099,11 @@ exports.useIsUserLoggedIn = useIsUserLoggedIn;
4602
5099
  exports.useLaunchWorkspaceMutation = useLaunchWorkspaceMutation;
4603
5100
  exports.useLazyFetchUserDetailsQuery = useLazyFetchUserDetailsQuery;
4604
5101
  exports.useLazyGeneralGQLQuery = useLazyGeneralGQLQuery;
5102
+ exports.useLazyGetAggsNoFilterSelfQuery = useLazyGetAggsNoFilterSelfQuery;
4605
5103
  exports.useLazyGetAggsQuery = useLazyGetAggsQuery;
4606
5104
  exports.useLazyGetAuthzMappingsQuery = useLazyGetAuthzMappingsQuery;
5105
+ exports.useLazyGetAuthzResourcesQuery = useLazyGetAuthzResourcesQuery;
5106
+ exports.useLazyGetCSRFQuery = useLazyGetCSRFQuery;
4607
5107
  exports.useLazyGetCrosswalkDataQuery = useLazyGetCrosswalkDataQuery;
4608
5108
  exports.useLazyGetDownloadQuery = useLazyGetDownloadQuery;
4609
5109
  exports.useLazyGetExternalLoginsQuery = useLazyGetExternalLoginsQuery;
@@ -4612,12 +5112,17 @@ exports.useLazyGetProjectsQuery = useLazyGetProjectsQuery;
4612
5112
  exports.useLazyGetSowerJobListQuery = useLazyGetSowerJobListQuery;
4613
5113
  exports.useLazyGetSubmissionGraphQLQuery = useLazyGetSubmissionGraphQLQuery;
4614
5114
  exports.useLazyIsExternalConnectedQuery = useLazyIsExternalConnectedQuery;
5115
+ exports.useLazyRequestQuery = useLazyRequestQuery;
4615
5116
  exports.usePrevious = usePrevious;
4616
5117
  exports.useRemoveCredentialMutation = useRemoveCredentialMutation;
5118
+ exports.useRequestByIdQuery = useRequestByIdQuery;
5119
+ exports.useRequestQuery = useRequestQuery;
5120
+ exports.useRequestorStatusQuery = useRequestorStatusQuery;
4617
5121
  exports.useSetCurrentPayModelMutation = useSetCurrentPayModelMutation;
4618
5122
  exports.useSubmitSowerJobMutation = useSubmitSowerJobMutation;
4619
5123
  exports.useTerminateWorkspaceMutation = useTerminateWorkspaceMutation;
4620
5124
  exports.useUserAuth = useUserAuth;
5125
+ exports.useUserRequestQuery = useUserRequestQuery;
4621
5126
  exports.userHasCreateOrUpdateOnAnyProject = userHasCreateOrUpdateOnAnyProject;
4622
5127
  exports.userHasDataUpload = userHasDataUpload;
4623
5128
  exports.userHasMethodForServiceOnProject = userHasMethodForServiceOnProject;