@gen3/frontend 0.11.31 → 0.11.33

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 (237) hide show
  1. package/dist/cjs/index.js +1510 -123
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.d.ts +1 -1
  4. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.d.ts.map +1 -1
  5. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.js +15 -11
  6. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.js.map +1 -1
  7. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.stories.d.ts +10 -1
  8. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.stories.d.ts.map +1 -1
  9. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.stories.js +4 -0
  10. package/dist/dts/components/AddtoDataLibrary/AddToDataLibrary.stories.js.map +1 -1
  11. package/dist/dts/components/AddtoDataLibrary/types.d.ts +2 -1
  12. package/dist/dts/components/AddtoDataLibrary/types.d.ts.map +1 -1
  13. package/dist/dts/components/Buttons/DownloadButtons/JSONObjectDownloadButton.js +1 -0
  14. package/dist/dts/components/Buttons/DownloadButtons/JSONObjectDownloadButton.js.map +1 -1
  15. package/dist/dts/components/Buttons/DownloadButtons/index.d.ts +2 -0
  16. package/dist/dts/components/Buttons/DownloadButtons/index.d.ts.map +1 -1
  17. package/dist/dts/components/Buttons/DownloadButtons/index.js +2 -0
  18. package/dist/dts/components/Buttons/DownloadButtons/index.js.map +1 -1
  19. package/dist/dts/components/Buttons/FunctionButton.d.ts +32 -0
  20. package/dist/dts/components/Buttons/FunctionButton.d.ts.map +1 -0
  21. package/dist/dts/components/Buttons/FunctionButton.js +99 -0
  22. package/dist/dts/components/Buttons/FunctionButton.js.map +1 -0
  23. package/dist/dts/components/CollapsableSidebar/CollapsableSidebar.stories.d.ts +1 -1
  24. package/dist/dts/components/CollapsableSidebar/CollapsableSidebar.stories.d.ts.map +1 -1
  25. package/dist/dts/components/DataItems/TruncatedStringWithTooltip.stories.d.ts +1 -1
  26. package/dist/dts/components/DataItems/TruncatedStringWithTooltip.stories.d.ts.map +1 -1
  27. package/dist/dts/components/Login/LoginPanel.d.ts.map +1 -1
  28. package/dist/dts/components/Login/LoginPanel.js +10 -4
  29. package/dist/dts/components/Login/LoginPanel.js.map +1 -1
  30. package/dist/dts/components/MessageCards/MessagePage.d.ts +7 -0
  31. package/dist/dts/components/MessageCards/MessagePage.d.ts.map +1 -0
  32. package/dist/dts/components/MessageCards/MessagePage.js +8 -0
  33. package/dist/dts/components/MessageCards/MessagePage.js.map +1 -0
  34. package/dist/dts/components/MessageCards/index.d.ts +2 -1
  35. package/dist/dts/components/MessageCards/index.d.ts.map +1 -1
  36. package/dist/dts/components/MessageCards/index.js +2 -1
  37. package/dist/dts/components/MessageCards/index.js.map +1 -1
  38. package/dist/dts/components/Providers/Gen3Provider.d.ts +13 -13
  39. package/dist/dts/components/SegmentedControl.stories.d.ts +2 -2
  40. package/dist/dts/components/SegmentedControl.stories.d.ts.map +1 -1
  41. package/dist/dts/components/Tables/ColumnOrdering.d.ts +11 -0
  42. package/dist/dts/components/Tables/ColumnOrdering.d.ts.map +1 -0
  43. package/dist/dts/components/Tables/ColumnOrdering.js +92 -0
  44. package/dist/dts/components/Tables/ColumnOrdering.js.map +1 -0
  45. package/dist/dts/components/Tables/ShowingCount.d.ts +12 -0
  46. package/dist/dts/components/Tables/ShowingCount.d.ts.map +1 -0
  47. package/dist/dts/components/Tables/ShowingCount.js +17 -0
  48. package/dist/dts/components/Tables/ShowingCount.js.map +1 -0
  49. package/dist/dts/components/Tables/TableHeader.d.ts +25 -0
  50. package/dist/dts/components/Tables/TableHeader.d.ts.map +1 -0
  51. package/dist/dts/components/Tables/TableHeader.js +84 -0
  52. package/dist/dts/components/Tables/TableHeader.js.map +1 -0
  53. package/dist/dts/components/Tables/TablePagination.d.ts +13 -0
  54. package/dist/dts/components/Tables/TablePagination.d.ts.map +1 -0
  55. package/dist/dts/components/Tables/TablePagination.js +67 -0
  56. package/dist/dts/components/Tables/TablePagination.js.map +1 -0
  57. package/dist/dts/components/Tables/types.d.ts +66 -0
  58. package/dist/dts/components/Tables/types.d.ts.map +1 -1
  59. package/dist/dts/components/Tables/utils.d.ts +16 -0
  60. package/dist/dts/components/Tables/utils.d.ts.map +1 -1
  61. package/dist/dts/components/Tables/utils.js +47 -0
  62. package/dist/dts/components/Tables/utils.js.map +1 -1
  63. package/dist/dts/components/facets/FacetTabs.js +1 -1
  64. package/dist/dts/components/facets/FacetTabs.js.map +1 -1
  65. package/dist/dts/components/facets/FiltersPanel.d.ts +3 -3
  66. package/dist/dts/components/facets/FiltersPanel.d.ts.map +1 -1
  67. package/dist/dts/components/facets/FiltersPanel.js.map +1 -1
  68. package/dist/dts/components/facets/Panels/DropdownPanel.d.ts +2 -1
  69. package/dist/dts/components/facets/Panels/DropdownPanel.d.ts.map +1 -1
  70. package/dist/dts/components/facets/Panels/DropdownPanel.js +7 -7
  71. package/dist/dts/components/facets/Panels/DropdownPanel.js.map +1 -1
  72. package/dist/dts/components/facets/Panels/types.d.ts +2 -2
  73. package/dist/dts/components/facets/Panels/types.d.ts.map +1 -1
  74. package/dist/dts/features/Analysis/AnalysisCard.stories.d.ts +2 -2
  75. package/dist/dts/features/Analysis/AnalysisCard.stories.d.ts.map +1 -1
  76. package/dist/dts/features/Analysis/AnalysisCardCompact.stories.d.ts +6 -6
  77. package/dist/dts/features/Analysis/AnalysisCardCompact.stories.d.ts.map +1 -1
  78. package/dist/dts/features/Analysis/AnalysisCenterWithSections.stories.d.ts +1 -1
  79. package/dist/dts/features/Analysis/AnalysisCenterWithSections.stories.d.ts.map +1 -1
  80. package/dist/dts/features/Analysis/AnalysisPanel.stories.d.ts +2 -2
  81. package/dist/dts/features/Analysis/AnalysisPanel.stories.d.ts.map +1 -1
  82. package/dist/dts/features/CohortBuilder/CohortPanel.d.ts.map +1 -1
  83. package/dist/dts/features/CohortBuilder/CohortPanel.js +3 -3
  84. package/dist/dts/features/CohortBuilder/CohortPanel.js.map +1 -1
  85. package/dist/dts/features/CohortBuilder/ExplorerTable/AccessCellRenderers.d.ts +3 -0
  86. package/dist/dts/features/CohortBuilder/ExplorerTable/AccessCellRenderers.d.ts.map +1 -0
  87. package/dist/dts/features/CohortBuilder/ExplorerTable/AccessCellRenderers.js +46 -0
  88. package/dist/dts/features/CohortBuilder/ExplorerTable/AccessCellRenderers.js.map +1 -0
  89. package/dist/dts/features/CohortBuilder/ExplorerTable/ArrayCellRenderer.d.ts +1 -2
  90. package/dist/dts/features/CohortBuilder/ExplorerTable/ArrayCellRenderer.d.ts.map +1 -1
  91. package/dist/dts/features/CohortBuilder/ExplorerTable/ArrayCellRenderer.js.map +1 -1
  92. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.d.ts +1 -3
  93. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.d.ts.map +1 -1
  94. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.js +0 -1
  95. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.js.map +1 -1
  96. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTable.d.ts +1 -1
  97. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTable.d.ts.map +1 -1
  98. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTable.js +43 -13
  99. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTable.js.map +1 -1
  100. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTableCellRenderers.d.ts +1 -3
  101. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTableCellRenderers.d.ts.map +1 -1
  102. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTableCellRenderers.js +64 -0
  103. package/dist/dts/features/CohortBuilder/ExplorerTable/ExplorerTableCellRenderers.js.map +1 -1
  104. package/dist/dts/features/CohortBuilder/ExplorerTable/SubTables/ExpandingSubtable.js +1 -1
  105. package/dist/dts/features/CohortBuilder/ExplorerTable/SubTables/ExpandingSubtable.js.map +1 -1
  106. package/dist/dts/features/CohortBuilder/ExplorerTable/SubTables/SubtableAccordian.d.ts.map +1 -1
  107. package/dist/dts/features/CohortBuilder/ExplorerTable/SubTables/SubtableAccordian.js +1 -1
  108. package/dist/dts/features/CohortBuilder/ExplorerTable/SubTables/SubtableAccordian.js.map +1 -1
  109. package/dist/dts/features/CohortBuilder/ExplorerTable/context.d.ts +5 -0
  110. package/dist/dts/features/CohortBuilder/ExplorerTable/context.d.ts.map +1 -0
  111. package/dist/dts/features/CohortBuilder/ExplorerTable/context.js +5 -0
  112. package/dist/dts/features/CohortBuilder/ExplorerTable/context.js.map +1 -0
  113. package/dist/dts/features/CohortBuilder/ExplorerTable/index.d.ts +3 -2
  114. package/dist/dts/features/CohortBuilder/ExplorerTable/index.d.ts.map +1 -1
  115. package/dist/dts/features/CohortBuilder/ExplorerTable/index.js +3 -1
  116. package/dist/dts/features/CohortBuilder/ExplorerTable/index.js.map +1 -1
  117. package/dist/dts/features/CohortBuilder/ExplorerTable/types.d.ts +12 -2
  118. package/dist/dts/features/CohortBuilder/ExplorerTable/types.d.ts.map +1 -1
  119. package/dist/dts/features/CohortBuilder/ExplorerTable/utils.d.ts +16 -2
  120. package/dist/dts/features/CohortBuilder/ExplorerTable/utils.d.ts.map +1 -1
  121. package/dist/dts/features/CohortBuilder/ExplorerTable/utils.js +17 -3
  122. package/dist/dts/features/CohortBuilder/ExplorerTable/utils.js.map +1 -1
  123. package/dist/dts/features/CohortBuilder/Repository/FileFacetPanel.d.ts +11 -0
  124. package/dist/dts/features/CohortBuilder/Repository/FileFacetPanel.d.ts.map +1 -0
  125. package/dist/dts/features/CohortBuilder/Repository/FileFacetPanel.js +92 -0
  126. package/dist/dts/features/CohortBuilder/Repository/FileFacetPanel.js.map +1 -0
  127. package/dist/dts/features/CohortBuilder/Repository/Repository.d.ts +4 -0
  128. package/dist/dts/features/CohortBuilder/Repository/Repository.d.ts.map +1 -0
  129. package/dist/dts/features/CohortBuilder/Repository/Repository.js +14 -0
  130. package/dist/dts/features/CohortBuilder/Repository/Repository.js.map +1 -0
  131. package/dist/dts/features/CohortBuilder/Repository/RepositoryPanel.d.ts +4 -0
  132. package/dist/dts/features/CohortBuilder/Repository/RepositoryPanel.d.ts.map +1 -0
  133. package/dist/dts/features/CohortBuilder/Repository/RepositoryPanel.js +43 -0
  134. package/dist/dts/features/CohortBuilder/Repository/RepositoryPanel.js.map +1 -0
  135. package/dist/dts/features/CohortBuilder/Repository/Stats.d.ts +9 -0
  136. package/dist/dts/features/CohortBuilder/Repository/Stats.d.ts.map +1 -0
  137. package/dist/dts/features/CohortBuilder/Repository/Stats.js +9 -0
  138. package/dist/dts/features/CohortBuilder/Repository/Stats.js.map +1 -0
  139. package/dist/dts/features/CohortBuilder/Repository/hooks.d.ts +9 -0
  140. package/dist/dts/features/CohortBuilder/Repository/hooks.d.ts.map +1 -0
  141. package/dist/dts/features/CohortBuilder/Repository/hooks.js +53 -0
  142. package/dist/dts/features/CohortBuilder/Repository/hooks.js.map +1 -0
  143. package/dist/dts/features/CohortBuilder/Repository/index.d.ts +4 -0
  144. package/dist/dts/features/CohortBuilder/Repository/index.d.ts.map +1 -0
  145. package/dist/dts/features/CohortBuilder/Repository/index.js +3 -0
  146. package/dist/dts/features/CohortBuilder/Repository/index.js.map +1 -0
  147. package/dist/dts/features/CohortBuilder/Repository/types.d.ts +57 -0
  148. package/dist/dts/features/CohortBuilder/Repository/types.d.ts.map +1 -0
  149. package/dist/dts/features/CohortBuilder/Repository/types.js +2 -0
  150. package/dist/dts/features/CohortBuilder/Repository/types.js.map +1 -0
  151. package/dist/dts/features/CohortBuilder/downloads/downloadActionHook.d.ts.map +1 -1
  152. package/dist/dts/features/CohortBuilder/downloads/downloadActionHook.js +4 -1
  153. package/dist/dts/features/CohortBuilder/downloads/downloadActionHook.js.map +1 -1
  154. package/dist/dts/features/CohortBuilder/index.d.ts +4 -2
  155. package/dist/dts/features/CohortBuilder/index.d.ts.map +1 -1
  156. package/dist/dts/features/CohortBuilder/index.js +4 -2
  157. package/dist/dts/features/CohortBuilder/index.js.map +1 -1
  158. package/dist/dts/features/CohortBuilder/types.d.ts +1 -3
  159. package/dist/dts/features/CohortBuilder/types.d.ts.map +1 -1
  160. package/dist/dts/features/CohortBuilder/types.js.map +1 -1
  161. package/dist/dts/features/Dictionary/Dictionary.d.ts.map +1 -1
  162. package/dist/dts/features/Dictionary/Dictionary.js +5 -2
  163. package/dist/dts/features/Dictionary/Dictionary.js.map +1 -1
  164. package/dist/dts/features/Dictionary/GraphView.d.ts +9 -0
  165. package/dist/dts/features/Dictionary/GraphView.d.ts.map +1 -0
  166. package/dist/dts/features/Dictionary/GraphView.js +99 -0
  167. package/dist/dts/features/Dictionary/GraphView.js.map +1 -0
  168. package/dist/dts/features/Dictionary/graphViewDataUtils.d.ts +114 -0
  169. package/dist/dts/features/Dictionary/graphViewDataUtils.d.ts.map +1 -0
  170. package/dist/dts/features/Dictionary/graphViewDataUtils.js +332 -0
  171. package/dist/dts/features/Dictionary/graphViewDataUtils.js.map +1 -0
  172. package/dist/dts/features/Dictionary/utils.d.ts.map +1 -1
  173. package/dist/dts/features/Dictionary/utils.js.map +1 -1
  174. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.stories.d.ts +1 -1
  175. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.stories.d.ts.map +1 -1
  176. package/dist/dts/features/Discovery/ActionBar/DataLibraryActionButton.stories.d.ts +1 -1
  177. package/dist/dts/features/Discovery/ActionBar/DataLibraryActionButton.stories.d.ts.map +1 -1
  178. package/dist/dts/features/Navigation/Footer/Footer.stories.d.ts +1 -1
  179. package/dist/dts/features/Navigation/Footer/Footer.stories.d.ts.map +1 -1
  180. package/dist/dts/features/Navigation/TopBar/IconButton.stories.d.ts +1 -1
  181. package/dist/dts/features/Navigation/TopBar/IconButton.stories.d.ts.map +1 -1
  182. package/dist/dts/features/Navigation/TopBar/TopBar.stories.d.ts +1 -1
  183. package/dist/dts/features/Navigation/TopBar/TopBar.stories.d.ts.map +1 -1
  184. package/dist/dts/index.d.ts +3 -2
  185. package/dist/dts/index.d.ts.map +1 -1
  186. package/dist/dts/index.js +5 -5
  187. package/dist/dts/index.js.map +1 -1
  188. package/dist/dts/lib/common/staticProps.d.ts.map +1 -1
  189. package/dist/dts/lib/common/staticProps.js +0 -1
  190. package/dist/dts/lib/common/staticProps.js.map +1 -1
  191. package/dist/dts/pages/404/Custom404Page.stories.d.ts +1 -1
  192. package/dist/dts/pages/404/Custom404Page.stories.d.ts.map +1 -1
  193. package/dist/dts/pages/Repository/Repository.d.ts +4 -0
  194. package/dist/dts/pages/Repository/Repository.d.ts.map +1 -0
  195. package/dist/dts/pages/Repository/Repository.js +25 -0
  196. package/dist/dts/pages/Repository/Repository.js.map +1 -0
  197. package/dist/dts/pages/Repository/data.d.ts +4 -0
  198. package/dist/dts/pages/Repository/data.d.ts.map +1 -0
  199. package/dist/dts/pages/Repository/data.js +93 -0
  200. package/dist/dts/pages/Repository/data.js.map +1 -0
  201. package/dist/dts/pages/Repository/index.d.ts +4 -0
  202. package/dist/dts/pages/Repository/index.d.ts.map +1 -0
  203. package/dist/dts/pages/Repository/index.js +4 -0
  204. package/dist/dts/pages/Repository/index.js.map +1 -0
  205. package/dist/dts/pages/Repository/types.d.ts +6 -0
  206. package/dist/dts/pages/Repository/types.d.ts.map +1 -0
  207. package/dist/dts/pages/Repository/types.js +2 -0
  208. package/dist/dts/pages/Repository/types.js.map +1 -0
  209. package/dist/dts/pages/TabbedCohortBuilder/TabbedCohortBuilderPage.d.ts.map +1 -1
  210. package/dist/dts/pages/TabbedCohortBuilder/TabbedCohortBuilderPage.js +1 -1
  211. package/dist/dts/pages/TabbedCohortBuilder/TabbedCohortBuilderPage.js.map +1 -1
  212. package/dist/dts/types/common.d.ts +4 -0
  213. package/dist/dts/types/common.d.ts.map +1 -1
  214. package/dist/dts/types/constants.d.ts +2 -0
  215. package/dist/dts/types/constants.d.ts.map +1 -1
  216. package/dist/dts/types/constants.js +2 -0
  217. package/dist/dts/types/constants.js.map +1 -1
  218. package/dist/dts/types/icons.d.ts +4 -3
  219. package/dist/dts/types/icons.d.ts.map +1 -1
  220. package/dist/dts/types/icons.js +4 -3
  221. package/dist/dts/types/icons.js.map +1 -1
  222. package/dist/dts/utils/RendererFactory.d.ts +1 -14
  223. package/dist/dts/utils/RendererFactory.d.ts.map +1 -1
  224. package/dist/dts/utils/RendererFactory.js.map +1 -1
  225. package/dist/dts/utils/time.d.ts +4 -0
  226. package/dist/dts/utils/time.d.ts.map +1 -1
  227. package/dist/dts/utils/time.js +4 -4
  228. package/dist/dts/utils/time.js.map +1 -1
  229. package/dist/dts/utils/validators.d.ts +2 -0
  230. package/dist/dts/utils/validators.d.ts.map +1 -0
  231. package/dist/dts/utils/validators.js +2 -0
  232. package/dist/dts/utils/validators.js.map +1 -0
  233. package/dist/esm/index.js +1514 -137
  234. package/dist/esm/index.js.map +1 -1
  235. package/dist/index.d.ts +158 -32
  236. package/dist/tsconfig.tsbuildinfo +1 -1
  237. package/package.json +6 -9
