@gen3/frontend 0.10.89 → 0.10.91

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 (171) hide show
  1. package/dist/cjs/index.js +694 -174
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/components/Profile/CredentialsTable.d.ts.map +1 -1
  4. package/dist/dts/components/Profile/CredentialsTable.js +2 -1
  5. package/dist/dts/components/Profile/CredentialsTable.js.map +1 -1
  6. package/dist/dts/components/Providers/Gen3Provider.d.ts.map +1 -1
  7. package/dist/dts/components/Providers/Gen3Provider.js +6 -8
  8. package/dist/dts/components/Providers/Gen3Provider.js.map +1 -1
  9. package/dist/dts/components/Providers/ResourceMonitor.d.ts.map +1 -1
  10. package/dist/dts/components/Providers/ResourceMonitor.js +0 -1
  11. package/dist/dts/components/Providers/ResourceMonitor.js.map +1 -1
  12. package/dist/dts/features/Analysis/AnalysisCardCompact.stories.d.ts +6 -6
  13. package/dist/dts/features/Authz/Gen3Authz.js +2 -2
  14. package/dist/dts/features/Authz/Gen3Authz.js.map +1 -1
  15. package/dist/dts/features/Authz/Policies/PoliciesTable.d.ts.map +1 -1
  16. package/dist/dts/features/Authz/Policies/PoliciesTable.js +3 -3
  17. package/dist/dts/features/Authz/Policies/PoliciesTable.js.map +1 -1
  18. package/dist/dts/features/Authz/Resources/ResourcesTable.d.ts.map +1 -1
  19. package/dist/dts/features/Authz/Resources/ResourcesTable.js +2 -2
  20. package/dist/dts/features/Authz/Resources/ResourcesTable.js.map +1 -1
  21. package/dist/dts/features/Authz/Roles/RolesTable.js +1 -1
  22. package/dist/dts/features/Authz/Roles/RolesTable.js.map +1 -1
  23. package/dist/dts/features/Authz/Users/NewUserPanel.js +1 -1
  24. package/dist/dts/features/Authz/Users/NewUserPanel.js.map +1 -1
  25. package/dist/dts/features/Authz/Users/UserTable.js +1 -1
  26. package/dist/dts/features/Authz/Users/UserTable.js.map +1 -1
  27. package/dist/dts/features/Authz/index.d.ts +2 -2
  28. package/dist/dts/features/Authz/index.d.ts.map +1 -1
  29. package/dist/dts/features/Authz/index.js +2 -2
  30. package/dist/dts/features/Authz/index.js.map +1 -1
  31. package/dist/dts/features/CohortBuilder/CohortBuilder.js +1 -1
  32. package/dist/dts/features/CohortBuilder/CohortBuilder.js.map +1 -1
  33. package/dist/dts/features/CohortDiscovery/CohortDiscovery.js +2 -2
  34. package/dist/dts/features/CohortDiscovery/CohortDiscovery.js.map +1 -1
  35. package/dist/dts/features/DataLibrary/DataLibraryLists.d.ts.map +1 -1
  36. package/dist/dts/features/DataLibrary/DataLibraryLists.js +32 -19
  37. package/dist/dts/features/DataLibrary/DataLibraryLists.js.map +1 -1
  38. package/dist/dts/features/DataLibrary/DatalistAccordionItem.d.ts +3 -4
  39. package/dist/dts/features/DataLibrary/DatalistAccordionItem.d.ts.map +1 -1
  40. package/dist/dts/features/DataLibrary/DatalistAccordionItem.js +11 -9
  41. package/dist/dts/features/DataLibrary/DatalistAccordionItem.js.map +1 -1
  42. package/dist/dts/features/DataLibrary/DatasetAccordionControl.d.ts.map +1 -1
  43. package/dist/dts/features/DataLibrary/DatasetAccordionControl.js +1 -1
  44. package/dist/dts/features/DataLibrary/DatasetAccordionControl.js.map +1 -1
  45. package/dist/dts/features/DataLibrary/QueryDetails.d.ts.map +1 -1
  46. package/dist/dts/features/DataLibrary/QueryDetails.js +6 -2
  47. package/dist/dts/features/DataLibrary/QueryDetails.js.map +1 -1
  48. package/dist/dts/features/DataLibrary/SearchAndActions.d.ts +4 -2
  49. package/dist/dts/features/DataLibrary/SearchAndActions.d.ts.map +1 -1
  50. package/dist/dts/features/DataLibrary/SearchAndActions.js +4 -3
  51. package/dist/dts/features/DataLibrary/SearchAndActions.js.map +1 -1
  52. package/dist/dts/features/DataLibrary/selection/exportActions.d.ts +1 -1
  53. package/dist/dts/features/DataLibrary/selection/exportActions.d.ts.map +1 -1
  54. package/dist/dts/features/DataLibrary/selection/exportActions.js +1 -1
  55. package/dist/dts/features/DataLibrary/selection/exportActions.js.map +1 -1
  56. package/dist/dts/features/DataLibrary/selection/registeredActions.d.ts +1 -4
  57. package/dist/dts/features/DataLibrary/selection/registeredActions.d.ts.map +1 -1
  58. package/dist/dts/features/DataLibrary/selection/registeredActions.js.map +1 -1
  59. package/dist/dts/features/DataLibrary/selection/selection.d.ts +3 -3
  60. package/dist/dts/features/DataLibrary/selection/selection.d.ts.map +1 -1
  61. package/dist/dts/features/DataLibrary/selection/selection.js +2 -2
  62. package/dist/dts/features/DataLibrary/selection/selection.js.map +1 -1
  63. package/dist/dts/features/DataLibrary/selection/types.d.ts +4 -2
  64. package/dist/dts/features/DataLibrary/selection/types.d.ts.map +1 -1
  65. package/dist/dts/features/DataLibrary/selection/utils.js +3 -3
  66. package/dist/dts/features/DataLibrary/selection/utils.js.map +1 -1
  67. package/dist/dts/features/DataLibrary/tables/DatasetContentsTable.d.ts.map +1 -1
  68. package/dist/dts/features/DataLibrary/tables/DatasetContentsTable.js +2 -2
  69. package/dist/dts/features/DataLibrary/tables/DatasetContentsTable.js.map +1 -1
  70. package/dist/dts/features/DataLibrary/types.d.ts +1 -0
  71. package/dist/dts/features/DataLibrary/types.d.ts.map +1 -1
  72. package/dist/dts/features/DataLibrary/types.js.map +1 -1
  73. package/dist/dts/features/Discovery/ActionBar/ActionBar.d.ts +5 -4
  74. package/dist/dts/features/Discovery/ActionBar/ActionBar.d.ts.map +1 -1
  75. package/dist/dts/features/Discovery/ActionBar/ActionBar.js +16 -10
  76. package/dist/dts/features/Discovery/ActionBar/ActionBar.js.map +1 -1
  77. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.d.ts +1 -1
  78. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.d.ts.map +1 -1
  79. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.js +86 -44
  80. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.js.map +1 -1
  81. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.stories.d.ts +1 -1
  82. package/dist/dts/features/Discovery/ActionBar/DataLibraryActionButton.d.ts +1 -1
  83. package/dist/dts/features/Discovery/ActionBar/DataLibraryActionButton.js +3 -3
  84. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.d.ts +2 -2
  85. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.d.ts.map +1 -1
  86. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.js +2 -2
  87. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.js.map +1 -1
  88. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.d.ts +2 -2
  89. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.d.ts.map +1 -1
  90. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.js +58 -9
  91. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.js.map +1 -1
  92. package/dist/dts/features/Discovery/ActionBar/types.d.ts +10 -2
  93. package/dist/dts/features/Discovery/ActionBar/types.d.ts.map +1 -1
  94. package/dist/dts/features/Discovery/DataLoaders/IndexedMetadata/DataLoader.d.ts.map +1 -1
  95. package/dist/dts/features/Discovery/DataLoaders/IndexedMetadata/DataLoader.js +3 -1
  96. package/dist/dts/features/Discovery/DataLoaders/IndexedMetadata/DataLoader.js.map +1 -1
  97. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.d.ts.map +1 -1
  98. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.js +6 -2
  99. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.js.map +1 -1
  100. package/dist/dts/features/Discovery/DataLoaders/utils.d.ts +2 -2
  101. package/dist/dts/features/Discovery/DataLoaders/utils.d.ts.map +1 -1
  102. package/dist/dts/features/Discovery/DataLoaders/utils.js +87 -41
  103. package/dist/dts/features/Discovery/DataLoaders/utils.js.map +1 -1
  104. package/dist/dts/features/Discovery/DiscoveryIndexPanel.d.ts +13 -0
  105. package/dist/dts/features/Discovery/DiscoveryIndexPanel.d.ts.map +1 -1
  106. package/dist/dts/features/Discovery/DiscoveryIndexPanel.js +38 -14
  107. package/dist/dts/features/Discovery/DiscoveryIndexPanel.js.map +1 -1
  108. package/dist/dts/features/Discovery/DiscoveryTable.d.ts +2 -1
  109. package/dist/dts/features/Discovery/DiscoveryTable.d.ts.map +1 -1
  110. package/dist/dts/features/Discovery/DiscoveryTable.js +18 -6
  111. package/dist/dts/features/Discovery/DiscoveryTable.js.map +1 -1
  112. package/dist/dts/features/Discovery/StudyPage/DownloadLinksPanel.d.ts.map +1 -1
  113. package/dist/dts/features/Discovery/StudyPage/DownloadLinksPanel.js +2 -1
  114. package/dist/dts/features/Discovery/StudyPage/DownloadLinksPanel.js.map +1 -1
  115. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.js +2 -2
  116. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.js.map +1 -1
  117. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.d.ts +2 -1
  118. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.d.ts.map +1 -1
  119. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js +1 -1
  120. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js.map +1 -1
  121. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.d.ts +2 -1
  122. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.d.ts.map +1 -1
  123. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.js +30 -11
  124. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.js.map +1 -1
  125. package/dist/dts/features/Discovery/TableRenderers/types.d.ts +2 -1
  126. package/dist/dts/features/Discovery/TableRenderers/types.d.ts.map +1 -1
  127. package/dist/dts/features/Discovery/constants.d.ts +2 -0
  128. package/dist/dts/features/Discovery/constants.d.ts.map +1 -0
  129. package/dist/dts/features/Discovery/constants.js +2 -0
  130. package/dist/dts/features/Discovery/constants.js.map +1 -0
  131. package/dist/dts/features/Discovery/index.d.ts +2 -1
  132. package/dist/dts/features/Discovery/index.d.ts.map +1 -1
  133. package/dist/dts/features/Discovery/index.js +2 -1
  134. package/dist/dts/features/Discovery/index.js.map +1 -1
  135. package/dist/dts/features/Discovery/types.d.ts +12 -15
  136. package/dist/dts/features/Discovery/types.d.ts.map +1 -1
  137. package/dist/dts/features/Discovery/types.js +2 -1
  138. package/dist/dts/features/Discovery/types.js.map +1 -1
  139. package/dist/dts/features/Discovery/utils.d.ts +8 -2
  140. package/dist/dts/features/Discovery/utils.d.ts.map +1 -1
  141. package/dist/dts/features/Discovery/utils.js +37 -4
  142. package/dist/dts/features/Discovery/utils.js.map +1 -1
  143. package/dist/dts/features/Navigation/TopBar/TopBar.d.ts.map +1 -1
  144. package/dist/dts/features/Navigation/TopBar/TopBar.js +1 -1
  145. package/dist/dts/features/Navigation/TopBar/TopBar.js.map +1 -1
  146. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.js +1 -1
  147. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.js.map +1 -1
  148. package/dist/dts/lib/content/filesystem.js +1 -1
  149. package/dist/dts/lib/content/filesystem.js.map +1 -1
  150. package/dist/dts/lib/session/session.d.ts.map +1 -1
  151. package/dist/dts/lib/session/session.js +2 -1
  152. package/dist/dts/lib/session/session.js.map +1 -1
  153. package/dist/dts/pages/Explorer/data.d.ts.map +1 -1
  154. package/dist/dts/pages/Explorer/data.js +2 -2
  155. package/dist/dts/pages/Explorer/data.js.map +1 -1
  156. package/dist/dts/utils/authMapping.d.ts +2 -2
  157. package/dist/dts/utils/authMapping.d.ts.map +1 -1
  158. package/dist/dts/utils/authMapping.js.map +1 -1
  159. package/dist/esm/index.js +698 -179
  160. package/dist/esm/index.js.map +1 -1
  161. package/dist/index.d.ts +33 -16
  162. package/dist/tsconfig.tsbuildinfo +1 -1
  163. package/package.json +3 -3
  164. package/dist/dts/features/Authz/Provider.d.ts +0 -44
  165. package/dist/dts/features/Authz/Provider.d.ts.map +0 -1
  166. package/dist/dts/features/Authz/Provider.js +0 -55
  167. package/dist/dts/features/Authz/Provider.js.map +0 -1
  168. package/dist/dts/features/Discovery/utils/processDataAccess.d.ts +0 -3
  169. package/dist/dts/features/Discovery/utils/processDataAccess.d.ts.map +0 -1
  170. package/dist/dts/features/Discovery/utils/processDataAccess.js +0 -73
  171. package/dist/dts/features/Discovery/utils/processDataAccess.js.map +0 -1
