@gen3/frontend 0.10.89 → 0.10.92

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 (308) hide show
  1. package/dist/cjs/index.js +995 -176
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/components/CountButton/CountButton.d.ts +19 -0
  4. package/dist/dts/components/CountButton/CountButton.d.ts.map +1 -0
  5. package/dist/dts/components/CountButton/CountButton.js +18 -0
  6. package/dist/dts/components/CountButton/CountButton.js.map +1 -0
  7. package/dist/dts/components/Login/LoginPanel.d.ts.map +1 -1
  8. package/dist/dts/components/Login/LoginPanel.js +2 -1
  9. package/dist/dts/components/Login/LoginPanel.js.map +1 -1
  10. package/dist/dts/components/Login/test/utils.test.d.ts +2 -0
  11. package/dist/dts/components/Login/test/utils.test.d.ts.map +1 -0
  12. package/dist/dts/components/Login/test/utils.test.js +39 -0
  13. package/dist/dts/components/Login/test/utils.test.js.map +1 -0
  14. package/dist/dts/components/Login/utils.d.ts +15 -0
  15. package/dist/dts/components/Login/utils.d.ts.map +1 -0
  16. package/dist/dts/components/Login/utils.js +31 -0
  17. package/dist/dts/components/Login/utils.js.map +1 -0
  18. package/dist/dts/components/Profile/CredentialsTable.d.ts.map +1 -1
  19. package/dist/dts/components/Profile/CredentialsTable.js +2 -1
  20. package/dist/dts/components/Profile/CredentialsTable.js.map +1 -1
  21. package/dist/dts/components/Providers/Gen3Provider.d.ts.map +1 -1
  22. package/dist/dts/components/Providers/Gen3Provider.js +6 -8
  23. package/dist/dts/components/Providers/Gen3Provider.js.map +1 -1
  24. package/dist/dts/components/Providers/ResourceMonitor.d.ts.map +1 -1
  25. package/dist/dts/components/Providers/ResourceMonitor.js +0 -1
  26. package/dist/dts/components/Providers/ResourceMonitor.js.map +1 -1
  27. package/dist/dts/features/Analysis/AnalysisCardCompact.stories.d.ts +6 -6
  28. package/dist/dts/features/Authz/Gen3Authz.js +2 -2
  29. package/dist/dts/features/Authz/Gen3Authz.js.map +1 -1
  30. package/dist/dts/features/Authz/Policies/PoliciesTable.d.ts.map +1 -1
  31. package/dist/dts/features/Authz/Policies/PoliciesTable.js +3 -3
  32. package/dist/dts/features/Authz/Policies/PoliciesTable.js.map +1 -1
  33. package/dist/dts/features/Authz/Resources/ResourcesTable.d.ts.map +1 -1
  34. package/dist/dts/features/Authz/Resources/ResourcesTable.js +2 -2
  35. package/dist/dts/features/Authz/Resources/ResourcesTable.js.map +1 -1
  36. package/dist/dts/features/Authz/Roles/RolesTable.js +1 -1
  37. package/dist/dts/features/Authz/Roles/RolesTable.js.map +1 -1
  38. package/dist/dts/features/Authz/Users/NewUserPanel.js +1 -1
  39. package/dist/dts/features/Authz/Users/NewUserPanel.js.map +1 -1
  40. package/dist/dts/features/Authz/Users/UserTable.js +1 -1
  41. package/dist/dts/features/Authz/Users/UserTable.js.map +1 -1
  42. package/dist/dts/features/Authz/index.d.ts +2 -2
  43. package/dist/dts/features/Authz/index.d.ts.map +1 -1
  44. package/dist/dts/features/Authz/index.js +2 -2
  45. package/dist/dts/features/Authz/index.js.map +1 -1
  46. package/dist/dts/features/CohortBuilder/CohortBuilder.js +1 -1
  47. package/dist/dts/features/CohortBuilder/CohortBuilder.js.map +1 -1
  48. package/dist/dts/features/CohortBuilder/cohortUtils.d.ts +4 -0
  49. package/dist/dts/features/CohortBuilder/cohortUtils.d.ts.map +1 -0
  50. package/dist/dts/features/CohortBuilder/cohortUtils.js +23 -0
  51. package/dist/dts/features/CohortBuilder/cohortUtils.js.map +1 -0
  52. package/dist/dts/features/CohortDiscovery/ActionButtons/ActionButtonGroup.d.ts +5 -0
  53. package/dist/dts/features/CohortDiscovery/ActionButtons/ActionButtonGroup.d.ts.map +1 -0
  54. package/dist/dts/features/CohortDiscovery/ActionButtons/ActionButtonGroup.js +13 -0
  55. package/dist/dts/features/CohortDiscovery/ActionButtons/ActionButtonGroup.js.map +1 -0
  56. package/dist/dts/features/CohortDiscovery/ActionButtons/SaveActionButton.d.ts +5 -0
  57. package/dist/dts/features/CohortDiscovery/ActionButtons/SaveActionButton.d.ts.map +1 -0
  58. package/dist/dts/features/CohortDiscovery/ActionButtons/SaveActionButton.js +28 -0
  59. package/dist/dts/features/CohortDiscovery/ActionButtons/SaveActionButton.js.map +1 -0
  60. package/dist/dts/features/CohortDiscovery/CohortDiscovery.js +2 -2
  61. package/dist/dts/features/CohortDiscovery/CohortDiscovery.js.map +1 -1
  62. package/dist/dts/features/CohortDiscovery/CohortManager.d.ts +6 -0
  63. package/dist/dts/features/CohortDiscovery/CohortManager.d.ts.map +1 -0
  64. package/dist/dts/features/CohortDiscovery/CohortManager.js +55 -0
  65. package/dist/dts/features/CohortDiscovery/CohortManager.js.map +1 -0
  66. package/dist/dts/features/CohortDiscovery/CohortManagerSlice.d.ts +135 -0
  67. package/dist/dts/features/CohortDiscovery/CohortManagerSlice.d.ts.map +1 -0
  68. package/dist/dts/features/CohortDiscovery/CohortManagerSlice.js +40 -0
  69. package/dist/dts/features/CohortDiscovery/CohortManagerSlice.js.map +1 -0
  70. package/dist/dts/features/CohortDiscovery/CohortSelectors.d.ts +23 -0
  71. package/dist/dts/features/CohortDiscovery/CohortSelectors.d.ts.map +1 -0
  72. package/dist/dts/features/CohortDiscovery/CohortSelectors.js +35 -0
  73. package/dist/dts/features/CohortDiscovery/CohortSelectors.js.map +1 -0
  74. package/dist/dts/features/CohortDiscovery/CohortSlice.d.ts +91 -0
  75. package/dist/dts/features/CohortDiscovery/CohortSlice.d.ts.map +1 -0
  76. package/dist/dts/features/CohortDiscovery/CohortSlice.js +93 -0
  77. package/dist/dts/features/CohortDiscovery/CohortSlice.js.map +1 -0
  78. package/dist/dts/features/CohortDiscovery/FacetDefinitionsSlice.d.ts +15 -0
  79. package/dist/dts/features/CohortDiscovery/FacetDefinitionsSlice.d.ts.map +1 -0
  80. package/dist/dts/features/CohortDiscovery/FacetDefinitionsSlice.js +38 -0
  81. package/dist/dts/features/CohortDiscovery/FacetDefinitionsSlice.js.map +1 -0
  82. package/dist/dts/features/CohortDiscovery/RequestManagerSlice.d.ts +162 -0
  83. package/dist/dts/features/CohortDiscovery/RequestManagerSlice.d.ts.map +1 -0
  84. package/dist/dts/features/CohortDiscovery/RequestManagerSlice.js +53 -0
  85. package/dist/dts/features/CohortDiscovery/RequestManagerSlice.js.map +1 -0
  86. package/dist/dts/features/CohortDiscovery/Requests/DataAccessRequestForm.d.ts +10 -0
  87. package/dist/dts/features/CohortDiscovery/Requests/DataAccessRequestForm.d.ts.map +1 -0
  88. package/dist/dts/features/CohortDiscovery/Requests/DataAccessRequestForm.js +85 -0
  89. package/dist/dts/features/CohortDiscovery/Requests/DataAccessRequestForm.js.map +1 -0
  90. package/dist/dts/features/CohortDiscovery/Requests/RequestsPanel.d.ts +3 -0
  91. package/dist/dts/features/CohortDiscovery/Requests/RequestsPanel.d.ts.map +1 -0
  92. package/dist/dts/features/CohortDiscovery/Requests/RequestsPanel.js +8 -0
  93. package/dist/dts/features/CohortDiscovery/Requests/RequestsPanel.js.map +1 -0
  94. package/dist/dts/features/CohortDiscovery/Requests/RequestsTable.d.ts +3 -0
  95. package/dist/dts/features/CohortDiscovery/Requests/RequestsTable.d.ts.map +1 -0
  96. package/dist/dts/features/CohortDiscovery/Requests/RequestsTable.js +67 -0
  97. package/dist/dts/features/CohortDiscovery/Requests/RequestsTable.js.map +1 -0
  98. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsPanel.d.ts +3 -0
  99. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsPanel.d.ts.map +1 -0
  100. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsPanel.js +9 -0
  101. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsPanel.js.map +1 -0
  102. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsTable.d.ts +7 -0
  103. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsTable.d.ts.map +1 -0
  104. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsTable.js +101 -0
  105. package/dist/dts/features/CohortDiscovery/SaveCohorts/SavedCohortsTable.js.map +1 -0
  106. package/dist/dts/features/CohortDiscovery/api/analysisApiCohortDiscovery.d.ts +3 -0
  107. package/dist/dts/features/CohortDiscovery/api/analysisApiCohortDiscovery.d.ts.map +1 -0
  108. package/dist/dts/features/CohortDiscovery/api/analysisApiCohortDiscovery.js +82 -0
  109. package/dist/dts/features/CohortDiscovery/api/analysisApiCohortDiscovery.js.map +1 -0
  110. package/dist/dts/features/CohortDiscovery/appApi.d.ts +10 -1
  111. package/dist/dts/features/CohortDiscovery/appApi.d.ts.map +1 -1
  112. package/dist/dts/features/CohortDiscovery/appApi.js.map +1 -1
  113. package/dist/dts/features/CohortDiscovery/appApiRTKQ.d.ts +1 -0
  114. package/dist/dts/features/CohortDiscovery/appApiRTKQ.d.ts.map +1 -0
  115. package/dist/dts/features/CohortDiscovery/appApiRTKQ.js +101 -0
  116. package/dist/dts/features/CohortDiscovery/appApiRTKQ.js.map +1 -0
  117. package/dist/dts/features/CohortDiscovery/queryApi.d.ts +32 -0
  118. package/dist/dts/features/CohortDiscovery/queryApi.d.ts.map +1 -0
  119. package/dist/dts/features/CohortDiscovery/queryApi.js +498 -0
  120. package/dist/dts/features/CohortDiscovery/queryApi.js.map +1 -0
  121. package/dist/dts/features/CohortDiscovery/tableSettings.d.ts +3 -0
  122. package/dist/dts/features/CohortDiscovery/tableSettings.d.ts.map +1 -0
  123. package/dist/dts/features/CohortDiscovery/tableSettings.js +68 -0
  124. package/dist/dts/features/CohortDiscovery/tableSettings.js.map +1 -0
  125. package/dist/dts/features/DataLibrary/DataLibrary.d.ts.map +1 -1
  126. package/dist/dts/features/DataLibrary/DataLibrary.js +1 -0
  127. package/dist/dts/features/DataLibrary/DataLibrary.js.map +1 -1
  128. package/dist/dts/features/DataLibrary/DataLibraryLists.d.ts.map +1 -1
  129. package/dist/dts/features/DataLibrary/DataLibraryLists.js +35 -18
  130. package/dist/dts/features/DataLibrary/DataLibraryLists.js.map +1 -1
  131. package/dist/dts/features/DataLibrary/DatalistAccordionItem.d.ts +4 -5
  132. package/dist/dts/features/DataLibrary/DatalistAccordionItem.d.ts.map +1 -1
  133. package/dist/dts/features/DataLibrary/DatalistAccordionItem.js +12 -12
  134. package/dist/dts/features/DataLibrary/DatalistAccordionItem.js.map +1 -1
  135. package/dist/dts/features/DataLibrary/DatasetAccordionControl.d.ts +3 -2
  136. package/dist/dts/features/DataLibrary/DatasetAccordionControl.d.ts.map +1 -1
  137. package/dist/dts/features/DataLibrary/DatasetAccordionControl.js +1 -1
  138. package/dist/dts/features/DataLibrary/DatasetAccordionControl.js.map +1 -1
  139. package/dist/dts/features/DataLibrary/QueryDetails.d.ts.map +1 -1
  140. package/dist/dts/features/DataLibrary/QueryDetails.js +6 -2
  141. package/dist/dts/features/DataLibrary/QueryDetails.js.map +1 -1
  142. package/dist/dts/features/DataLibrary/SearchAndActions.d.ts +4 -2
  143. package/dist/dts/features/DataLibrary/SearchAndActions.d.ts.map +1 -1
  144. package/dist/dts/features/DataLibrary/SearchAndActions.js +4 -3
  145. package/dist/dts/features/DataLibrary/SearchAndActions.js.map +1 -1
  146. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/exportMetadataToWorkspace.d.ts +3 -0
  147. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/exportMetadataToWorkspace.d.ts.map +1 -0
  148. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/exportMetadataToWorkspace.js +178 -0
  149. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/exportMetadataToWorkspace.js.map +1 -0
  150. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/providerErrorNotification.d.ts +9 -0
  151. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/providerErrorNotification.d.ts.map +1 -0
  152. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/providerErrorNotification.js +7 -0
  153. package/dist/dts/features/DataLibrary/selection/actions/exportDatasetsToWorkspace/providerErrorNotification.js.map +1 -0
  154. package/dist/dts/features/DataLibrary/selection/actions/exportToManifest.d.ts +3 -0
  155. package/dist/dts/features/DataLibrary/selection/actions/exportToManifest.d.ts.map +1 -0
  156. package/dist/dts/features/DataLibrary/selection/actions/exportToManifest.js +80 -0
  157. package/dist/dts/features/DataLibrary/selection/actions/exportToManifest.js.map +1 -0
  158. package/dist/dts/features/DataLibrary/selection/exportActions.d.ts +1 -1
  159. package/dist/dts/features/DataLibrary/selection/exportActions.d.ts.map +1 -1
  160. package/dist/dts/features/DataLibrary/selection/exportActions.js +15 -10
  161. package/dist/dts/features/DataLibrary/selection/exportActions.js.map +1 -1
  162. package/dist/dts/features/DataLibrary/selection/registeredActions.d.ts +1 -4
  163. package/dist/dts/features/DataLibrary/selection/registeredActions.d.ts.map +1 -1
  164. package/dist/dts/features/DataLibrary/selection/registeredActions.js +8 -0
  165. package/dist/dts/features/DataLibrary/selection/registeredActions.js.map +1 -1
  166. package/dist/dts/features/DataLibrary/selection/selectedItemActions.d.ts.map +1 -1
  167. package/dist/dts/features/DataLibrary/selection/selectedItemActions.js +4 -0
  168. package/dist/dts/features/DataLibrary/selection/selectedItemActions.js.map +1 -1
  169. package/dist/dts/features/DataLibrary/selection/selection.d.ts +3 -3
  170. package/dist/dts/features/DataLibrary/selection/selection.d.ts.map +1 -1
  171. package/dist/dts/features/DataLibrary/selection/selection.js +2 -2
  172. package/dist/dts/features/DataLibrary/selection/selection.js.map +1 -1
  173. package/dist/dts/features/DataLibrary/selection/tests/utils.unit.test.js +71 -1
  174. package/dist/dts/features/DataLibrary/selection/tests/utils.unit.test.js.map +1 -1
  175. package/dist/dts/features/DataLibrary/selection/types.d.ts +5 -3
  176. package/dist/dts/features/DataLibrary/selection/types.d.ts.map +1 -1
  177. package/dist/dts/features/DataLibrary/selection/utils.d.ts +4 -2
  178. package/dist/dts/features/DataLibrary/selection/utils.d.ts.map +1 -1
  179. package/dist/dts/features/DataLibrary/selection/utils.js +21 -3
  180. package/dist/dts/features/DataLibrary/selection/utils.js.map +1 -1
  181. package/dist/dts/features/DataLibrary/tables/DatasetContentsTable.d.ts.map +1 -1
  182. package/dist/dts/features/DataLibrary/tables/DatasetContentsTable.js +2 -2
  183. package/dist/dts/features/DataLibrary/tables/DatasetContentsTable.js.map +1 -1
  184. package/dist/dts/features/DataLibrary/types.d.ts +8 -2
  185. package/dist/dts/features/DataLibrary/types.d.ts.map +1 -1
  186. package/dist/dts/features/DataLibrary/types.js +18 -0
  187. package/dist/dts/features/DataLibrary/types.js.map +1 -1
  188. package/dist/dts/features/Discovery/ActionBar/ActionBar.d.ts +5 -4
  189. package/dist/dts/features/Discovery/ActionBar/ActionBar.d.ts.map +1 -1
  190. package/dist/dts/features/Discovery/ActionBar/ActionBar.js +19 -10
  191. package/dist/dts/features/Discovery/ActionBar/ActionBar.js.map +1 -1
  192. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.d.ts +1 -1
  193. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.d.ts.map +1 -1
  194. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.js +109 -50
  195. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.js.map +1 -1
  196. package/dist/dts/features/Discovery/ActionBar/AddToDataLibrary.stories.d.ts +1 -1
  197. package/dist/dts/features/Discovery/ActionBar/DataLibraryActionButton.d.ts +1 -1
  198. package/dist/dts/features/Discovery/ActionBar/DataLibraryActionButton.js +3 -3
  199. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.d.ts +2 -2
  200. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.d.ts.map +1 -1
  201. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.js +2 -2
  202. package/dist/dts/features/Discovery/ActionBar/DownloadAsZipButton.js.map +1 -1
  203. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.d.ts +2 -2
  204. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.d.ts.map +1 -1
  205. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.js +59 -10
  206. package/dist/dts/features/Discovery/ActionBar/DownloadManifestButton.js.map +1 -1
  207. package/dist/dts/features/Discovery/ActionBar/types.d.ts +12 -2
  208. package/dist/dts/features/Discovery/ActionBar/types.d.ts.map +1 -1
  209. package/dist/dts/features/Discovery/DataLoaders/IndexedMetadata/DataLoader.d.ts.map +1 -1
  210. package/dist/dts/features/Discovery/DataLoaders/IndexedMetadata/DataLoader.js +3 -1
  211. package/dist/dts/features/Discovery/DataLoaders/IndexedMetadata/DataLoader.js.map +1 -1
  212. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.d.ts.map +1 -1
  213. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.js +6 -2
  214. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.js.map +1 -1
  215. package/dist/dts/features/Discovery/DataLoaders/utils.d.ts +2 -2
  216. package/dist/dts/features/Discovery/DataLoaders/utils.d.ts.map +1 -1
  217. package/dist/dts/features/Discovery/DataLoaders/utils.js +87 -41
  218. package/dist/dts/features/Discovery/DataLoaders/utils.js.map +1 -1
  219. package/dist/dts/features/Discovery/Discovery.d.ts.map +1 -1
  220. package/dist/dts/features/Discovery/Discovery.js +1 -0
  221. package/dist/dts/features/Discovery/Discovery.js.map +1 -1
  222. package/dist/dts/features/Discovery/DiscoveryIndexPanel.d.ts +13 -0
  223. package/dist/dts/features/Discovery/DiscoveryIndexPanel.d.ts.map +1 -1
  224. package/dist/dts/features/Discovery/DiscoveryIndexPanel.js +39 -14
  225. package/dist/dts/features/Discovery/DiscoveryIndexPanel.js.map +1 -1
  226. package/dist/dts/features/Discovery/DiscoveryTable.d.ts +2 -1
  227. package/dist/dts/features/Discovery/DiscoveryTable.d.ts.map +1 -1
  228. package/dist/dts/features/Discovery/DiscoveryTable.js +18 -6
  229. package/dist/dts/features/Discovery/DiscoveryTable.js.map +1 -1
  230. package/dist/dts/features/Discovery/StudyPage/DownloadLinksPanel.d.ts.map +1 -1
  231. package/dist/dts/features/Discovery/StudyPage/DownloadLinksPanel.js +2 -1
  232. package/dist/dts/features/Discovery/StudyPage/DownloadLinksPanel.js.map +1 -1
  233. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.js +2 -2
  234. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.js.map +1 -1
  235. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.d.ts +2 -1
  236. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.d.ts.map +1 -1
  237. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js +1 -1
  238. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js.map +1 -1
  239. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.d.ts +2 -1
  240. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.d.ts.map +1 -1
  241. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.js +40 -11
  242. package/dist/dts/features/Discovery/TableRenderers/DataAccessCellRenderers.js.map +1 -1
  243. package/dist/dts/features/Discovery/TableRenderers/types.d.ts +2 -1
  244. package/dist/dts/features/Discovery/TableRenderers/types.d.ts.map +1 -1
  245. package/dist/dts/features/Discovery/constants.d.ts +2 -0
  246. package/dist/dts/features/Discovery/constants.d.ts.map +1 -0
  247. package/dist/dts/features/Discovery/constants.js +2 -0
  248. package/dist/dts/features/Discovery/constants.js.map +1 -0
  249. package/dist/dts/features/Discovery/index.d.ts +2 -1
  250. package/dist/dts/features/Discovery/index.d.ts.map +1 -1
  251. package/dist/dts/features/Discovery/index.js +2 -1
  252. package/dist/dts/features/Discovery/index.js.map +1 -1
  253. package/dist/dts/features/Discovery/types.d.ts +13 -15
  254. package/dist/dts/features/Discovery/types.d.ts.map +1 -1
  255. package/dist/dts/features/Discovery/types.js +2 -1
  256. package/dist/dts/features/Discovery/types.js.map +1 -1
  257. package/dist/dts/features/Discovery/utils.d.ts +8 -2
  258. package/dist/dts/features/Discovery/utils.d.ts.map +1 -1
  259. package/dist/dts/features/Discovery/utils.js +37 -4
  260. package/dist/dts/features/Discovery/utils.js.map +1 -1
  261. package/dist/dts/features/Navigation/TopBar/TopBar.d.ts.map +1 -1
  262. package/dist/dts/features/Navigation/TopBar/TopBar.js +1 -1
  263. package/dist/dts/features/Navigation/TopBar/TopBar.js.map +1 -1
  264. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.d.ts.map +1 -1
  265. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.js +3 -1
  266. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.js.map +1 -1
  267. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.js +1 -1
  268. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.js.map +1 -1
  269. package/dist/dts/lib/content/filesystem.js +1 -1
  270. package/dist/dts/lib/content/filesystem.js.map +1 -1
  271. package/dist/dts/lib/session/session.d.ts.map +1 -1
  272. package/dist/dts/lib/session/session.js +5 -2
  273. package/dist/dts/lib/session/session.js.map +1 -1
  274. package/dist/dts/pages/DataLibrary/DataLibrary.d.ts.map +1 -1
  275. package/dist/dts/pages/DataLibrary/DataLibrary.js +1 -0
  276. package/dist/dts/pages/DataLibrary/DataLibrary.js.map +1 -1
  277. package/dist/dts/pages/DataLibrary/data.js +2 -2
  278. package/dist/dts/pages/DataLibrary/data.js.map +1 -1
  279. package/dist/dts/pages/Discovery/data.d.ts.map +1 -1
  280. package/dist/dts/pages/Discovery/data.js +22 -11
  281. package/dist/dts/pages/Discovery/data.js.map +1 -1
  282. package/dist/dts/pages/Explorer/data.d.ts.map +1 -1
  283. package/dist/dts/pages/Explorer/data.js +2 -2
  284. package/dist/dts/pages/Explorer/data.js.map +1 -1
  285. package/dist/dts/types/constants.d.ts +2 -0
  286. package/dist/dts/types/constants.d.ts.map +1 -0
  287. package/dist/dts/types/constants.js +2 -0
  288. package/dist/dts/types/constants.js.map +1 -0
  289. package/dist/dts/utils/authMapping.d.ts +2 -2
  290. package/dist/dts/utils/authMapping.d.ts.map +1 -1
  291. package/dist/dts/utils/authMapping.js.map +1 -1
  292. package/dist/dts/utils/sizes.d.ts +4 -0
  293. package/dist/dts/utils/sizes.d.ts.map +1 -0
  294. package/dist/dts/utils/sizes.js +25 -0
  295. package/dist/dts/utils/sizes.js.map +1 -0
  296. package/dist/esm/index.js +1000 -182
  297. package/dist/esm/index.js.map +1 -1
  298. package/dist/index.d.ts +36 -18
  299. package/dist/tsconfig.tsbuildinfo +1 -1
  300. package/package.json +3 -3
  301. package/dist/dts/features/Authz/Provider.d.ts +0 -44
  302. package/dist/dts/features/Authz/Provider.d.ts.map +0 -1
  303. package/dist/dts/features/Authz/Provider.js +0 -55
  304. package/dist/dts/features/Authz/Provider.js.map +0 -1
  305. package/dist/dts/features/Discovery/utils/processDataAccess.d.ts +0 -3
  306. package/dist/dts/features/Discovery/utils/processDataAccess.d.ts.map +0 -1
  307. package/dist/dts/features/Discovery/utils/processDataAccess.js +0 -73
  308. package/dist/dts/features/Discovery/utils/processDataAccess.js.map +0 -1