package/dist/esm/index.js CHANGED
@@ -1,26 +1,26 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { createContext, useState, useMemo, useEffect, useRef, useCallback, useContext, createElement, forwardRef, useReducer } from 'react';
4
- import { useUserAuth, useCoreSelector, selectUserDetails, useGetAuthzMappingsQuery, fetchFence, isFetchError, WorkspaceStatus, useGetWorkspaceStatusQuery, useGetWorkspacePayModelsQuery, useTerminateWorkspaceMutation, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, useCoreDispatch, setActiveWorkspaceStatus, RequestedWorkspaceStatus, setRequestedWorkspaceStatus, isTimeGreaterThan, useGetCSRFQuery, useLazyFetchUserDetailsQuery, selectUserAuthStatus, GEN3_REDIRECT_URL, GEN3_FENCE_API, showModal, Modals, isAuthenticated, useGetLoginProvidersQuery, hideModal, selectCurrentModal, fieldNameToTitle, isOperationWithField, extractEnumFilterValue, selectIndexedFilterByName, selectShouldShareFilters, selectSharedFilters, updateCohortFilter as updateCohortFilter$1, isOperatorWithFieldAndArrayOfOperands, isUnion, removeCohortFilter as removeCohortFilter$1, trimFirstFieldNameToTitle, selectAllCohortFiltersCollapsed, Accessibility, toggleCohortBuilderAllFilters, setShouldShareFilters, useIsUserLoggedIn, GEN3_DOMAIN, useDataLibrary, DataLibraryStoreMode, buildListItemsGroupedByDataset, extractFileDatasetsInRecords, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, useGetRawDataAndTotalCountsQuery, selectIndexFilters, isJSONValue, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, toggleCohortBuilderCategoryFilter, selectCohortFilterExpanded, setCohortFilterCombineMode, selectCohortFilterCombineMode, selectCohortFilters, setCohortFilter as setCohortFilter$1, clearCohortFilters as clearCohortFilters$1, handleOperation, selectAvailableCohorts, selectCurrentCohortId as selectCurrentCohortId$1, selectCurrentCohortModified, selectCurrentCohortSaved, setCohortIndexFilters, setCurrentCohortId as setCurrentCohortId$1, selectCurrentCohortName as selectCurrentCohortName$1, useGetAggsQuery, isIntersection, useGetCountsQuery, selectAllCohorts as selectAllCohorts$1, selectCurrentCohort as selectCurrentCohort$1, isIndexedFilterSetEmpty, removeCohort as removeCohort$1, updateCohortName as updateCohortName$1, createNewCohort as createNewCohort$1, duplicateCohort, setSharedFilters, usePrevious, selectHeadersWithCSRFToken, GEN3_GUPPY_API, useLaunchWorkspaceMutation, selectActiveWorkspaceStatus, isFetchBaseQueryError, setActiveWorkspace, getCurrentTimestamp, selectWorkspaceStatusFromService, selectActiveWorkspaceId, useGetWorkspaceOptionsQuery, GEN3_WORKSPACE_API, useGetExternalLoginsQuery, useSetCurrentPayModelMutation, PodStatus, PodConditionType, isWorkspaceRunningOrStopping, GEN3_API, GEN3_COMMONS_NAME, CohortStorage, createAppStore, getRemoteSupportServiceRegistry, isHttpStatusError, MissingServiceConfigurationError, useLazyGetAggsQuery, useCreateRequestMutation, buildGetAggregationQuery, processHistogramResponse, roundHistogramResponse, selectCSRFToken, useUserRequestQuery, getGen3AppId, createGen3AppWithOwnStore, useGeneralGQLQuery, createAppApiForRTKQ, useGetDictionaryQuery, useGetMetadataByIdQuery, createGen3App, CoreProvider, fetchJSONDataFromURL, HttpMethod, groupSharedFields, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetProjectsDetailsQuery, useGetSubmissionsQuery, isCohortItem, isFileItem, fetchFencePresignedURL, HTTPError, getFederatedLoginStatus, queryMultipleMDSRecords, GEN3_MANIFEST_API, extractIndexFromDataLibraryCohort, isFilterSet, getNumberOfItemsInDatalist, isAdditionalDataItem, useLazyGetCrosswalkDataQuery, useLazyGetCountsQuery } from '@gen3/core';
5
- import { LoadingOverlay, Card, Group, Avatar, Text, Checkbox, Stack, Center, Loader, Tooltip, UnstyledButton, ThemeIcon, Box, Select, Button, Divider, Textarea, FileButton, Anchor, Modal, Grid, Table, ColorSwatch, useMantineTheme, Accordion, Switch, SegmentedControl as SegmentedControl$1, ActionIcon, Badge, TextInput, NumberInput, RangeSlider, MultiSelect, Tabs, SimpleGrid, Highlight, MantineProvider, Flex, Menu, Alert, Drawer, CopyButton, factory, useProps, getStyleObject, Paper, useCombobox, Combobox, ScrollArea, Autocomplete, Title, Transition, rem, Stepper, Spoiler, Image as Image$1, NavLink, List, createTheme, Pagination, FileInput, CloseButton } from '@mantine/core';
3
+ import React__default, { createContext, useState, useMemo, useEffect, useRef, useCallback, useContext, createElement, forwardRef, useLayoutEffect, useReducer } from 'react';
4
+ import { useUserAuth, useCoreSelector, selectUserDetails, useGetAuthzMappingsQuery, fetchFence, isFetchError, WorkspaceStatus, useGetWorkspaceStatusQuery, useGetWorkspacePayModelsQuery, useTerminateWorkspaceMutation, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, useCoreDispatch, setActiveWorkspaceStatus, RequestedWorkspaceStatus, setRequestedWorkspaceStatus, isTimeGreaterThan as isTimeGreaterThan$1, useGetCSRFQuery, useLazyFetchUserDetailsQuery, selectUserAuthStatus, GEN3_REDIRECT_URL, GEN3_FENCE_API, showModal, Modals, isAuthenticated, useGetLoginProvidersQuery, hideModal, selectCurrentModal, fieldNameToTitle, isOperationWithField, extractEnumFilterValue, selectIndexedFilterByName, selectShouldShareFilters, selectSharedFilters, updateCohortFilter as updateCohortFilter$1, isOperatorWithFieldAndArrayOfOperands, isUnion, removeCohortFilter as removeCohortFilter$1, trimFirstFieldNameToTitle, selectAllCohortFiltersCollapsed, Accessibility, toggleCohortBuilderAllFilters, setShouldShareFilters, useIsUserLoggedIn, GEN3_DOMAIN, useDataLibrary, DataLibraryStoreMode, buildListItemsGroupedByDataset, extractFileDatasetsInRecords, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, ExtractValueFromObject, useGetRawDataAndTotalCountsQuery, humanify, selectIndexFilters, isJSONValue, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, toggleCohortBuilderCategoryFilter, selectCohortFilterExpanded, setCohortFilterCombineMode, selectCohortFilterCombineMode, selectCohortFilters, setCohortFilter as setCohortFilter$1, clearCohortFilters as clearCohortFilters$1, handleOperation, selectAvailableCohorts, selectCurrentCohortId as selectCurrentCohortId$1, selectCurrentCohortModified, selectCurrentCohortSaved, setCohortIndexFilters, setCurrentCohortId as setCurrentCohortId$1, selectCurrentCohortName as selectCurrentCohortName$1, useGetAggsQuery, isIntersection, useGetCountsQuery, selectAllCohorts as selectAllCohorts$1, selectCurrentCohort as selectCurrentCohort$1, isIndexedFilterSetEmpty, removeCohort as removeCohort$1, updateCohortName as updateCohortName$1, createNewCohort as createNewCohort$1, duplicateCohort, setSharedFilters, usePrevious, useGeneralGQLQuery, convertFilterSetToGqlFilter, customQueryStrForField, selectHeadersWithCSRFToken, GEN3_GUPPY_API, useLaunchWorkspaceMutation, selectActiveWorkspaceStatus, isFetchBaseQueryError, setActiveWorkspace, getCurrentTimestamp as getCurrentTimestamp$1, selectWorkspaceStatusFromService, selectActiveWorkspaceId, useGetWorkspaceOptionsQuery, GEN3_WORKSPACE_API, useGetExternalLoginsQuery, useSetCurrentPayModelMutation, PodStatus, PodConditionType, isWorkspaceRunningOrStopping, GEN3_API, GEN3_COMMONS_NAME, CohortStorage, createAppStore, getRemoteSupportServiceRegistry, isHttpStatusError, MissingServiceConfigurationError, useLazyGetAggsQuery, useCreateRequestMutation, buildGetAggregationQuery, processHistogramResponse, roundHistogramResponse, selectCSRFToken, useUserRequestQuery, getGen3AppId, createGen3AppWithOwnStore, createAppApiForRTKQ, useGetDictionaryQuery, useGetMetadataByIdQuery, createGen3App, CoreProvider, fetchJSONDataFromURL, HttpMethod, groupSharedFields, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetProjectsDetailsQuery, useGetSubmissionsQuery, isCohortItem, isFileItem, fetchFencePresignedURL, HTTPError, getFederatedLoginStatus, queryMultipleMDSRecords, GEN3_MANIFEST_API, extractIndexFromDataLibraryCohort, isFilterSet, getNumberOfItemsInDatalist, isAdditionalDataItem, useLazyGetCrosswalkDataQuery, useLazyGetCountsQuery } from '@gen3/core';
5
+ import { LoadingOverlay, Card, Group, Avatar, Text, Checkbox, Stack, Center, Loader, Tooltip, UnstyledButton, ThemeIcon, Box, Select, Button, Divider, Textarea, FileButton, Anchor, Modal, Grid, Table, ColorSwatch, useMantineTheme, Accordion, Switch, SegmentedControl as SegmentedControl$1, ActionIcon, Badge, TextInput, NumberInput, RangeSlider, MultiSelect, ScrollArea, Tabs, SimpleGrid, Highlight, MantineProvider, Flex, Menu, Alert, Drawer, CopyButton, factory, useProps, getStyleObject, Paper, useCombobox, Combobox, Autocomplete, Title, Transition, rem, Stepper, Spoiler, Image as Image$1, NavLink, List as List$1, createTheme, Pagination, FileInput, CloseButton } from '@mantine/core';
6
6
  import { useDeepCompareEffect, useDeepCompareMemo, useDeepCompareCallback } from 'use-deep-compare';
7
7
  import { useRouter } from 'next/router';
8
8
  import { usePathname } from 'next/navigation';
9
- import { MdLogin, MdClose, MdAddCircle, MdRemoveCircle, MdExpandLess, MdExpandMore, MdSearch, MdFlip, MdLockOutline, MdLibraryAdd, MdAdd, MdKeyboardDoubleArrowLeft, MdUndo, MdInfo, MdDownload, MdOutlineArrowBack, MdOutlineArrowForward, MdKeyboardArrowDown, MdKeyboardArrowUp, MdContentCopy, MdGroup, MdOutlineBarChart, MdOutlineSearch, MdFormatQuote, MdDelete, MdOutlineRemoveCircle } from 'react-icons/md';
9
+ import { MdLogin, MdClose, MdAddCircle, MdRemoveCircle, MdExpandLess, MdExpandMore, MdSearch, MdFlip, MdLockOutline, MdLibraryAdd, MdAdd, MdKeyboardDoubleArrowLeft, MdUndo, MdInfo, MdDragIndicator, MdDownload, MdOutlineArrowBack, MdOutlineArrowForward, MdKeyboardArrowDown, MdKeyboardArrowUp, MdContentCopy, MdPerson, MdSave, MdGroup, MdOutlineBarChart, MdOutlineSearch, MdFormatQuote, MdDelete, MdOutlineRemoveCircle } from 'react-icons/md';
10
10
  import { getCookie, deleteCookie, setCookie } from 'cookies-next';
11
11
  import useSWR from 'swr';
12
12
  import { errors, importSPKI, jwtVerify, decodeJwt } from 'jose';
13
13
  import { notifications, showNotification, cleanNotifications, Notifications } from '@mantine/notifications';
14
14
  import tinycolor from 'tinycolor2';
15
- import { capitalize as capitalize$1, toString, isArray, uniqueId, reduce, includes, isPlainObject, get, omit, partial, cloneDeep, unset } from 'lodash';
15
+ import { capitalize as capitalize$1, toString, isArray, isEqual, uniqueId, reduce, includes, isPlainObject, get, omit, partial, cloneDeep, unset } from 'lodash';
16
16
  import { twMerge } from 'tailwind-merge';
17
- import { BsExclamationTriangle, BsArrowsFullscreen } from 'react-icons/bs';
17
+ import { BsExclamationTriangle, BsList, BsX, BsArrowsFullscreen } from 'react-icons/bs';
18
18
  import { IoMdInformationCircleOutline, IoMdArrowDropdown, IoMdRefresh, IoMdLogIn } from 'react-icons/io';
19
19
  import Markdown from 'react-markdown';
20
20
  import remarkGfm from 'remark-gfm';
21
21
  import { useCookies } from 'react-cookie';
22
22
  import FileSaver from 'file-saver';
23
- import { useClipboard, useResizeObserver, useDisclosure, useElementSize, useDidUpdate, mergeRefs, useReducedMotion, useMediaQuery, useFullscreen, useLocalStorage, useScrollIntoView, getHotkeyHandler } from '@mantine/hooks';
23
+ import { useClipboard, useResizeObserver, useDisclosure, useElementSize, useDidUpdate, mergeRefs, useReducedMotion, useViewportSize, useMediaQuery, useFullscreen, useLocalStorage, useScrollIntoView, getHotkeyHandler } from '@mantine/hooks';
24
24
  import { defaultComposer } from 'default-composer';
25
25
  import { Icon, addCollection } from '@iconify-icon/react';
26
26
  import { init, getInstanceByDom, graphic } from 'echarts';
@@ -45,6 +45,11 @@ import MiniSearch from 'minisearch';
45
45
  import uniq from 'lodash/uniq';
46
46
  import sum from 'lodash/sum';
47
47
  import { LuCircleSlash, LuClock, LuLock, LuUnlock } from 'react-icons/lu';
48
+ import { filesize } from 'filesize';
49
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
50
+ import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
51
+ import { CSS } from '@dnd-kit/utilities';
52
+ import { restrictToVerticalAxis, restrictToWindowEdges, restrictToParentElement } from '@dnd-kit/modifiers';
48
53
  import Cookies from 'universal-cookie';