package/dist/esm/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { createContext, useState, useMemo, useEffect, useCallback, useContext, useRef, createElement, forwardRef, useReducer } from 'react';
4
- import { useUserAuth, useCoreSelector, selectUserDetails, useGetAuthzMappingsQuery, fetchFence, isFetchError, WorkspaceStatus, useGetWorkspaceStatusQuery, useGetWorkspacePayModelsQuery, useTerminateWorkspaceMutation, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, useCoreDispatch, setActiveWorkspaceStatus, RequestedWorkspaceStatus, setRequestedWorkspaceStatus, isTimeGreaterThan, useLazyFetchUserDetailsQuery, selectUserAuthStatus, GEN3_REDIRECT_URL, GEN3_FENCE_API, showModal, Modals, isAuthenticated, useGetLoginProvidersQuery, hideModal, useGetCSRFQuery, selectCurrentModal, fieldNameToTitle, useIsUserLoggedIn, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, isOperationWithField, extractEnumFilterValue, selectIndexedFilterByName, selectShouldShareFilters, selectSharedFilters, updateCohortFilter, isOperatorWithFieldAndArrayOfOperands, removeCohortFilter, setCohortFilter, clearCohortFilters, handleOperation, selectCohortFilters, setCohortIndexFilters, toggleCohortBuilderCategoryFilter, selectCohortFilterExpanded, setCohortFilterCombineMode, selectCohortFilterCombineMode, selectCurrentCohortId, selectCurrentCohortName, useGeneralGQLQuery, selectIndexFilters, useGetRawDataAndTotalCountsQuery, Accessibility, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, trimFirstFieldNameToTitle, selectAllCohortFiltersCollapsed, toggleCohortBuilderAllFilters, setShouldShareFilters, useGetAggsQuery, useGetAggsNoFilterSelfQuery, isIntersection, useGetCountsQuery, setSharedFilters, selectHeadersWithCSRFToken, GEN3_GUPPY_API, useLaunchWorkspaceMutation, selectActiveWorkspaceStatus, isFetchBaseQueryError, setActiveWorkspace, getCurrentTimestamp, selectWorkspaceStatusFromService, selectActiveWorkspaceId, useGetWorkspaceOptionsQuery, GEN3_WORKSPACE_API, useGetExternalLoginsQuery, useSetCurrentPayModelMutation, PodStatus, PodConditionType, isWorkspaceRunningOrStopping, GEN3_COMMONS_NAME, createAppStore, createGen3AppWithOwnStore, createAppApiForRTKQ, getGen3AppId, useGetDictionaryQuery, useGetMetadataByIdQuery, createGen3App, CoreProvider, fetchJSONDataFromURL, groupSharedFields, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetProjectsDetailsQuery, useGetSubmissionsQuery, isCohortItem, isFileItem, fetchFencePresignedURL, HTTPError, isFilterSet, getNumberOfItemsInDatalist, isAdditionalDataItem, getTimestamp, useDataLibrary, useLazyGetCrosswalkDataQuery } from '@gen3/core';
5
- import { LoadingOverlay, Card, Group, Avatar, Text, Checkbox, Stack, Tooltip, UnstyledButton, ThemeIcon, Center, Box, Select, Button, Divider, Textarea, FileButton, Anchor, Modal, Grid, Table, ColorSwatch, useMantineTheme, Loader, Paper, Menu, Badge, Alert, Tabs, Accordion, Drawer, CopyButton, factory, useProps, getStyleObject, SegmentedControl, Switch, Autocomplete, TextInput, Title, ActionIcon, NumberInput, RangeSlider, MultiSelect, Transition, rem, Stepper, Image as Image$1, NavLink, Flex, ScrollArea, Highlight, List, createTheme, Pagination, FileInput, CloseButton } from '@mantine/core';
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, useIsUserLoggedIn, GEN3_DOMAIN, useDataLibrary, buildListItemsGroupedByDataset, extractFileDatasetsInRecords, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, isOperationWithField, extractEnumFilterValue, selectIndexedFilterByName, selectShouldShareFilters, selectSharedFilters, updateCohortFilter, isOperatorWithFieldAndArrayOfOperands, removeCohortFilter, setCohortFilter, clearCohortFilters, handleOperation, selectCohortFilters, setCohortIndexFilters, toggleCohortBuilderCategoryFilter, selectCohortFilterExpanded, setCohortFilterCombineMode, selectCohortFilterCombineMode, selectCurrentCohortId, selectCurrentCohortName, useGeneralGQLQuery, selectIndexFilters, useGetRawDataAndTotalCountsQuery, Accessibility, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, trimFirstFieldNameToTitle, selectAllCohortFiltersCollapsed, toggleCohortBuilderAllFilters, setShouldShareFilters, useGetAggsQuery, useGetAggsNoFilterSelfQuery, isIntersection, useGetCountsQuery, setSharedFilters, selectHeadersWithCSRFToken, GEN3_GUPPY_API, useLaunchWorkspaceMutation, selectActiveWorkspaceStatus, isFetchBaseQueryError, setActiveWorkspace, getCurrentTimestamp, selectWorkspaceStatusFromService, selectActiveWorkspaceId, useGetWorkspaceOptionsQuery, GEN3_WORKSPACE_API, useGetExternalLoginsQuery, useSetCurrentPayModelMutation, PodStatus, PodConditionType, isWorkspaceRunningOrStopping, GEN3_COMMONS_NAME, createAppStore, createGen3AppWithOwnStore, createAppApiForRTKQ, getGen3AppId, useGetDictionaryQuery, useGetMetadataByIdQuery, createGen3App, CoreProvider, fetchJSONDataFromURL, HttpMethod, groupSharedFields, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetProjectsDetailsQuery, useGetSubmissionsQuery, isCohortItem, isFileItem, fetchFencePresignedURL, HTTPError, extractIndexFromDataLibraryCohort, isFilterSet, getNumberOfItemsInDatalist, isAdditionalDataItem, useLazyGetCrosswalkDataQuery } from '@gen3/core';
5
+ import { LoadingOverlay, Card, Group, Avatar, Text, Checkbox, Stack, Tooltip, UnstyledButton, ThemeIcon, Center, Box, Select, Button, Divider, Textarea, FileButton, Anchor, Modal, Grid, Table, ColorSwatch, useMantineTheme, Loader, Paper, Menu, Badge, Alert, Tabs, Accordion, Drawer, CopyButton, factory, useProps, getStyleObject, SegmentedControl, useCombobox, Combobox, TextInput, ScrollArea, Switch, Autocomplete, Title, ActionIcon, NumberInput, RangeSlider, MultiSelect, Transition, rem, Stepper, Image as Image$1, NavLink, Flex, Highlight, List, 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, MdKeyboardDoubleArrowLeft, MdUndo, MdSearch, MdInfo, MdExpandLess, MdExpandMore, MdFlip, MdAddCircle, MdRemoveCircle, MdOutlineArrowBack, MdOutlineArrowForward, MdKeyboardArrowDown, MdKeyboardArrowUp, MdDownload, MdGroup, MdOutlineBarChart, MdOutlineSearch, MdFormatQuote, MdDelete, MdOutlineRemoveCircle } from 'react-icons/md';
9
+ import { MdLogin, MdClose, MdKeyboardDoubleArrowLeft, MdUndo, MdSearch, MdInfo, MdExpandLess, MdExpandMore, MdFlip, MdAddCircle, MdRemoveCircle, MdOutlineArrowBack, MdOutlineArrowForward, MdKeyboardArrowDown, MdKeyboardArrowUp, MdDownload, MdGroup, MdOutlineBarChart, MdOutlineSearch, MdFormatQuote, MdDelete, MdAdd, MdOutlineRemoveCircle } from 'react-icons/md';
10
10
  import { getCookie, deleteCookie, setCookie } from 'cookies-next';
11
11
  import 'swr';
12
12
  import { errors, importSPKI, jwtVerify, decodeJwt } from 'jose';