package/dist/esm/index.js CHANGED
@@ -1,18 +1,18 @@
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, DataLibraryStoreMode, 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, getFederatedLoginStatus, queryMultipleMDSRecords, GEN3_MANIFEST_API, 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';
13
13
  import { notifications, showNotification, cleanNotifications, Notifications } from '@mantine/notifications';
14
14
  import tinycolor from 'tinycolor2';
15
- import { capitalize as capitalize$1, toString, isArray, get, omit, partial } from 'lodash';
15
+ import { capitalize as capitalize$1, toString, isArray, get, omit, partial, cloneDeep, unset } from 'lodash';
16
16
  import { twMerge } from 'tailwind-merge';
17
17
  import { BsExclamationTriangle, BsArrowsFullscreen } from 'react-icons/bs';
18
18
  import Markdown from 'react-markdown';
@@ -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));
@@ -878,7 +878,7 @@ const UPDATE_SESSION_LIMIT = MinutesToMilliseconds(5);
878
878
  await getUserDetails();
879
879
  };
880
880
  const sessionInfo = useManageSession(userStatus);
881
- // for now we are using the user status to determine if the user is logged in
881
+ // for now, we are using the user status to determine if the user is logged in
882
882
  const updateSession = useCallback(()=>updateSessionWithUserStatus(), [
883
883
  updateSessionWithUserStatus
884
884
  ]);
@@ -904,9 +904,11 @@ const UPDATE_SESSION_LIMIT = MinutesToMilliseconds(5);
904
904
  };
905
905
  window.addEventListener('mousedown', updateUserActivity);
906
906
  window.addEventListener('keypress', updateUserActivity);
907
+ window.addEventListener('updateUserActivity', updateUserActivity);
907
908
  return ()=>{
908
909
  window.removeEventListener('mousedown', updateUserActivity);
909
910
  window.removeEventListener('keypress', updateUserActivity);
911
+ window.removeEventListener('updateUserActivity', updateUserActivity);
910
912
  };
911
913
  }, []); // only call on mount/dismount