49
54
  import GraphiQL from 'graphiql';
50
55
  import fs from 'fs';
@@ -56,7 +61,6 @@ import { createSlice, nanoid, createEntityAdapter, createAsyncThunk, createSelec
56
61
  import createWebStorage from 'redux-persist/lib/storage/createWebStorage';
57
62
  import dynamic from 'next/dynamic';
58
63
  import YAML from 'yaml';
59
- import { filesize } from 'filesize';
60
64
  import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
61
65
  import plugin from 'tailwindcss/plugin';
62
66
  import cookie from 'cookie';
@@ -530,6 +534,48 @@ const create10ColorAccessibleContrast = (pallet)=>{
530
534
  * @param {number} seconds - The time in seconds to be converted.
531
535
  * @returns {number} The equivalent time in milliseconds.
532
536
  */ const convertSecondsToMilliseconds = (seconds)=>seconds * 1000;
537
+ // Using the built-in Date object
538
+ const getCurrentTimestamp = ()=>{
539
+ return Date.now(); // Returns milliseconds since Unix epoch
540
+ };
541
+ // Get a readable timestamp for logging/display
542
+ const getFormattedTimestamp = ()=>{
543
+ return new Date().toISOString();
544
+ };
545
+ // Compare two timestamps and get difference in milliseconds
546
+ const getTimeDifferenceMs = (startTime, endTime = Date.now())=>{
547
+ return endTime - startTime;
548
+ };
549
+ // Check if time difference is greater than specified minutes
550
+ const isTimeGreaterThan = (startTime, minutes)=>{
551
+ const diffMs = getTimeDifferenceMs(startTime);
552
+ const diffMinutes = diffMs / (1000 * 60);
553
+ return diffMinutes > minutes;
554
+ };
555
+ // Get human-readable duration
556
+ const getReadableDuration = (milliseconds)=>{
557
+ const seconds = Math.floor(milliseconds / 1000);
558
+ const minutes = Math.floor(seconds / 60);
559
+ const hours = Math.floor(minutes / 60);
560
+ if (hours > 0) {
561
+ return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
562
+ }
563
+ if (minutes > 0) {
564
+ return `${minutes}m ${seconds % 60}s`;
565
+ }
566
+ return `${seconds}s`;
567
+ };
568
+ // Example usage:
569
+ const measureExecutionTime = async (func)=>{
570
+ const startTime = getCurrentTimestamp();
571
+ await func();
572
+ const duration = getTimeDifferenceMs(startTime);
573
+ return getReadableDuration(duration);
574
+ };
575
+ // Performance monitoring with high-resolution timestamps
576
+ const getHighResolutionTimestamp = ()=>{
577
+ return performance.now(); // More precise than Date.now() for performance measurements
578
+ };
533
579
  const MinutesToMilliseconds = (minutes)=>minutes * 60 * 1000;
534
580
 
535
581
  const convertPathsToTree = (paths)=>{
@@ -853,7 +899,7 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
853
899
  workspaceStatusData,
854
900
  requestedStatus
855
901
  ]);
856
- if (requestedStatus === RequestedWorkspaceStatus.Launch && isTimeGreaterThan(requestedStatusTimestamp, 8)) {
902
+ if (requestedStatus === RequestedWorkspaceStatus.Launch && isTimeGreaterThan$1(requestedStatusTimestamp, 8)) {
857
903
  terminateWorkspace();
858
904
  dispatch(setRequestedWorkspaceStatus(RequestedWorkspaceStatus.Terminate));
859
905
  notifyUser('Workspace Startup', 'Workspace failed to start. Shutting down', 2);
@@ -1226,6 +1272,14 @@ const EmptyTableMessage = ({ message })=>{
1226
1272
  });
1227
1273
  };
1228
1274
 
1275
+ const MessagePage = ({ children })=>{
1276
+ // place children in center of div that is 1/2 the visible height
1277
+ return /*#__PURE__*/ jsx("div", {
1278
+ className: "flex justify-center items-center w-full h-vh",
1279
+ children: children
1280
+ });
1281
+ };
1282
+
1229
1283
  const LoginProviderMultipleItems = ({ provider, handleLoginSelected })=>{
1230
1284
  const [value, setValue] = useState(null);
1231
1285
  return /*#__PURE__*/ jsxs("div", {
@@ -1689,12 +1743,20 @@ const filterRedirect = (redirect)=>{
1689
1743
  } else {
1690
1744
  redirectPath = redirect ?? '/';
1691
1745
  }
1692
- return GEN3_REDIRECT_URL ? `${GEN3_REDIRECT_URL}/${redirectPath}` : redirectPath;
1746
+ if (!GEN3_REDIRECT_URL) {
1747
+ return redirectPath;
1748
+ }
1749
+ // Remove trailing slash from base URL and leading slash from path
1750
+ const baseUrl = GEN3_REDIRECT_URL.replace(/\/+$/, '');
1751
+ const cleanPath = redirectPath.replace(/^\/+/, '');
1752
+ // Join with a single slash, ensuring we don't create double slashes
1753
+ return cleanPath ? `${baseUrl}/${cleanPath}` : baseUrl;
1693
1754
  };
1694
1755
  const LoginPanel = (loginConfig)=>{
1695
1756
  const { image, topContent, bottomContent } = loginConfig;
1696
1757
  const router = useRouter();
1697
- const { query: { referer } } = router;
1758
+ const { query: { referer: refererQuery, redirect: redirectQuery } } = router;
1759
+ const referer = redirectQuery || refererQuery; // either referer or redirect query param
1698
1760
  const handleFenceLoginSelected = useCallback(async (loginURL)=>{
1699
1761
  router.push(`${appendParameterToUrl(loginURL, 'redirect', filterRedirect(referer))}`).catch((e)=>{
1700
1762
  showNotification({
@@ -5027,61 +5089,65 @@ const DropdownPanel = ({ index, filters, tabTitle, facetDefinitions, facetDataHo
5027
5089
  onChange: onAccessChange,
5028
5090
  accessLevel: accessLevel
5029
5091
  }) : null,
5030
- /*#__PURE__*/ jsxs(Stack, {
5031
- className: "bg-base-max py-4 px-2 h-full w-full",
5032
- children: [
5033
- Object.keys(sharedFilters).length > 0 && /*#__PURE__*/ jsxs(Group, {
5034
- gap: "xs",
5035
- justify: "space-between",
5036
- children: [
5037
- /*#__PURE__*/ jsxs("div", {
5038
- className: "flex items-center space-x-1",
5039
- children: [
5040
- /*#__PURE__*/ jsx(Icon, {
5041
- icon: "gen3:share",
5042
- height: 16,
5043
- width: 16,
5044
- color: theme.colors.accent[4]
5045
- }),
5046
- /*#__PURE__*/ jsx(Text, {
5047
- size: "sm",
5048
- children: "Set the shared filters for all"
5049
- }),
5050
- /*#__PURE__*/ jsx(Tooltip, {
5051
- label: "If enabled any filter set on this tab will be applied to every tab where occurs.",
5052
- position: "top",
5053
- withArrow: true,
5054
- children: /*#__PURE__*/ jsx(Icon, {
5055
- icon: "gen3:info",
5056
- height: 12,
5057
- width: 12,
5092
+ /*#__PURE__*/ jsx(ScrollArea, {
5093
+ type: "auto",
5094
+ className: "flex-1 min-h-0 w-full",
5095
+ children: /*#__PURE__*/ jsxs(Stack, {
5096
+ className: "bg-base-max py-4 px-2 h-screen w-full",
5097
+ children: [
5098
+ Object.keys(sharedFilters).length > 0 && /*#__PURE__*/ jsxs(Group, {
5099
+ gap: "xs",
5100
+ justify: "space-between",
5101
+ children: [
5102
+ /*#__PURE__*/ jsxs("div", {
5103
+ className: "flex items-center space-x-1",
5104
+ children: [
5105
+ /*#__PURE__*/ jsx(Icon, {
5106
+ icon: "gen3:share",
5107
+ height: 16,
5108
+ width: 16,
5058
5109
  color: theme.colors.accent[4]
5110
+ }),
5111
+ /*#__PURE__*/ jsx(Text, {
5112
+ size: "sm",
5113
+ children: "Set the shared filters for all"
5114
+ }),
5115
+ /*#__PURE__*/ jsx(Tooltip, {
5116
+ label: "If enabled any filter set on this tab will be applied to every tab where occurs.",
5117
+ position: "top",
5118
+ withArrow: true,
5119
+ children: /*#__PURE__*/ jsx(Icon, {
5120
+ icon: "gen3:info",
5121
+ height: 12,
5122
+ width: 12,
5123
+ color: theme.colors.accent[4]
5124
+ })
5059
5125
  })
5060
- })
5061
- ]
5062
- }),
5063
- /*#__PURE__*/ jsx(Switch, {
5064
- checked: shareFilters,
5065
- onChange: (event)=>handleSharedFiltersChange(event.currentTarget.checked)
5066
- })
5067
- ]
5068
- }),
5069
- filters.tabs.length > 1 && /*#__PURE__*/ jsx(Select, {
5070
- classNames: {
5071
- options: 'border-1 border-base-dark',
5072
- option: 'hover:bg-primary-lightest'
5073
- },
5074
- withCheckIcon: false,
5075
- data: items,
5076
- value: value === null ? '0' : value,
5077
- onChange: setValue
5078
- }),
5079
- Object.keys(facetDefinitions).length > 0 ? /*#__PURE__*/ jsx(FiltersPanel, {
5080
- fields: fields,
5081
- dataFunctions: facetDataHooks,
5082
- valueLabel: tabTitle
5083
- }) : null
5084
- ]
5126
+ ]
5127
+ }),
5128
+ /*#__PURE__*/ jsx(Switch, {
5129
+ checked: shareFilters,
5130
+ onChange: (event)=>handleSharedFiltersChange(event.currentTarget.checked)
5131
+ })
5132
+ ]
5133
+ }),
5134
+ filters.tabs.length > 1 && /*#__PURE__*/ jsx(Select, {
5135
+ classNames: {
5136
+ options: 'border-1 border-base-dark',
5137
+ option: 'hover:bg-primary-lightest'
5138
+ },
5139
+ withCheckIcon: false,
5140
+ data: items,
5141
+ value: value === null ? '0' : value,
5142
+ onChange: setValue
5143
+ }),
5144
+ Object.keys(facetDefinitions).length > 0 ? /*#__PURE__*/ jsx(FiltersPanel, {
5145
+ fields: fields,
5146
+ dataFunctions: facetDataHooks,
5147
+ valueLabel: tabTitle
5148
+ }) : null
5149
+ ]
5150
+ })
5085
5151
  })
5086
5152
  ]
5087
5153
  });
@@ -5365,7 +5431,7 @@ const FacetGroup = ({ facets, children })=>{
5365
5431
  const availableFields = facets.map((f)=>f.field);
5366
5432
  useScrollToHash(availableFields, false);
5367
5433
  return /*#__PURE__*/ jsx("div", {
5368
- className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 3xl:grid-cols-5 w-content gap-4 ml-2 w-full",
5434
+ className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 3xl:grid-cols-5 w-content gap-4 mt-6 px-2 w-full",
5369
5435
  "data-testid": "title-cohort-builder-facet-groups",
5370
5436
  children: children
5371
5437
  });
@@ -8167,6 +8233,7 @@ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, i
8167
8233
  DataLibraryActionButton.displayName = 'DataLibraryActionButton';
8168
8234
 
8169
8235
  const MANIFEST_FILENAME = 'manifest.json';
8236
+ const XL_BREAKPOINT = 1280;
8170
8237
 
8171
8238
  /**
8172
8239
  * Determines the disabled state and the reason for disabling based on authentication status,
@@ -10491,6 +10558,52 @@ const DetailsDrawer = ({ id, title, panel, panelProps })=>{
10491
10558
  });
10492
10559
  };
10493
10560
 
10561
+ // TODO: refine this to make more general
10562
+ const extractProgramAndProjectNames = (path)=>{
10563
+ // Regular expression to match the pattern /programs/{programName}/projects/{projectName}
10564
+ const regex = /\/programs\/([^/]+)\/projects\/([^/]+)/;
10565
+ const match = path.match(regex);
10566
+ if (match) {
10567
+ return {
10568
+ programName: match[1],
10569
+ projectName: match[2]
10570
+ };
10571
+ }
10572
+ return {
10573
+ programName: null,
10574
+ projectName: null
10575
+ };
10576
+ };
10577
+ const isStringToColorTable = (value)=>{
10578
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
10579
+ return false;
10580
+ }
10581
+ for(const key in value){
10582
+ if (typeof key !== 'string' || typeof value[key] !== 'string') {
10583
+ return false;
10584
+ }
10585
+ }
10586
+ return true;
10587
+ };
10588
+ const ProjectAccessCellRenderer = ({ cell }, params)=>{
10589
+ const value = cell.getValue();
10590
+ if (typeof value !== 'string') return /*#__PURE__*/ jsx("span", {
10591
+ children: "Bad Value"
10592
+ });
10593
+ const { projectName } = extractProgramAndProjectNames(value);
10594
+ let color = 'primary.4';
10595
+ if (params && isStringToColorTable(params?.colorTable)) {
10596
+ if (projectName) {
10597
+ color = ExtractValueFromObject(params.colorTable, projectName, color);
10598
+ }
10599
+ }
10600
+ return /*#__PURE__*/ jsx(Badge, {
10601
+ fullWidth: true,
10602
+ color: color,
10603
+ children: projectName
10604
+ });
10605
+ };
10606
+
10494
10607
  // TODO need to type this
10495
10608
  const RenderArrayCell = ({ cell })=>{
10496
10609
  const value = cell.getValue();
@@ -10535,6 +10648,11 @@ const ValueCellRenderer = ({ cell })=>{
10535
10648
  children: cell.getValue()
10536
10649
  });
10537
10650
  };
10651
+ const FilesizeRenderer = ({ cell })=>{
10652
+ return /*#__PURE__*/ jsx("span", {
10653
+ children: filesize(cell.getValue())
10654
+ });
10655
+ };
10538
10656
  const ArrayCellFunctionCatalog = {
10539
10657
  NegativePositive: RenderArrayCellNegativePositive,
10540
10658
  default: RenderArrayCell
@@ -10556,6 +10674,66 @@ const RenderLinkCell = ({ cell }, ...args)=>{
10556
10674
  })
10557
10675
  });
10558
10676
  };
10677
+ const isRenderNextLinkCellWithIconParams = (value)=>{
10678
+ if (typeof value !== 'object' || value === null) {
10679
+ return false;
10680
+ }
10681
+ const obj = value;
10682
+ return (obj.baseURL === undefined || typeof obj.baseURL === 'string') && (obj.icon === undefined || typeof obj.icon === 'string') && (obj.size === undefined || typeof obj.size === 'string') && (obj.linkField === undefined || typeof obj.linkField === 'string');
10683
+ };
10684
+ const RenderLinkCellWithIcon = ({ cell }, ...args)=>{
10685
+ let baseURL = '';
10686
+ let icon = null;
10687
+ let size = 'sm';
10688
+ let iconHeight = '1em';
10689
+ let linkField = undefined;
10690
+ let classNames = {
10691
+ text: ''
10692
+ };
10693
+ const params = args[0];
10694
+ if (isRenderNextLinkCellWithIconParams(params)) {
10695
+ baseURL = params.baseURL ?? baseURL;
10696
+ if (params.icon) {
10697
+ icon = params.icon;
10698
+ }
10699
+ size = params.size ?? size;
10700
+ iconHeight = params.iconHeight ?? iconHeight;
10701
+ linkField = params.linkField ?? undefined;
10702
+ classNames = params?.classNames ?? {
10703
+ icon: '',
10704
+ text: ''
10705
+ };
10706
+ }
10707
+ let linkURL = `${baseURL}${cell.getValue()}`;
10708
+ if (linkField) {
10709
+ const value = cell.row.original[linkField];
10710
+ if (typeof value === 'string') {
10711
+ linkURL = `${baseURL}${value}`;
10712
+ }
10713
+ }
10714
+ return /*#__PURE__*/ jsx(Link, {
10715
+ href: linkURL,
10716
+ target: "_blank",
10717
+ rel: "noreferrer",
10718
+ children: /*#__PURE__*/ jsxs("div", {
10719
+ className: "flex items-center gap-1",
10720
+ children: [
10721
+ icon && /*#__PURE__*/ jsx(Icon, {
10722
+ height: iconHeight,
10723
+ icon: icon
10724
+ }),
10725
+ /*#__PURE__*/ jsx(Text, {
10726
+ fw: 700,
10727
+ size: size,
10728
+ classNames: {
10729
+ root: classNames?.text
10730
+ },
10731
+ children: cell.getValue()
10732
+ })
10733
+ ]
10734
+ })
10735
+ });
10736
+ };
10559
10737
  const RenderLinkCellUsingValueMap = ({ cell }, ...args)=>{
10560
10738
  let href = null;
10561
10739
  if (typeof args[0] === 'object' && Object.keys(args[0]).includes('valueToURL')) {
@@ -10588,7 +10766,8 @@ const RenderLinkCellUsingValueMap = ({ cell }, ...args)=>{
10588
10766
  };
10589
10767
  const LinkCellFunctionCatalog = {
10590
10768
  default: RenderLinkCell,
10591
- linkWithValueMap: RenderLinkCellUsingValueMap
10769
+ linkWithValueMap: RenderLinkCellUsingValueMap,
10770
+ linkWithIcon: RenderLinkCellWithIcon
10592
10771
  };
10593
10772
  let instance$2;
10594
10773
  const ExplorerTableCellRendererFactory = ()=>{
@@ -10601,7 +10780,13 @@ const ExplorerTableCellRendererFactory = ()=>{
10601
10780
  const registerExplorerDefaultCellRenderers = ()=>{
10602
10781
  ExplorerTableCellRendererFactory().registerRendererCatalog({
10603
10782
  value: {
10604
- default: ValueCellRenderer
10783
+ default: ValueCellRenderer,
10784
+ filesize: FilesizeRenderer
10785
+ }
10786
+ });
10787
+ ExplorerTableCellRendererFactory().registerRendererCatalog({
10788
+ access: {
10789
+ projectAccess: ProjectAccessCellRenderer
10605
10790
  }
10606
10791
  });
10607
10792
  ExplorerTableCellRendererFactory().registerRendererCatalog({
@@ -10641,7 +10826,7 @@ const isRecordAny = (obj)=>{
10641
10826
  return obj !== null && typeof obj === 'object';
10642
10827
  };
10643
10828
  const createTableColumns = (tableConfig)=>{
10644
- return tableConfig.fields.map((field)=>{
10829
+ const tableColumns = tableConfig.fields.map((field)=>{
10645
10830
  const columnDef = tableConfig?.columns?.[field];
10646
10831
  const cellRendererFunc = columnDef?.type ? ExplorerTableCellRendererFactory().getRenderer(columnDef?.type, columnDef?.cellRenderFunction ?? 'default') : undefined;
10647
10832
  const cellRendererFuncParams = columnDef?.params && isRecordAny(columnDef?.params) ? columnDef?.params : {};
@@ -10653,9 +10838,22 @@ const createTableColumns = (tableConfig)=>{
10653
10838
  accessorFn: columnDef?.accessorPath ? jsonPathAccessor(columnDef.accessorPath) : undefined,
10654
10839
  Cell: cellRendererFunc && columnDef?.params ? (cell)=>cellRendererFunc(cell, cellRendererFuncParams) : cellRendererFunc ? cellRendererFunc : undefined,
10655
10840
  size: columnDef?.width,
10656
- enableSorting: columnDef?.sortable ?? undefined
10841
+ enableSorting: columnDef?.sortable ?? undefined,
10842
+ visible: columnDef?.visible ?? true,
10843
+ lockVisible: columnDef?.lockVisible ?? false
10657
10844
  };
10658
- }, []);
10845
+ });
10846
+ const lockedVisibility = tableConfig.fields.reduce((acc, field)=>{
10847
+ const columnDef = tableConfig?.columns?.[field];
10848
+ if (columnDef && columnDef?.lockVisible) {
10849
+ acc[field] = columnDef?.visible ?? true; // assume visible by default
10850
+ }
10851
+ return acc;
10852
+ }, {});
10853
+ return {
10854
+ tableColumns: tableColumns,
10855
+ lockedVisibility: lockedVisibility
10856
+ };
10659
10857
  };
10660
10858
  const createArrayTableColumns = (root, tableConfig)=>{
10661
10859
  return tableConfig.fields.map((field)=>{
@@ -10765,7 +10963,7 @@ const ExpandingSubtable = ({ config, data })=>{
10765
10963
  const [expanded, setExpanded] = useState(false);
10766
10964
  const [headerHeight, setHeaderHeight] = useState(0);
10767
10965
  const theme = useMantineTheme();
10768
- const expandedTableColumns = useDeepCompareMemo(()=>{
10966
+ const { tableColumns: expandedTableColumns } = useDeepCompareMemo(()=>{
10769
10967
  return createTableColumns(config);
10770
10968
  }, [
10771
10969
  config
@@ -10947,6 +11145,350 @@ const QueryRowDetailsPanel = ({ id, index, tableConfig, accessibility })=>{
10947
11145
  });
10948
11146
  };
10949
11147
 
11148
+ function ColumnOrdering({ table, handleColumnOrderingReset, columnOrder, setColumnOrder, noColumnOrdering = [] }) {
11149
+ const [showColumnMenu, setShowColumnMenu] = useState(false);
11150
+ const [searchValue, setSearchValue] = useState('');
11151
+ const [columesVisible, setColumsnVisible] = useState([]);
11152
+ const isBackToDefaults = isEqual(table.initialState.columnOrder, columnOrder) && isEqual(table.initialState.columnVisibility, Object.fromEntries(Object.entries(table.getState().columnVisibility).filter(([, value])=>!value)));
11153
+ const sensors = useSensors(useSensor(PointerSensor, {
11154
+ activationConstraint: {
11155
+ distance: 5
11156
+ }
11157
+ }), useSensor(KeyboardSensor, {
11158
+ coordinateGetter: sortableKeyboardCoordinates
11159
+ }));
11160
+ const handleDragEnd = (event)=>{
11161
+ const { active, over } = event;
11162
+ if (active?.id && over?.id && active?.id !== over?.id) {
11163
+ setColumnOrder((items)=>{
11164
+ const oldIndex = items.indexOf(active?.id);
11165
+ const newIndex = items.indexOf(over?.id);
11166
+ return arrayMove(items, oldIndex, newIndex);
11167
+ });
11168
+ }
11169
+ };
11170
+ return /*#__PURE__*/ jsxs(Menu, {
11171
+ position: "bottom-end",
11172
+ middlewares: {
11173
+ shift: false,
11174
+ flip: false
11175
+ },
11176
+ onChange: setShowColumnMenu,
11177
+ offset: 0,
11178
+ zIndex: 400,
11179
+ withinPortal: true,
11180
+ children: [
11181
+ /*#__PURE__*/ jsx(Tooltip, {
11182
+ label: "Customize Columns",
11183
+ disabled: showColumnMenu,
11184
+ children: /*#__PURE__*/ jsx(Menu.Target, {
11185
+ children: /*#__PURE__*/ jsx(ActionIcon, {
11186
+ variant: "outline",
11187
+ size: "lg",
11188
+ "aria-label": "Customize Columns",
11189
+ color: "primary",
11190
+ "data-testid": "button-column-selector-box",
11191
+ className: `${showColumnMenu && 'border-2 border-primary'} hover:bg-primary hover:text-base-max`,
11192
+ children: !showColumnMenu ? /*#__PURE__*/ jsx(BsList, {
11193
+ size: "1.5rem",
11194
+ "aria-hidden": "true"
11195
+ }) : /*#__PURE__*/ jsx(BsX, {
11196
+ size: "2rem",
11197
+ "aria-hidden": "true"
11198
+ })
11199
+ })
11200
+ })
11201
+ }),
11202
+ /*#__PURE__*/ jsxs(Menu.Dropdown, {
11203
+ className: "bg-base-max border-2 border-primary p-2 rounded-md",
11204
+ "data-testid": "column-selector-popover-modal",
11205
+ children: [
11206
+ /*#__PURE__*/ jsxs("div", {
11207
+ className: "flex justify-between items-center",
11208
+ children: [
11209
+ /*#__PURE__*/ jsx("span", {
11210
+ className: "font-bold text-primary-darkest tracking-normal",
11211
+ children: "Customize Columns"
11212
+ }),
11213
+ /*#__PURE__*/ jsx(Tooltip, {
11214
+ label: "Restore defaults",
11215
+ disabled: isBackToDefaults,
11216
+ zIndex: 400,
11217
+ children: /*#__PURE__*/ jsx("span", {
11218
+ children: /*#__PURE__*/ jsx(ActionIcon, {
11219
+ onClick: handleColumnOrderingReset,
11220
+ className: isBackToDefaults ? 'invisible' : 'border-0',
11221
+ "data-testid": "restore-default-icon",
11222
+ "aria-label": "restore default column ordering",
11223
+ children: /*#__PURE__*/ jsx(FaUndo, {
11224
+ size: "1rem"
11225
+ })
11226
+ })
11227
+ })
11228
+ })
11229
+ ]
11230
+ }),
11231
+ /*#__PURE__*/ jsx(Divider, {
11232
+ color: "base.2",
11233
+ className: "mt-1"
11234
+ }),
11235
+ /*#__PURE__*/ jsx(TextInput, {
11236
+ value: searchValue,
11237
+ onChange: (event)=>setSearchValue(event.currentTarget.value.trim()),
11238
+ placeholder: "Filter Columns",
11239
+ "aria-label": "Search input for columns",
11240
+ leftSection: /*#__PURE__*/ jsx(MdSearch, {
11241
+ "aria-hidden": "true"
11242
+ }),
11243
+ className: "mb-2 mt-4",
11244
+ "data-testid": "textbox-column-selector"
11245
+ }),
11246
+ /*#__PURE__*/ jsx(DndContext, {
11247
+ sensors: sensors,
11248
+ collisionDetection: closestCenter,
11249
+ onDragEnd: handleDragEnd,
11250
+ modifiers: [
11251
+ restrictToVerticalAxis,
11252
+ restrictToWindowEdges,
11253
+ restrictToParentElement
11254
+ ],
11255
+ children: /*#__PURE__*/ jsx(SortableContext, {
11256
+ items: table.getAllLeafColumns(),
11257
+ strategy: verticalListSortingStrategy,
11258
+ children: /*#__PURE__*/ jsx(List, {
11259
+ columns: table.getAllLeafColumns(),
11260
+ searchValue: searchValue,
11261
+ noColumnOrdering: noColumnOrdering
11262
+ })
11263
+ })
11264
+ })
11265
+ ]
11266
+ })
11267
+ ]
11268
+ });
11269
+ }
11270
+ function List({ columns, searchValue, noColumnOrdering = [] }) {
11271
+ return /*#__PURE__*/ jsx("ul", {
11272
+ children: columns.filter((column)=>{
11273
+ if (!noColumnOrdering.includes(column.id)) {
11274
+ return humanify({
11275
+ term: column.id
11276
+ }).toLowerCase().includes(searchValue.toLowerCase());
11277
+ } else {
11278
+ return column.id;
11279
+ }
11280
+ }).map((column, index)=>{
11281
+ return !noColumnOrdering.includes(column.id) ? /*#__PURE__*/ jsx(DraggableColumnItem, {
11282
+ column: column,
11283
+ isNotLast: index < columns.length - 1
11284
+ }, column.id) : /*#__PURE__*/ jsx("li", {
11285
+ className: "hide"
11286
+ }, column.id);
11287
+ })
11288
+ });
11289
+ }
11290
+ function DraggableColumnItem({ column, isNotLast }) {
11291
+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
11292
+ id: column.id
11293
+ });
11294
+ const style = {
11295
+ transform: CSS.Transform.toString(transform),
11296
+ transition
11297
+ };
11298
+ return /*#__PURE__*/ jsx("li", {
11299
+ ref: setNodeRef,
11300
+ style: style,
11301
+ ...listeners,
11302
+ className: ` ${isNotLast ? 'mb-2' : ''}`,
11303
+ "data-testid": `column-selector-row-${column.id}`,
11304
+ children: /*#__PURE__*/ jsxs("div", {
11305
+ ...attributes,
11306
+ role: undefined,
11307
+ className: "flex gap-2 items-center bg-nci-violet-lightest px-1 py-1.5 h-6 cursor-move",
11308
+ children: [
11309
+ /*#__PURE__*/ jsx(MdDragIndicator, {
11310
+ size: "1rem",
11311
+ className: "text-primary"
11312
+ }),
11313
+ /*#__PURE__*/ jsx(Switch, {
11314
+ labelPosition: "left",
11315
+ label: typeof column?.columnDef?.header === 'string' ? column.columnDef.header : humanify({
11316
+ term: column.id
11317
+ }),
11318
+ classNames: {
11319
+ root: 'w-full',
11320
+ body: 'grow flex justify-between',
11321
+ label: 'text-xs font-medium tracking-normal'
11322
+ },
11323
+ color: "accent",
11324
+ checked: column.getIsVisible(),
11325
+ onChange: ()=>column.toggleVisibility(),
11326
+ onKeyDown: (e)=>{
11327
+ if (e.code === 'Space') {
11328
+ e.preventDefault();
11329
+ column.toggleVisibility();
11330
+ }
11331
+ },
11332
+ size: "xs",
11333
+ "data-testid": "switch-toggle"
11334
+ })
11335
+ ]
11336
+ })
11337
+ });
11338
+ }
11339
+
11340
+ const TitleWrapper = ({ title })=>/*#__PURE__*/ jsx("div", {
11341
+ className: "uppercase text-lg text-left ml-0 lg:ml-auto gap-x-2",
11342
+ children: title
11343
+ });
11344
+ const TotalDetailWrapper = ({ detail, className = '' })=>/*#__PURE__*/ jsx("div", {
11345
+ className: `self-center uppercase text-lg text-left ml-0 lg:ml-auto ${className}`,
11346
+ children: detail
11347
+ });
11348
+ const TooltipWrapper = ({ children, tooltip, searchFocused, baseZIndex })=>/*#__PURE__*/ jsx(Tooltip, {
11349
+ multiline: true,
11350
+ label: tooltip,
11351
+ position: "bottom-start",
11352
+ offset: 0,
11353
+ opened: searchFocused,
11354
+ zIndex: baseZIndex + 1,
11355
+ classNames: {
11356
+ tooltip: 'w-72 border border-base-lighter absolute bg-white p-2 text-nci-gray text-sm overflow-wrap break-all rounded-b rounded-t-none font-content'
11357
+ },
11358
+ children: children
11359
+ });
11360
+ const SearchInput = ({ searchTerm, placeholder, tooltip, searchFocused, baseZIndex, onClear, onChange, onFocus, onBlur })=>{
11361
+ const TooltipContainer = tooltip ? TooltipWrapper : React__default.Fragment;
11362
+ return /*#__PURE__*/ jsx(TooltipContainer, {
11363
+ tooltip: tooltip,
11364
+ baseZIndex: baseZIndex,
11365
+ searchFocused: searchFocused,
11366
+ children: /*#__PURE__*/ jsx(TextInput, {
11367
+ leftSection: /*#__PURE__*/ jsx(MdSearch, {
11368
+ size: 24,
11369
+ "aria-hidden": "true"
11370
+ }),
11371
+ "data-testid": "textbox-table-search-bar",
11372
+ placeholder: placeholder ?? 'Search',
11373
+ "aria-label": "Table Search Input",
11374
+ size: "sm",
11375
+ rightSection: searchTerm.length > 0 && /*#__PURE__*/ jsx(ActionIcon, {
11376
+ onClick: onClear,
11377
+ className: "border-0",
11378
+ children: /*#__PURE__*/ jsx(MdClose, {
11379
+ "aria-label": "clear search"
11380
+ })
11381
+ }),
11382
+ value: searchTerm,
11383
+ onChange: onChange,
11384
+ onFocus: onFocus,
11385
+ onBlur: onBlur,
11386
+ classNames: {
11387
+ input: `border-base-lighter focus:border-2 focus:border-primary${tooltip ? ' focus:rounded-b-none' : ''}`,
11388
+ wrapper: 'xl:w-72'
11389
+ }
11390
+ })
11391
+ });
11392
+ };
11393
+ function TableHeader({ additionalControls, tableTotalDetail, tableTitle, search, showControls, handleChange, table, columnOrder, setColumnOrder, baseZIndex, customBreakpoint, noColumnOrdering }) {
11394
+ const [searchTerm, setSearchTerm] = useState(search?.defaultSearchTerm ?? '');
11395
+ const [searchFocused, setSearchFocused] = useState(false);
11396
+ const inputRef = useRef(null); // updated apr 10 25 to get build to work
11397
+ const timeoutRef = useRef(null); // updated apr 10 25 to get build to work
11398
+ const shouldShowControls = search?.enabled || showControls;
11399
+ const { width } = useViewportSize();
11400
+ useEffect(()=>{
11401
+ if (search?.defaultSearchTerm) {
11402
+ inputRef.current?.focus();
11403
+ }
11404
+ }, [
11405
+ search?.defaultSearchTerm
11406
+ ]);
11407
+ const handleInputChange = (e)=>{
11408
+ const newSearchTerm = e.target.value;
11409
+ setSearchTerm(newSearchTerm);
11410
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
11411
+ timeoutRef.current = setTimeout(()=>{
11412
+ handleChange({
11413
+ newSearch: newSearchTerm.trim()
11414
+ });
11415
+ }, 400);
11416
+ };
11417
+ const handleClearClick = ()=>{
11418
+ setSearchTerm('');
11419
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
11420
+ handleChange({
11421
+ newSearch: ''
11422
+ });
11423
+ };
11424
+ const renderSearchAndControls = ()=>/*#__PURE__*/ jsxs("div", {
11425
+ className: "flex items-center gap-2",
11426
+ "data-testid": "table-options-menu",
11427
+ children: [
11428
+ search?.enabled && /*#__PURE__*/ jsx(SearchInput, {
11429
+ searchTerm: searchTerm,
11430
+ placeholder: search?.placeholder,
11431
+ tooltip: search?.tooltip,
11432
+ searchFocused: searchFocused,
11433
+ baseZIndex: baseZIndex,
11434
+ onClear: handleClearClick,
11435
+ onChange: handleInputChange,
11436
+ onFocus: ()=>setSearchFocused(true),
11437
+ onBlur: ()=>setSearchFocused(false)
11438
+ }),
11439
+ showControls && /*#__PURE__*/ jsx(ColumnOrdering, {
11440
+ table: table,
11441
+ handleColumnOrderingReset: ()=>{
11442
+ table.resetColumnVisibility();
11443
+ table.resetColumnOrder();
11444
+ },
11445
+ columnOrder: columnOrder,
11446
+ setColumnOrder: setColumnOrder,
11447
+ noColumnOrdering: noColumnOrdering
11448
+ })
11449
+ ]
11450
+ });
11451
+ const breakpoint = customBreakpoint ?? XL_BREAKPOINT;
11452
+ let detailClass = '';
11453
+ if (tableTitle !== undefined) {
11454
+ if (width >= breakpoint && shouldShowControls) {
11455
+ detailClass = 'ml-auto';
11456
+ }
11457
+ } else {
11458
+ if (width >= breakpoint && additionalControls) {
11459
+ detailClass = 'ml-auto';
11460
+ } else {
11461
+ detailClass = 'order-first basis-full grow-0 shrink-0 -mb-2';
11462
+ }
11463
+ }
11464
+ return /*#__PURE__*/ jsxs("div", {
11465
+ className: `flex flex-wrap gap-4 items-center mb-2 ${!additionalControls && !tableTitle ? 'justify-end' : 'justify-between'}`,
11466
+ children: [
11467
+ tableTitle && /*#__PURE__*/ jsx("div", {
11468
+ className: additionalControls || shouldShowControls && width < breakpoint ? 'basis-full grow-0 shrink-0 -mb-2' : '',
11469
+ children: /*#__PURE__*/ jsx(TitleWrapper, {
11470
+ title: tableTitle
11471
+ })
11472
+ }),
11473
+ additionalControls && additionalControls,
11474
+ tableTotalDetail && /*#__PURE__*/ jsx("div", {
11475
+ className: detailClass,
11476
+ children: /*#__PURE__*/ jsx(TotalDetailWrapper, {
11477
+ detail: tableTotalDetail
11478
+ })
11479
+ }),
11480
+ shouldShowControls && renderSearchAndControls()
11481
+ ]
11482
+ });
11483
+ }
11484
+
11485
+ // Provides the bottom X position so components can align themselves with the table
11486
+ function emptyFn() {}
11487
+ const TableXPositionContext = /*#__PURE__*/ createContext({
11488
+ xPosition: undefined,
11489
+ setXPosition: emptyFn
11490
+ });
11491
+
10950
11492
  const DEFAULT_PAGE_LIMIT_LABEL = 'Rows per Page (Limited to 10,0000):';
10951
11493
  const DEFAULT_PAGE_LIMIT = 10000;
10952
11494
  /**
@@ -10956,11 +11498,12 @@ const DEFAULT_PAGE_LIMIT = 10000;
10956
11498
  * @param index - Offset to use for fetching/displaying pages of rows
10957
11499
  * @param tableConfig - Inherited from ExplorerPageGetServerSideProps
10958
11500
  * @param accessibility - set the access level for the cohort data
10959
- */ const ExplorerTable = ({ index, tableConfig, accessibility, classNames, size = 'sm' })=>{
11501
+ */ const ExplorerTable = ({ index, tableConfig, accessibility, classNames, size = 'sm', additionalControls, tableTotalDetail, tableTitle })=>{
10960
11502
  const [pagination, setPagination] = useState({
10961
11503
  pageIndex: 0,
10962
- pageSize: 10
11504
+ pageSize: 20
10963
11505
  });
11506
+ const ref = useRef(null);
10964
11507
  const DetailsComponent = useMemo(()=>{
10965
11508
  if (!tableConfig?.detailsConfig || !tableConfig?.detailsConfig?.panel || tableConfig?.detailsConfig?.mode === 'none') return null;
10966
11509
  return tableConfig?.detailsConfig?.panelContainer === 'drawer' ? DetailsDrawer : DetailsModal;
@@ -10968,6 +11511,7 @@ const DEFAULT_PAGE_LIMIT = 10000;
10968
11511
  const [sorting, setSorting] = useState([]);
10969
11512
  const [rowSelection, setRowSelection] = useState({});
10970
11513
  const [selectedRow, setSelectedRow] = useState(undefined);
11514
+ const [columnVisibility, setColumnVisibility] = useState({});
10971
11515
  // const DetailsPanel = useMemo(
10972
11516
  // () =>
10973
11517
  // ExplorerTableDetailsPanelFactory().getRenderer(
@@ -10977,11 +11521,23 @@ const DEFAULT_PAGE_LIMIT = 10000;
10977
11521
  // [tableConfig?.detailsConfig?.panel],
10978
11522
  // );
10979
11523
  const DetailsPanel = useMemo(()=>QueryRowDetailsPanel, []);
10980
- const tableColumns = useDeepCompareMemo(()=>{
11524
+ const handleColumnVisibilityChange = (updater)=>{
11525
+ const newState = typeof updater === 'function' ? updater(columnVisibility) : updater;
11526
+ setColumnVisibility({
11527
+ ...newState,
11528
+ ...{
11529
+ 'mrt-row-expand': false,
11530
+ ...lockedVisibility
11531
+ }
11532
+ });
11533
+ };
11534
+ const { tableColumns, lockedVisibility } = useDeepCompareMemo(()=>{
10981
11535
  return createTableColumns(tableConfig);
10982
11536
  }, [
10983
11537
  tableConfig
10984
11538
  ]);
11539
+ const [columnOrder, setColumnOrder] = useState(tableColumns.map((column)=>column.id));
11540
+ const handleSearchOrPageChange = useCallback((params)=>null, []);
10985
11541
  // TODO: add support for nested fields
10986
11542
  const fields = useMemo(()=>tableColumns.map((column)=>column.field), [
10987
11543
  tableColumns
@@ -11003,7 +11559,8 @@ const DEFAULT_PAGE_LIMIT = 10000;
11003
11559
  };
11004
11560
  }, []);
11005
11561
  const cohortFilters = useCoreSelector((state)=>selectIndexFilters(state, index));
11006
- const { data, isLoading, isError, isFetching } = useGetRawDataAndTotalCountsQuery({
11562
+ const { xPosition, setXPosition } = useContext(TableXPositionContext);
11563
+ const { data, isLoading, isError, isFetching, isSuccess } = useGetRawDataAndTotalCountsQuery({
11007
11564
  type: index,
11008
11565
  fields: fields,
11009
11566
  filters: cohortFilters,
@@ -11059,12 +11616,17 @@ const DEFAULT_PAGE_LIMIT = 10000;
11059
11616
  onSortingChange: setSorting,
11060
11617
  enableTopToolbar: false,
11061
11618
  enableExpandAll: false,
11619
+ enableHiding: true,
11620
+ enableColumnActions: false,
11062
11621
  displayColumnDefOptions: {
11063
11622
  'mrt-row-expand': {
11064
11623
  enableHiding: true
11065
11624
  }
11066
11625
  },
11626
+ onColumnVisibilityChange: handleColumnVisibilityChange,
11067
11627
  enableExpanding: !!tableConfig?.detailsConfig,
11628
+ //enableColumnOrdering: tableConfig?.columnSorting,
11629
+ // enableHiding: tableConfig?.columnHiding,
11068
11630
  getRowId: getRowId(tableConfig),
11069
11631
  rowCount: totalRowCount,
11070
11632
  icons: TableIcons,
@@ -11115,9 +11677,8 @@ const DEFAULT_PAGE_LIMIT = 10000;
11115
11677
  showAlertBanner: isError,
11116
11678
  density: 'xs',
11117
11679
  rowSelection: rowSelection,
11118
- columnVisibility: {
11119
- 'mrt-row-expand': false
11120
- }
11680
+ columnVisibility: columnVisibility,
11681
+ columnOrder: columnOrder
11121
11682
  },
11122
11683
  mantineTableBodyRowProps: tableConfig.detailsConfig?.mode === 'click' ? ({ row })=>({
11123
11684
  onClick: ()=>{
@@ -11149,6 +11710,16 @@ const DEFAULT_PAGE_LIMIT = 10000;
11149
11710
  } else return null;
11150
11711
  } : undefined
11151
11712
  });
11713
+ const rowCount = table.getRowModel().rows.length;
11714
+ useLayoutEffect(()=>{
11715
+ if (setXPosition && xPosition === undefined && isSuccess && rowCount > 0 && ref.current) {
11716
+ setXPosition(ref?.current?.getBoundingClientRect()?.bottom);
11717
+ }
11718
+ }, [
11719
+ setXPosition,
11720
+ xPosition,
11721
+ rowCount
11722
+ ]);
11152
11723
  return /*#__PURE__*/ jsx(React__default.Fragment, {
11153
11724
  children: /*#__PURE__*/ jsxs(StudyProvider, {
11154
11725
  children: [
@@ -11166,11 +11737,25 @@ const DEFAULT_PAGE_LIMIT = 10000;
11166
11737
  accessibility
11167
11738
  }
11168
11739
  }),
11169
- /*#__PURE__*/ jsx("div", {
11170
- className: "inline-block overflow-x-scroll",
11171
- children: /*#__PURE__*/ jsx(MantineReactTable, {
11172
- table: table
11173
- })
11740
+ /*#__PURE__*/ jsxs("div", {
11741
+ className: "inline-block overflow-x-scroll ",
11742
+ ref: ref,
11743
+ children: [
11744
+ (tableConfig?.showTableHeaderControls || tableConfig.columnSorting || tableConfig?.columnHiding) && /*#__PURE__*/ jsx(TableHeader, {
11745
+ table: table,
11746
+ columnOrder: columnOrder,
11747
+ setColumnOrder: setColumnOrder,
11748
+ handleChange: handleSearchOrPageChange,
11749
+ additionalControls: additionalControls,
11750
+ tableTitle: tableTitle,
11751
+ tableTotalDetail: tableTotalDetail,
11752
+ showControls: tableConfig?.showTableHeaderControls,
11753
+ noColumnOrdering: Object.keys(lockedVisibility)
11754
+ }),
11755
+ /*#__PURE__*/ jsx(MantineReactTable, {
11756
+ table: table
11757
+ })
11758
+ ]
11174
11759
  })
11175
11760
  ]
11176
11761
  })
@@ -11382,16 +11967,19 @@ const useGuppyActionButton = ({ Modal403 = Modals.NoAccessModal, Modal400 = Moda
11382
11967
  modal: Modal400,
11383
11968
  message: errorMessage
11384
11969
  }));
11970
+ console.error(error);
11385
11971
  } else if (errorMessage === 'Your token is invalid or expired. Please get a new token.') {
11386
11972
  dispatch(showModal({
11387
11973
  modal: Modal403,
11388
11974
  message: errorMessage
11389
11975
  }));
11976
+ console.error(error);
11390
11977
  } else {
11391
11978
  dispatch(showModal({
11392
11979
  modal: Modal400,
11393
11980
  message: customErrorMessage || errorMessage
11394
11981
  }));
11982
+ console.error(error);
11395
11983
  }
11396
11984
  }, [
11397
11985
  Modal400,
@@ -12505,6 +13093,7 @@ const JSONObjectDownloadButton = ({ getData, filename = 'data.json', icon = 'gen
12505
13093
  })
12506
13094
  });
12507
13095
  };
13096
+ JSONObjectDownloadButton.displayName = 'JSONObjectDownloadButton';
12508
13097
 
12509
13098
  const UploadJSONButton = ({ handleFileChange, tooltip, icon = 'gen3:upload' })=>{
12510
13099
  const [file, setFile] = useState(null);
@@ -13179,7 +13768,7 @@ const EmptyData = {};
13179
13768
  charts,
13180
13769
  chartsSection
13181
13770
  ]);
13182
- const { data: counts, isFetching: isCountsFetching, isSuccess: isCountSuccess, isError: isCountsError } = useGetCountsQuery({
13771
+ const { data: counts, isFetching: isCountsFetching, isError: isCountsError } = useGetCountsQuery({
13183
13772
  type: index,
13184
13773
  filters: cohortFilters,
13185
13774
  accessibility: accessLevel,
@@ -13802,53 +14391,341 @@ const TabbedCohortBuilder = ({ index, tabsConfiguration })=>{
13802
14391
  const facetDataHooks = useDeepCompareMemo(()=>{
13803
14392
  return {
13804
14393
  // TODO: see if there a better way to do this
13805
- enum: EnumHookInstances,
13806
- exact: EnumHookInstances,
13807
- multiselect: EnumHookInstances,
13808
- range: RangeHookInstances,
13809
- age: RangeHookInstances,
13810
- year: RangeHookInstances,
13811
- years: RangeHookInstances,
13812
- days: RangeHookInstances,
13813
- percent: RangeHookInstances,
13814
- datetime: RangeHookInstances,
13815
- toggle: RangeHookInstances,
13816
- upload: EnumHookInstances
14394
+ enum: EnumHookInstances,
14395
+ exact: EnumHookInstances,
14396
+ multiselect: EnumHookInstances,
14397
+ range: RangeHookInstances,
14398
+ age: RangeHookInstances,
14399
+ year: RangeHookInstances,
14400
+ years: RangeHookInstances,
14401
+ days: RangeHookInstances,
14402
+ percent: RangeHookInstances,
14403
+ datetime: RangeHookInstances,
14404
+ toggle: RangeHookInstances,
14405
+ upload: EnumHookInstances
14406
+ };
14407
+ }, [
14408
+ getEnumFacetData,
14409
+ getRangeFacetData,
14410
+ index
14411
+ ]);
14412
+ return /*#__PURE__*/ jsx(Stack, {
14413
+ gap: "xs",
14414
+ align: "stretch",
14415
+ classNames: {
14416
+ root: 'w-full'
14417
+ },
14418
+ children: /*#__PURE__*/ jsx(FacetTabs, {
14419
+ activeTab: activeTab,
14420
+ setActiveTab: setActiveTab,
14421
+ facetDefinitions: facetDefinitions,
14422
+ tabsConfig: tabsConfig,
14423
+ usedFacets: cohortBuilderFilters,
14424
+ hooks: facetDataHooks,
14425
+ customFacetHooks: {
14426
+ useCustomFacets,
14427
+ useAvailableCustomFacets: (usedFacets, onlyFiltersWithValues, queryOptions)=>({
14428
+ data: {},
14429
+ isSuccess: true
14430
+ }),
14431
+ useAddCustomFilter: ()=>(filter)=>{},
14432
+ useRemoveCustomFilter: ()=>(filter)=>{}
14433
+ },
14434
+ getFacetLabel: ()=>'Cases',
14435
+ cardScrollMargin: calculateStickyHeaderHeight(),
14436
+ useFieldNameToTitle: useFieldNameToTitle
14437
+ })
14438
+ });
14439
+ };
14440
+
14441
+ const useGetFacetValuesQuery = (args)=>{
14442
+ const { data, isSuccess, isFetching, isError } = useGetAggsQuery(args);
14443
+ return {
14444
+ data: data ?? {},
14445
+ isError,
14446
+ isFetching,
14447
+ isSuccess
14448
+ };
14449
+ };
14450
+ const buildFileStatsdQuery = (type, fileSizeField, cohortItemIdField, fileItemIdField)=>{
14451
+ const fileStatsQuery = `query repositoryTotals ($filter: JSON, $accessibility:Accessibility) {
14452
+ _aggregation {
14453
+ ${type} (accessibility: $accessibility, filter: $filter) {
14454
+ ${customQueryStrForField(fileItemIdField, '{_totalCount }')}
14455
+ ${customQueryStrForField(fileSizeField, ' { histogram {sum} }')}
14456
+ ${customQueryStrForField(cohortItemIdField, '{_cardinalityCount }')}
14457
+ }
14458
+ }
14459
+ }`;
14460
+ return fileStatsQuery;
14461
+ };
14462
+ const useTotalFileSizeQuery = ({ repositoryFilters, repositoryIndex, cohortIndex, fileSizeField, cohortItemIdField, fileItemIdField, accessibility = Accessibility.ALL })=>{
14463
+ const [totals, setTotals] = useState({
14464
+ totalFileSize: 0,
14465
+ totalCaseCount: 0,
14466
+ totalFileCount: 0
14467
+ });
14468
+ const query = buildFileStatsdQuery(repositoryIndex, fileSizeField, cohortItemIdField, fileItemIdField);
14469
+ const { data, isSuccess, isFetching, isError } = useGeneralGQLQuery({
14470
+ query,
14471
+ variables: {
14472
+ accessibility,
14473
+ filter: convertFilterSetToGqlFilter(repositoryFilters)
14474
+ }
14475
+ });
14476
+ useDeepCompareEffect(()=>{
14477
+ if (isSuccess) {
14478
+ const response = data.data;
14479
+ const totalFileSize = response?._aggregation?.[repositoryIndex]?.[fileSizeField]?.histogram?.[0]?.sum || 0;
14480
+ const totalCaseCount = response?._aggregation?.[repositoryIndex]?.[cohortItemIdField]?._cardinalityCount || 0;
14481
+ const totalFileCount = response?._aggregation?.[repositoryIndex]?.[fileItemIdField]?._totalCount || 0;
14482
+ setTotals({
14483
+ totalFileSize,
14484
+ totalCaseCount,
14485
+ totalFileCount
14486
+ });
14487
+ }
14488
+ }, [
14489
+ data,
14490
+ isSuccess
14491
+ ]);
14492
+ return {
14493
+ data: totals,
14494
+ isError,
14495
+ isFetching,
14496
+ isSuccess
14497
+ };
14498
+ };
14499
+
14500
+ const Stats = ({ totalCaseCount, totalFileSize, totalFileCount, isFetching })=>/*#__PURE__*/ jsxs("div", {
14501
+ className: "flex gap-1 text-xl items-center uppercase flex-wrap",
14502
+ children: [
14503
+ /*#__PURE__*/ jsxs("div", {
14504
+ children: [
14505
+ "Total of",
14506
+ ' ',
14507
+ /*#__PURE__*/ jsx("strong", {
14508
+ children: !isFetching ? totalFileCount.toLocaleString() : '--'
14509
+ }),
14510
+ ' ',
14511
+ totalFileCount !== 1 ? 'Files' : 'File'
14512
+ ]
14513
+ }),
14514
+ /*#__PURE__*/ jsxs("div", {
14515
+ children: [
14516
+ /*#__PURE__*/ jsx(MdPerson, {
14517
+ className: "ml-2 mr-1 mb-1 inline-block",
14518
+ "aria-hidden": "true"
14519
+ }),
14520
+ /*#__PURE__*/ jsx("strong", {
14521
+ className: "mr-1",
14522
+ children: totalCaseCount
14523
+ }),
14524
+ totalCaseCount !== 1 ? 'Cases' : 'Case'
14525
+ ]
14526
+ }),
14527
+ /*#__PURE__*/ jsxs("div", {
14528
+ children: [
14529
+ /*#__PURE__*/ jsx(MdSave, {
14530
+ className: "ml-2 mr-1 mb-1 inline-block",
14531
+ "aria-hidden": "true"
14532
+ }),
14533
+ filesize(totalFileSize)
14534
+ ]
14535
+ })
14536
+ ]
14537
+ });
14538
+
14539
+ const FileFacetPanel = ({ filters, index, tabTitle, fieldMapping })=>{
14540
+ const repositoryFilters = useCoreSelector((state)=>selectIndexFilters(state, index));
14541
+ const fields = useMemo(()=>getAllFieldsFromFilterConfigs(filters?.tabs ?? []), [
14542
+ filters?.tabs
14543
+ ]);
14544
+ const [accessLevel, setAccessLevel] = useState(Accessibility.ALL);
14545
+ const [facetDefinitions, setFacetDefinitions] = useState({});
14546
+ const { data: facetData, isSuccess: isFacetsQuerySuccess, isFetching: isFacetsQueryFetching, isError: isFacetsQueryError } = useGetFacetValuesQuery({
14547
+ type: index,
14548
+ fields: fields,
14549
+ filters: repositoryFilters
14550
+ });
14551
+ // Set the facet definitions based on the data only the first time the data is loaded
14552
+ useDeepCompareEffect(()=>{
14553
+ if (isFacetsQuerySuccess && Object.keys(facetDefinitions).length === 0) {
14554
+ const configFacetDefs = filters?.tabs.reduce((acc, tab)=>{
14555
+ return {
14556
+ ...tab.fieldsConfig,
14557
+ ...acc
14558
+ };
14559
+ }, {});
14560
+ const facetDefs = classifyFacets(facetData, index, fieldMapping ?? [], configFacetDefs ?? {});
14561
+ setFacetDefinitions(facetDefs);
14562
+ }
14563
+ }, [
14564
+ isFacetsQuerySuccess,
14565
+ facetData,
14566
+ facetDefinitions,
14567
+ index,
14568
+ fieldMapping
14569
+ ]);
14570
+ const getEnumFacetData = useDeepCompareCallback((field)=>{
14571
+ let filters = undefined;
14572
+ let combineMode = 'or';
14573
+ if (field in repositoryFilters.root) {
14574
+ if (isIntersection(repositoryFilters.root[field])) {
14575
+ const intersectionFilters = removeIntersectionFromEnum(repositoryFilters.root[field]);
14576
+ if (intersectionFilters) {
14577
+ filters = extractEnumFilterValue(intersectionFilters);
14578
+ combineMode = 'and';
14579
+ }
14580
+ } else {
14581
+ filters = extractEnumFilterValue(repositoryFilters.root[field]);
14582
+ }
14583
+ }
14584
+ return {
14585
+ data: processBucketData(facetData?.[field]),
14586
+ enumFilters: filters,
14587
+ combineMode: combineMode,
14588
+ isSuccess: isFacetsQuerySuccess,
14589
+ isFetching: isFacetsQueryFetching
14590
+ };
14591
+ }, [
14592
+ repositoryFilters.root,
14593
+ facetData,
14594
+ isFacetsQuerySuccess
14595
+ ]);
14596
+ const facetDataHooks = useDeepCompareMemo(()=>{
14597
+ return {
14598
+ // TODO: see if there a better way to do this
14599
+ enum: {
14600
+ useGetFacetData: getEnumFacetData,
14601
+ useUpdateFacetFilters: partial(useUpdateFilters$1, index),
14602
+ useGetFacetFilters: partial(useGetFacetFilters$1, index),
14603
+ useClearFilter: partial(useClearFilters$1, index),
14604
+ useFilterExpanded: partial(useFilterExpandedState$1, index),
14605
+ useToggleExpandFilter: partial(useToggleExpandFilter$1, index),
14606
+ useGetCombineMode: partial(useCohortFilterCombineState, index),
14607
+ useSetCombineMode: partial(useSetCohortFilterCombineState, index),
14608
+ useFieldNameToTitle: useFieldNameToTitle,
14609
+ useTotalCounts: undefined,
14610
+ useUpdateCombineMode: ()=>null
14611
+ }
13817
14612
  };
13818
14613
  }, [
13819
14614
  getEnumFacetData,
13820
- getRangeFacetData,
13821
14615
  index
13822
14616
  ]);
13823
- return /*#__PURE__*/ jsx(Stack, {
13824
- gap: "xs",
13825
- align: "stretch",
13826
- classNames: {
13827
- root: 'w-full'
14617
+ if (isFacetsQueryError) {
14618
+ return /*#__PURE__*/ jsx(ErrorCard, {
14619
+ message: "Unable to fetch data from server"
14620
+ }); // TODO: replace with configurable message
14621
+ }
14622
+ return /*#__PURE__*/ jsx(DropdownPanel, {
14623
+ index: index,
14624
+ filters: filters,
14625
+ facetDefinitions: facetDefinitions,
14626
+ facetDataHooks: facetDataHooks,
14627
+ showAccessLevel: false,
14628
+ tabTitle: tabTitle,
14629
+ onAccessChange: setAccessLevel,
14630
+ accessLevel: accessLevel
14631
+ });
14632
+ };
14633
+
14634
+ const RepositoryPanel = ({ guppyConfig, filters, table, dropdowns, buttons, loginForDownload, fileStatsConfiguration })=>{
14635
+ useMediaQuery('(min-width: 639px)');
14636
+ useMediaQuery('(min-width: 1373px)');
14637
+ useMediaQuery('(min-width: 1600px)');
14638
+ const [tableXPosition, setTableXPosition] = useState(undefined);
14639
+ const defaultDropdowns = useMemo(()=>dropdowns ?? {}, [
14640
+ dropdowns
14641
+ ]);
14642
+ const defaultButtons = useMemo(()=>buttons ?? [], [
14643
+ buttons
14644
+ ]);
14645
+ const [accessLevel, setAccessLevel] = useState(Accessibility.ALL);
14646
+ const index = guppyConfig.dataType;
14647
+ useMemo(()=>getAllFieldsFromFilterConfigs(filters?.tabs ?? []), [
14648
+ filters?.tabs
14649
+ ]);
14650
+ const repositoryFilters = useCoreSelector((state)=>selectIndexFilters(state, index));
14651
+ const { data: fileSizeSliceData, isFetching: isFileSizeFetching } = useTotalFileSizeQuery({
14652
+ repositoryFilters: repositoryFilters,
14653
+ ...fileStatsConfiguration
14654
+ });
14655
+ if (fileStatsConfiguration) return /*#__PURE__*/ jsx(TableXPositionContext.Provider, {
14656
+ value: {
14657
+ xPosition: tableXPosition,
14658
+ setXPosition: setTableXPosition
13828
14659
  },
13829
- children: /*#__PURE__*/ jsx(FacetTabs, {
13830
- activeTab: activeTab,
13831
- setActiveTab: setActiveTab,
13832
- facetDefinitions: facetDefinitions,
13833
- tabsConfig: tabsConfig,
13834
- usedFacets: cohortBuilderFilters,
13835
- hooks: facetDataHooks,
13836
- customFacetHooks: {
13837
- useCustomFacets,
13838
- useAvailableCustomFacets: (usedFacets, onlyFiltersWithValues, queryOptions)=>({
13839
- data: {},
13840
- isSuccess: true
14660
+ children: /*#__PURE__*/ jsx("div", {
14661
+ className: "flex flex-col mt-3 relative px-4 bg-base-lightest w-full",
14662
+ children: /*#__PURE__*/ jsxs("div", {
14663
+ className: "flex w-full pt-2",
14664
+ children: [
14665
+ /*#__PURE__*/ jsx("div", {
14666
+ id: "cohort-builder-filters",
14667
+ className: "flex-shrink-0 md:w-1/4 lg:w-1/5",
14668
+ children: filters?.tabs && /*#__PURE__*/ jsx(FileFacetPanel, {
14669
+ index: index,
14670
+ filters: filters,
14671
+ tabTitle: "Files",
14672
+ fieldMapping: guppyConfig?.fieldMapping ?? []
14673
+ })
13841
14674
  }),
13842
- useAddCustomFilter: ()=>(filter)=>{},
13843
- useRemoveCustomFilter: ()=>(filter)=>{}
13844
- },
13845
- getFacetLabel: ()=>'Cases',
13846
- cardScrollMargin: calculateStickyHeaderHeight(),
13847
- useFieldNameToTitle: useFieldNameToTitle
14675
+ /*#__PURE__*/ jsx("div", {
14676
+ id: "cohort-builder-content",
14677
+ className: "flex flex-col md:w-3/4 lg:w-4/5 pl-4",
14678
+ children: table?.enabled && /*#__PURE__*/ jsx(ExplorerTable, {
14679
+ index: index,
14680
+ tableConfig: table,
14681
+ accessibility: accessLevel,
14682
+ additionalControls: /*#__PURE__*/ jsx(DownloadsPanel, {
14683
+ dropdowns: defaultDropdowns,
14684
+ buttons: defaultButtons,
14685
+ loginForDownload: loginForDownload,
14686
+ index: index,
14687
+ totalCount: fileSizeSliceData.totalCaseCount ?? 0,
14688
+ fields: table?.fields ?? [],
14689
+ filter: repositoryFilters
14690
+ }),
14691
+ tableTotalDetail: /*#__PURE__*/ jsx("div", {
14692
+ className: "ml-auto",
14693
+ children: /*#__PURE__*/ jsx(Stats, {
14694
+ totalFileCount: fileSizeSliceData.totalFileCount,
14695
+ totalCaseCount: fileSizeSliceData.totalCaseCount,
14696
+ totalFileSize: fileSizeSliceData.totalFileSize,
14697
+ isFetching: isFileSizeFetching
14698
+ })
14699
+ })
14700
+ })
14701
+ })
14702
+ ]
14703
+ })
13848
14704
  })
13849
14705
  });
13850
14706
  };
13851
14707
 
14708
+ const validateObjectHasRequiredFields = (obj, requiredFields)=>requiredFields.every((field)=>obj[field] !== undefined);
14709
+
14710
+ const Repository = ({ filters, guppyConfig, table, buttons, loginForDownload, dropdowns, fileStatsConfiguration })=>{
14711
+ if (!fileStatsConfiguration || !validateObjectHasRequiredFields(fileStatsConfiguration, Object.keys(fileStatsConfiguration))) {
14712
+ return /*#__PURE__*/ jsx(MessagePage, {
14713
+ children: /*#__PURE__*/ jsx(ErrorCard, {
14714
+ message: "Invalid file stats configuration"
14715
+ })
14716
+ });
14717
+ }
14718
+ return /*#__PURE__*/ jsx(RepositoryPanel, {
14719
+ guppyConfig: guppyConfig,
14720
+ filters: filters,
14721
+ table: table,
14722
+ dropdowns: dropdowns,
14723
+ buttons: buttons,
14724
+ loginForDownload: loginForDownload,
14725
+ fileStatsConfiguration: fileStatsConfiguration
14726
+ }, "Repository-Panel");
14727
+ };
14728
+
13852
14729
  /**
13853
14730
  * Fetches graphql data from a graphql endpoint if one is specified, or guppy by default.
13854
14731
  * @param graphQLEndpoint - The location of the graphql endpoint.
@@ -14053,7 +14930,7 @@ const WorkspaceStatusProvider = ({ children })=>{
14053
14930
  id: id,
14054
14931
  status: WorkspaceStatus.Launching,
14055
14932
  requestedStatus: RequestedWorkspaceStatus.Launch,
14056
- requestedStatusTimestamp: getCurrentTimestamp()
14933
+ requestedStatusTimestamp: getCurrentTimestamp$1()
14057
14934
  }));
14058
14935
  };
14059
14936
  const toggleFullscreen = ()=>switchScreenMode();
@@ -15308,7 +16185,6 @@ var ContentSource$1 = ContentSource.getInstance();
15308
16185
  if (isHeaderMetadata(loadedHeaderMetadata)) {
15309
16186
  headerMetadata = loadedHeaderMetadata;
15310
16187
  } else {
15311
- console.log('loadedHeaderMetadata', loadedHeaderMetadata);
15312
16188
  console.warn('headerMetadata is not a valid HeaderMetadata object');
15313
16189
  }
15314
16190
  } catch (error) {
@@ -19159,7 +20035,7 @@ const PropertiesTable = ({ properties, required, category, subCategory, selected
19159
20035
  header: 'Type',
19160
20036
  size: 90,
19161
20037
  Cell: ({ cell, row })=>{
19162
- return /*#__PURE__*/ jsx(List, {
20038
+ return /*#__PURE__*/ jsx(List$1, {
19163
20039
  size: "sm",
19164
20040
  spacing: "xs",
19165
20041
  center: true,
@@ -19170,7 +20046,7 @@ const PropertiesTable = ({ properties, required, category, subCategory, selected
19170
20046
  size: "0.5rem"
19171
20047
  }),
19172
20048
  id: `${category}-${subCategory}-${row.original.property_id}-list`,
19173
- children: cell.getValue().map((type, index)=>/*#__PURE__*/ jsx(List.Item, {
20049
+ children: cell.getValue().map((type, index)=>/*#__PURE__*/ jsx(List$1.Item, {
19174
20050
  children: type
19175
20051
  }, `${row.original.property_id}-${type}-${index}`))
19176
20052
  });
@@ -19370,6 +20246,428 @@ var CategoryPanel$1 = /*#__PURE__*/ React__default.memo(CategoryPanel, (prevProp
19370
20246
  return prevProps.category === nextProps.category && selectedItems.node === prevProps.category && prevProps.selectedId === nextProps.selectedId && prevProps.scrollToSelection === nextProps.scrollToSelection;
19371
20247
  });
19372
20248
 
20249
+ /**
20250
+ * Get subgroup links from link
20251
+ * @param {object} link - array of links
20252
+ * @param {object} nameToNode - key (node name) value (node object) map
20253
+ * @param {string} sourceId - source id for subgroup links
20254
+ * This function traverse links recursively and return all nested subgroup lnks
20255
+ */ const getSubgroupLinks = (link, nameToNode, sourceId)=>{
20256
+ let subgroupLinks = [];
20257
+ if (link.subgroup) {
20258
+ link.subgroup.forEach((sgLink)=>{
20259
+ if (sgLink.subgroup) {
20260
+ subgroupLinks = subgroupLinks.concat(getSubgroupLinks(sgLink, nameToNode, sourceId));
20261
+ } else {
20262
+ subgroupLinks.push({
20263
+ source: nameToNode[sourceId],
20264
+ target: nameToNode[sgLink.target_type],
20265
+ exists: 1,
20266
+ ...sgLink
20267
+ });
20268
+ }
20269
+ });
20270
+ }
20271
+ return subgroupLinks;
20272
+ };
20273
+ /**
20274
+ * Given a data dictionary that defines a set of nodes
20275
+ * and edges, returns the nodes and edges in correct format
20276
+ *
20277
+ * @method createNodesAndEdges
20278
+ * @param props: Object (normally taken from redux state) that includes dictionary
20279
+ * property defining the dictionary as well as other optional properties
20280
+ * such as counts_search and links_search (created by getCounts) with
20281
+ * information about the number of each type (node) and link (between
20282
+ * nodes with a link's source and target types) that actually
20283
+ * exist in the data
20284
+ * @param createAll: Include all nodes and edges or only those that are populated in
20285
+ * counts_search and links_search
20286
+ * @param nodesToHide: Array of nodes to hide from graph
20287
+ * @returns { nodes, edges } Object containing nodes and edges
20288
+ */ function createNodesAndEdges(props, createAll, nodesToHide = [
20289
+ 'program'
20290
+ ]) {
20291
+ const { dictionary } = props;
20292
+ const nodes = Object.keys(dictionary).filter((key)=>!key.startsWith('_') && dictionary[key].type === 'object' && dictionary[key].category !== 'internal' && !nodesToHide.includes(key)).map((key)=>{
20293
+ let count = 0;
20294
+ if (props.counts_search) {
20295
+ count = props.counts_search[`_${key}_count`];
20296
+ }
20297
+ return {
20298
+ name: dictionary[key].title,
20299
+ count,
20300
+ ...dictionary[key]
20301
+ };
20302
+ }).filter((node)=>createAll);
20303
+ const nameToNode = nodes.reduce((db, node)=>{
20304
+ db[node.id] = node;
20305
+ return db;
20306
+ }, {});
20307
+ const hideDb = nodesToHide.reduce((db, name)=>{
20308
+ db[name] = true;
20309
+ return db;
20310
+ }, {});
20311
+ const edges = nodes.filter((node)=>node.links !== undefined && node.links.length > 0).reduce((list, node)=>{
20312
+ const newLinks = node.links.map((link)=>({
20313
+ source: node,
20314
+ target: nameToNode[link.target_type],
20315
+ exists: 1,
20316
+ ...link
20317
+ }));
20318
+ return list.concat(newLinks);
20319
+ }, []).reduce((list, link)=>{
20320
+ let result = list;
20321
+ if (link.target) {
20322
+ result.push(link);
20323
+ }
20324
+ if (link.subgroup) {
20325
+ const sgLinks = getSubgroupLinks(link, nameToNode, link.source.id);
20326
+ result = result.concat(sgLinks);
20327
+ }
20328
+ return result;
20329
+ }, []).filter(// target type exist and is not in hide list
20330
+ (link)=>link.target && link.target.id in nameToNode && !(link.target.id in hideDb)).map((link)=>{
20331
+ // decorate each link with its "exists" count if available
20332
+ // (number of instances of link between source and target types in the data)
20333
+ const res = link;
20334
+ res.exists = props.links_search ? props.links_search[`${res.source.id}_${res.name}_to_${res.target.id}_link`] : 0;
20335
+ return res;
20336
+ }).filter(// filter out if no instances of this link exists and createAll is not specified
20337
+ (link)=>createAll);
20338
+ return {
20339
+ nodes,
20340
+ edges
20341
+ };
20342
+ }
20343
+ /**
20344
+ * Find the root of the given graph (no edges out)
20345
+ * @method findRoot
20346
+ * @param nodes
20347
+ * @param edges
20348
+ * @return {string} rootName or null if no root
20349
+ */ function findRoot(nodes, edges) {
20350
+ const couldBeRoot = edges.reduce((db, edge)=>{
20351
+ // At some point the d3 force layout converts
20352
+ // edge.source and edge.target into node references ...
20353
+ const sourceName = typeof edge.source === 'object' ? edge.source.id : edge.source;
20354
+ if (db[sourceName]) {
20355
+ db[sourceName] = false;
20356
+ }
20357
+ return db;
20358
+ }, // initialize emptyDb - any node could be the root
20359
+ nodes.reduce((emptyDb, node)=>{
20360
+ const res = emptyDb;
20361
+ res[node.id] = true;
20362
+ return res;
20363
+ }, {}));
20364
+ const rootNode = nodes.find((n)=>couldBeRoot[n.id]);
20365
+ return rootNode ? rootNode.id : null;
20366
+ }
20367
+ /**
20368
+ * Recursive helper function for getTreeHierarchy
20369
+ * Returns the hierarchy of the tree in the form of a map
20370
+ * Each (key, value) consists of (node, node's descendants including the node itself)
20371
+ * @method getTreeHierarchyHelper
20372
+ * @param root
20373
+ * @param name2EdgesIn
20374
+ * @param hierarchy
20375
+ * @return {map}
20376
+ */ function getTreeHierarchyHelper(node, name2EdgesIn, hierarchy) {
20377
+ const descendants = new Set();
20378
+ descendants.add(node);
20379
+ hierarchy.set(node, descendants);
20380
+ name2EdgesIn[node].forEach((edge)=>{
20381
+ const sourceName = typeof edge.source === 'object' ? edge.source.id : edge.source;
20382
+ if (!hierarchy.get(sourceName)) {
20383
+ hierarchy = getTreeHierarchyHelper(sourceName, name2EdgesIn, hierarchy);
20384
+ descendants.add(sourceName);
20385
+ hierarchy.get(sourceName).forEach((n)=>{
20386
+ descendants.add(n);
20387
+ });
20388
+ }
20389
+ });
20390
+ hierarchy.set(node, descendants);
20391
+ return hierarchy;
20392
+ }
20393
+ /**
20394
+ * Returns the hierarchy of the tree in the form of a map
20395
+ * Each (key, value) consists of (node, node's descendants including the node itself)
20396
+ * @method getTreeHierarchy
20397
+ * @param root
20398
+ * @param name2EdgesIn
20399
+ * @return {map}
20400
+ */ function getTreeHierarchy(root, name2EdgesIn) {
20401
+ return getTreeHierarchyHelper(root, name2EdgesIn, new Map());
20402
+ }
20403
+ /**
20404
+ * Arrange nodes in dictionary graph breadth first, and build level database.
20405
+ * If a node links to multiple parents, then place it under the highest parent ...
20406
+ * Exported for testing.
20407
+ *
20408
+ * @param {Array} nodes
20409
+ * @param {Array} edges
20410
+ * @return { nodesBreadthFirst, treeLevel2Names, name2Level } where
20411
+ * nodesBreadthFirst is array of node names, and
20412
+ * treeLevel2Names is an array of arrays of node names,
20413
+ * and name2Level is a mapping of node name to level
20414
+ */ function nodesBreadthFirst(nodes, edges) {
20415
+ const result = {
20416
+ bfOrder: [],
20417
+ treeLevel2Names: [],
20418
+ name2Level: {}
20419
+ };
20420
+ // mapping of node name to edges that point into that node
20421
+ const name2EdgesIn = edges.reduce((db, edge)=>{
20422
+ // At some point the d3 force layout converts edge.source
20423
+ // and edge.target into node references ...
20424
+ const targetName = typeof edge.target === 'object' ? edge.target.id : edge.target;
20425
+ if (db[targetName]) {
20426
+ db[targetName].push(edge);
20427
+ } else {
20428
+ console.error(`Edge points to unknown node: ${targetName}`);
20429
+ }
20430
+ return db;
20431
+ }, // initialize emptyDb - include nodes that have no incoming edges (leaves)
20432
+ nodes.reduce((emptyDb, node)=>{
20433
+ const res = emptyDb;
20434
+ res[node.id] = [];
20435
+ return res;
20436
+ }, {}));
20437
+ // root node has no edges coming out of it, just edges coming in
20438
+ const root = findRoot(nodes, edges);
20439
+ if (!root) {
20440
+ console.log('Could not find root of given graph');
20441
+ return result;
20442
+ }
20443
+ const processedNodes = new Set(); // account for nodes that link to multiple other nodes
20444
+ let queue = [];
20445
+ queue.push({
20446
+ query: root,
20447
+ level: 0
20448
+ });
20449
+ // just 2b safe - could be user gives us a graph without a 'project'
20450
+ if (!name2EdgesIn[root]) {
20451
+ name2EdgesIn[root] = [];
20452
+ }
20453
+ const name2ActualLvl = {};
20454
+ const hierarchy = getTreeHierarchy(root, name2EdgesIn);
20455
+ // Run through this once to determine the actual level of each node
20456
+ for(let head = 0; head < queue.length; head += 1){
20457
+ const { query, level } = queue[head]; // breadth first
20458
+ name2ActualLvl[query] = level;
20459
+ name2EdgesIn[query].forEach((edge)=>{
20460
+ // At some point the d3 force layout converts edge.source
20461
+ // and edge.target into node references ...
20462
+ const sourceName = typeof edge.source === 'object' ? edge.source.id : edge.source;
20463
+ if (name2EdgesIn[sourceName]) {
20464
+ const isAncestor = hierarchy.get(sourceName).has(query);
20465
+ // only push node if it is not an ancestor of the current node, or else --> cycle
20466
+ if (!isAncestor) {
20467
+ queue.push({
20468
+ query: sourceName,
20469
+ level: level + 1
20470
+ });
20471
+ }
20472
+ } else {
20473
+ console.log(`Edge comes from unknown node ${sourceName}`);
20474
+ }
20475
+ });
20476
+ }
20477
+ // Reset and run for real
20478
+ queue = [];
20479
+ queue.push({
20480
+ query: root,
20481
+ level: 0
20482
+ });
20483
+ // queue.shift is O(n), so just keep pushing, and move the head
20484
+ for(let head = 0; head < queue.length; head += 1){
20485
+ const { query, level } = queue[head]; // breadth first
20486
+ result.bfOrder.push(query);
20487
+ processedNodes.add(query);
20488
+ if (result.treeLevel2Names.length <= level) {
20489
+ result.treeLevel2Names.push([]);
20490
+ }
20491
+ result.treeLevel2Names[level].push(query);
20492
+ result.name2Level[query] = level;
20493
+ name2EdgesIn[query].forEach((edge)=>{
20494
+ // At some point the d3 force layout converts edge.source
20495
+ // and edge.target into node references ...
20496
+ const sourceName = typeof edge.source === 'object' ? edge.source.id : edge.source;
20497
+ if (name2EdgesIn[sourceName]) {
20498
+ if (!processedNodes.has(sourceName) && name2ActualLvl[sourceName] === level + 1) {
20499
+ //
20500
+ // edge source has not yet been processed via another link from the source
20501
+ // to a node higher in the graph
20502
+ //
20503
+ processedNodes.add(sourceName); // don't double-queue a node
20504
+ queue.push({
20505
+ query: sourceName,
20506
+ level: level + 1
20507
+ });
20508
+ }
20509
+ } else {
20510
+ console.log(`Edge comes from unknown node ${sourceName}`);
20511
+ }
20512
+ });
20513
+ }
20514
+ return result;
20515
+ }
20516
+ const placeNodesOnGraph = (treeLevel2Names, nodesById)=>{
20517
+ let currentX = 0;
20518
+ let currentY = 0;
20519
+ const xSpacing = 300;
20520
+ const ySpacing = 100;
20521
+ const positions = [];
20522
+ treeLevel2Names.forEach((level)=>{
20523
+ level.forEach((id)=>{
20524
+ positions.push({
20525
+ id: id,
20526
+ name: nodesById[id].name,
20527
+ x: currentX,
20528
+ y: currentY
20529
+ });
20530
+ currentY += ySpacing;
20531
+ });
20532
+ currentY = 0;
20533
+ currentX += xSpacing;
20534
+ });
20535
+ return positions;
20536
+ };
20537
+ const linksForGraph = (edges)=>{
20538
+ return edges.map((edge)=>{
20539
+ return {
20540
+ source: edge.source.id,
20541
+ target: edge.target.id
20542
+ };
20543
+ });
20544
+ };
20545
+ //TODO posably get this from somewhere else
20546
+ // object of nodes by ID for easy lookup
20547
+ const getNodesById = (nodes)=>{
20548
+ return nodes.reduce((db, node)=>{
20549
+ db[node.id] = node;
20550
+ return db;
20551
+ }, {});
20552
+ };
20553
+ const formatDataForGraph = (categories)=>{
20554
+ //TODO cash all this unchanging data
20555
+ const { nodes, edges } = createNodesAndEdges({
20556
+ dictionary: categories
20557
+ }, true, []);
20558
+ const nodeTree = nodesBreadthFirst(nodes, edges);
20559
+ console.log('nodes edges', nodes, edges);
20560
+ console.log('nodesBreadthFirst', nodeTree);
20561
+ const nodesById = getNodesById(nodes);
20562
+ const graphData = placeNodesOnGraph(nodeTree.treeLevel2Names, nodesById);
20563
+ console.log('placeNodesOnGraph', graphData);
20564
+ const graphLinks = linksForGraph(edges);
20565
+ console.log('linksForGraph', graphLinks);
20566
+ return {
20567
+ data: graphData,
20568
+ links: graphLinks
20569
+ };
20570
+ };
20571
+
20572
+ const GraphView = ({ categories, dictionary, selectedId })=>{
20573
+ const [zoomLevel, setZoomLevel] = useState(0); // TODO Start here for zoom level
20574
+ const dataAndLinks = formatDataForGraph(dictionary);
20575
+ console.log('GraphView dictionary', dictionary);
20576
+ console.log('GraphView categories', categories);
20577
+ console.log('GraphView selectedId', selectedId);
20578
+ const chartDefinition = useMemo(()=>{
20579
+ return {
20580
+ tooltip: {
20581
+ trigger: 'item',
20582
+ triggerOn: 'mousemove'
20583
+ },
20584
+ toolbox: {
20585
+ show: true,
20586
+ left: 'left',
20587
+ orient: 'vertical',
20588
+ itemSize: 30,
20589
+ iconStyle: {
20590
+ borderWidth: 0,
20591
+ opacity: 0.8
20592
+ },
20593
+ emphasis: {
20594
+ iconStyle: {
20595
+ opacity: 1,
20596
+ color: '#3283c8'
20597
+ }
20598
+ },
20599
+ feature: {
20600
+ restore: {
20601
+ show: true,
20602
+ title: 'Reset',
20603
+ icon: 'image://data:image/gif;base64,R0lGODlhHgAeAKEAADKDyP///zKDyDKDyCH5BAEKAAIALAAAAAAeAB4AAAJChI+py+0Powm02irP3TRPfnkAJjZkuZxooq5a57Jw/AY00sY5lO+PjwKWhCKix5hBSpQRJm+2BFmKUueoCr1pt5ICADs='
20604
+ },
20605
+ myZoomIn: {
20606
+ show: true,
20607
+ title: 'Zoom In',
20608
+ icon: 'image://data:image/gif;base64,R0lGODlhHgAeAKEAADKDyP///zKDyDKDyCH5BAEKAAIALAAAAAAeAB4AAAJAhI+py+0PIww0yFnvq1Y37n1ZuICkYp5Iqhps+27cTNfdauc0qvcU79NpYiciyRhCepTDUcvlfDIvU0n1ic2GCgA7',
20609
+ onclick: (params)=>{
20610
+ const series = params?.option?.series;
20611
+ const zoom = series && series[0] ? series[0].zoom : 1;
20612
+ setZoomLevel((zoom || 1) + 0.1);
20613
+ }
20614
+ },
20615
+ myZoomOut: {
20616
+ show: true,
20617
+ title: 'Zoom Out',
20618
+ icon: 'image://data:image/gif;base64,R0lGODlhHgAeAKEAADKDyP///zKDyDKDyCH5BAEKAAIALAAAAAAeAB4AAAIohI+py+0Po5y02ouz3rz7PwXiSJbmqJzqmq4u2b4vSNf2jef6zvd1AQA7',
20619
+ onclick: (params)=>{
20620
+ const series = params?.option?.series;
20621
+ const zoom = series && series[0] ? series[0].zoom : 1;
20622
+ setZoomLevel((zoom || 1) - 0.1);
20623
+ }
20624
+ }
20625
+ }
20626
+ },
20627
+ //https://echarts.apache.org/en/option.html#legend
20628
+ series: {
20629
+ type: 'graph',
20630
+ roam: true,
20631
+ zoom: zoomLevel,
20632
+ label: {
20633
+ show: true,
20634
+ position: 'right',
20635
+ backgroundColor: 'white'
20636
+ },
20637
+ symbol: 'circle',
20638
+ emphasis: {
20639
+ focus: 'adjacency'
20640
+ },
20641
+ //edgeSymbol: ['circle', 'circle'],
20642
+ //edgeSymbolSize: [4, 4],
20643
+ lineStyle: {
20644
+ opacity: 0.9,
20645
+ width: 2,
20646
+ curveness: 0,
20647
+ cap: 'square'
20648
+ },
20649
+ //https://echarts.apache.org/en/option.html#series-tree.data
20650
+ data: dataAndLinks.data,
20651
+ links: dataAndLinks.links,
20652
+ top: '10%',
20653
+ left: '5%'
20654
+ }
20655
+ };
20656
+ }, [
20657
+ dataAndLinks,
20658
+ zoomLevel
20659
+ ]);
20660
+ //TODO: import real data
20661
+ //TODO: connections between nodes
20662
+ //TODO: ZOOM IN AND OUT AND MOVE AROUND controls?
20663
+ return /*#__PURE__*/ jsx("div", {
20664
+ className: "w-full h-full min-h-[800px]",
20665
+ children: /*#__PURE__*/ jsx(ReactECharts, {
20666
+ option: chartDefinition
20667
+ })
20668
+ });
20669
+ };
20670
+
19373
20671
  const Dictionary = ()=>{
19374
20672
  const [selectedId, setSelectedId] = useState('');
19375
20673
  const [view, setView] = useState('table');
@@ -19388,6 +20686,11 @@ const Dictionary = ()=>{
19388
20686
  scrollIntoView,
19389
20687
  targetRef
19390
20688
  ]);
20689
+ const categoryPanelTable = Object.keys(categories).length && Object.keys(categories).map((category)=>/*#__PURE__*/ jsx(CategoryPanel$1, {
20690
+ category: category,
20691
+ selectedId: selectedId,
20692
+ scrollToSelection: scrollToSelection
20693
+ }, category));
19391
20694
  return /*#__PURE__*/ jsxs(Fragment, {
19392
20695
  children: [
19393
20696
  /*#__PURE__*/ jsx("div", {
@@ -19428,11 +20731,26 @@ const Dictionary = ()=>{
19428
20731
  ref: scrollableRef,
19429
20732
  children: /*#__PURE__*/ jsx("div", {
19430
20733
  className: "h-full",
19431
- children: Object.keys(categories).length && Object.keys(categories).map((category)=>/*#__PURE__*/ jsx(CategoryPanel$1, {
19432
- category: category,
19433
- selectedId: selectedId,
19434
- scrollToSelection: scrollToSelection
19435
- }, category))
20734
+ children: config?.showGraph ? /*#__PURE__*/ jsxs(Tabs, {
20735
+ value: view,
20736
+ keepMounted: false,
20737
+ className: "h-full",
20738
+ children: [
20739
+ /*#__PURE__*/ jsx(Tabs.Panel, {
20740
+ value: "table",
20741
+ children: categoryPanelTable
20742
+ }),
20743
+ /*#__PURE__*/ jsx(Tabs.Panel, {
20744
+ value: "graph",
20745
+ className: "h-full",
20746
+ children: /*#__PURE__*/ jsx(GraphView, {
20747
+ categories: categories,
20748
+ dictionary: dictionary,
20749
+ selectedId: selectedId
20750
+ })
20751
+ })
20752
+ ]
20753
+ }) : categoryPanelTable
19436
20754
  })
19437
20755
  })
19438
20756
  ]
@@ -19484,7 +20802,7 @@ const buildValueElements = (element)=>{
19484
20802
  case 'string':
19485
20803
  return /*#__PURE__*/ jsx("span", {});
19486
20804
  case 'enum':
19487
- return /*#__PURE__*/ jsx(List, {
20805
+ return /*#__PURE__*/ jsx(List$1, {
19488
20806
  size: "sm",
19489
20807
  spacing: "xs",
19490
20808
  center: true,
@@ -19495,7 +20813,7 @@ const buildValueElements = (element)=>{
19495
20813
  size: "0.5rem"
19496
20814
  }),
19497
20815
  id: `${element.id}-enum-value-list`,
19498
- children: element?.enum?.map((value)=>/*#__PURE__*/ jsx(List.Item, {
20816
+ children: element?.enum?.map((value)=>/*#__PURE__*/ jsx(List$1.Item, {
19499
20817
  children: value
19500
20818
  }, `value-enum-${element.id}-${value}`))
19501
20819
  });
@@ -20499,7 +21817,7 @@ const GetSharedFieldMapping = async (cohortBuilderConfiguration)=>{
20499
21817
  }
20500
21818
  return sharedFiltersMap;
20501
21819
  };
20502
- const DefaultAccessControlConfiguration = {
21820
+ const DefaultAccessControlConfiguration$1 = {
20503
21821
  dataMode: GuppyDataAccessMode.REGULAR,
20504
21822
  tierLimit: -1,
20505
21823
  showAccessLevelControl: false
@@ -20527,7 +21845,7 @@ const ExplorerPageGetServerSideProps = async ()=>{
20527
21845
  explorerConfig: cohortBuilderConfiguration.explorerConfig,
20528
21846
  // headerMetadata: cohortBuilderConfiguration.headerMetadata,
20529
21847
  accessControl: {
20530
- ...DefaultAccessControlConfiguration,
21848
+ ...DefaultAccessControlConfiguration$1,
20531
21849
  ...cohortBuilderConfiguration.accessControl ?? {}
20532
21850
  }
20533
21851
  }
@@ -20568,7 +21886,7 @@ const ExplorerPageGetServerSidePropsForConfigId = async (context)=>{
20568
21886
  explorerConfig: cohortBuilderConfiguration.explorerConfig,
20569
21887
  // headerMetadata: { ...(cohortBuilderConfiguration?.headerMetadata ? cohortBuilderConfiguration.headerMetadata : {}) },
20570
21888
  accessControl: {
20571
- ...DefaultAccessControlConfiguration,
21889
+ ...DefaultAccessControlConfiguration$1,
20572
21890
  ...cohortBuilderConfiguration.accessControl ?? {}
20573
21891
  }
20574
21892
  }
@@ -25909,7 +27227,7 @@ const TabbedCohortBuilderPage = ({ headerProps, footerProps, configuration })=>{
25909
27227
  children: [
25910
27228
  /*#__PURE__*/ jsx(CohortManager$1, {
25911
27229
  rightPanel: /*#__PURE__*/ jsx(CountsPanel, {
25912
- index: "case"
27230
+ index: configuration.index
25913
27231
  })
25914
27232
  }),
25915
27233
  /*#__PURE__*/ jsx(QueryExpression, {
@@ -25918,7 +27236,7 @@ const TabbedCohortBuilderPage = ({ headerProps, footerProps, configuration })=>{
25918
27236
  ]
25919
27237
  }),
25920
27238
  /*#__PURE__*/ jsx("div", {
25921
- className: "w-full mt-60 mr-4",
27239
+ className: "w-full mt-80 mr-4",
25922
27240
  children: /*#__PURE__*/ jsx(TabbedCohortBuilder, {
25923
27241
  ...configuration
25924
27242
  })
@@ -25951,6 +27269,65 @@ const TabbedCohortBuilderPageGetServerSideProps = async ()=>{
25951
27269
  }
25952
27270
  };
25953
27271
 
27272
+ const RepositoryPage = ({ headerProps, footerProps, configuration, headerMetadata })=>{
27273
+ if (configuration === undefined) {
27274
+ return /*#__PURE__*/ jsx(Center, {
27275
+ maw: 400,
27276
+ h: 100,
27277
+ mx: "auto",
27278
+ children: /*#__PURE__*/ jsx("div", {
27279
+ children: "Repository config is not defined. Page disabled"
27280
+ })
27281
+ });
27282
+ }
27283
+ console.log('RepositoryPage', configuration);
27284
+ return /*#__PURE__*/ jsx(NavPageLayout, {
27285
+ headerProps,
27286
+ footerProps,
27287
+ headerMetadata: {
27288
+ title: 'Gen3 Repository Page',
27289
+ content: 'Repository Page',
27290
+ key: 'gen3-repository-page',
27291
+ ...headerMetadata ? headerMetadata : {},
27292
+ ...configuration?.headerMetadata ? configuration.headerMetadata : {}
27293
+ },
27294
+ children: /*#__PURE__*/ jsx(Repository, {
27295
+ ...configuration
27296
+ })
27297
+ });
27298
+ };
27299
+
27300
+ const DefaultAccessControlConfiguration = {
27301
+ dataMode: GuppyDataAccessMode.REGULAR,
27302
+ tierLimit: -1,
27303
+ showAccessLevelControl: false
27304
+ };
27305
+ const RepositoryPageGetServerSideProps = async ()=>{
27306
+ try {
27307
+ const repositoryConfiguration = await ContentSource$1.getContentDatabase().get(`${GEN3_COMMONS_NAME}/repository.json`);
27308
+ return {
27309
+ props: {
27310
+ ...await getNavPageLayoutPropsFromConfig(),
27311
+ configuration: repositoryConfiguration,
27312
+ // headerMetadata: cohortBuilderConfiguration.headerMetadata,
27313
+ accessControl: {
27314
+ ...DefaultAccessControlConfiguration
27315
+ }
27316
+ }
27317
+ };
27318
+ } catch (err) {
27319
+ if (err instanceof Error) {
27320
+ console.warn('Explorer config cannot be read', err);
27321
+ }
27322
+ return {
27323
+ props: {
27324
+ ...await getNavPageLayoutPropsFromConfig(),
27325
+ configuration: undefined
27326
+ }
27327
+ };
27328
+ }
27329
+ };
27330
+
25954
27331
  const TailwindConfig = (themer)=>{
25955
27332
  return {
25956
27333
  important: '#__next',
@@ -26397,5 +27774,5 @@ const staticNotebookAPI = async (req, res)=>{
26397
27774
  });
26398
27775
  };
26399
27776
 
26400
- export { AISearchPageGetServerSideProps, AccessLevel, AccordionPanel, ActionBar, ActionButton, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AnalysisCenter, AnalysisCenterWithSections, AnalysisEditorPage, AnalysisEditorPageGetServerSideProps, AnalysisPage, AnalysisPageGetServerSideProps, AuthzPage, BAD_DATA_MESSAGE, Banner, BaseModal, Charts, CohortBuilder$1 as CohortBuilder, CohortManager$1 as CohortManager, CohortManagerAndExpression, CollapsableCharts, CollapsableSidebar, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource$1 as ContentSource, CountsValue, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DAYS_IN_YEAR, DEFAULT_MAXIMUM, DEFAULT_MINIMUM, DEFAULT_VISIBLE_ITEMS$1 as DEFAULT_VISIBLE_ITEMS, DataLibraryPage, DataLibraryPageGetServerSideProps, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, DropdownButton, DropdownPanel, DropdownWithIcon, EnumFacet, EnumFacetChart, ErrorCard, ExactValueFacet, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerPageGetServerSidePropsForConfigId, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FacetControlsHeader, FacetExpander, FacetSelector, FacetSortPanel, FacetTabs, FiltersPanel, FirstTimeModal, Footer, Gen3Button, Gen3ButtonReverse, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header$1 as Header, HoverLink, LandingPage, LandingPageGetServerSideProps, LoginButton$1 as LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, MinutesToMilliseconds, MultiSelectValueFacet, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, NotebookLitePage, NotebookLitePageGetStaticProps, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, ProtectedContent, QueryExpression, QueryExpressionContext, QueryExpressionSection, QueryPage, QueryPageGetServerSideProps, RangeFacet, ReactECharts, ResourcesFilters, SPECIAL_CASE_FIELDS, SegmentedControl, SessionExpiredModal, SinglePageStudyDetailsPanel, StaticNotebookIFrame, StaticNotebookViewer, StudyDetailsPanel, StudyGroup, StudyGroupPanel, StudyProvider, SubmissionPage, SubmissionPageGetServerSideProps, TabbedCohortBuilder, TabbedCohortBuilderPage, TabbedCohortBuilderPageGetServerSideProps, TabbedPanel, TagCloud, TailwindConfig, TopBar, UploadJSONButton, User, Workspace, WorkspaceNoAccessPage, WorkspaceNoAccessPageServerSideProps, WorkspacePage, WorkspacePageGetServerSideProps, accessibleFieldName, addIntersectionToIncludes, addUnion, analysisApiCohortDiscovery, buildNested, capitalize, classifyFacets, compareKeysAscending, compareKeysDescending, computeRowSpan, convertMinutesToMilliseconds, convertPathsToTree, convertSecondsToMilliseconds, convertToStringArray, create10ColorAccessibleContrast, create10ColorPallet, createMantineTheme, credentialsLogin, credentialsLogout, extractObjectKey, extractRangeValues, filterAggregationsDataKeys, focusStyles, getAllFieldsFromFilterConfigs, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isEnumFacetResponse, isHeaderMetadata, isPropertyKey, isTextTransform$1 as isTextTransform, mapFacetSortToSortType, processBucketData, processLabel$1 as processLabel, processRangeData, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortSimilarityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, registerMetadataSchemaApp, removeIntersectionFromEnum, removeKey$1 as removeKey, removeUnion, resourcePathFromProjectID, sessionLogout, sessionToken, staticNotebookAPI, stripTrailingSlash, toCountsString, toDisplayName, truncateString, unixTimeToString, updateFacetEnum, useClearFilters$1 as useClearFilters, useDiscoveryContext, useExtractEnumFilterValues, useExtractRangeFilterValues, useFieldNameToTitle, useGetFacetFilters$1 as useGetFacetFilters, useUpdateFilters$1 as useUpdateFilters, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
27777
+ export { AISearchPageGetServerSideProps, AccessLevel, AccordionPanel, ActionBar, ActionButton, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AnalysisCenter, AnalysisCenterWithSections, AnalysisEditorPage, AnalysisEditorPageGetServerSideProps, AnalysisPage, AnalysisPageGetServerSideProps, AuthzPage, BAD_DATA_MESSAGE, Banner, BaseModal, Charts, CohortBuilder$1 as CohortBuilder, CohortManager$1 as CohortManager, CohortManagerAndExpression, CollapsableCharts, CollapsableSidebar, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource$1 as ContentSource, CountsValue, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DAYS_IN_YEAR, DEFAULT_MAXIMUM, DEFAULT_MINIMUM, DEFAULT_VISIBLE_ITEMS$1 as DEFAULT_VISIBLE_ITEMS, DataLibraryPage, DataLibraryPageGetServerSideProps, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, DownloadButton, DropdownButton, DropdownPanel, DropdownWithIcon, EnumFacet, EnumFacetChart, ErrorCard, ExactValueFacet, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerPageGetServerSidePropsForConfigId, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FacetControlsHeader, FacetExpander, FacetSelector, FacetSortPanel, FacetTabs, FiltersPanel, FirstTimeModal, Footer, Gen3Button, Gen3ButtonReverse, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header$1 as Header, HoverLink, JSONObjectDownloadButton, LandingPage, LandingPageGetServerSideProps, LoginButton$1 as LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, MinutesToMilliseconds, MultiSelectValueFacet, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, NotebookLitePage, NotebookLitePageGetStaticProps, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, ProtectedContent, QueryExpression, QueryExpressionContext, QueryExpressionSection, QueryPage, QueryPageGetServerSideProps, RangeFacet, ReactECharts, Repository, RepositoryPage, RepositoryPageGetServerSideProps, ResourcesFilters, SPECIAL_CASE_FIELDS, SegmentedControl, SessionExpiredModal, SinglePageStudyDetailsPanel, StaticNotebookIFrame, StaticNotebookViewer, StudyDetailsPanel, StudyGroup, StudyGroupPanel, StudyProvider, SubmissionPage, SubmissionPageGetServerSideProps, TabbedCohortBuilder, TabbedCohortBuilderPage, TabbedCohortBuilderPageGetServerSideProps, TabbedPanel, TableXPositionContext, TagCloud, TailwindConfig, TopBar, UploadJSONButton, User, Workspace, WorkspaceNoAccessPage, WorkspaceNoAccessPageServerSideProps, WorkspacePage, WorkspacePageGetServerSideProps, accessibleFieldName, addIntersectionToIncludes, addUnion, analysisApiCohortDiscovery, buildNested, capitalize, classifyFacets, compareKeysAscending, compareKeysDescending, computeRowSpan, convertMinutesToMilliseconds, convertPathsToTree, convertSecondsToMilliseconds, convertToStringArray, create10ColorAccessibleContrast, create10ColorPallet, createMantineTheme, credentialsLogin, credentialsLogout, extractObjectKey, extractRangeValues, filterAggregationsDataKeys, focusStyles, getAllFieldsFromFilterConfigs, getCurrentUnixTimestamp, getFormattedTimestamp, getHighResolutionTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isEnumFacetResponse, isHeaderMetadata, isPropertyKey, isTextTransform$1 as isTextTransform, isTimeGreaterThan, mapFacetSortToSortType, measureExecutionTime, processBucketData, processLabel$1 as processLabel, processRangeData, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortSimilarityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, registerMetadataSchemaApp, removeIntersectionFromEnum, removeKey$1 as removeKey, removeUnion, resourcePathFromProjectID, sessionLogout, sessionToken, staticNotebookAPI, stripTrailingSlash, toCountsString, toDisplayName, truncateString, unixTimeToString, updateFacetEnum, useClearFilters$1 as useClearFilters, useDiscoveryContext, useExtractEnumFilterValues, useExtractRangeFilterValues, useFieldNameToTitle, useGetFacetFilters$1 as useGetFacetFilters, useUpdateFilters$1 as useUpdateFilters, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
26401
27778
  //# sourceMappingURL=index.js.map