@@ -32,7 +32,7 @@ import { PiDotsThreeCircleThin, PiTrash, PiSparkleFill, PiCaretUpFill, PiCaretDo
32
32
  import Head from 'next/head';
33
33
  import { useMantineReactTable, MantineReactTable } from 'mantine-react-table';
34
34
  import { JSONPath } from 'jsonpath-plus';
35
- import { LuClock, LuCircleSlash, LuUnlock, LuLock } from 'react-icons/lu';
35
+ import { LuCircleSlash, LuClock, LuLock, LuUnlock } from 'react-icons/lu';
36
36
  import { FiDownload, FiMoreVertical } from 'react-icons/fi';
37
37
  import { TiArrowSortedDown, TiArrowSortedUp, TiArrowUnsorted } from 'react-icons/ti';
38
38
  import { flushSync } from 'react-dom';
@@ -662,7 +662,6 @@ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figu
662
662
  const dispatch = useCoreDispatch();
663
663
  useEffect(()=>{
664
664
  if (isWorkspaceStatusError) {
665
- console.error('Workspace model error: ', workspaceStatusError.toString());
666
665
  dispatch(setActiveWorkspaceStatus(WorkspaceStatus.StatusError));
667
666
  setPollingInterval(0); // stop polling
668
667
  setPaymentPollingInterval(0);
@@ -865,6 +864,7 @@ const UPDATE_SESSION_LIMIT = MinutesToMilliseconds(5);
865
864
  */ const SessionProvider = ({ children, updateSessionTime = 5, inactiveTimeLimit = 20, workspaceInactivityTimeLimit = 0, logoutInactiveUsers = true, monitorWorkspace = true })=>{
866
865
  const router = useRouter();
867
866
  const coreDispatch = useCoreDispatch();
867
+ useGetCSRFQuery();
868
868
  useWorkspaceResourceMonitor(monitorWorkspace); // monitor workspaces if any are running or configured
869
869
  const [getUserDetails] = useLazyFetchUserDetailsQuery(); // Fetch user details
870
870
  const userStatus = useCoreSelector((state)=>selectUserAuthStatus(state));
@@ -3727,6 +3727,23 @@ const NavPageLayout = ({ headerProps, footerProps, mainProps, headerData, childr
3727
3727
 
3728
3728
  var classes = {"tableRow":"DiscoveryTable-module_tableRow__yFUJZ"};
3729
3729
 
3730
+ const isSearchKV = (obj)=>{
3731
+ return obj && obj.key && obj.value;
3732
+ };
3733
+ const isSearchKVArray = (obj)=>{
3734
+ return obj && Array.isArray(obj) && obj.every(isSearchKV);
3735
+ };
3736
+ const accessibleFieldName = '__accessible';
3737
+ var AccessLevel = /*#__PURE__*/ function(AccessLevel) {
3738
+ AccessLevel[AccessLevel["ACCESSIBLE"] = 1] = "ACCESSIBLE";
3739
+ AccessLevel[AccessLevel["UNACCESSIBLE"] = 2] = "UNACCESSIBLE";
3740
+ AccessLevel[AccessLevel["WAITING"] = 3] = "WAITING";
3741
+ AccessLevel[AccessLevel["NOT_AVAILABLE"] = 4] = "NOT_AVAILABLE";
3742
+ AccessLevel[AccessLevel["OTHER"] = 5] = "OTHER";
3743
+ AccessLevel[AccessLevel["MIXED"] = 6] = "MIXED";
3744
+ return AccessLevel;
3745
+ }({});
3746
+
3730
3747
  const jsonPathAccessor$1 = (path)=>(row)=>{
3731
3748
  // TODO: add logging if path is not found
3732
3749
  return JSONPath({
@@ -3735,7 +3752,14 @@ const jsonPathAccessor$1 = (path)=>(row)=>{
3735
3752
  });
3736
3753
  };
3737
3754
  const getTagInfo = (tagData, tagsConfig)=>{
3738
- const categoryConfig = tagsConfig.tagCategories.find((category)=>category.name === tagData.category);
3755
+ if (tagData.category === undefined) {
3756
+ return {
3757
+ color: 'darkgray',
3758
+ display: tagsConfig?.showUnknownTags ?? false,
3759
+ label: tagData.name
3760
+ };
3761
+ }
3762
+ const categoryConfig = tagsConfig?.tagCategories.find((category)=>category.name === tagData.category);
3739
3763
  if (categoryConfig === undefined) return {
3740
3764
  color: 'gray',
3741
3765
  display: tagsConfig?.showUnknownTags ?? false,
@@ -3752,6 +3776,29 @@ const getManualSortingAndPagination = (config)=>{
3752
3776
  const sortingAndPagination = config?.features?.dataLoader?.sortingAndPagination ?? defaultFeature;
3753
3777
  return sortingAndPagination === 'server';
3754
3778
  };
3779
+ /**
3780
+ * Converts a numeric value to its equivalent AccessLevel enum value
3781
+ * @param value - The numeric value to convert (1-6)
3782
+ * @returns The corresponding AccessLevel enum value or undefined if not found
3783
+ */ const getAccessLevelFromNumber = (value)=>{
3784
+ if (value === undefined) return undefined;
3785
+ switch(value){
3786
+ case AccessLevel.ACCESSIBLE:
3787
+ return AccessLevel.ACCESSIBLE;
3788
+ case AccessLevel.UNACCESSIBLE:
3789
+ return AccessLevel.UNACCESSIBLE;
3790
+ case AccessLevel.WAITING:
3791
+ return AccessLevel.WAITING;
3792
+ case AccessLevel.NOT_AVAILABLE:
3793
+ return AccessLevel.NOT_AVAILABLE;
3794
+ case AccessLevel.OTHER:
3795
+ return AccessLevel.OTHER;
3796
+ case AccessLevel.MIXED:
3797
+ return AccessLevel.MIXED;
3798
+ default:
3799
+ return undefined;
3800
+ }
3801
+ };
3755
3802
 
3756
3803
  const defaultCellRenderer = (value, params)=>{
3757
3804
  if (value === undefined || value === null || toString(value) === '') {
@@ -3762,11 +3809,8 @@ const defaultCellRenderer = (value, params)=>{
3762
3809
  ]
3763
3810
  });
3764
3811
  }
3765
- return /*#__PURE__*/ jsxs(Text, {
3766
- children: [
3767
- toString(value),
3768
- "dfdsfdsf"
3769
- ]
3812
+ return /*#__PURE__*/ jsx(Text, {
3813
+ children: toString(value)
3770
3814
  });
3771
3815
  };
3772
3816
  class DiscoveryCellRendererFactory {
@@ -3911,45 +3955,94 @@ const DiscoveryProvider = ({ children, discoveryIndexConfig })=>{
3911
3955
  });
3912
3956
  };
3913
3957
 
3914
- const isSearchKV = (obj)=>{
3915
- return obj && obj.key && obj.value;
3916
- };
3917
- const isSearchKVArray = (obj)=>{
3918
- return obj && Array.isArray(obj) && obj.every(isSearchKV);
3958
+ const buildTooltip = (mainMessage, secondaryMessage)=>{
3959
+ return /*#__PURE__*/ jsxs("div", {
3960
+ className: "flex flex-col",
3961
+ children: [
3962
+ /*#__PURE__*/ jsxs(Text, {
3963
+ size: "sm",
3964
+ children: [
3965
+ " ",
3966
+ mainMessage,
3967
+ " "
3968
+ ]
3969
+ }),
3970
+ secondaryMessage ? /*#__PURE__*/ jsxs("div", {
3971
+ className: "flex flex-col items-start my-1",
3972
+ children: [
3973
+ /*#__PURE__*/ jsx(Divider, {}),
3974
+ /*#__PURE__*/ jsx(Text, {
3975
+ size: "xs",
3976
+ children: secondaryMessage
3977
+ })
3978
+ ]
3979
+ }) : null
3980
+ ]
3981
+ });
3919
3982
  };
3920
- const accessibleFieldName = '__accessible';
3921
- var AccessLevel = /*#__PURE__*/ function(AccessLevel) {
3922
- AccessLevel[AccessLevel["ACCESSIBLE"] = 1] = "ACCESSIBLE";
3923
- AccessLevel[AccessLevel["UNACCESSIBLE"] = 2] = "UNACCESSIBLE";
3924
- AccessLevel[AccessLevel["PENDING"] = 3] = "PENDING";
3925
- AccessLevel[AccessLevel["NOT_AVAILABLE"] = 4] = "NOT_AVAILABLE";
3926
- AccessLevel[AccessLevel["OTHER"] = 5] = "OTHER";
3927
- return AccessLevel;
3928
- }({});
3929
-
3930
- const DataAccessCellRenderer = ({ value })=>{
3931
- if (value === AccessLevel.PENDING) {
3932
- return /*#__PURE__*/ jsx(LuClock, {
3933
- color: "yellow",
3934
- children: "Your access to this study is pending."
3983
+ const DataAccessCellRenderer = ({ cell, row }, params)=>{
3984
+ const authzField = params?.authzField || 'authz';
3985
+ let value = cell?.getValue();
3986
+ const authorization = row?.original?.[authzField] || undefined;
3987
+ if (isArray(value)) value = value[0];
3988
+ const accessLevel = getAccessLevelFromNumber(value);
3989
+ if (!accessLevel) {
3990
+ return /*#__PURE__*/ jsx(Tooltip, {
3991
+ label: buildTooltip('Unable to determine access level'),
3992
+ children: /*#__PURE__*/ jsx(LuCircleSlash, {
3993
+ className: "text-utility-error"
3994
+ })
3935
3995
  });
3936
3996
  }
3937
- if (value === AccessLevel.NOT_AVAILABLE) {
3938
- return /*#__PURE__*/ jsx(LuCircleSlash, {
3939
- color: "red",
3940
- children: "Cannot determine access to this study. Please contact the study owner."
3997
+ if (accessLevel === AccessLevel.WAITING) {
3998
+ return /*#__PURE__*/ jsx(Tooltip, {
3999
+ label: buildTooltip('Data are not yet available'),
4000
+ children: /*#__PURE__*/ jsx(LuClock, {
4001
+ className: "text-utility-warning"
4002
+ })
3941
4003
  });
3942
4004
  }
3943
- if (value === AccessLevel.ACCESSIBLE) {
3944
- return /*#__PURE__*/ jsx(LuUnlock, {
3945
- color: "green",
3946
- children: "You have access to this study."
4005
+ if (accessLevel === AccessLevel.MIXED) {
4006
+ return /*#__PURE__*/ jsx(Tooltip, {
4007
+ label: buildTooltip('You have mixed acccess'),
4008
+ children: /*#__PURE__*/ jsxs(Group, {
4009
+ children: [
4010
+ /*#__PURE__*/ jsx(LuLock, {
4011
+ className: "text-utility-warning"
4012
+ }),
4013
+ /*#__PURE__*/ jsx(LuUnlock, {
4014
+ className: "text-utility-warning"
4015
+ })
4016
+ ]
4017
+ })
3947
4018
  });
3948
4019
  }
3949
- if (value === AccessLevel.UNACCESSIBLE) {
3950
- return /*#__PURE__*/ jsx(LuLock, {
3951
- color: "red",
3952
- children: "You do not have access to this study."
4020
+ if (accessLevel === AccessLevel.NOT_AVAILABLE) {
4021
+ return /*#__PURE__*/ jsx(Tooltip, {
4022
+ label: buildTooltip('No data is shared'),
4023
+ children: /*#__PURE__*/ jsx(LuCircleSlash, {
4024
+ className: "text-utility-error"
4025
+ })
4026
+ });
4027
+ }
4028
+ if (accessLevel === AccessLevel.ACCESSIBLE) {
4029
+ return /*#__PURE__*/ jsx(Tooltip, {
4030
+ label: buildTooltip('You have access to this study', `read access to ${authorization}`),
4031
+ children: /*#__PURE__*/ jsx("div", {
4032
+ children: /*#__PURE__*/ jsx(LuUnlock, {
4033
+ className: "text-utility-success"
4034
+ })
4035
+ })
4036
+ });
4037
+ }
4038
+ if (accessLevel === AccessLevel.UNACCESSIBLE) {
4039
+ return /*#__PURE__*/ jsx(Tooltip, {
4040
+ label: buildTooltip('You currently do not have access to this study', `you need read access to ${authorization}`),
4041
+ children: /*#__PURE__*/ jsx("div", {
4042
+ children: /*#__PURE__*/ jsx(LuLock, {
4043
+ className: "text-utility-error"
4044
+ })
4045
+ })
3953
4046
  });
3954
4047
  }
3955
4048
  return /*#__PURE__*/ jsx(React__default.Fragment, {});
@@ -4127,13 +4220,10 @@ const RenderLinkWithURL = ({ value, cell }, params)=>{
4127
4220
  onClick: (ev)=>ev.stopPropagation(),
4128
4221
  target: "_blank",
4129
4222
  rel: "noreferrer",
4130
- children: /*#__PURE__*/ jsxs(Text, {
4223
+ children: /*#__PURE__*/ jsx(Text, {
4131
4224
  c: "utility.0",
4132
4225
  tt: ttValue,
4133
- children: [
4134
- content,
4135
- " fgh"
4136
- ]
4226
+ children: content
4137
4227
  })
4138
4228
  });
4139
4229
  };
@@ -4807,14 +4897,20 @@ const DownloadLinksPanel = ({ studyData, downloadLinks, downloadLinkFields = {
4807
4897
  }
4808
4898
  const id = entry[downloadLinkFields.idField];
4809
4899
  return /*#__PURE__*/ jsxs(Group, {
4900
+ justify: "space-between",
4810
4901
  gap: "md",
4811
4902
  children: [
4812
4903
  /*#__PURE__*/ jsx(Text, {
4813
4904
  children: entry['titleField'] || ''
4814
4905
  }),
4815
4906
  /*#__PURE__*/ jsx(Button, {
4907
+ component: "a",
4908
+ href: `${GEN3_FENCE_API}/data/${id}?expires_in=900&redirect`,
4909
+ target: "_blank",
4910
+ rel: "noreferrer",
4911
+ type: "text",
4816
4912
  leftSection: /*#__PURE__*/ jsx(FiDownload, {}),
4817
- disabled: !id,
4913
+ "data-disabled": !id,
4818
4914
  children: "Download File"
4819
4915
  })
4820
4916
  ]
@@ -4993,14 +5089,16 @@ const TableIcons = {
4993
5089
  })
4994
5090
  };
4995
5091
 
4996
- const extractCellValue = (func)=>({ cell })=>func({
5092
+ const extractCellValue = (func)=>({ cell, row })=>func({
4997
5093
  value: cell.getValue(),
4998
- cell
5094
+ cell,
5095
+ row
4999
5096
  });
5000
- const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPagination, pagination, sorting })=>{
5097
+ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPagination, setSelection, pagination, sorting })=>{
5001
5098
  const { discoveryConfig: config, setStudyDetails } = useDiscoveryContext();
5002
5099
  const { isLoading, isError, isFetching } = dataRequestStatus;
5003
5100
  const manualSortingAndPagination = getManualSortingAndPagination(config);
5101
+ const [rowSelection, setRowSelection] = useState({}); //ts type available
5004
5102
  const cols = useDeepCompareMemo(()=>{
5005
5103
  const studyColumns = config.studyColumns ?? [];
5006
5104
  return studyColumns.map((columnDef, idx)=>{
@@ -5040,6 +5138,7 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
5040
5138
  enableColumnActions: false,
5041
5139
  enableStickyHeader: true,
5042
5140
  enableStickyFooter: true,
5141
+ getRowId: (originalRow)=>config?.minimalFieldMapping?.uid && config.minimalFieldMapping.uid in originalRow ? originalRow[config.minimalFieldMapping.uid] : originalRow?.id ?? undefined,
5043
5142
  // TODO: keep this to explore later
5044
5143
  // mantineTableContainerProps: ({ table }) => {
5045
5144
  // return {
@@ -5049,7 +5148,9 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
5049
5148
  // };
5050
5149
  // },
5051
5150
  renderDetailPanel: config.studyPreviewField ? DiscoveryTableRowRenderer(config.studyPreviewField) : undefined,
5151
+ onRowSelectionChange: setRowSelection,
5052
5152
  state: {
5153
+ rowSelection,
5053
5154
  isLoading,
5054
5155
  ...manualSortingAndPagination ? {
5055
5156
  pagination,
@@ -5096,6 +5197,13 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
5096
5197
  }
5097
5198
  }
5098
5199
  });
5200
+ useDeepCompareEffect(()=>{
5201
+ //fetch data based on row selection state or something
5202
+ setSelection(rowSelection ? Object.keys(rowSelection) : []);
5203
+ }, [
5204
+ rowSelection,
5205
+ setSelection
5206
+ ]);
5099
5207
  return /*#__PURE__*/ jsxs(React__default.Fragment, {
5100
5208
  children: [
5101
5209
  /*#__PURE__*/ jsx(StudyDetails, {}),
@@ -5391,10 +5499,10 @@ const AdvancedSearchPanel = (props)=>{
5391
5499
  });
5392
5500
  };
5393
5501
 
5394
- const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, icon = undefined, disabled = false, toolTip = undefined, onClick = ()=>null, active = false, showIcon = true, loginRequired = false, ...buttonProps }, ref)=>{
5502
+ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, icon = undefined, disabled = false, tooltip = undefined, onClick = ()=>null, active = false, showIcon = true, loginRequired = false, ...buttonProps }, ref)=>{
5395
5503
  // TODO Test what idp was used to login and restrict actions to that idp or all or none
5396
5504
  const requiresLogin = !useIsUserLoggedIn() && loginRequired;
5397
- const buttonUcon = active ? /*#__PURE__*/ jsx(Loader, {
5505
+ const buttonIcon = active ? /*#__PURE__*/ jsx(Loader, {
5398
5506
  size: "sm",
5399
5507
  className: "p-1"
5400
5508
  }) : /*#__PURE__*/ jsx(FiDownload, {
@@ -5402,13 +5510,13 @@ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, i
5402
5510
  size: 16
5403
5511
  });
5404
5512
  return /*#__PURE__*/ jsx(Tooltip, {
5405
- disabled: !toolTip,
5406
- label: toolTip,
5513
+ disabled: !tooltip,
5514
+ label: tooltip,
5407
5515
  children: /*#__PURE__*/ jsx(Button, {
5408
5516
  ref: ref,
5409
5517
  onClick: onClick,
5410
5518
  disabled: disabled || requiresLogin,
5411
- leftSection: showIcon ? buttonUcon : undefined,
5519
+ leftSection: showIcon ? buttonIcon : undefined,
5412
5520
  ...buttonProps,
5413
5521
  children: label
5414
5522
  })
@@ -5416,21 +5524,297 @@ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, i
5416
5524
  });
5417
5525
  DataLibraryActionButton.displayName = 'DataLibraryActionButton';
5418
5526
 
5419
- const ActionBar = ({ config })=>{
5420
- const { buttons } = config;
5527
+ const MANIFEST_FILENAME = 'manifest.json';
5528
+ /**
5529
+ * Determines the disabled state and the reason for disabling based on authentication status,
5530
+ * selection count, and requirement for login.
5531
+ *
5532
+ * @param {boolean} isAuthenticated - Indicates whether the user is authenticated.
5533
+ * @param {number} numSelected - The number of items selected for the operation.
5534
+ * @param {boolean} requiresLogin - Specifies whether login is required to perform the operation.
5535
+ * @returns {Object} An object containing the following properties:
5536
+ * - {boolean} disabled - True if the action should be disabled, false otherwise.
5537
+ * - {string} [disabledReason] - The reason why the action is disabled (if applicable).
5538
+ */ const getDisabledState = (isAuthenticated, numSelected, requiresLogin)=>{
5539
+ const LOGIN_REQUIRED_MSG = 'You must be logged in to download a manifest';
5540
+ const NO_SELECTION_MSG = 'You must select at least one study to download a manifest';
5541
+ if (requiresLogin && !isAuthenticated) {
5542
+ return {
5543
+ disabled: true,
5544
+ disabledReason: LOGIN_REQUIRED_MSG
5545
+ };
5546
+ }
5547
+ if (numSelected === 0) {
5548
+ return {
5549
+ disabled: true,
5550
+ disabledReason: NO_SELECTION_MSG
5551
+ };
5552
+ }
5553
+ return {
5554
+ disabled: false
5555
+ }; // Default enabled state.
5556
+ };
5557
+ const handleDownloadManifestClick = ({ exportDataFields, selectedResources })=>{
5558
+ const { dataObjectField } = exportDataFields;
5559
+ if (dataObjectField === undefined) {
5560
+ notifications.show({
5561
+ title: 'Error notification',
5562
+ message: 'Missing required configuration field `config.features.export.manifestFieldName'
5563
+ });
5564
+ return;
5565
+ }
5566
+ // combine manifests from all selected studies
5567
+ const manifest = [];
5568
+ selectedResources.forEach((study)=>{
5569
+ if (study[dataObjectField]) {
5570
+ const studyDataObject = study[dataObjectField];
5571
+ if ('commons_url' in study && !GEN3_DOMAIN?.includes(study.commons_url)) {
5572
+ // PlanX addition to allow hostname based DRS in manifest download clients
5573
+ // like FUSE
5574
+ manifest.push(...studyDataObject.map((x)=>({
5575
+ ...x,
5576
+ commons_url: 'commons_url' in x ? x.commons_url : study.commons_url
5577
+ })));
5578
+ } else {
5579
+ manifest.push(...studyDataObject);
5580
+ }
5581
+ }
5582
+ });
5583
+ // download the manifest
5584
+ if (manifest.length === 0) {
5585
+ notifications.show({
5586
+ title: 'Export warning',
5587
+ message: 'None of the selected studies have any data objects. Please select a different study or select a different data object field.'
5588
+ });
5589
+ return;
5590
+ }
5591
+ const blob = new Blob([
5592
+ JSON.stringify(manifest, null, 2)
5593
+ ], {
5594
+ type: 'text/json'
5595
+ });
5596
+ FileSaver.saveAs(blob, MANIFEST_FILENAME);
5597
+ };
5598
+ const DownloadManifestButton = ({ buttonConfig, selectedResources, exportDataFields })=>{
5599
+ const { isAuthenticated } = useIsAuthenticated();
5600
+ const { disabled, disabledReason } = getDisabledState(isAuthenticated, selectedResources.length, buttonConfig?.requiresLogin ?? false);
5601
+ return /*#__PURE__*/ jsx(DataLibraryActionButton, {
5602
+ "data-testid": "download-manifest-button",
5603
+ label: buttonConfig?.label ?? 'Download Manifest',
5604
+ icon: /*#__PURE__*/ jsx(FiDownload, {}),
5605
+ disabled: disabled,
5606
+ tooltip: disabledReason ?? buttonConfig?.tooltip ?? 'Download Manifest of selected studies',
5607
+ onClick: ()=>{
5608
+ handleDownloadManifestClick({
5609
+ selectedResources: selectedResources,
5610
+ exportDataFields: exportDataFields
5611
+ });
5612
+ }
5613
+ });
5614
+ };
5615
+
5616
+ const extractIdToLabel = (data)=>!data ? {} : Object.keys(data).reduce((acc, id)=>{
5617
+ acc[id] = data[id].name;
5618
+ return acc;
5619
+ }, {});
5620
+ const createTooltipLabel = (error, isLoggedIn, requiresLogin, numSelected, currentListName)=>{
5621
+ if (error) return 'Error saving to data library. Please try again later';
5622
+ if (!isLoggedIn && requiresLogin) return 'Please log in to save to data library';
5623
+ if (numSelected === 0) return 'Please select at least one study to save to data library';
5624
+ if (!currentListName) return 'Please select or create a list';
5625
+ return 'Add selections to list';
5626
+ };
5627
+ const AddToDataLibrary = ({ buttonConfig, selectedResources, exportDataFields, classNames = {} })=>{
5628
+ const [selectItems, setSelectItems] = useState({});
5629
+ const [currentList, setCurrentList] = useState(null);
5630
+ const [error, setError] = useState(null);
5631
+ const [currentListName, setCurrentListName] = useState('');
5632
+ const combobox = useCombobox({
5633
+ onDropdownClose: ()=>combobox.resetSelectedOption()
5634
+ });
5635
+ const userStatus = useCoreSelector((state)=>selectUserAuthStatus(state));
5636
+ const isLoggedIn = isAuthenticated(userStatus);
5637
+ const isDisabled = error !== null || selectedResources.length === 0 || !currentListName || buttonConfig?.requiresLogin && !isLoggedIn;
5638
+ const tooltipLabel = createTooltipLabel(error, isLoggedIn, buttonConfig.requiresLogin, selectedResources.length, currentListName);
5639
+ const classNamesDefaults = {
5640
+ root: 'w-1/2'
5641
+ };
5642
+ const mergedClassnames = mergeDefaultTailwindClassnames(classNamesDefaults, classNames);
5643
+ const { dataLibrary, updateListInDataLibrary, addListToDataLibrary, isLoading, error: dataLibraryError } = useDataLibrary();
5644
+ const saveToList = (listname, listId = undefined)=>{
5645
+ if (selectedResources.length === 0) return;
5646
+ const items = buildListItemsGroupedByDataset(extractFileDatasetsInRecords(selectedResources, exportDataFields));
5647
+ if (listId) {
5648
+ if (Object.keys(items).length === 0) {
5649
+ notifications.show({
5650
+ id: 'update-datalibrary-no-items-to-update-notification',
5651
+ position: 'top-center',
5652
+ withCloseButton: true,
5653
+ autoClose: 5000,
5654
+ title: 'Save to list',
5655
+ message: `No data objects selected to save to list ${listname}.`,
5656
+ loading: false
5657
+ });
5658
+ return;
5659
+ }
5660
+ updateListInDataLibrary({
5661
+ id: listId,
5662
+ name: listname,
5663
+ items: {
5664
+ ...dataLibrary[listId].items,
5665
+ ...items
5666
+ }
5667
+ });
5668
+ notifications.show({
5669
+ id: 'update-datalibrary-list-notification',
5670
+ position: 'top-center',
5671
+ withCloseButton: true,
5672
+ autoClose: 5000,
5673
+ title: 'Save to list',
5674
+ message: `${Object.values(items)} saved to list ${listname} successfully.`,
5675
+ loading: isLoading
5676
+ });
5677
+ } else {
5678
+ addListToDataLibrary(items, listname);
5679
+ notifications.show({
5680
+ id: 'update-datalibrary-list-notification',
5681
+ position: 'top-center',
5682
+ withCloseButton: true,
5683
+ autoClose: 5000,
5684
+ title: 'Save to list',
5685
+ message: `${Object.values(items)} saved to list ${listname} successfully.`,
5686
+ loading: isLoading
5687
+ });
5688
+ }
5689
+ };
5690
+ const exactOptionMatch = Object.values(selectItems).some((listName)=>listName === currentListName);
5691
+ const filteredOptions = exactOptionMatch ? selectItems : Object.entries(selectItems).reduce((acc, [listId, listName])=>{
5692
+ if (listName.toLowerCase().includes(currentListName.toLowerCase().trim())) {
5693
+ acc[listId] = listName;
5694
+ }
5695
+ return acc;
5696
+ }, {});
5697
+ const options = useMemo(()=>Object.entries(filteredOptions).map(([listId, listName])=>/*#__PURE__*/ jsx(Combobox.Option, {
5698
+ value: listId,
5699
+ children: listName
5700
+ }, listId)), [
5701
+ filteredOptions
5702
+ ]);
5703
+ useEffect(()=>{
5704
+ if (options.length === 0) setCurrentList(null);
5705
+ }, [
5706
+ options
5707
+ ]);
5708
+ useDeepCompareEffect(()=>{
5709
+ if (dataLibrary && !dataLibraryError) {
5710
+ const listItems = extractIdToLabel(dataLibrary);
5711
+ setSelectItems(listItems);
5712
+ }
5713
+ setError(dataLibraryError);
5714
+ if (dataLibraryError) {
5715
+ notifications.show({
5716
+ id: 'update-datalibrary-error-notification',
5717
+ position: 'top-center',
5718
+ withCloseButton: true,
5719
+ autoClose: 5000,
5720
+ title: 'Error',
5721
+ message: `Error saving to data library. Please try again later.`,
5722
+ loading: false
5723
+ });
5724
+ }
5725
+ }, [
5726
+ dataLibrary,
5727
+ dataLibraryError
5728
+ ]);
5729
+ return /*#__PURE__*/ jsxs(Group, {
5730
+ "data-testid": "add-to-data-library",
5731
+ wrap: "nowrap",
5732
+ classNames: {
5733
+ root: mergedClassnames.root
5734
+ },
5735
+ children: [
5736
+ /*#__PURE__*/ jsxs(Combobox, {
5737
+ onOptionSubmit: (selectedValue)=>{
5738
+ setCurrentList(selectedValue);
5739
+ setCurrentListName(selectItems[selectedValue]);
5740
+ combobox.closeDropdown();
5741
+ },
5742
+ store: combobox,
5743
+ withinPortal: false,
5744
+ children: [
5745
+ /*#__PURE__*/ jsx(Combobox.Target, {
5746
+ children: /*#__PURE__*/ jsx(TextInput, {
5747
+ placeholder: "Select/Search/Create List",
5748
+ value: currentListName ?? '',
5749
+ className: 'w-full',
5750
+ onChange: (event)=>{
5751
+ setCurrentListName(event.currentTarget.value);
5752
+ combobox.openDropdown();
5753
+ combobox.updateSelectedOptionIndex();
5754
+ },
5755
+ onClick: ()=>combobox.openDropdown(),
5756
+ onFocus: ()=>combobox.openDropdown(),
5757
+ onBlur: ()=>combobox.closeDropdown()
5758
+ })
5759
+ }),
5760
+ /*#__PURE__*/ jsx(Combobox.Dropdown, {
5761
+ children: /*#__PURE__*/ jsx(Combobox.Options, {
5762
+ children: /*#__PURE__*/ jsx(ScrollArea.Autosize, {
5763
+ mah: 200,
5764
+ type: "scroll",
5765
+ children: options.length === 0 ? /*#__PURE__*/ jsx(Combobox.Empty, {
5766
+ children: "Click button to create new list"
5767
+ }) : options
5768
+ })
5769
+ })
5770
+ })
5771
+ ]
5772
+ }),
5773
+ /*#__PURE__*/ jsx(Tooltip, {
5774
+ label: tooltipLabel,
5775
+ children: /*#__PURE__*/ jsx(Button, {
5776
+ classNames: {
5777
+ root: 'w-1/3'
5778
+ },
5779
+ loading: isLoading,
5780
+ disabled: isDisabled,
5781
+ onClick: ()=>{
5782
+ if (currentList) {
5783
+ saveToList(selectItems[currentList], currentList);
5784
+ } else {
5785
+ saveToList(currentListName, undefined);
5786
+ }
5787
+ },
5788
+ children: options.length === 0 && currentListName.length > 0 ? 'Save to New List' : buttonConfig?.label ?? 'Save to List'
5789
+ })
5790
+ })
5791
+ ]
5792
+ });
5793
+ };
5794
+
5795
+ const createActionButton = ({ buttonConfig, selectedResources, exportDataFields })=>{
5796
+ return ({
5797
+ manifest: /*#__PURE__*/ jsx(DownloadManifestButton, {
5798
+ buttonConfig: buttonConfig,
5799
+ selectedResources: selectedResources,
5800
+ exportDataFields: exportDataFields
5801
+ }, buttonConfig.type),
5802
+ addToDataLibrary: /*#__PURE__*/ jsx(AddToDataLibrary, {
5803
+ buttonConfig: buttonConfig,
5804
+ selectedResources: selectedResources,
5805
+ exportDataFields: exportDataFields
5806
+ }, buttonConfig.type)
5807
+ })[buttonConfig.type];
5808
+ };
5809
+ const ActionBar = ({ buttons, selectedResources, exportDataFields, verifyExternalLogins })=>{
5421
5810
  return /*#__PURE__*/ jsx("div", {
5422
5811
  className: "flex items-center justify-end py-1 px-2 mb-1 w-full gap-x-1.5 ",
5423
- children: buttons?.map((button, index)=>{
5424
- return /*#__PURE__*/ jsx(DataLibraryActionButton, {
5425
- label: button.label,
5426
- icon: /*#__PURE__*/ jsx(FiDownload, {}),
5427
- toolTip: button.tooltip,
5428
- loginRequired: config?.loginRequireForAllButtons ?? true,
5429
- onClick: ()=>{
5430
- console.log('Download $[button.label]');
5431
- }
5432
- }, `action-button-${index}`);
5433
- // }
5812
+ children: buttons?.map((button)=>{
5813
+ return createActionButton({
5814
+ buttonConfig: button,
5815
+ selectedResources,
5816
+ exportDataFields
5817
+ });
5434
5818
  })
5435
5819
  });
5436
5820
  };
@@ -5684,26 +6068,41 @@ const userHasMethodForServiceOnResource = (method, service, resourcePath, userAu
5684
6068
  return actions !== undefined && actions.some((x)=>(x.service === service || x.service === '*') && (x.method === method || x.method === '*'));
5685
6069
  };
5686
6070
 
6071
+ const METADATA_ITEM_AUTHORIZATION_FIELD = '__accessible';
6072
+
5687
6073
  /**
5688
- * Check for non-numeric items in an array and convert them to numbers.
5689
- * Handles strings, numbers, and nested arrays.
5690
- * It will silently convert any non-numeric items to 0 so as not to break the sum.
5691
- * @param fields - array of fields to check
5692
- */ const checkForNonNumericItems = (fields)=>fields.map((item)=>{
5693
- if (typeof item === 'number') {
5694
- return item;
5695
- }
5696
- // parse any string representation of an integer
5697
- if (typeof item === 'string') {
5698
- return parseInt(item, 10) || 0;
5699
- }
5700
- // if it's an array, recurse and sum the result
5701
- if (Array.isArray(item)) {
5702
- return sum(checkForNonNumericItems(item));
5703
- }
5704
- // if it's not a number, return 0 so as not to break the sum
5705
- return 0;
5706
- });
6074
+ * Parses a single value into a number
6075
+ * @param item - Value to convert
6076
+ * @returns Numeric representation of the value
6077
+ */ const parseNumericValue = (item)=>{
6078
+ const DEFAULT_VALUE = 0;
6079
+ // Handle undefined values
6080
+ if (item === undefined) {
6081
+ return DEFAULT_VALUE;
6082
+ }
6083
+ // Numbers can be used directly
6084
+ if (typeof item === 'number' && !Number.isNaN(item)) {
6085
+ return item;
6086
+ }
6087
+ // Parse string representations of numbers
6088
+ if (typeof item === 'string') {
6089
+ const parsedValue = parseInt(item, 10);
6090
+ return Number.isNaN(parsedValue) ? DEFAULT_VALUE : parsedValue;
6091
+ }
6092
+ // Recursively handle arrays by summing their numeric values
6093
+ if (Array.isArray(item)) {
6094
+ return convertToNumbers(item).reduce((acc, val)=>acc + val, 0);
6095
+ }
6096
+ // Return default for any other types
6097
+ return DEFAULT_VALUE;
6098
+ };
6099
+ /**
6100
+ * Converts various types of values to numbers
6101
+ * @param fields - Array of values to convert
6102
+ * @returns Array of numbers, with non-numeric values converted to 0
6103
+ */ const convertToNumbers = (fields)=>{
6104
+ return fields.map(parseNumericValue);
6105
+ };
5707
6106
  /**
5708
6107
  * Process a summary statistic using the provided data and summary config
5709
6108
  * @param {JSONObject }data
@@ -5720,7 +6119,7 @@ const userHasMethodForServiceOnResource = (method, service, resourcePath, userAu
5720
6119
  case 'sum':
5721
6120
  {
5722
6121
  // parse any string representation of an integer
5723
- fields = checkForNonNumericItems(fields);
6122
+ fields = convertToNumbers(fields);
5724
6123
  return sum(fields).toLocaleString();
5725
6124
  }
5726
6125
  case 'count':
@@ -5746,21 +6145,45 @@ const processAllSummaries = (data, summaries)=>{
5746
6145
  ];
5747
6146
  }, []);
5748
6147
  };
5749
- const processAuthorizations = (data, config, authMapping)=>{
6148
+ const processAuthorizations = (data, config, userAuthMapping)=>{
6149
+ const { enabled } = config.features.authorization;
6150
+ if (!enabled) {
6151
+ return data;
6152
+ }
6153
+ if (!userAuthMapping) {
6154
+ throw new Error('Arborist must be enabled for the Discovery page to work if authorization is enabled in the Discovery page. Set `useArboristUI: true` in the portal config.');
6155
+ }
6156
+ const hostnameWithSubdomain = window.location.hostname; // TODO: replace this with useRouter
6157
+ // mark studies as accessible or inaccessible to user
5750
6158
  const { authzField, dataAvailabilityField } = config.minimalFieldMapping;
5751
- const { supportedValues } = config.features.authorization;
5752
- return data.map((study)=>{
5753
- if (typeof study[authzField] !== 'string') return study;
5754
- const studyAuthz = study[authzField];
5755
- let accessible;
5756
- if (supportedValues?.pending?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'pending') {
5757
- accessible = AccessLevel.PENDING;
5758
- } else if (supportedValues?.notAvailable?.enabled && !study[authzField]) {
6159
+ const { supportedValues, isMesh } = config.features.authorization;
6160
+ const studiesWithAccessibleField = data.map((study)=>{
6161
+ let accessible = AccessLevel.NOT_AVAILABLE;
6162
+ if (supportedValues?.unaccessible?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'unaccessible') {
6163
+ accessible = AccessLevel.UNACCESSIBLE;
6164
+ } else if (supportedValues?.notAvailable?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'not_available') {
5759
6165
  accessible = AccessLevel.NOT_AVAILABLE;
6166
+ } else if (supportedValues?.waiting?.enabled && !study[authzField]) {
6167
+ accessible = AccessLevel.WAITING;
5760
6168
  } else {
5761
- const isAuthorized = userHasMethodForServiceOnResource('read', '*', studyAuthz, authMapping) || userHasMethodForServiceOnResource('read', 'peregrine', studyAuthz, authMapping) || userHasMethodForServiceOnResource('read', 'guppy', studyAuthz, authMapping) || userHasMethodForServiceOnResource('read-storage', 'fence', studyAuthz, authMapping);
6169
+ let authMapping = {};
6170
+ if (isMesh) {
6171
+ let commonsURL = study.commons_url; // TODO: configure this value
6172
+ if (commonsURL && commonsURL.startsWith('http')) {
6173
+ commonsURL = new URL(commonsURL).hostname;
6174
+ }
6175
+ authMapping = userAuthMapping[commonsURL || hostnameWithSubdomain] || {};
6176
+ } else {
6177
+ authMapping = Object.values(userAuthMapping)[0];
6178
+ }
6179
+ // TODO: This needs to be configurable GFF-294
6180
+ const isAuthorized = userHasMethodForServiceOnResource('read', '*', study[authzField], authMapping) || userHasMethodForServiceOnResource('read', 'peregrine', study[authzField], authMapping) || userHasMethodForServiceOnResource('read', 'guppy', study[authzField], authMapping) || userHasMethodForServiceOnResource('read-storage', 'fence', study[authzField], authMapping);
5762
6181
  if (supportedValues?.accessible?.enabled && isAuthorized) {
5763
- accessible = AccessLevel.ACCESSIBLE;
6182
+ if (supportedValues?.mixed?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'mixed_availability') {
6183
+ accessible = AccessLevel.MIXED;
6184
+ } else {
6185
+ accessible = AccessLevel.ACCESSIBLE;
6186
+ }
5764
6187
  } else if (supportedValues?.unaccessible?.enabled && !isAuthorized) {
5765
6188
  accessible = AccessLevel.UNACCESSIBLE;
5766
6189
  } else {
@@ -5769,9 +6192,10 @@ const processAuthorizations = (data, config, authMapping)=>{
5769
6192
  }
5770
6193
  return {
5771
6194
  ...study,
5772
- __accessible: accessible
6195
+ [METADATA_ITEM_AUTHORIZATION_FIELD]: accessible
5773
6196
  };
5774
6197
  });
6198
+ return studiesWithAccessibleField;
5775
6199
  };
5776
6200
  const processChartData = (data, pathsToProcess)=>{
5777
6201
  // Initialize results object
@@ -5878,7 +6302,9 @@ const useGetMDSData = ({ guidType = 'unregistered_discovery_metadata', maxStudie
5878
6302
  ] : acc;
5879
6303
  }, []);
5880
6304
  if (discoveryConfig?.features?.authorization.enabled) {
5881
- setMDSData(processAuthorizations(studyData, discoveryConfig, authMapping));
6305
+ setMDSData(processAuthorizations(studyData, discoveryConfig, {
6306
+ default: authMapping
6307
+ }));
5882
6308
  } else setMDSData(studyData);
5883
6309
  }
5884
6310
  }, [
@@ -5917,7 +6343,9 @@ const useGetAggMDSData = ({ guidType = 'unregistered_discovery_metadata', maxStu
5917
6343
  useEffect(()=>{
5918
6344
  if (data && isSuccess) {
5919
6345
  if (discoveryConfig?.features?.authorization.enabled) {
5920
- setMDSData(processAuthorizations(data.data, discoveryConfig, authMapping));
6346
+ setMDSData(processAuthorizations(data.data, discoveryConfig, {
6347
+ default: authMapping
6348
+ }));
5921
6349
  } else setMDSData(data.data);
5922
6350
  }
5923
6351
  }, [
@@ -6698,7 +7126,9 @@ const useGetIndexedMDSData = ({ guidType = 'unregistered_discovery_metadata', ma
6698
7126
  if (data && isSuccess) {
6699
7127
  const studyData = data.data;
6700
7128
  if (discoveryConfig?.features?.authorization.enabled) {
6701
- setMDSData(processAuthorizations(studyData, discoveryConfig, authMapping));
7129
+ setMDSData(processAuthorizations(studyData, discoveryConfig, {
7130
+ default: authMapping
7131
+ }));
6702
7132
  } else setMDSData(studyData);
6703
7133
  } else setMDSData([]);
6704
7134
  }, [
@@ -6760,7 +7190,20 @@ const registerDefaultDiscoveryDataLoaders = ()=>{
6760
7190
  };
6761
7191
  registerDefaultDiscoveryDataLoaders();
6762
7192
 
6763
- const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
7193
+ /**
7194
+ * DiscoveryIndexPanel is a React functional component that renders a discovery panel interface.
7195
+ * It includes features such as search, sorting, filtering, charts, export functionality, and a discovery table.
7196
+ * The component uses hooks for handling state, API data loading, and interface interactions.
7197
+ *
7198
+ * @param {Object} props - The properties object passed to the component.
7199
+ * @param {Object} props.discoveryConfig - Configuration object for setting up the discovery panel.
7200
+ * @param {Object} props.discoveryConfig.features - Defines enabled features (e.g., search, charts, export).
7201
+ * @param {Object} props.discoveryConfig.minimalFieldMapping - Field mapping configuration, such as `uid`.
7202
+ * @param {JSX.Element} props.indexSelector - React component for selecting an index in the discovery panel.
7203
+ *
7204
+ * @return {JSX.Element} A fully featured discovery interface including search functionality, a table, charts, filters, and more.
7205
+ */ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
7206
+ console.log(discoveryConfig);
6764
7207
  const dataHook = useMemo(()=>getDiscoveryDataLoader(discoveryConfig?.features?.dataLoader?.dataFetchFunction) ?? useLoadAllMDSData, [
6765
7208
  discoveryConfig?.features?.dataLoader?.dataFetchFunction
6766
7209
  ]);
@@ -6770,6 +7213,7 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6770
7213
  });
6771
7214
  const parentDivRef = useRef(null);
6772
7215
  const [searchBarTerm, setSearchBarTerm] = useState([]);
7216
+ const [selections, setSelections] = useState([]); // table selections
6773
7217
  const [advancedSearchTerms, setAdvancedSearchTerms] = useState({
6774
7218
  operation: SearchCombination.and,
6775
7219
  filters: {}
@@ -6795,6 +7239,15 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6795
7239
  searchTerms: searchParam,
6796
7240
  discoveryConfig
6797
7241
  });
7242
+ const selectedRecords = useMemo(()=>{
7243
+ const uidField = discoveryConfig?.minimalFieldMapping?.uid ?? 'guid';
7244
+ const filterSelectedMembers = (data)=>data.filter((member)=>uidField in member && selections.includes(member[uidField]));
7245
+ return filterSelectedMembers(data);
7246
+ }, [
7247
+ data,
7248
+ discoveryConfig?.minimalFieldMapping?.uid,
7249
+ selections
7250
+ ]);
6798
7251
  const [sorting, setSorting] = useState([]);
6799
7252
  const [showAdvancedSearch, { toggle: toggleAdvancedSearch }] = useDisclosure(false);
6800
7253
  if (dataRequestStatus.isLoading) {
@@ -6868,8 +7321,11 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6868
7321
  color: "accent",
6869
7322
  children: "Filters"
6870
7323
  }) : false,
6871
- discoveryConfig?.features?.exportToDataLibrary?.enabled ? /*#__PURE__*/ jsx(ActionBar, {
6872
- config: discoveryConfig.features.exportToDataLibrary
7324
+ discoveryConfig?.features?.exportFromDiscovery?.enabled ? /*#__PURE__*/ jsx(ActionBar, {
7325
+ buttons: discoveryConfig.features.exportFromDiscovery.buttons,
7326
+ exportDataFields: discoveryConfig.features.exportFromDiscovery.exportDataFields,
7327
+ selectedResources: selectedRecords,
7328
+ verifyExternalLogins: discoveryConfig.features.exportFromDiscovery.verifyExternalLogins
6873
7329
  }) : null
6874
7330
  ]
6875
7331
  }),
@@ -6890,6 +7346,7 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6890
7346
  dataRequestStatus: dataRequestStatus,
6891
7347
  setPagination: setPagination,
6892
7348
  setSorting: setSorting,
7349
+ setSelection: setSelections,
6893
7350
  pagination: pagination,
6894
7351
  sorting: sorting
6895
7352
  })
@@ -10992,7 +11449,7 @@ const TabsLayoutToComponentProp = (tabsLayout)=>{
10992
11449
  }
10993
11450
  };
10994
11451
  const CohortBuilder = ({ explorerConfig, sharedFiltersMap = null, tabsLayout = 'left' })=>{
10995
- const { isFetching } = useGetCSRFQuery();
11452
+ useGetCSRFQuery();
10996
11453
  const dispatch = useCoreDispatch();
10997
11454
  dispatch(setSharedFilters(sharedFiltersMap ?? {}));
10998
11455
  return /*#__PURE__*/ jsx("div", {
@@ -12302,7 +12759,7 @@ class FilesystemContent {
12302
12759
  try {
12303
12760
  return await JSON.parse(fs.readFileSync(path.join(this.rootPath, filepath)).toString('utf8'));
12304
12761
  } catch (err) {
12305
- throw new Error(`Cannot process ${filepath} `);
12762
+ throw new Error(`Cannot process ${path.join(this.rootPath, filepath)} `);
12306
12763
  }
12307
12764
  }
12308
12765
  async getAll(filepath, filter) {
@@ -12819,8 +13276,8 @@ const IndexPanel = ({ dataConfig, tabs, tabTitle })=>{
12819
13276
 
12820
13277
  const persistor = persistStore(AppStore);
12821
13278
  const CohortDiscovery = (config)=>{
12822
- const { isLoading } = useGetCSRFQuery(); // need for Guppy
12823
- if (isLoading) {
13279
+ const { isFetching } = useGetCSRFQuery(); // needed for Guppy
13280
+ if (isFetching) {
12824
13281
  return /*#__PURE__*/ jsx(Center, {
12825
13282
  maw: 400,
12826
13283
  h: 100,
@@ -15154,24 +15611,25 @@ const createMantineTheme = (fonts, colors)=>{
15154
15611
  Pagination: Pagination.extend({
15155
15612
  defaultProps: {
15156
15613
  getControlProps: (control)=>{
15614
+ //Add 508 localization to Pagination, not needed if using react table
15157
15615
  if (control === 'first') {
15158
15616
  return {
15159
- "aria-label": "First"
15617
+ 'aria-label': 'First'
15160
15618
  };
15161
15619
  }
15162
15620
  if (control === 'last') {
15163
15621
  return {
15164
- "aria-label": "Last"
15622
+ 'aria-label': 'Last'
15165
15623
  };
15166
15624
  }
15167
15625
  if (control === 'next') {
15168
15626
  return {
15169
- "aria-label": "Next"
15627
+ 'aria-label': 'Next'
15170
15628
  };
15171
15629
  }
15172
15630
  if (control === 'previous') {
15173
15631
  return {
15174
- "aria-label": "Previous"
15632
+ 'aria-label': 'Previous'
15175
15633
  };
15176
15634
  }
15177
15635
  return {};
@@ -15586,7 +16044,7 @@ const GetSharedFieldMapping = async (cohortBuilderConfiguration)=>{
15586
16044
  // create shared filter from Gen3 graphql mapping
15587
16045
  const indices = cohortBuilderConfiguration?.explorerConfig.map((tab)=>tab.guppyConfig.dataType);
15588
16046
  try {
15589
- const data = await fetchJSONDataFromURL(`${GEN3_GUPPY_API}/graphql`, true, 'POST', {
16047
+ const data = await fetchJSONDataFromURL(`${GEN3_GUPPY_API}/graphql`, true, HttpMethod.POST, {
15590
16048
  query: `{ _mapping { ${indices.join(' ')} }}`,
15591
16049
  variables: {}
15592
16050
  });
@@ -16060,7 +16518,7 @@ const getStatus = (expiration, now)=>{
16060
16518
  * with the ability to delete a given credential using useRemoveCredentialMutation() hook
16061
16519
  * @returns {JSX.Element} The JSX element representing the credentials table.
16062
16520
  */ const CredentialsTable = ()=>{
16063
- const { data: csrfToken } = useGetCSRFQuery();
16521
+ const { data: csrfToken, isFetching: isCSRFFetching } = useGetCSRFQuery();
16064
16522
  const { data: credentials } = useGetCredentialsQuery();
16065
16523
  const [removeCredential] = useRemoveCredentialMutation();
16066
16524
  const columns = useMemo(()=>{
@@ -16122,7 +16580,10 @@ const getStatus = (expiration, now)=>{
16122
16580
  mantineSearchTextInputProps: {
16123
16581
  placeholder: 'Search API Keys'
16124
16582
  },
16125
- icons: TableIcons
16583
+ icons: TableIcons,
16584
+ state: {
16585
+ isLoading: isCSRFFetching
16586
+ }
16126
16587
  });
16127
16588
  return /*#__PURE__*/ jsx(MantineReactTable, {
16128
16589
  table: table
@@ -16732,7 +17193,7 @@ const AuthzContext = /*#__PURE__*/ createContext({
16732
17193
  },
16733
17194
  dispatch: ()=>null
16734
17195
  });
16735
- const AuthzProvider = ({ children, authz = {
17196
+ const AuthzAdminProvider = ({ children, authz = {
16736
17197
  users: [],
16737
17198
  groups: [],
16738
17199
  roles: [],
@@ -17312,7 +17773,7 @@ const Gen3Authz = ({ authz })=>{
17312
17773
  /*#__PURE__*/ jsx("h1", {
17313
17774
  children: "Gen3 Authz"
17314
17775
  }),
17315
- /*#__PURE__*/ jsx(AuthzProvider, {
17776
+ /*#__PURE__*/ jsx(AuthzAdminProvider, {
17316
17777
  authz: authz,
17317
17778
  children: /*#__PURE__*/ jsxs(Tabs, {
17318
17779
  orientation: "vertical",
@@ -18596,12 +19057,12 @@ const getDataLibraryItem = (dataLibrary, listId, dataId, fileId)=>{
18596
19057
  };
18597
19058
  } else {
18598
19059
  if (!fileId) return undefined;
18599
- if (!(fileId in datasetOrCohort.items)) return undefined;
18600
- if (isFileItem(datasetOrCohort.items[fileId])) {
19060
+ if (!(fileId in datasetOrCohort.members)) return undefined;
19061
+ if (isFileItem(datasetOrCohort.members[fileId])) {
18601
19062
  return {
18602
19063
  datasetName: name,
18603
19064
  datasetId: dataId,
18604
- ...datasetOrCohort.items[fileId]
19065
+ ...datasetOrCohort.members[fileId]
18605
19066
  };
18606
19067
  }
18607
19068
  return undefined;
@@ -18808,7 +19269,7 @@ const getNumberOfSelectedItemsInList = (selections, listId)=>{
18808
19269
  };
18809
19270
  const isListInSelection = (listId, selections)=>listId in selections;
18810
19271
 
18811
- const SearchAndActions = ({ createList, gatherData, size = 'sm' })=>{
19272
+ const SearchAndActions = ({ createList, gatherData, size = 'sm', enableCreateNewList = false, enableDownloadManifest = false })=>{
18812
19273
  const { selections, clearSelections } = useDataLibrarySelection();
18813
19274
  const retrieveDisabled = Object.keys(selections).length === 0;
18814
19275
  const iconSize = IconSize[size] || IconSize['sm'];
@@ -18848,6 +19309,38 @@ const SearchAndActions = ({ createList, gatherData, size = 'sm' })=>{
18848
19309
  height: iconSize
18849
19310
  })
18850
19311
  })
19312
+ }),
19313
+ enableCreateNewList && /*#__PURE__*/ jsx(Tooltip, {
19314
+ label: "Create a new empty list",
19315
+ children: /*#__PURE__*/ jsx(Button, {
19316
+ hidden: true,
19317
+ size: "compact-md",
19318
+ variant: "outline",
19319
+ onClick: ()=>createList({}),
19320
+ "aria-label": "create a new list",
19321
+ classNames: {
19322
+ root: 'bg-base-max hover:bg-base-light'
19323
+ },
19324
+ children: /*#__PURE__*/ jsx(MdAdd, {
19325
+ size: "1.5em"
19326
+ })
19327
+ })
19328
+ }),
19329
+ enableCreateNewList && /*#__PURE__*/ jsx(Tooltip, {
19330
+ label: "Download Manifest of selected items",
19331
+ children: /*#__PURE__*/ jsx(Button, {
19332
+ size: "compact-md",
19333
+ variant: "outline",
19334
+ "aria-label": "Download Manifest of Selected Items",
19335
+ classNames: {
19336
+ root: 'bg-base-max hover:bg-base-light'
19337
+ },
19338
+ children: /*#__PURE__*/ jsx(Icon, {
19339
+ icon: "gen3:download-alt",
19340
+ height: 24,
19341
+ width: 24
19342
+ })
19343
+ })
18851
19344
  })
18852
19345
  ]
18853
19346
  })
@@ -19255,7 +19748,7 @@ const sendExistingPFBToURL = async (validatedSelections, params, done = ()=>null
19255
19748
  withCloseButton: true,
19256
19749
  autoClose: 5000,
19257
19750
  title: 'Action Error',
19258
- message: error.status in HTTPUserFriendlyErrorMessages ? HTTPUserFriendlyErrorMessages[error.status] : 'An error has occured to prevent exporting PFB',
19751
+ message: error.status in HTTPUserFriendlyErrorMessages ? HTTPUserFriendlyErrorMessages[error.status] : 'An error has occurred to prevent exporting PFB',
19259
19752
  color: 'red',
19260
19753
  loading: false
19261
19754
  });
@@ -19524,7 +20017,7 @@ const SelectedItemsModal = (props)=>{
19524
20017
  * it iterates through the dataset items and sets the keys of file items
19525
20018
  * to true in the returned object.
19526
20019
  *
19527
- * @param {RegisteredDataListEntry | CohortItem} dataSetOrCohort - The dataset or cohort item to process.
20020
+ * @param {DataLibraryDataset | CohortItem} dataSetOrCohort - The dataset or cohort item to process.
19528
20021
  * @returns {SelectedMembers} An object representing the selected members.
19529
20022
  */ const getDatasetMembers = (dataSetOrCohort)=>{
19530
20023
  if (isCohortItem(dataSetOrCohort)) {
@@ -19532,7 +20025,7 @@ const SelectedItemsModal = (props)=>{
19532
20025
  [dataSetOrCohort.id]: true
19533
20026
  };
19534
20027
  }
19535
- return Object.entries(dataSetOrCohort.items).reduce((acc, [key, item])=>{
20028
+ return Object.entries(dataSetOrCohort.members).reduce((acc, [key, item])=>{
19536
20029
  if (isFileItem(item)) acc[key] = true;
19537
20030
  return acc;
19538
20031
  }, {});
@@ -19732,7 +20225,7 @@ const DatasetAccordionControl = ({ listName, numberOfItems, updatedTime, created
19732
20225
  ]
19733
20226
  }),
19734
20227
  /*#__PURE__*/ jsx(Tooltip, {
19735
- label: `Delete ${listName}. Will not delete dataset`,
20228
+ label: `Delete list ${listName}. Will not delete the actual dataset`,
19736
20229
  children: /*#__PURE__*/ jsx(ActionIcon, {
19737
20230
  color: "accent.4",
19738
20231
  variant: "transparent",
@@ -19949,12 +20442,18 @@ const LabeledText = ({ label, text })=>{
19949
20442
  ]
19950
20443
  });
19951
20444
  };
19952
- const QueryDetails = ({ name, schemaVersion, index, data, id })=>{
20445
+ const QueryDetails = ({ name, schemaVersion, data, id })=>{
19953
20446
  if (!data) {
19954
20447
  return /*#__PURE__*/ jsx(ErrorCard, {
19955
20448
  message: "No cohort query"
19956
20449
  });
19957
20450
  }
20451
+ const index = extractIndexFromDataLibraryCohort(data);
20452
+ if (!index) {
20453
+ return /*#__PURE__*/ jsx(ErrorCard, {
20454
+ message: "Not able to extract index from cohort query"
20455
+ });
20456
+ }
19958
20457
  return /*#__PURE__*/ jsxs("div", {
19959
20458
  className: "flex flex-col",
19960
20459
  children: [
@@ -20119,11 +20618,12 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20119
20618
  } : {}
20120
20619
  };
20121
20620
  },
20122
- renderRowActions: ({ row })=>/*#__PURE__*/ jsx(Tooltip, {
20123
- label: row.original.isCohort ? 'Remove cohort from list' : 'Remove dataset from list',
20621
+ renderRowActions: ({ row })=>{
20622
+ return /*#__PURE__*/ jsx(Tooltip, {
20623
+ label: row.original.isCohort === 'True' ? 'Remove cohort from list' : 'Remove dataset from list',
20124
20624
  children: /*#__PURE__*/ jsxs(Button, {
20125
20625
  variant: "transparent",
20126
- "aria-label": `remove ${row.original.isCohort ? 'cohort' : 'dataset'} ${row.original.name} from list`,
20626
+ "aria-label": `remove ${row.original.isCohort === 'True' ? 'cohort' : 'dataset'} ${row.original.name} from list`,
20127
20627
  onClick: ()=>{
20128
20628
  removeList(row.id);
20129
20629
  },
@@ -20134,7 +20634,8 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20134
20634
  row.original.itemType
20135
20635
  ]
20136
20636
  })
20137
- }),
20637
+ });
20638
+ },
20138
20639
  mantineDetailPanelProps: {
20139
20640
  style: {
20140
20641
  padding: '0px',
@@ -20180,11 +20681,9 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20180
20681
  *
20181
20682
  * @param {Object} dataListAccordionItemParams - Parameters for the DataListAccordionItem.
20182
20683
  * @param {Object} dataListAccordionItemParams.dataList - The data list to be displayed in the accordion item.
20183
- * @param {Function} dataListAccordionItemParams.updateListInDataLibrary - Function to update the list in the data library.
20184
- * @param {Function} dataListAccordionItemParams.deleteListFromDataLibrary - Function to delete the list from the data library.
20185
20684
  *
20186
20685
  * @return {JSX.Element} A rendered accordion item component with controls for data list updates and deletions.
20187
- */ const DatalistAccordionItem = ({ dataList, updateListInDataLibrary, deleteListFromDataLibrary, size = 'sm' })=>{
20686
+ */ const DatalistAccordionItem = ({ dataList, updateListInDataLibrary, deleteListFromDataLibrary, isUpdating, size = 'sm' })=>{
20188
20687
  const [selectedState, setSelectedState] = useState('unchecked');
20189
20688
  const { id: listId, name: listName } = dataList;
20190
20689
  const numberOfItemsInList = useMemo(()=>{
@@ -20194,10 +20693,13 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20194
20693
  ]);
20195
20694
  const { selections, updateSelections, removeListMember, removeList } = useDataLibrarySelection();
20196
20695
  const updateList = async (update)=>{
20197
- await updateListInDataLibrary(listId, {
20198
- ...dataList,
20696
+ await updateListInDataLibrary({
20697
+ ...{
20698
+ name: listName,
20699
+ items: dataList.items
20700
+ },
20199
20701
  ...update,
20200
- updatedTime: getTimestamp()
20702
+ id: listId
20201
20703
  });
20202
20704
  };
20203
20705
  const tableRowData = useMemo(()=>Object.entries(dataList.items).reduce((acc, [datasetId, dataItem])=>{
@@ -20215,7 +20717,7 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20215
20717
  });
20216
20718
  } else {
20217
20719
  // handle RegisteredDataListEntry
20218
- Object.entries(dataItem.items).forEach(([itemId, item])=>{
20720
+ Object.entries(dataItem.members).forEach(([itemId, item])=>{
20219
20721
  if (isFileItem(item)) {
20220
20722
  files.push({
20221
20723
  ...item,
@@ -20267,10 +20769,10 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20267
20769
  const removeItemFromList = async (itemId)=>{
20268
20770
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
20269
20771
  const { [itemId]: _removedKey, ...newObject } = dataList.items;
20270
- await updateListInDataLibrary(listId, {
20271
- ...dataList,
20272
- items: newObject,
20273
- updatedTime: getTimestamp()
20772
+ await updateListInDataLibrary({
20773
+ id: listId,
20774
+ name: dataList.name,
20775
+ items: newObject
20274
20776
  });
20275
20777
  // update selections
20276
20778
  removeListMember(listId, itemId);
@@ -20286,12 +20788,16 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20286
20788
  return /*#__PURE__*/ jsxs(Accordion.Item, {
20287
20789
  value: listName,
20288
20790
  className: "group",
20791
+ pos: "relative",
20289
20792
  children: [
20793
+ /*#__PURE__*/ jsx(LoadingOverlay, {
20794
+ visible: isUpdating === listId
20795
+ }),
20290
20796
  /*#__PURE__*/ jsx(DatasetAccordionControl, {
20291
20797
  listName: listName,
20292
20798
  numberOfItems: numberOfItemsInList,
20293
- updatedTime: dataList.updatedTime,
20294
- createdTime: dataList.createdTime,
20799
+ updatedTime: dataList.updated_time,
20800
+ createdTime: dataList.created_time,
20295
20801
  updateHandler: updateList,
20296
20802
  deleteListHandler: ()=>deleteListFromDataLibrary(listId),
20297
20803
  selectListHandler: handleSelectList,
@@ -20310,34 +20816,41 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20310
20816
  }, listName);
20311
20817
  };
20312
20818
 
20313
- const DataLibraryLists = ({ useAPI, actions, size })=>{
20314
- const { dataLibrary, isError, isLoading, error: dataLibraryError, addListToDataLibrary, updateListInDataLibrary, deleteListFromDataLibrary } = useDataLibrary(useAPI);
20819
+ const DataLibraryLists = ({ requiresLogin = true, actions, size })=>{
20820
+ const { dataLibrary, isLoading, isUpdating, error: dataLibraryError, addListToDataLibrary, updateListInDataLibrary, deleteListFromDataLibrary } = useDataLibrary();
20821
+ const { isAuthenticated } = useIsAuthenticated();
20315
20822
  const [selectedItemsOpen, { open, close }] = useDisclosure(false);
20316
20823
  const { gatherSelectedItems } = useDataLibrarySelection();
20317
20824
  const gatherData = ()=>{
20318
20825
  gatherSelectedItems(dataLibrary);
20319
20826
  open();
20320
20827
  };
20321
- if (isError) {
20322
- let message = 'There was a error getting the library';
20323
- if (dataLibraryError && 'data' in dataLibraryError && dataLibraryError?.status in HTTPUserFriendlyErrorMessages) {
20324
- message = HTTPUserFriendlyErrorMessages[dataLibraryError?.status];
20325
- }
20326
- return /*#__PURE__*/ jsx("div", {
20327
- className: "flex flex-col w-full ml-2",
20328
- children: /*#__PURE__*/ jsx(Center, {
20329
- children: /*#__PURE__*/ jsx(ErrorCard, {
20330
- message: message
20828
+ if (dataLibraryError?.isError) {
20829
+ if (dataLibraryError?.status === 401) {
20830
+ let message = 'You are not authorized to access the library.';
20831
+ if (requiresLogin) {
20832
+ if (!isAuthenticated) message = 'Data Library requires login. Please log in to continue.';
20833
+ else message = 'You are not authorized to access the library. Please contact your site administrator.';
20834
+ }
20835
+ return /*#__PURE__*/ jsx("div", {
20836
+ className: "flex flex-col w-full ml-2",
20837
+ children: /*#__PURE__*/ jsx(Center, {
20838
+ children: /*#__PURE__*/ jsx(ErrorCard, {
20839
+ message: message
20840
+ })
20331
20841
  })
20332
- })
20842
+ });
20843
+ } else notifications.show({
20844
+ position: 'top-center',
20845
+ color: 'red',
20846
+ title: 'Data Library Error',
20847
+ message: dataLibraryError?.message,
20848
+ autoClose: 2000
20333
20849
  });
20334
20850
  }
20335
20851
  return /*#__PURE__*/ jsxs("div", {
20336
20852
  className: "flex flex-col w-full ml-2",
20337
20853
  children: [
20338
- /*#__PURE__*/ jsx(LoadingOverlay, {
20339
- visible: isLoading
20340
- }),
20341
20854
  /*#__PURE__*/ jsx(SelectedItemsModal, {
20342
20855
  opened: selectedItemsOpen,
20343
20856
  onClose: close,
@@ -20348,23 +20861,29 @@ const DataLibraryLists = ({ useAPI, actions, size })=>{
20348
20861
  createList: addListToDataLibrary,
20349
20862
  gatherData: gatherData
20350
20863
  }),
20351
- /*#__PURE__*/ jsx("div", {
20864
+ /*#__PURE__*/ jsxs("div", {
20352
20865
  className: "flex items-center",
20353
- children: /*#__PURE__*/ jsx(Accordion, {
20354
- chevronPosition: "left",
20355
- classNames: {
20356
- root: 'w-full',
20357
- control: 'data-active:bg-secondary-lightest'
20358
- },
20359
- children: dataLibrary && Object.values(dataLibrary).map((datalist)=>{
20360
- return /*#__PURE__*/ jsx(DatalistAccordionItem, {
20361
- dataList: datalist,
20362
- size: size,
20363
- updateListInDataLibrary: updateListInDataLibrary,
20364
- deleteListFromDataLibrary: deleteListFromDataLibrary
20365
- }, datalist.id);
20866
+ children: [
20867
+ /*#__PURE__*/ jsx(LoadingOverlay, {
20868
+ visible: isLoading
20869
+ }),
20870
+ /*#__PURE__*/ jsx(Accordion, {
20871
+ chevronPosition: "left",
20872
+ classNames: {
20873
+ root: 'w-full',
20874
+ control: 'data-active:bg-secondary-lightest'
20875
+ },
20876
+ children: dataLibrary && Object.values(dataLibrary).map((datalist)=>{
20877
+ return /*#__PURE__*/ jsx(DatalistAccordionItem, {
20878
+ dataList: datalist,
20879
+ size: size,
20880
+ isUpdating: isUpdating,
20881
+ updateListInDataLibrary: updateListInDataLibrary,
20882
+ deleteListFromDataLibrary: deleteListFromDataLibrary
20883
+ }, datalist.id);
20884
+ })
20366
20885
  })
20367
- })
20886
+ ]
20368
20887
  })
20369
20888
  ]
20370
20889
  });
@@ -21025,5 +21544,5 @@ async function credentialsLogout(req, res) {
21025
21544
  res.redirect(307, '/');
21026
21545
  }
21027
21546
 
21028
- export { AISearchPageGetServerSideProps, ActionButton, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AnalysisCenter, AnalysisCenterWithSections, AnalysisEditorPage, AnalysisEditorPageGetServerSideProps, AnalysisPage, AnalysisPageGetServerSideProps, AuthzPage, BaseModal, Charts, CohortBuilder, CohortManager, CollapsableSidebar, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource$1 as ContentSource, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DataLibraryPage, DataLibraryPageGetServerSideProps, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, DropdownButton, EnumFacetChart, ErrorCard, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerPageGetServerSidePropsForConfigId, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FirstTimeModal, Footer, Gen3Button, Gen3ButtonReverse, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header, HoverLink, LandingPage, LandingPageGetServerSideProps, LoginButton$1 as LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, MinutesToMilliseconds, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, NotebookLitePage, NotebookLitePageGetStaticProps, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, ProtectedContent, QueryPage, QueryPageGetServerSideProps, ReactECharts, ResourcesFilters, SPECIAL_CASE_FIELDS, SessionExpiredModal, StudyGroup, SubmissionPage, SubmissionPageGetServerSideProps, TagCloud, TailwindConfig, TopBar, UploadJSONButton, User, Workspace, WorkspaceNoAccessPage, WorkspaceNoAccessPageServerSideProps, WorkspacePage, WorkspacePageGetServerSideProps, capitalize, computeRowSpan, convertMinutesToMilliseconds, convertSecondsToMilliseconds, create10ColorAccessibleContrast, create10ColorPallet, createMantineTheme, credentialsLogin, credentialsLogout, extractObjectKey, focusStyles, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isPropertyKey, isTextTransform$1 as isTextTransform, processLabel$1 as processLabel, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortSimilarityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, registerMetadataSchemaApp, removeKey$1 as removeKey, resourcePathFromProjectID, sessionLogout, sessionToken, stripTrailingSlash, toDisplayName, truncateString, unixTimeToString, useDiscoveryContext, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
21547
+ export { AISearchPageGetServerSideProps, ActionBar, ActionButton, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AnalysisCenter, AnalysisCenterWithSections, AnalysisEditorPage, AnalysisEditorPageGetServerSideProps, AnalysisPage, AnalysisPageGetServerSideProps, AuthzPage, BaseModal, Charts, CohortBuilder, CohortManager, CollapsableSidebar, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource$1 as ContentSource, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DataLibraryPage, DataLibraryPageGetServerSideProps, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, DropdownButton, EnumFacetChart, ErrorCard, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerPageGetServerSidePropsForConfigId, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FirstTimeModal, Footer, Gen3Button, Gen3ButtonReverse, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header, HoverLink, LandingPage, LandingPageGetServerSideProps, LoginButton$1 as LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, MinutesToMilliseconds, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, NotebookLitePage, NotebookLitePageGetStaticProps, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, ProtectedContent, QueryPage, QueryPageGetServerSideProps, ReactECharts, ResourcesFilters, SPECIAL_CASE_FIELDS, SessionExpiredModal, StudyGroup, SubmissionPage, SubmissionPageGetServerSideProps, TagCloud, TailwindConfig, TopBar, UploadJSONButton, User, Workspace, WorkspaceNoAccessPage, WorkspaceNoAccessPageServerSideProps, WorkspacePage, WorkspacePageGetServerSideProps, capitalize, computeRowSpan, convertMinutesToMilliseconds, convertSecondsToMilliseconds, create10ColorAccessibleContrast, create10ColorPallet, createMantineTheme, credentialsLogin, credentialsLogout, extractObjectKey, focusStyles, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isPropertyKey, isTextTransform$1 as isTextTransform, processLabel$1 as processLabel, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortSimilarityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, registerMetadataSchemaApp, removeKey$1 as removeKey, resourcePathFromProjectID, sessionLogout, sessionToken, stripTrailingSlash, toDisplayName, truncateString, unixTimeToString, useDiscoveryContext, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
21029
21548
  //# sourceMappingURL=index.js.map