912
914
  useInterval(()=>{
@@ -1467,6 +1469,35 @@ function hashCode(str) {
1467
1469
  }
1468
1470
  };
1469
1471
 
1472
+ /**
1473
+ * Determines the correct separator to append additional parameters to a URL
1474
+ * @param {string} url - The URL to examine
1475
+ * @returns {string} - Either '?' or '&' depending on whether the URL already has parameters
1476
+ */ const getUrlSeparator = (url)=>{
1477
+ // Check if the URL already contains a question mark
1478
+ return url.includes('?') ? '&' : '?';
1479
+ };
1480
+ /**
1481
+ * Adds a parameter to a URL using the correct separator
1482
+ * @param {string} url - The URL to add the parameter to
1483
+ * @param {string} paramName - The parameter name
1484
+ * @param {string} paramValue - The parameter value
1485
+ * @returns {string} - The URL with the added parameter
1486
+ */ const appendParameterToUrl = (url, paramName, paramValue)=>{
1487
+ if (!url || false) {
1488
+ return url;
1489
+ }
1490
+ // Extract hash fragment if present
1491
+ const [baseUrl, hash] = url.split('#');
1492
+ const hashFragment = hash ? `#${hash}` : '';
1493
+ // Determine separator and append parameter
1494
+ const separator = getUrlSeparator(baseUrl);
1495
+ const encodedParamName = encodeURIComponent(paramName);
1496
+ const encodedParamValue = encodeURIComponent(paramValue);
1497
+ // Construct the final URL with parameter and hash fragment
1498
+ return `${baseUrl}${separator}${encodedParamName}=${encodedParamValue}${hashFragment}`;
1499
+ };
1500
+
1470
1501
  const filterRedirect = (redirect)=>{
1471
1502
  let redirectPath = '';
1472
1503
  if (Array.isArray(redirect)) {
@@ -1481,7 +1512,7 @@ const LoginPanel = (loginConfig)=>{
1481
1512
  const router = useRouter();
1482
1513
  const { query: { referer } } = router;
1483
1514
  const handleFenceLoginSelected = useCallback(async (loginURL)=>{
1484
- router.push(`${loginURL}?redirect=${filterRedirect(referer)}`).catch((e)=>{
1515
+ router.push(`${appendParameterToUrl(loginURL, 'redirect', filterRedirect(referer))}`).catch((e)=>{
1485
1516
  showNotification({
1486
1517
  title: 'Login Error',
1487
1518
  message: `error logging in ${e.message}`
@@ -3037,6 +3068,22 @@ const Gen3Link = ({ className, href, linkType, text, showExternalIcon = false })
3037
3068
  });
3038
3069
  };
3039
3070
 
3071
+ /**
3072
+ * Type guard for ValidFileItemWithParentDatasetNameAndID
3073
+ * Checks if the object has the properties that define this interface
3074
+ */ const isValidFileItemWithParentDatasetNameAndID = (item)=>{
3075
+ if (!item || typeof item !== 'object') {
3076
+ return false;
3077
+ }
3078
+ const fileItem = item;
3079
+ // Check required properties from FileItemWithParentDatasetNameAndID
3080
+ if (typeof fileItem.datasetName !== 'string' || typeof fileItem.datasetId !== 'string') {
3081
+ return false;
3082
+ }
3083
+ // We can assume it's a FileItem if it has the required properties from parent interfaces
3084
+ // Additional checks could be added if FileItem has required properties
3085
+ return true;
3086
+ };
3040
3087
  const IconSize = {
3041
3088
  xs: 14,
3042
3089
  sm: 16,
@@ -3727,6 +3774,23 @@ const NavPageLayout = ({ headerProps, footerProps, mainProps, headerData, childr
3727
3774
 
3728
3775
  var classes = {"tableRow":"DiscoveryTable-module_tableRow__yFUJZ"};
3729
3776
 
3777
+ const isSearchKV = (obj)=>{
3778
+ return obj && obj.key && obj.value;
3779
+ };
3780
+ const isSearchKVArray = (obj)=>{
3781
+ return obj && Array.isArray(obj) && obj.every(isSearchKV);
3782
+ };
3783
+ const accessibleFieldName = '__accessible';
3784
+ var AccessLevel = /*#__PURE__*/ function(AccessLevel) {
3785
+ AccessLevel[AccessLevel["ACCESSIBLE"] = 1] = "ACCESSIBLE";
3786
+ AccessLevel[AccessLevel["UNACCESSIBLE"] = 2] = "UNACCESSIBLE";
3787
+ AccessLevel[AccessLevel["WAITING"] = 3] = "WAITING";
3788
+ AccessLevel[AccessLevel["NOT_AVAILABLE"] = 4] = "NOT_AVAILABLE";
3789
+ AccessLevel[AccessLevel["OTHER"] = 5] = "OTHER";
3790
+ AccessLevel[AccessLevel["MIXED"] = 6] = "MIXED";
3791
+ return AccessLevel;
3792
+ }({});
3793
+
3730
3794
  const jsonPathAccessor$1 = (path)=>(row)=>{
3731
3795
  // TODO: add logging if path is not found
3732
3796
  return JSONPath({
@@ -3735,7 +3799,14 @@ const jsonPathAccessor$1 = (path)=>(row)=>{
3735
3799
  });
3736
3800
  };
3737
3801
  const getTagInfo = (tagData, tagsConfig)=>{
3738
- const categoryConfig = tagsConfig.tagCategories.find((category)=>category.name === tagData.category);
3802
+ if (tagData.category === undefined) {
3803
+ return {
3804
+ color: 'darkgray',
3805
+ display: tagsConfig?.showUnknownTags ?? false,
3806
+ label: tagData.name
3807
+ };
3808
+ }
3809
+ const categoryConfig = tagsConfig?.tagCategories.find((category)=>category.name === tagData.category);
3739
3810
  if (categoryConfig === undefined) return {
3740
3811
  color: 'gray',
3741
3812
  display: tagsConfig?.showUnknownTags ?? false,
@@ -3752,6 +3823,29 @@ const getManualSortingAndPagination = (config)=>{
3752
3823
  const sortingAndPagination = config?.features?.dataLoader?.sortingAndPagination ?? defaultFeature;
3753
3824
  return sortingAndPagination === 'server';
3754
3825
  };
3826
+ /**
3827
+ * Converts a numeric value to its equivalent AccessLevel enum value
3828
+ * @param value - The numeric value to convert (1-6)
3829
+ * @returns The corresponding AccessLevel enum value or undefined if not found
3830
+ */ const getAccessLevelFromNumber = (value)=>{
3831
+ if (value === undefined) return undefined;
3832
+ switch(value){
3833
+ case AccessLevel.ACCESSIBLE:
3834
+ return AccessLevel.ACCESSIBLE;
3835
+ case AccessLevel.UNACCESSIBLE:
3836
+ return AccessLevel.UNACCESSIBLE;
3837
+ case AccessLevel.WAITING:
3838
+ return AccessLevel.WAITING;
3839
+ case AccessLevel.NOT_AVAILABLE:
3840
+ return AccessLevel.NOT_AVAILABLE;
3841
+ case AccessLevel.OTHER:
3842
+ return AccessLevel.OTHER;
3843
+ case AccessLevel.MIXED:
3844
+ return AccessLevel.MIXED;
3845
+ default:
3846
+ return undefined;
3847
+ }
3848
+ };
3755
3849
 
3756
3850
  const defaultCellRenderer = (value, params)=>{
3757
3851
  if (value === undefined || value === null || toString(value) === '') {
@@ -3762,11 +3856,8 @@ const defaultCellRenderer = (value, params)=>{
3762
3856
  ]
3763
3857
  });
3764
3858
  }
3765
- return /*#__PURE__*/ jsxs(Text, {
3766
- children: [
3767
- toString(value),
3768
- "dfdsfdsf"
3769
- ]
3859
+ return /*#__PURE__*/ jsx(Text, {
3860
+ children: toString(value)
3770
3861
  });
3771
3862
  };
3772
3863
  class DiscoveryCellRendererFactory {
@@ -3911,45 +4002,106 @@ const DiscoveryProvider = ({ children, discoveryIndexConfig })=>{
3911
4002
  });
3912
4003
  };
3913
4004
 
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);
4005
+ const buildTooltip = (mainMessage, secondaryMessage)=>{
4006
+ return /*#__PURE__*/ jsxs("div", {
4007
+ className: "flex flex-col",
4008
+ children: [
4009
+ /*#__PURE__*/ jsxs(Text, {
4010
+ size: "sm",
4011
+ children: [
4012
+ " ",
4013
+ mainMessage,
4014
+ " "
4015
+ ]
4016
+ }),
4017
+ secondaryMessage ? /*#__PURE__*/ jsxs("div", {
4018
+ className: "flex flex-col items-start my-1",
4019
+ children: [
4020
+ /*#__PURE__*/ jsx(Divider, {}),
4021
+ /*#__PURE__*/ jsx(Text, {
4022
+ size: "xs",
4023
+ children: secondaryMessage
4024
+ })
4025
+ ]
4026
+ }) : null
4027
+ ]
4028
+ });
3919
4029
  };
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."
4030
+ const DataAccessCellRenderer = ({ cell, row }, params)=>{
4031
+ const { discoveryConfig: config } = useDiscoveryContext();
4032
+ const authzField = config.minimalFieldMapping?.authzField || 'authz';
4033
+ let value = cell?.getValue();
4034
+ const authorization = row?.original?.[authzField] || undefined;
4035
+ const dataObjectField = config.features.exportFromDiscovery?.exportDataFields.dataObjectField;
4036
+ row?.original?.num_fileobject || 0;
4037
+ if (isArray(value)) value = value[0];
4038
+ const accessLevel = getAccessLevelFromNumber(value);
4039
+ const numFileObjects = dataObjectField && row?.original?.[dataObjectField] ? row?.original?.[dataObjectField] : 0;
4040
+ if (numFileObjects === 0) {
4041
+ return /*#__PURE__*/ jsx(Tooltip, {
4042
+ label: buildTooltip('No data attached to this study'),
4043
+ children: /*#__PURE__*/ jsx(LuCircleSlash, {
4044
+ className: "text-utility-error"
4045
+ })
3935
4046
  });
3936
4047
  }
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."
4048
+ if (!accessLevel) {
4049
+ return /*#__PURE__*/ jsx(Tooltip, {
4050
+ label: buildTooltip('Unable to determine access level'),
4051
+ children: /*#__PURE__*/ jsx(LuCircleSlash, {
4052
+ className: "text-utility-error"
4053
+ })
3941
4054
  });
3942
4055
  }
3943
- if (value === AccessLevel.ACCESSIBLE) {
3944
- return /*#__PURE__*/ jsx(LuUnlock, {
3945
- color: "green",
3946
- children: "You have access to this study."
4056
+ if (accessLevel === AccessLevel.WAITING) {
4057
+ return /*#__PURE__*/ jsx(Tooltip, {
4058
+ label: buildTooltip('Data are not yet available'),
4059
+ children: /*#__PURE__*/ jsx(LuClock, {
4060
+ className: "text-utility-warning"
4061
+ })
3947
4062
  });
3948
4063
  }
3949
- if (value === AccessLevel.UNACCESSIBLE) {
3950
- return /*#__PURE__*/ jsx(LuLock, {
3951
- color: "red",
3952
- children: "You do not have access to this study."
4064
+ if (accessLevel === AccessLevel.MIXED) {
4065
+ return /*#__PURE__*/ jsx(Tooltip, {
4066
+ label: buildTooltip('You have mixed acccess'),
4067
+ children: /*#__PURE__*/ jsxs(Group, {
4068
+ children: [
4069
+ /*#__PURE__*/ jsx(LuLock, {
4070
+ className: "text-utility-warning"
4071
+ }),
4072
+ /*#__PURE__*/ jsx(LuUnlock, {
4073
+ className: "text-utility-warning"
4074
+ })
4075
+ ]
4076
+ })
4077
+ });
4078
+ }
4079
+ if (accessLevel === AccessLevel.NOT_AVAILABLE) {
4080
+ return /*#__PURE__*/ jsx(Tooltip, {
4081
+ label: buildTooltip('No data is shared'),
4082
+ children: /*#__PURE__*/ jsx(LuCircleSlash, {
4083
+ className: "text-utility-error"
4084
+ })
4085
+ });
4086
+ }
4087
+ if (accessLevel === AccessLevel.ACCESSIBLE) {
4088
+ return /*#__PURE__*/ jsx(Tooltip, {
4089
+ label: buildTooltip('You have access to this study', `read access to ${authorization}`),
4090
+ children: /*#__PURE__*/ jsx("div", {
4091
+ children: /*#__PURE__*/ jsx(LuUnlock, {
4092
+ className: "text-utility-success"
4093
+ })
4094
+ })
4095
+ });
4096
+ }
4097
+ if (accessLevel === AccessLevel.UNACCESSIBLE) {
4098
+ return /*#__PURE__*/ jsx(Tooltip, {
4099
+ label: buildTooltip('You currently do not have access to this study', `you need read access to ${authorization}`),
4100
+ children: /*#__PURE__*/ jsx("div", {
4101
+ children: /*#__PURE__*/ jsx(LuLock, {
4102
+ className: "text-utility-error"
4103
+ })
4104
+ })
3953
4105
  });
3954
4106
  }
3955
4107
  return /*#__PURE__*/ jsx(React__default.Fragment, {});
@@ -4127,13 +4279,10 @@ const RenderLinkWithURL = ({ value, cell }, params)=>{
4127
4279
  onClick: (ev)=>ev.stopPropagation(),
4128
4280
  target: "_blank",
4129
4281
  rel: "noreferrer",
4130
- children: /*#__PURE__*/ jsxs(Text, {
4282
+ children: /*#__PURE__*/ jsx(Text, {
4131
4283
  c: "utility.0",
4132
4284
  tt: ttValue,
4133
- children: [
4134
- content,
4135
- " fgh"
4136
- ]
4285
+ children: content
4137
4286
  })
4138
4287
  });
4139
4288
  };
@@ -4807,14 +4956,20 @@ const DownloadLinksPanel = ({ studyData, downloadLinks, downloadLinkFields = {
4807
4956
  }
4808
4957
  const id = entry[downloadLinkFields.idField];
4809
4958
  return /*#__PURE__*/ jsxs(Group, {
4959
+ justify: "space-between",
4810
4960
  gap: "md",
4811
4961
  children: [
4812
4962
  /*#__PURE__*/ jsx(Text, {
4813
4963
  children: entry['titleField'] || ''
4814
4964
  }),
4815
4965
  /*#__PURE__*/ jsx(Button, {
4966
+ component: "a",
4967
+ href: `${GEN3_FENCE_API}/data/${id}?expires_in=900&redirect`,
4968
+ target: "_blank",
4969
+ rel: "noreferrer",
4970
+ type: "text",
4816
4971
  leftSection: /*#__PURE__*/ jsx(FiDownload, {}),
4817
- disabled: !id,
4972
+ "data-disabled": !id,
4818
4973
  children: "Download File"
4819
4974
  })
4820
4975
  ]
@@ -4993,14 +5148,16 @@ const TableIcons = {
4993
5148
  })
4994
5149
  };
4995
5150
 
4996
- const extractCellValue = (func)=>({ cell })=>func({
5151
+ const extractCellValue = (func)=>({ cell, row })=>func({
4997
5152
  value: cell.getValue(),
4998
- cell
5153
+ cell,
5154
+ row
4999
5155
  });
5000
- const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPagination, pagination, sorting })=>{
5156
+ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPagination, setSelection, pagination, sorting })=>{
5001
5157
  const { discoveryConfig: config, setStudyDetails } = useDiscoveryContext();
5002
5158
  const { isLoading, isError, isFetching } = dataRequestStatus;
5003
5159
  const manualSortingAndPagination = getManualSortingAndPagination(config);
5160
+ const [rowSelection, setRowSelection] = useState({}); //ts type available
5004
5161
  const cols = useDeepCompareMemo(()=>{
5005
5162
  const studyColumns = config.studyColumns ?? [];
5006
5163
  return studyColumns.map((columnDef, idx)=>{
@@ -5040,6 +5197,7 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
5040
5197
  enableColumnActions: false,
5041
5198
  enableStickyHeader: true,
5042
5199
  enableStickyFooter: true,
5200
+ getRowId: (originalRow)=>config?.minimalFieldMapping?.uid && config.minimalFieldMapping.uid in originalRow ? originalRow[config.minimalFieldMapping.uid] : originalRow?.id ?? undefined,
5043
5201
  // TODO: keep this to explore later
5044
5202
  // mantineTableContainerProps: ({ table }) => {
5045
5203
  // return {
@@ -5049,7 +5207,9 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
5049
5207
  // };
5050
5208
  // },
5051
5209
  renderDetailPanel: config.studyPreviewField ? DiscoveryTableRowRenderer(config.studyPreviewField) : undefined,
5210
+ onRowSelectionChange: setRowSelection,
5052
5211
  state: {
5212
+ rowSelection,
5053
5213
  isLoading,
5054
5214
  ...manualSortingAndPagination ? {
5055
5215
  pagination,
@@ -5096,6 +5256,13 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
5096
5256
  }
5097
5257
  }
5098
5258
  });
5259
+ useDeepCompareEffect(()=>{
5260
+ //fetch data based on row selection state or something
5261
+ setSelection(rowSelection ? Object.keys(rowSelection) : []);
5262
+ }, [
5263
+ rowSelection,
5264
+ setSelection
5265
+ ]);
5099
5266
  return /*#__PURE__*/ jsxs(React__default.Fragment, {
5100
5267
  children: [
5101
5268
  /*#__PURE__*/ jsx(StudyDetails, {}),
@@ -5391,10 +5558,10 @@ const AdvancedSearchPanel = (props)=>{
5391
5558
  });
5392
5559
  };
5393
5560
 
5394
- const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, icon = undefined, disabled = false, toolTip = undefined, onClick = ()=>null, active = false, showIcon = true, loginRequired = false, ...buttonProps }, ref)=>{
5561
+ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, icon = undefined, disabled = false, tooltip = undefined, onClick = ()=>null, active = false, showIcon = true, loginRequired = false, ...buttonProps }, ref)=>{
5395
5562
  // TODO Test what idp was used to login and restrict actions to that idp or all or none
5396
5563
  const requiresLogin = !useIsUserLoggedIn() && loginRequired;
5397
- const buttonUcon = active ? /*#__PURE__*/ jsx(Loader, {
5564
+ const buttonIcon = active ? /*#__PURE__*/ jsx(Loader, {
5398
5565
  size: "sm",
5399
5566
  className: "p-1"
5400
5567
  }) : /*#__PURE__*/ jsx(FiDownload, {
@@ -5402,13 +5569,13 @@ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, i
5402
5569
  size: 16
5403
5570
  });
5404
5571
  return /*#__PURE__*/ jsx(Tooltip, {
5405
- disabled: !toolTip,
5406
- label: toolTip,
5572
+ disabled: !tooltip,
5573
+ label: tooltip,
5407
5574
  children: /*#__PURE__*/ jsx(Button, {
5408
5575
  ref: ref,
5409
5576
  onClick: onClick,
5410
5577
  disabled: disabled || requiresLogin,
5411
- leftSection: showIcon ? buttonUcon : undefined,
5578
+ leftSection: showIcon ? buttonIcon : undefined,
5412
5579
  ...buttonProps,
5413
5580
  children: label
5414
5581
  })
@@ -5416,21 +5583,315 @@ const DataLibraryActionButton = /*#__PURE__*/ forwardRef(({ label = undefined, i
5416
5583
  });
5417
5584
  DataLibraryActionButton.displayName = 'DataLibraryActionButton';
5418
5585
 
5419
- const ActionBar = ({ config })=>{
5420
- const { buttons } = config;
5586
+ const MANIFEST_FILENAME = 'manifest.json';
5587
+
5588
+ /**
5589
+ * Determines the disabled state and the reason for disabling based on authentication status,
5590
+ * selection count, and requirement for login.
5591
+ *
5592
+ * @param {boolean} isAuthenticated - Indicates whether the user is authenticated.
5593
+ * @param {number} numSelected - The number of items selected for the operation.
5594
+ * @param {boolean} requiresLogin - Specifies whether login is required to perform the operation.
5595
+ * @returns {Object} An object containing the following properties:
5596
+ * - {boolean} disabled - True if the action should be disabled, false otherwise.
5597
+ * - {string} [disabledReason] - The reason why the action is disabled (if applicable).
5598
+ */ const getDisabledState = (isAuthenticated, numSelected, requiresLogin)=>{
5599
+ const LOGIN_REQUIRED_MSG = 'You must be logged in to download a manifest';
5600
+ const NO_SELECTION_MSG = 'You must select at least one study to download a manifest';
5601
+ if (requiresLogin && !isAuthenticated) {
5602
+ return {
5603
+ disabled: true,
5604
+ disabledReason: LOGIN_REQUIRED_MSG
5605
+ };
5606
+ }
5607
+ if (numSelected === 0) {
5608
+ return {
5609
+ disabled: true,
5610
+ disabledReason: NO_SELECTION_MSG
5611
+ };
5612
+ }
5613
+ return {
5614
+ disabled: false
5615
+ }; // Default enabled state.
5616
+ };
5617
+ const handleDownloadManifestClick = ({ exportDataFields, selectedResources })=>{
5618
+ const { dataObjectField } = exportDataFields;
5619
+ if (dataObjectField === undefined) {
5620
+ notifications.show({
5621
+ title: 'Error notification',
5622
+ message: 'Missing required configuration field `config.features.export.manifestFieldName'
5623
+ });
5624
+ return;
5625
+ }
5626
+ // combine manifests from all selected studies
5627
+ const manifest = [];
5628
+ selectedResources.forEach((study)=>{
5629
+ if (study[dataObjectField]) {
5630
+ const studyDataObject = study[dataObjectField];
5631
+ if ('commons_url' in study && !GEN3_DOMAIN?.includes(study.commons_url)) {
5632
+ // PlanX addition to allow hostname based DRS in manifest download clients
5633
+ // like FUSE
5634
+ manifest.push(...studyDataObject.map((x)=>({
5635
+ ...x,
5636
+ commons_url: 'commons_url' in x ? x.commons_url : study.commons_url
5637
+ })));
5638
+ } else {
5639
+ manifest.push(...studyDataObject);
5640
+ }
5641
+ }
5642
+ });
5643
+ // download the manifest
5644
+ if (manifest.length === 0) {
5645
+ notifications.show({
5646
+ title: 'Export warning',
5647
+ message: 'None of the selected studies have any data objects. Please select a different study or select a different data object field.'
5648
+ });
5649
+ return;
5650
+ }
5651
+ const blob = new Blob([
5652
+ JSON.stringify(manifest, null, 2)
5653
+ ], {
5654
+ type: 'text/json'
5655
+ });
5656
+ FileSaver.saveAs(blob, MANIFEST_FILENAME);
5657
+ };
5658
+ const DownloadManifestButton = ({ buttonConfig, selectedResources, exportDataFields })=>{
5659
+ const { isAuthenticated } = useIsAuthenticated();
5660
+ const { disabled, disabledReason } = getDisabledState(isAuthenticated, selectedResources.length, buttonConfig?.requiresLogin ?? false);
5661
+ return /*#__PURE__*/ jsx(DataLibraryActionButton, {
5662
+ "data-testid": "download-manifest-button",
5663
+ label: buttonConfig?.label ?? 'Download Manifest',
5664
+ icon: /*#__PURE__*/ jsx(FiDownload, {}),
5665
+ disabled: disabled,
5666
+ tooltip: disabledReason ?? buttonConfig?.tooltip ?? 'Download Manifest of selected studies',
5667
+ onClick: ()=>{
5668
+ handleDownloadManifestClick({
5669
+ selectedResources: selectedResources,
5670
+ exportDataFields: exportDataFields
5671
+ });
5672
+ }
5673
+ });
5674
+ };
5675
+
5676
+ const extractIdToLabel = (data)=>!data ? {} : Object.keys(data).reduce((acc, id)=>{
5677
+ acc[id] = data[id].name;
5678
+ return acc;
5679
+ }, {});
5680
+ const createTooltipLabel = (error, isLoggedIn, requiresLogin, numSelected, currentListName)=>{
5681
+ if (error) return 'Error saving to data library. Please try again later';
5682
+ if (!isLoggedIn && requiresLogin) return 'Please log in to save to data library';
5683
+ if (numSelected === 0) return 'Please select at least one study to save to data library';
5684
+ if (!currentListName) return 'Please select or create a list';
5685
+ return 'Add selections to list';
5686
+ };
5687
+ const AddToDataLibrary = ({ buttonConfig, selectedResources, exportDataFields, dataLibraryStoreMode = DataLibraryStoreMode.ApiOnly, classNames = {} })=>{
5688
+ const [selectItems, setSelectItems] = useState({});
5689
+ const [currentList, setCurrentList] = useState(null);
5690
+ const [error, setError] = useState(null);
5691
+ const [currentListName, setCurrentListName] = useState('');
5692
+ const combobox = useCombobox({
5693
+ onDropdownClose: ()=>combobox.resetSelectedOption()
5694
+ });
5695
+ const userStatus = useCoreSelector((state)=>selectUserAuthStatus(state));
5696
+ const isLoggedIn = isAuthenticated(userStatus);
5697
+ const isDisabled = error !== null || selectedResources.length === 0 || !currentListName || buttonConfig?.requiresLogin && !isLoggedIn;
5698
+ const tooltipLabel = createTooltipLabel(error, isLoggedIn, buttonConfig.requiresLogin, selectedResources.length, currentListName);
5699
+ const classNamesDefaults = {
5700
+ root: 'w-1/2'
5701
+ };
5702
+ const mergedClassnames = mergeDefaultTailwindClassnames(classNamesDefaults, classNames);
5703
+ const { dataLibrary, updateListInDataLibrary, addListToDataLibrary, isLoading, isUpdating, error: dataLibraryError } = useDataLibrary({
5704
+ storageMode: dataLibraryStoreMode
5705
+ });
5706
+ const saveToList = (listname, listId = undefined)=>{
5707
+ if (selectedResources.length === 0) return;
5708
+ const items = buildListItemsGroupedByDataset(extractFileDatasetsInRecords(selectedResources, exportDataFields));
5709
+ if (Object.keys(items).length === 0) {
5710
+ notifications.show({
5711
+ id: 'update-datalibrary-no-items-to-update-notification',
5712
+ position: 'top-center',
5713
+ withCloseButton: true,
5714
+ autoClose: 5000,
5715
+ title: 'Save to list',
5716
+ message: `No data objects selected to save to list ${listname}.`,
5717
+ loading: false
5718
+ });
5719
+ return;
5720
+ }
5721
+ if (listId) {
5722
+ // updating list
5723
+ updateListInDataLibrary({
5724
+ id: listId,
5725
+ name: listname,
5726
+ items: {
5727
+ ...dataLibrary[listId].items,
5728
+ ...items
5729
+ }
5730
+ }).then((results)=>{
5731
+ if (results.isError) notifications.show({
5732
+ id: 'update-datalibrary-list-error-notification',
5733
+ position: 'top-center',
5734
+ withCloseButton: true,
5735
+ autoClose: 5000,
5736
+ title: 'Save to list',
5737
+ message: `Error saving to list ${listname}.`,
5738
+ loading: isUpdating !== null
5739
+ });
5740
+ else notifications.show({
5741
+ id: 'update-datalibrary-list-notification',
5742
+ position: 'top-center',
5743
+ withCloseButton: true,
5744
+ autoClose: 5000,
5745
+ title: 'Save to list',
5746
+ message: `${Object.values(items).length} datasets saved to list ${listname}.`,
5747
+ loading: isUpdating !== null
5748
+ });
5749
+ });
5750
+ } else {
5751
+ addListToDataLibrary(items, listname).then((results)=>{
5752
+ if (results.isError) notifications.show({
5753
+ id: 'update-datalibrary-list-error-notification',
5754
+ position: 'top-center',
5755
+ withCloseButton: true,
5756
+ autoClose: 5000,
5757
+ title: 'Save to list',
5758
+ message: `Error saving to list ${listname}.`,
5759
+ loading: isUpdating !== null
5760
+ });
5761
+ else notifications.show({
5762
+ id: 'update-datalibrary-list-notification',
5763
+ position: 'top-center',
5764
+ withCloseButton: true,
5765
+ autoClose: 5000,
5766
+ title: 'Save to list',
5767
+ message: `${Object.values(items).length} datasets saved to list ${listname}.`,
5768
+ loading: isLoading
5769
+ });
5770
+ });
5771
+ }
5772
+ };
5773
+ const exactOptionMatch = Object.values(selectItems).some((listName)=>listName === currentListName);
5774
+ const filteredOptions = exactOptionMatch ? selectItems : Object.entries(selectItems).reduce((acc, [listId, listName])=>{
5775
+ if (listName.toLowerCase().includes(currentListName.toLowerCase().trim())) {
5776
+ acc[listId] = listName;
5777
+ }
5778
+ return acc;
5779
+ }, {});
5780
+ const options = useMemo(()=>Object.entries(filteredOptions).map(([listId, listName])=>/*#__PURE__*/ jsx(Combobox.Option, {
5781
+ value: listId,
5782
+ children: listName
5783
+ }, listId)), [
5784
+ filteredOptions
5785
+ ]);
5786
+ useEffect(()=>{
5787
+ if (options.length === 0) setCurrentList(null);
5788
+ }, [
5789
+ options
5790
+ ]);
5791
+ useDeepCompareEffect(()=>{
5792
+ if (dataLibrary) if (!dataLibraryError) {
5793
+ const listItems = extractIdToLabel(dataLibrary);
5794
+ setSelectItems(listItems);
5795
+ } else {
5796
+ setError(dataLibraryError);
5797
+ }
5798
+ }, [
5799
+ dataLibrary,
5800
+ dataLibraryError
5801
+ ]);
5802
+ return /*#__PURE__*/ jsxs(Group, {
5803
+ "data-testid": "add-to-data-library",
5804
+ wrap: "nowrap",
5805
+ classNames: {
5806
+ root: mergedClassnames.root
5807
+ },
5808
+ children: [
5809
+ /*#__PURE__*/ jsxs(Combobox, {
5810
+ onOptionSubmit: (selectedValue)=>{
5811
+ setCurrentList(selectedValue);
5812
+ setCurrentListName(selectItems[selectedValue]);
5813
+ combobox.closeDropdown();
5814
+ },
5815
+ store: combobox,
5816
+ withinPortal: false,
5817
+ children: [
5818
+ /*#__PURE__*/ jsx(Combobox.Target, {
5819
+ children: /*#__PURE__*/ jsx(TextInput, {
5820
+ placeholder: "Select/Search/Create List",
5821
+ value: currentListName ?? '',
5822
+ className: 'w-full',
5823
+ onChange: (event)=>{
5824
+ setCurrentListName(event.currentTarget.value);
5825
+ combobox.openDropdown();
5826
+ combobox.updateSelectedOptionIndex();
5827
+ },
5828
+ onClick: ()=>combobox.openDropdown(),
5829
+ onFocus: ()=>combobox.openDropdown(),
5830
+ onBlur: ()=>combobox.closeDropdown()
5831
+ })
5832
+ }),
5833
+ /*#__PURE__*/ jsx(Combobox.Dropdown, {
5834
+ children: /*#__PURE__*/ jsx(Combobox.Options, {
5835
+ children: /*#__PURE__*/ jsx(ScrollArea.Autosize, {
5836
+ mah: 200,
5837
+ type: "scroll",
5838
+ children: options.length === 0 ? /*#__PURE__*/ jsx(Combobox.Empty, {
5839
+ children: "Click button to create new list"
5840
+ }) : options
5841
+ })
5842
+ })
5843
+ })
5844
+ ]
5845
+ }),
5846
+ /*#__PURE__*/ jsx(Tooltip, {
5847
+ label: tooltipLabel,
5848
+ children: /*#__PURE__*/ jsx(Button, {
5849
+ classNames: {
5850
+ root: 'w-1/3'
5851
+ },
5852
+ loading: isLoading,
5853
+ disabled: isDisabled,
5854
+ onClick: ()=>{
5855
+ if (currentList) {
5856
+ saveToList(selectItems[currentList], currentList);
5857
+ } else {
5858
+ saveToList(currentListName, undefined);
5859
+ }
5860
+ },
5861
+ children: options.length === 0 && currentListName.length > 0 ? 'Save to New List' : buttonConfig?.label ?? 'Save to List'
5862
+ })
5863
+ })
5864
+ ]
5865
+ });
5866
+ };
5867
+
5868
+ const createActionButton = ({ buttonConfig, selectedResources, exportDataFields, verifyExternalLogins, dataLibraryStoreMode })=>{
5869
+ return ({
5870
+ manifest: /*#__PURE__*/ jsx(DownloadManifestButton, {
5871
+ buttonConfig: buttonConfig,
5872
+ selectedResources: selectedResources,
5873
+ exportDataFields: exportDataFields
5874
+ }, buttonConfig.type),
5875
+ addToDataLibrary: /*#__PURE__*/ jsx(AddToDataLibrary, {
5876
+ buttonConfig: buttonConfig,
5877
+ selectedResources: selectedResources,
5878
+ exportDataFields: exportDataFields,
5879
+ verifyExternalLogins: verifyExternalLogins,
5880
+ dataLibraryStoreMode: dataLibraryStoreMode
5881
+ }, buttonConfig.type)
5882
+ })[buttonConfig.type];
5883
+ };
5884
+ const ActionBar = ({ buttons, selectedResources, exportDataFields, verifyExternalLogins, dataLibraryStoreMode = DataLibraryStoreMode.ApiOnly })=>{
5421
5885
  return /*#__PURE__*/ jsx("div", {
5422
5886
  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
- // }
5887
+ children: buttons?.map((button)=>{
5888
+ return createActionButton({
5889
+ buttonConfig: button,
5890
+ selectedResources,
5891
+ exportDataFields,
5892
+ verifyExternalLogins,
5893
+ dataLibraryStoreMode
5894
+ });
5434
5895
  })
5435
5896
  });
5436
5897
  };
@@ -5684,26 +6145,41 @@ const userHasMethodForServiceOnResource = (method, service, resourcePath, userAu
5684
6145
  return actions !== undefined && actions.some((x)=>(x.service === service || x.service === '*') && (x.method === method || x.method === '*'));
5685
6146
  };
5686
6147
 
6148
+ const METADATA_ITEM_AUTHORIZATION_FIELD = '__accessible';
6149
+
5687
6150
  /**
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
- });
6151
+ * Parses a single value into a number
6152
+ * @param item - Value to convert
6153
+ * @returns Numeric representation of the value
6154
+ */ const parseNumericValue = (item)=>{
6155
+ const DEFAULT_VALUE = 0;
6156
+ // Handle undefined values
6157
+ if (item === undefined) {
6158
+ return DEFAULT_VALUE;
6159
+ }
6160
+ // Numbers can be used directly
6161
+ if (typeof item === 'number' && !Number.isNaN(item)) {
6162
+ return item;
6163
+ }
6164
+ // Parse string representations of numbers
6165
+ if (typeof item === 'string') {
6166
+ const parsedValue = parseInt(item, 10);
6167
+ return Number.isNaN(parsedValue) ? DEFAULT_VALUE : parsedValue;
6168
+ }
6169
+ // Recursively handle arrays by summing their numeric values
6170
+ if (Array.isArray(item)) {
6171
+ return convertToNumbers(item).reduce((acc, val)=>acc + val, 0);
6172
+ }
6173
+ // Return default for any other types
6174
+ return DEFAULT_VALUE;
6175
+ };
6176
+ /**
6177
+ * Converts various types of values to numbers
6178
+ * @param fields - Array of values to convert
6179
+ * @returns Array of numbers, with non-numeric values converted to 0
6180
+ */ const convertToNumbers = (fields)=>{
6181
+ return fields.map(parseNumericValue);
6182
+ };
5707
6183
  /**
5708
6184
  * Process a summary statistic using the provided data and summary config
5709
6185
  * @param {JSONObject }data
@@ -5720,7 +6196,7 @@ const userHasMethodForServiceOnResource = (method, service, resourcePath, userAu
5720
6196
  case 'sum':
5721
6197
  {
5722
6198
  // parse any string representation of an integer
5723
- fields = checkForNonNumericItems(fields);
6199
+ fields = convertToNumbers(fields);
5724
6200
  return sum(fields).toLocaleString();
5725
6201
  }
5726
6202
  case 'count':
@@ -5746,21 +6222,45 @@ const processAllSummaries = (data, summaries)=>{
5746
6222
  ];
5747
6223
  }, []);
5748
6224
  };
5749
- const processAuthorizations = (data, config, authMapping)=>{
6225
+ const processAuthorizations = (data, config, userAuthMapping)=>{
6226
+ const { enabled } = config.features.authorization;
6227
+ if (!enabled) {
6228
+ return data;
6229
+ }
6230
+ if (!userAuthMapping) {
6231
+ 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.');
6232
+ }
6233
+ const hostnameWithSubdomain = window.location.hostname; // TODO: replace this with useRouter
6234
+ // mark studies as accessible or inaccessible to user
5750
6235
  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]) {
6236
+ const { supportedValues, isMesh } = config.features.authorization;
6237
+ const studiesWithAccessibleField = data.map((study)=>{
6238
+ let accessible = AccessLevel.NOT_AVAILABLE;
6239
+ if (supportedValues?.unaccessible?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'unaccessible') {
6240
+ accessible = AccessLevel.UNACCESSIBLE;
6241
+ } else if (supportedValues?.notAvailable?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'not_available') {
5759
6242
  accessible = AccessLevel.NOT_AVAILABLE;
6243
+ } else if (supportedValues?.waiting?.enabled && !study[authzField]) {
6244
+ accessible = AccessLevel.WAITING;
5760
6245
  } else {
5761
- const isAuthorized = userHasMethodForServiceOnResource('read', '*', studyAuthz, authMapping) || userHasMethodForServiceOnResource('read', 'peregrine', studyAuthz, authMapping) || userHasMethodForServiceOnResource('read', 'guppy', studyAuthz, authMapping) || userHasMethodForServiceOnResource('read-storage', 'fence', studyAuthz, authMapping);
6246
+ let authMapping = {};
6247
+ if (isMesh) {
6248
+ let commonsURL = study.commons_url; // TODO: configure this value
6249
+ if (commonsURL && commonsURL.startsWith('http')) {
6250
+ commonsURL = new URL(commonsURL).hostname;
6251
+ }
6252
+ authMapping = userAuthMapping[commonsURL || hostnameWithSubdomain] || {};
6253
+ } else {
6254
+ authMapping = Object.values(userAuthMapping)[0];
6255
+ }
6256
+ // TODO: This needs to be configurable GFF-294
6257
+ 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
6258
  if (supportedValues?.accessible?.enabled && isAuthorized) {
5763
- accessible = AccessLevel.ACCESSIBLE;
6259
+ if (supportedValues?.mixed?.enabled && dataAvailabilityField && study[dataAvailabilityField] === 'mixed_availability') {
6260
+ accessible = AccessLevel.MIXED;
6261
+ } else {
6262
+ accessible = AccessLevel.ACCESSIBLE;
6263
+ }
5764
6264
  } else if (supportedValues?.unaccessible?.enabled && !isAuthorized) {
5765
6265
  accessible = AccessLevel.UNACCESSIBLE;
5766
6266
  } else {
@@ -5769,9 +6269,10 @@ const processAuthorizations = (data, config, authMapping)=>{
5769
6269
  }
5770
6270
  return {
5771
6271
  ...study,
5772
- __accessible: accessible
6272
+ [METADATA_ITEM_AUTHORIZATION_FIELD]: accessible
5773
6273
  };
5774
6274
  });
6275
+ return studiesWithAccessibleField;
5775
6276
  };
5776
6277
  const processChartData = (data, pathsToProcess)=>{
5777
6278
  // Initialize results object
@@ -5878,7 +6379,9 @@ const useGetMDSData = ({ guidType = 'unregistered_discovery_metadata', maxStudie
5878
6379
  ] : acc;
5879
6380
  }, []);
5880
6381
  if (discoveryConfig?.features?.authorization.enabled) {
5881
- setMDSData(processAuthorizations(studyData, discoveryConfig, authMapping));
6382
+ setMDSData(processAuthorizations(studyData, discoveryConfig, {
6383
+ default: authMapping
6384
+ }));
5882
6385
  } else setMDSData(studyData);
5883
6386
  }
5884
6387
  }, [
@@ -5917,7 +6420,9 @@ const useGetAggMDSData = ({ guidType = 'unregistered_discovery_metadata', maxStu
5917
6420
  useEffect(()=>{
5918
6421
  if (data && isSuccess) {
5919
6422
  if (discoveryConfig?.features?.authorization.enabled) {
5920
- setMDSData(processAuthorizations(data.data, discoveryConfig, authMapping));
6423
+ setMDSData(processAuthorizations(data.data, discoveryConfig, {
6424
+ default: authMapping
6425
+ }));
5921
6426
  } else setMDSData(data.data);
5922
6427
  }
5923
6428
  }, [
@@ -6698,7 +7203,9 @@ const useGetIndexedMDSData = ({ guidType = 'unregistered_discovery_metadata', ma
6698
7203
  if (data && isSuccess) {
6699
7204
  const studyData = data.data;
6700
7205
  if (discoveryConfig?.features?.authorization.enabled) {
6701
- setMDSData(processAuthorizations(studyData, discoveryConfig, authMapping));
7206
+ setMDSData(processAuthorizations(studyData, discoveryConfig, {
7207
+ default: authMapping
7208
+ }));
6702
7209
  } else setMDSData(studyData);
6703
7210
  } else setMDSData([]);
6704
7211
  }, [
@@ -6760,7 +7267,19 @@ const registerDefaultDiscoveryDataLoaders = ()=>{
6760
7267
  };
6761
7268
  registerDefaultDiscoveryDataLoaders();
6762
7269
 
6763
- const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
7270
+ /**
7271
+ * DiscoveryIndexPanel is a React functional component that renders a discovery panel interface.
7272
+ * It includes features such as search, sorting, filtering, charts, export functionality, and a discovery table.
7273
+ * The component uses hooks for handling state, API data loading, and interface interactions.
7274
+ *
7275
+ * @param {Object} props - The properties object passed to the component.
7276
+ * @param {Object} props.discoveryConfig - Configuration object for setting up the discovery panel.
7277
+ * @param {Object} props.discoveryConfig.features - Defines enabled features (e.g., search, charts, export).
7278
+ * @param {Object} props.discoveryConfig.minimalFieldMapping - Field mapping configuration, such as `uid`.
7279
+ * @param {JSX.Element} props.indexSelector - React component for selecting an index in the discovery panel.
7280
+ *
7281
+ * @return {JSX.Element} A fully featured discovery interface including search functionality, a table, charts, filters, and more.
7282
+ */ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6764
7283
  const dataHook = useMemo(()=>getDiscoveryDataLoader(discoveryConfig?.features?.dataLoader?.dataFetchFunction) ?? useLoadAllMDSData, [
6765
7284
  discoveryConfig?.features?.dataLoader?.dataFetchFunction
6766
7285
  ]);
@@ -6770,6 +7289,7 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6770
7289
  });
6771
7290
  const parentDivRef = useRef(null);
6772
7291
  const [searchBarTerm, setSearchBarTerm] = useState([]);
7292
+ const [selections, setSelections] = useState([]); // table selections
6773
7293
  const [advancedSearchTerms, setAdvancedSearchTerms] = useState({
6774
7294
  operation: SearchCombination.and,
6775
7295
  filters: {}
@@ -6795,6 +7315,16 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6795
7315
  searchTerms: searchParam,
6796
7316
  discoveryConfig
6797
7317
  });
7318
+ const selectedRecords = useMemo(()=>{
7319
+ const uidField = discoveryConfig?.minimalFieldMapping?.uid ?? 'guid';
7320
+ const filterSelectedMembers = (data)=>data.filter((member)=>uidField in member && selections.includes(member[uidField]));
7321
+ return filterSelectedMembers(data);
7322
+ }, [
7323
+ data,
7324
+ discoveryConfig?.minimalFieldMapping?.uid,
7325
+ selections
7326
+ ]);
7327
+ console.log('selectedRecords', selectedRecords);
6798
7328
  const [sorting, setSorting] = useState([]);
6799
7329
  const [showAdvancedSearch, { toggle: toggleAdvancedSearch }] = useDisclosure(false);
6800
7330
  if (dataRequestStatus.isLoading) {
@@ -6868,8 +7398,12 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6868
7398
  color: "accent",
6869
7399
  children: "Filters"
6870
7400
  }) : false,
6871
- discoveryConfig?.features?.exportToDataLibrary?.enabled ? /*#__PURE__*/ jsx(ActionBar, {
6872
- config: discoveryConfig.features.exportToDataLibrary
7401
+ discoveryConfig?.features?.exportFromDiscovery?.enabled ? /*#__PURE__*/ jsx(ActionBar, {
7402
+ buttons: discoveryConfig.features.exportFromDiscovery.buttons,
7403
+ exportDataFields: discoveryConfig.features.exportFromDiscovery.exportDataFields,
7404
+ selectedResources: selectedRecords,
7405
+ verifyExternalLogins: discoveryConfig.features.exportFromDiscovery.verifyExternalLogins,
7406
+ dataLibraryStoreMode: discoveryConfig.features.exportFromDiscovery.dataLibraryStoreMode
6873
7407
  }) : null
6874
7408
  ]
6875
7409
  }),
@@ -6890,6 +7424,7 @@ const DiscoveryIndexPanel = ({ discoveryConfig, indexSelector })=>{
6890
7424
  dataRequestStatus: dataRequestStatus,
6891
7425
  setPagination: setPagination,
6892
7426
  setSorting: setSorting,
7427
+ setSelection: setSelections,
6893
7428
  pagination: pagination,
6894
7429
  sorting: sorting
6895
7430
  })
@@ -10992,7 +11527,7 @@ const TabsLayoutToComponentProp = (tabsLayout)=>{
10992
11527
  }
10993
11528
  };
10994
11529
  const CohortBuilder = ({ explorerConfig, sharedFiltersMap = null, tabsLayout = 'left' })=>{
10995
- const { isFetching } = useGetCSRFQuery();
11530
+ useGetCSRFQuery();
10996
11531
  const dispatch = useCoreDispatch();
10997
11532
  dispatch(setSharedFilters(sharedFiltersMap ?? {}));
10998
11533
  return /*#__PURE__*/ jsx("div", {
@@ -11535,7 +12070,7 @@ const PaymentPanel = ()=>{
11535
12070
  setSelectedPayModel(data.currentPayModel.bmh_workspace_id ?? data.currentPayModel.workspace_type);
11536
12071
  return {
11537
12072
  usersPayModels,
11538
- workspaceName: data.currentPayModel.bmh_workspace_id.length > 0 ? data.currentPayModel.bmh_workspace_id.length : data.currentPayModel.workspace_type,
12073
+ workspaceName: data.currentPayModel.bmh_workspace_id.length > 0 ? data.currentPayModel.bmh_workspace_id : data.currentPayModel.workspace_type,
11539
12074
  totalUsage: data.currentPayModel['total-usage'],
11540
12075
  hardLimit: data.currentPayModel['hard-limit']
11541
12076
  };
@@ -11544,6 +12079,7 @@ const PaymentPanel = ()=>{
11544
12079
  ]);
11545
12080
  const PayModelSelectItem = ({ option })=>{
11546
12081
  const menuItem = usersPayModels[Number(option.value)];
12082
+ if (!menuItem) return null;
11547
12083
  return /*#__PURE__*/ jsx("div", {
11548
12084
  children: /*#__PURE__*/ jsxs(Group, {
11549
12085
  wrap: "nowrap",
@@ -12302,7 +12838,7 @@ class FilesystemContent {
12302
12838
  try {
12303
12839
  return await JSON.parse(fs.readFileSync(path.join(this.rootPath, filepath)).toString('utf8'));
12304
12840
  } catch (err) {
12305
- throw new Error(`Cannot process ${filepath} `);
12841
+ throw new Error(`Cannot process ${path.join(this.rootPath, filepath)} `);
12306
12842
  }
12307
12843
  }
12308
12844
  async getAll(filepath, filter) {
@@ -12819,8 +13355,8 @@ const IndexPanel = ({ dataConfig, tabs, tabTitle })=>{
12819
13355
 
12820
13356
  const persistor = persistStore(AppStore);
12821
13357
  const CohortDiscovery = (config)=>{
12822
- const { isLoading } = useGetCSRFQuery(); // need for Guppy
12823
- if (isLoading) {
13358
+ const { isFetching } = useGetCSRFQuery(); // needed for Guppy
13359
+ if (isFetching) {
12824
13360
  return /*#__PURE__*/ jsx(Center, {
12825
13361
  maw: 400,
12826
13362
  h: 100,
@@ -15154,24 +15690,25 @@ const createMantineTheme = (fonts, colors)=>{
15154
15690
  Pagination: Pagination.extend({
15155
15691
  defaultProps: {
15156
15692
  getControlProps: (control)=>{
15693
+ //Add 508 localization to Pagination, not needed if using react table
15157
15694
  if (control === 'first') {
15158
15695
  return {
15159
- "aria-label": "First"
15696
+ 'aria-label': 'First'
15160
15697
  };
15161
15698
  }
15162
15699
  if (control === 'last') {
15163
15700
  return {
15164
- "aria-label": "Last"
15701
+ 'aria-label': 'Last'
15165
15702
  };
15166
15703
  }
15167
15704
  if (control === 'next') {
15168
15705
  return {
15169
- "aria-label": "Next"
15706
+ 'aria-label': 'Next'
15170
15707
  };
15171
15708
  }
15172
15709
  if (control === 'previous') {
15173
15710
  return {
15174
- "aria-label": "Previous"
15711
+ 'aria-label': 'Previous'
15175
15712
  };
15176
15713
  }
15177
15714
  return {};
@@ -15231,6 +15768,7 @@ const MessagePanel = ({ message, isError = false })=>{
15231
15768
  const extractLabel = (c, idx)=>c.label ?? c.features?.pageTitle?.text ?? `Index ${idx.toString()}`;
15232
15769
  const Discovery = ({ discoveryConfig })=>{
15233
15770
  const [metadataIndex, setMetadataIndex] = useState('0');
15771
+ console.log('Discovery Component', discoveryConfig);
15234
15772
  const menuItems = useMemo(()=>{
15235
15773
  return discoveryConfig.metadataConfig.map((n, idx)=>{
15236
15774
  return {
@@ -15317,6 +15855,12 @@ const DiscoveryPage = ({ headerProps, footerProps, discoveryConfig })=>{
15317
15855
  const DiscoveryPageGetServerSideProps = async ()=>{
15318
15856
  try {
15319
15857
  const discoveryConfig = await ContentSource$1.getContentDatabase().get(`${GEN3_COMMONS_NAME}/discovery.json`);
15858
+ // need data library config for export from discovery using the DataLibrary
15859
+ const datalibraryConfig = await ContentSource$1.getContentDatabase().get(`${GEN3_COMMONS_NAME}/dataLibrary.json`);
15860
+ discoveryConfig.metadataConfig?.forEach((index)=>{
15861
+ if (index.features.exportFromDiscovery) index.features.exportFromDiscovery.dataLibraryStoreMode = datalibraryConfig?.storageMode ?? DataLibraryStoreMode.ApiOnly;
15862
+ });
15863
+ console.log('Updated Config', discoveryConfig);
15320
15864
  return {
15321
15865
  props: {
15322
15866
  ...await getNavPageLayoutPropsFromConfig(),
@@ -15586,7 +16130,7 @@ const GetSharedFieldMapping = async (cohortBuilderConfiguration)=>{
15586
16130
  // create shared filter from Gen3 graphql mapping
15587
16131
  const indices = cohortBuilderConfiguration?.explorerConfig.map((tab)=>tab.guppyConfig.dataType);
15588
16132
  try {
15589
- const data = await fetchJSONDataFromURL(`${GEN3_GUPPY_API}/graphql`, true, 'POST', {
16133
+ const data = await fetchJSONDataFromURL(`${GEN3_GUPPY_API}/graphql`, true, HttpMethod.POST, {
15590
16134
  query: `{ _mapping { ${indices.join(' ')} }}`,
15591
16135
  variables: {}
15592
16136
  });
@@ -16060,7 +16604,7 @@ const getStatus = (expiration, now)=>{
16060
16604
  * with the ability to delete a given credential using useRemoveCredentialMutation() hook
16061
16605
  * @returns {JSX.Element} The JSX element representing the credentials table.
16062
16606
  */ const CredentialsTable = ()=>{
16063
- const { data: csrfToken } = useGetCSRFQuery();
16607
+ const { data: csrfToken, isFetching: isCSRFFetching } = useGetCSRFQuery();
16064
16608
  const { data: credentials } = useGetCredentialsQuery();
16065
16609
  const [removeCredential] = useRemoveCredentialMutation();
16066
16610
  const columns = useMemo(()=>{
@@ -16122,7 +16666,10 @@ const getStatus = (expiration, now)=>{
16122
16666
  mantineSearchTextInputProps: {
16123
16667
  placeholder: 'Search API Keys'
16124
16668
  },
16125
- icons: TableIcons
16669
+ icons: TableIcons,
16670
+ state: {
16671
+ isLoading: isCSRFFetching
16672
+ }
16126
16673
  });
16127
16674
  return /*#__PURE__*/ jsx(MantineReactTable, {
16128
16675
  table: table
@@ -16732,7 +17279,7 @@ const AuthzContext = /*#__PURE__*/ createContext({
16732
17279
  },
16733
17280
  dispatch: ()=>null
16734
17281
  });
16735
- const AuthzProvider = ({ children, authz = {
17282
+ const AuthzAdminProvider = ({ children, authz = {
16736
17283
  users: [],
16737
17284
  groups: [],
16738
17285
  roles: [],
@@ -17312,7 +17859,7 @@ const Gen3Authz = ({ authz })=>{
17312
17859
  /*#__PURE__*/ jsx("h1", {
17313
17860
  children: "Gen3 Authz"
17314
17861
  }),
17315
- /*#__PURE__*/ jsx(AuthzProvider, {
17862
+ /*#__PURE__*/ jsx(AuthzAdminProvider, {
17316
17863
  authz: authz,
17317
17864
  children: /*#__PURE__*/ jsxs(Tabs, {
17318
17865
  orientation: "vertical",
@@ -18596,12 +19143,12 @@ const getDataLibraryItem = (dataLibrary, listId, dataId, fileId)=>{
18596
19143
  };
18597
19144
  } else {
18598
19145
  if (!fileId) return undefined;
18599
- if (!(fileId in datasetOrCohort.items)) return undefined;
18600
- if (isFileItem(datasetOrCohort.items[fileId])) {
19146
+ if (!(fileId in datasetOrCohort.members)) return undefined;
19147
+ if (isFileItem(datasetOrCohort.members[fileId])) {
18601
19148
  return {
18602
19149
  datasetName: name,
18603
19150
  datasetId: dataId,
18604
- ...datasetOrCohort.items[fileId]
19151
+ ...datasetOrCohort.members[fileId]
18605
19152
  };
18606
19153
  }
18607
19154
  return undefined;
@@ -18653,6 +19200,32 @@ const getUniqueItemKey = (item)=>{
18653
19200
  return `file_${item.datasetId}_${item.id}`;
18654
19201
  }
18655
19202
  };
19203
+ const selectionToManifest = (dataLibrarySelections)=>{
19204
+ return dataLibrarySelections.reduce((acc, item)=>{
19205
+ if (isValidFileItemWithParentDatasetNameAndID(item)) {
19206
+ acc.push({
19207
+ object_id: item.id,
19208
+ ...item.name ? {
19209
+ file_name: item.name
19210
+ } : {},
19211
+ ...item.size ? {
19212
+ file_size: Number(item.size)
19213
+ } : {},
19214
+ dataset_id: item.datasetId
19215
+ });
19216
+ }
19217
+ return acc;
19218
+ }, []);
19219
+ };
19220
+ const extractDatasetIds = (dataLibrarySelections)=>{
19221
+ const metadataIds = dataLibrarySelections.reduce((acc, item)=>{
19222
+ if (isFileItem(item)) {
19223
+ acc.add(item.datasetId);
19224
+ }
19225
+ return acc;
19226
+ }, new Set());
19227
+ return Array.from(metadataIds);
19228
+ };
18656
19229
 
18657
19230
  // Create the context
18658
19231
  const DataLibrarySelectionContext = /*#__PURE__*/ createContext(undefined);
@@ -18808,7 +19381,7 @@ const getNumberOfSelectedItemsInList = (selections, listId)=>{
18808
19381
  };
18809
19382
  const isListInSelection = (listId, selections)=>listId in selections;
18810
19383
 
18811
- const SearchAndActions = ({ createList, gatherData, size = 'sm' })=>{
19384
+ const SearchAndActions = ({ createList, gatherData, size = 'sm', enableCreateNewList = false, enableDownloadManifest = false })=>{
18812
19385
  const { selections, clearSelections } = useDataLibrarySelection();
18813
19386
  const retrieveDisabled = Object.keys(selections).length === 0;
18814
19387
  const iconSize = IconSize[size] || IconSize['sm'];
@@ -18848,6 +19421,38 @@ const SearchAndActions = ({ createList, gatherData, size = 'sm' })=>{
18848
19421
  height: iconSize
18849
19422
  })
18850
19423
  })
19424
+ }),
19425
+ enableCreateNewList && /*#__PURE__*/ jsx(Tooltip, {
19426
+ label: "Create a new empty list",
19427
+ children: /*#__PURE__*/ jsx(Button, {
19428
+ hidden: true,
19429
+ size: "compact-md",
19430
+ variant: "outline",
19431
+ onClick: ()=>createList({}),
19432
+ "aria-label": "create a new list",
19433
+ classNames: {
19434
+ root: 'bg-base-max hover:bg-base-light'
19435
+ },
19436
+ children: /*#__PURE__*/ jsx(MdAdd, {
19437
+ size: "1.5em"
19438
+ })
19439
+ })
19440
+ }),
19441
+ enableCreateNewList && /*#__PURE__*/ jsx(Tooltip, {
19442
+ label: "Download Manifest of selected items",
19443
+ children: /*#__PURE__*/ jsx(Button, {
19444
+ size: "compact-md",
19445
+ variant: "outline",
19446
+ "aria-label": "Download Manifest of Selected Items",
19447
+ classNames: {
19448
+ root: 'bg-base-max hover:bg-base-light'
19449
+ },
19450
+ children: /*#__PURE__*/ jsx(Icon, {
19451
+ icon: "gen3:download-alt",
19452
+ height: 24,
19453
+ width: 24
19454
+ })
19455
+ })
18851
19456
  })
18852
19457
  ]
18853
19458
  })
@@ -19174,6 +19779,11 @@ const evaluateGroupRule = (rule, items)=>{
19174
19779
  const fieldValue = items.map((item)=>item[rule.field]);
19175
19780
  return fieldValue.length === rule.total;
19176
19781
  }
19782
+ case 'greater':
19783
+ {
19784
+ const fieldValue = items.map((item)=>item[rule.field]);
19785
+ return fieldValue.length > rule.total;
19786
+ }
19177
19787
  }
19178
19788
  };
19179
19789
  /**
@@ -19211,7 +19821,7 @@ const isSendExistingPFBToURLParameters = (value)=>{
19211
19821
  const candidate = value;
19212
19822
  return 'targetURLTemplate' in candidate && typeof candidate.targetURLTemplate === 'string';
19213
19823
  };
19214
- const sendExistingPFBToURL = async (validatedSelections, params, done = ()=>null, error = ()=>null, onAbort = ()=>null, signal = undefined)=>{
19824
+ const sendExistingPFBToURL = async (validatedSelections, params, onDone = ()=>null, onError = ()=>null, onAbort = ()=>null, signal = undefined)=>{
19215
19825
  if (!isSendExistingPFBToURLParameters(params)) {
19216
19826
  console.error('Invalid parameters for sendPFBToURL action:', params);
19217
19827
  return;
@@ -19245,7 +19855,7 @@ const sendExistingPFBToURL = async (validatedSelections, params, done = ()=>null
19245
19855
  const targetURL = targetURLTemplate.replace(PRESIGNED_URL_TEMPLATE_VARIABLE, signedURL);
19246
19856
  return new Promise(()=>{
19247
19857
  if (window) window.open(targetURL, '_blank', 'noopener,noreferrer');
19248
- if (done) done(targetURL);
19858
+ if (onDone) onDone(targetURL);
19249
19859
  });
19250
19860
  } catch (error) {
19251
19861
  if (error instanceof HTTPError) {
@@ -19255,15 +19865,180 @@ const sendExistingPFBToURL = async (validatedSelections, params, done = ()=>null
19255
19865
  withCloseButton: true,
19256
19866
  autoClose: 5000,
19257
19867
  title: 'Action Error',
19258
- message: error.status in HTTPUserFriendlyErrorMessages ? HTTPUserFriendlyErrorMessages[error.status] : 'An error has occured to prevent exporting PFB',
19868
+ message: error.status in HTTPUserFriendlyErrorMessages ? HTTPUserFriendlyErrorMessages[error.status] : 'An error has occurred to prevent exporting PFB',
19259
19869
  color: 'red',
19260
19870
  loading: false
19261
19871
  });
19262
19872
  }
19263
- console.error('Error sending PFB to URL', error);
19264
- return new Promise(()=>{
19265
- error(error);
19873
+ if (error instanceof Error) {
19874
+ if (error.name == 'AbortError') {
19875
+ onAbort?.();
19876
+ }
19877
+ return new Promise(()=>{
19878
+ onError?.(error);
19879
+ });
19880
+ }
19881
+ }
19882
+ };
19883
+
19884
+ const exportToManifest = async (validatedSelections, params, onDone = ()=>null, onError = ()=>null, onAbort = ()=>null, signal = undefined)=>{
19885
+ const manifest = selectionToManifest(validatedSelections); // TODO md5sum? commons_name?
19886
+ try {
19887
+ const blob = new Blob([
19888
+ JSON.stringify(manifest, null, 2)
19889
+ ], {
19890
+ type: 'text/json'
19266
19891
  });
19892
+ FileSaver.saveAs(blob, MANIFEST_FILENAME);
19893
+ onDone?.();
19894
+ } catch (error) {
19895
+ if (error instanceof Error) {
19896
+ onError?.(error);
19897
+ } else onError?.(new Error('unknown error saving file'));
19898
+ }
19899
+ };
19900
+
19901
+ const ProvidersErrorPanel = ({ message, providers })=>{
19902
+ return /*#__PURE__*/ jsxs(Stack, {
19903
+ children: [
19904
+ /*#__PURE__*/ jsx(Text, {
19905
+ children: message
19906
+ }),
19907
+ /*#__PURE__*/ jsxs(Table, {
19908
+ children: [
19909
+ /*#__PURE__*/ jsx("thead", {
19910
+ children: /*#__PURE__*/ jsxs("tr", {
19911
+ children: [
19912
+ /*#__PURE__*/ jsx("th", {
19913
+ children: "Provider"
19914
+ }),
19915
+ /*#__PURE__*/ jsx("th", {
19916
+ children: "URL"
19917
+ })
19918
+ ]
19919
+ })
19920
+ }),
19921
+ /*#__PURE__*/ jsx("tbody", {
19922
+ children: providers.map((provider)=>/*#__PURE__*/ jsxs("tr", {
19923
+ children: [
19924
+ /*#__PURE__*/ jsx(Text, {
19925
+ children: provider.name
19926
+ }),
19927
+ /*#__PURE__*/ jsx(Text, {
19928
+ children: provider.base_url
19929
+ })
19930
+ ]
19931
+ }, provider.name))
19932
+ })
19933
+ ]
19934
+ })
19935
+ ]
19936
+ });
19937
+ };
19938
+
19939
+ const removeKeys = (obj, keysToRemove)=>{
19940
+ keysToRemove.forEach((key)=>{
19941
+ if (key.includes('.')) {
19942
+ const [firstKey, ...nestedKeys] = key.split('.');
19943
+ const nestedObj = get(obj, firstKey);
19944
+ unset(nestedObj, nestedKeys.join('.'));
19945
+ } else {
19946
+ unset(obj, key);
19947
+ }
19948
+ });
19949
+ return obj;
19950
+ };
19951
+ /**
19952
+ * Processes and assembles metadata by cloning objects, removing specified keys, and optionally accessing a defined metadata root.
19953
+ *
19954
+ * @param {Array<string>} keysToRemove - A list of keys to remove from each object in the selected resources after cloning.
19955
+ * @param {Array<Record<string, unknown>>} selectedResources - An array of resource objects to process and format.
19956
+ * @param {string} metadataRoot - The root key that holds the metadata in the objects. If present, this root is used as a starting point.
19957
+ * @returns {Array<Record<string, unknown>>} A new array of processed objects with the specified keys removed and metadata root applied when applicable.
19958
+ */ const assembleMetadata = (selectedResources, metadataRoot, keysToRemove)=>{
19959
+ return selectedResources.map((obj)=>{
19960
+ const clonedObj = cloneDeep(!obj[metadataRoot] ? obj : obj[metadataRoot]);
19961
+ // if there are keysToRemove, remove them
19962
+ if (keysToRemove) {
19963
+ return removeKeys(clonedObj, keysToRemove);
19964
+ }
19965
+ // Otherwise just return the cloned object
19966
+ return clonedObj;
19967
+ });
19968
+ };
19969
+ const exportMetadataToWorkspace = async (validatedSelections, params, onDone = ()=>null, onError = ()=>null, onAbort = ()=>null, signal = undefined)=>{
19970
+ // first need to get file manifest
19971
+ try {
19972
+ const fileManifest = selectionToManifest(validatedSelections);
19973
+ if (params?.verifyExternalLogins) {
19974
+ const results = await getFederatedLoginStatus(fileManifest);
19975
+ const { error: providersError, providersToAuthenticate, missingProviders } = results;
19976
+ if (providersError) {
19977
+ onError?.(providersError);
19978
+ return;
19979
+ }
19980
+ if (providersToAuthenticate && providersToAuthenticate?.length > 0 && missingProviders && missingProviders?.length > 0) {
19981
+ modals.open({
19982
+ id: 'export-dicovery-to-workspace-providers-to-authenticate-modal',
19983
+ title: 'Error: Export to Workspace',
19984
+ withCloseButton: true,
19985
+ children: /*#__PURE__*/ jsxs(Stack, {
19986
+ children: [
19987
+ /*#__PURE__*/ jsx(ProvidersErrorPanel, {
19988
+ message: "The following providers need to be authenticated",
19989
+ providers: providersToAuthenticate
19990
+ }),
19991
+ /*#__PURE__*/ jsx(ProvidersErrorPanel, {
19992
+ message: "The following providers need to be authenticated",
19993
+ providers: providersToAuthenticate
19994
+ })
19995
+ ]
19996
+ })
19997
+ });
19998
+ return;
19999
+ }
20000
+ if (providersToAuthenticate && providersToAuthenticate?.length > 0) {
20001
+ modals.open({
20002
+ id: 'export-dicovery-to-workspace-providers-to-authenticate-modal',
20003
+ title: 'Error: Export to Workspace',
20004
+ withCloseButton: true,
20005
+ children: /*#__PURE__*/ jsx(ProvidersErrorPanel, {
20006
+ message: "The following providers need to be authenticated",
20007
+ providers: providersToAuthenticate
20008
+ })
20009
+ });
20010
+ return;
20011
+ } else {
20012
+ if (missingProviders && missingProviders?.length > 0) {
20013
+ modals.open({
20014
+ id: 'export-dicovery-to-workspace-providers-to-authenticate-modal',
20015
+ title: 'Error: Export to Workspace',
20016
+ withCloseButton: true,
20017
+ children: /*#__PURE__*/ jsx(ProvidersErrorPanel, {
20018
+ message: "The following providers are missing",
20019
+ providers: missingProviders
20020
+ })
20021
+ });
20022
+ return;
20023
+ }
20024
+ }
20025
+ }
20026
+ // next get the metadata from the dataset id
20027
+ const metadataIds = extractDatasetIds(validatedSelections);
20028
+ const metadata = await queryMultipleMDSRecords(metadataIds, params?.useAggMDS, signal);
20029
+ const metadataObjects = Object.values(metadata).map((metadataObj)=>metadataObj);
20030
+ const filteredMetadata = assembleMetadata(metadataObjects, params?.metadataRoot ?? 'gen3_discovery', params?.keysToRemove);
20031
+ // save the metadata
20032
+ await fetchJSONDataFromURL(`${GEN3_MANIFEST_API}/metadata`, true, 'POST', JSON.stringify(filteredMetadata), signal);
20033
+ // save files manifest
20034
+ await fetchJSONDataFromURL(`${GEN3_MANIFEST_API}/`, true, 'POST', JSON.stringify(fileManifest), signal);
20035
+ onDone?.();
20036
+ } catch (error) {
20037
+ if (error instanceof Error) {
20038
+ if (error.name == 'AbortError') {
20039
+ onAbort?.();
20040
+ }
20041
+ } else onError?.(new Error('unknown error'));
19267
20042
  }
19268
20043
  };
19269
20044
 
@@ -19291,6 +20066,12 @@ const registerDefaultDataLibraryActions = ()=>{
19291
20066
  registerAction('export-pfb-to-url', {
19292
20067
  action: sendExistingPFBToURL
19293
20068
  });
20069
+ registerAction('export-from-discovery-to-manifest', {
20070
+ action: exportToManifest
20071
+ });
20072
+ registerAction('export-from-discovery-to-workspace', {
20073
+ action: exportMetadataToWorkspace
20074
+ });
19294
20075
  };
19295
20076
  registerDefaultDataLibraryActions();
19296
20077
 
@@ -19524,7 +20305,7 @@ const SelectedItemsModal = (props)=>{
19524
20305
  * it iterates through the dataset items and sets the keys of file items
19525
20306
  * to true in the returned object.
19526
20307
  *
19527
- * @param {RegisteredDataListEntry | CohortItem} dataSetOrCohort - The dataset or cohort item to process.
20308
+ * @param {DataLibraryDataset | CohortItem} dataSetOrCohort - The dataset or cohort item to process.
19528
20309
  * @returns {SelectedMembers} An object representing the selected members.
19529
20310
  */ const getDatasetMembers = (dataSetOrCohort)=>{
19530
20311
  if (isCohortItem(dataSetOrCohort)) {
@@ -19532,7 +20313,7 @@ const SelectedItemsModal = (props)=>{
19532
20313
  [dataSetOrCohort.id]: true
19533
20314
  };
19534
20315
  }
19535
- return Object.entries(dataSetOrCohort.items).reduce((acc, [key, item])=>{
20316
+ return Object.entries(dataSetOrCohort.members).reduce((acc, [key, item])=>{
19536
20317
  if (isFileItem(item)) acc[key] = true;
19537
20318
  return acc;
19538
20319
  }, {});
@@ -19732,7 +20513,7 @@ const DatasetAccordionControl = ({ listName, numberOfItems, updatedTime, created
19732
20513
  ]
19733
20514
  }),
19734
20515
  /*#__PURE__*/ jsx(Tooltip, {
19735
- label: `Delete ${listName}. Will not delete dataset`,
20516
+ label: `Delete list ${listName}. Will not delete the actual dataset`,
19736
20517
  children: /*#__PURE__*/ jsx(ActionIcon, {
19737
20518
  color: "accent.4",
19738
20519
  variant: "transparent",
@@ -19949,12 +20730,18 @@ const LabeledText = ({ label, text })=>{
19949
20730
  ]
19950
20731
  });
19951
20732
  };
19952
- const QueryDetails = ({ name, schemaVersion, index, data, id })=>{
20733
+ const QueryDetails = ({ name, schemaVersion, data, id })=>{
19953
20734
  if (!data) {
19954
20735
  return /*#__PURE__*/ jsx(ErrorCard, {
19955
20736
  message: "No cohort query"
19956
20737
  });
19957
20738
  }
20739
+ const index = extractIndexFromDataLibraryCohort(data);
20740
+ if (!index) {
20741
+ return /*#__PURE__*/ jsx(ErrorCard, {
20742
+ message: "Not able to extract index from cohort query"
20743
+ });
20744
+ }
19958
20745
  return /*#__PURE__*/ jsxs("div", {
19959
20746
  className: "flex flex-col",
19960
20747
  children: [
@@ -20119,11 +20906,12 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20119
20906
  } : {}
20120
20907
  };
20121
20908
  },
20122
- renderRowActions: ({ row })=>/*#__PURE__*/ jsx(Tooltip, {
20123
- label: row.original.isCohort ? 'Remove cohort from list' : 'Remove dataset from list',
20909
+ renderRowActions: ({ row })=>{
20910
+ return /*#__PURE__*/ jsx(Tooltip, {
20911
+ label: row.original.isCohort === 'True' ? 'Remove cohort from list' : 'Remove dataset from list',
20124
20912
  children: /*#__PURE__*/ jsxs(Button, {
20125
20913
  variant: "transparent",
20126
- "aria-label": `remove ${row.original.isCohort ? 'cohort' : 'dataset'} ${row.original.name} from list`,
20914
+ "aria-label": `remove ${row.original.isCohort === 'True' ? 'cohort' : 'dataset'} ${row.original.name} from list`,
20127
20915
  onClick: ()=>{
20128
20916
  removeList(row.id);
20129
20917
  },
@@ -20134,7 +20922,8 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20134
20922
  row.original.itemType
20135
20923
  ]
20136
20924
  })
20137
- }),
20925
+ });
20926
+ },
20138
20927
  mantineDetailPanelProps: {
20139
20928
  style: {
20140
20929
  padding: '0px',
@@ -20180,11 +20969,9 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20180
20969
  *
20181
20970
  * @param {Object} dataListAccordionItemParams - Parameters for the DataListAccordionItem.
20182
20971
  * @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
20972
  *
20186
20973
  * @return {JSX.Element} A rendered accordion item component with controls for data list updates and deletions.
20187
- */ const DatalistAccordionItem = ({ dataList, updateListInDataLibrary, deleteListFromDataLibrary, size = 'sm' })=>{
20974
+ */ const DatalistAccordionItem = ({ dataList, updateListInDataLibrary, deleteListFromDataLibrary, isUpdating, size = 'sm' })=>{
20188
20975
  const [selectedState, setSelectedState] = useState('unchecked');
20189
20976
  const { id: listId, name: listName } = dataList;
20190
20977
  const numberOfItemsInList = useMemo(()=>{
@@ -20194,10 +20981,13 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20194
20981
  ]);
20195
20982
  const { selections, updateSelections, removeListMember, removeList } = useDataLibrarySelection();
20196
20983
  const updateList = async (update)=>{
20197
- await updateListInDataLibrary(listId, {
20198
- ...dataList,
20984
+ return await updateListInDataLibrary({
20985
+ ...{
20986
+ name: listName,
20987
+ items: dataList.items
20988
+ },
20199
20989
  ...update,
20200
- updatedTime: getTimestamp()
20990
+ id: listId
20201
20991
  });
20202
20992
  };
20203
20993
  const tableRowData = useMemo(()=>Object.entries(dataList.items).reduce((acc, [datasetId, dataItem])=>{
@@ -20215,7 +21005,7 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20215
21005
  });
20216
21006
  } else {
20217
21007
  // handle RegisteredDataListEntry
20218
- Object.entries(dataItem.items).forEach(([itemId, item])=>{
21008
+ Object.entries(dataItem.members).forEach(([itemId, item])=>{
20219
21009
  if (isFileItem(item)) {
20220
21010
  files.push({
20221
21011
  ...item,
@@ -20267,10 +21057,10 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20267
21057
  const removeItemFromList = async (itemId)=>{
20268
21058
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
20269
21059
  const { [itemId]: _removedKey, ...newObject } = dataList.items;
20270
- await updateListInDataLibrary(listId, {
20271
- ...dataList,
20272
- items: newObject,
20273
- updatedTime: getTimestamp()
21060
+ await updateListInDataLibrary({
21061
+ id: listId,
21062
+ name: dataList.name,
21063
+ items: newObject
20274
21064
  });
20275
21065
  // update selections
20276
21066
  removeListMember(listId, itemId);
@@ -20286,12 +21076,16 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20286
21076
  return /*#__PURE__*/ jsxs(Accordion.Item, {
20287
21077
  value: listName,
20288
21078
  className: "group",
21079
+ pos: "relative",
20289
21080
  children: [
21081
+ /*#__PURE__*/ jsx(LoadingOverlay, {
21082
+ visible: isUpdating === listId
21083
+ }),
20290
21084
  /*#__PURE__*/ jsx(DatasetAccordionControl, {
20291
21085
  listName: listName,
20292
21086
  numberOfItems: numberOfItemsInList,
20293
- updatedTime: dataList.updatedTime,
20294
- createdTime: dataList.createdTime,
21087
+ updatedTime: dataList.updated_time,
21088
+ createdTime: dataList.created_time,
20295
21089
  updateHandler: updateList,
20296
21090
  deleteListHandler: ()=>deleteListFromDataLibrary(listId),
20297
21091
  selectListHandler: handleSelectList,
@@ -20310,18 +21104,37 @@ const DataSetContentsTable = ({ listId, data, removeList, size = 'sm' })=>{
20310
21104
  }, listName);
20311
21105
  };
20312
21106
 
20313
- const DataLibraryLists = ({ useAPI, actions, size })=>{
20314
- const { dataLibrary, isError, isLoading, error: dataLibraryError, addListToDataLibrary, updateListInDataLibrary, deleteListFromDataLibrary } = useDataLibrary(useAPI);
21107
+ const DataLibraryLists = ({ storageMode, requiresLogin = true, actions, size })=>{
21108
+ const { dataLibrary, isLoading, isUpdating, error: dataLibraryError, addListToDataLibrary, updateListInDataLibrary, deleteListFromDataLibrary } = useDataLibrary({
21109
+ storageMode
21110
+ });
21111
+ const { isAuthenticated } = useIsAuthenticated();
20315
21112
  const [selectedItemsOpen, { open, close }] = useDisclosure(false);
20316
21113
  const { gatherSelectedItems } = useDataLibrarySelection();
20317
21114
  const gatherData = ()=>{
20318
21115
  gatherSelectedItems(dataLibrary);
20319
21116
  open();
20320
21117
  };
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];
21118
+ // Use useEffect to show notifications only when error changes
21119
+ useDeepCompareEffect(()=>{
21120
+ if (dataLibraryError?.isError && dataLibraryError?.status !== 401) {
21121
+ notifications.show({
21122
+ position: 'top-center',
21123
+ color: 'red',
21124
+ title: 'Data Library Error',
21125
+ message: dataLibraryError?.message,
21126
+ autoClose: 2000
21127
+ });
21128
+ }
21129
+ }, [
21130
+ dataLibraryError
21131
+ ]);
21132
+ // Handle 401 error with UI rendering
21133
+ if (dataLibraryError?.isError && dataLibraryError?.status === 401) {
21134
+ let message = 'You are not authorized to access the library.';
21135
+ if (requiresLogin) {
21136
+ if (!isAuthenticated) message = 'Data Library requires login. Please log in to continue.';
21137
+ else message = 'You are not authorized to access the library. Please contact your site administrator.';
20325
21138
  }
20326
21139
  return /*#__PURE__*/ jsx("div", {
20327
21140
  className: "flex flex-col w-full ml-2",
@@ -20335,9 +21148,6 @@ const DataLibraryLists = ({ useAPI, actions, size })=>{
20335
21148
  return /*#__PURE__*/ jsxs("div", {
20336
21149
  className: "flex flex-col w-full ml-2",
20337
21150
  children: [
20338
- /*#__PURE__*/ jsx(LoadingOverlay, {
20339
- visible: isLoading
20340
- }),
20341
21151
  /*#__PURE__*/ jsx(SelectedItemsModal, {
20342
21152
  opened: selectedItemsOpen,
20343
21153
  onClose: close,
@@ -20348,29 +21158,36 @@ const DataLibraryLists = ({ useAPI, actions, size })=>{
20348
21158
  createList: addListToDataLibrary,
20349
21159
  gatherData: gatherData
20350
21160
  }),
20351
- /*#__PURE__*/ jsx("div", {
21161
+ /*#__PURE__*/ jsxs("div", {
20352
21162
  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);
21163
+ children: [
21164
+ /*#__PURE__*/ jsx(LoadingOverlay, {
21165
+ visible: isLoading
21166
+ }),
21167
+ /*#__PURE__*/ jsx(Accordion, {
21168
+ chevronPosition: "left",
21169
+ classNames: {
21170
+ root: 'w-full',
21171
+ control: 'data-active:bg-secondary-lightest'
21172
+ },
21173
+ children: dataLibrary && Object.values(dataLibrary).map((datalist)=>{
21174
+ return /*#__PURE__*/ jsx(DatalistAccordionItem, {
21175
+ dataList: datalist,
21176
+ size: size,
21177
+ isUpdating: isUpdating,
21178
+ updateListInDataLibrary: updateListInDataLibrary,
21179
+ deleteListFromDataLibrary: deleteListFromDataLibrary
21180
+ }, datalist.id);
21181
+ })
20366
21182
  })
20367
- })
21183
+ ]
20368
21184
  })
20369
21185
  ]
20370
21186
  });
20371
21187
  };
20372
21188
 
20373
21189
  const DataLibrary = (config)=>{
21190
+ console.log(config);
20374
21191
  return /*#__PURE__*/ jsx(DataLibrarySelectionProvider, {
20375
21192
  children: /*#__PURE__*/ jsx(DataLibraryLists, {
20376
21193
  ...config
@@ -20379,6 +21196,7 @@ const DataLibrary = (config)=>{
20379
21196
  };
20380
21197
 
20381
21198
  const DataLibraryPage = ({ headerProps, footerProps, config })=>{
21199
+ console.log('DataLibraryPage', config);
20382
21200
  return /*#__PURE__*/ jsx(NavPageLayout, {
20383
21201
  headerProps,
20384
21202
  footerProps,
@@ -20408,7 +21226,7 @@ const DataLibraryPageGetServerSideProps = async ()=>{
20408
21226
  props: {
20409
21227
  ...await getNavPageLayoutPropsFromConfig(),
20410
21228
  config: {
20411
- useAPI: false,
21229
+ storageMode: DataLibraryStoreMode.ApiOnly,
20412
21230
  actions: []
20413
21231
  }
20414
21232
  }
@@ -21025,5 +21843,5 @@ async function credentialsLogout(req, res) {
21025
21843
  res.redirect(307, '/');
21026
21844
  }
21027
21845
 
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 };
21846
+ 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
21847
  //# sourceMappingURL=index.js.map