synapse-react-client 4.0.36 → 4.0.38

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 (316) hide show
  1. package/dist/SWC.index.js +1 -1
  2. package/dist/aridhia-queries/index.js +11 -11
  3. package/dist/aridhia-queries/useAridhiaQuery.d.ts +1 -0
  4. package/dist/aridhia-queries/useAridhiaQuery.d.ts.map +1 -1
  5. package/dist/aridhia-queries/useAridhiaQuery.js +24 -17
  6. package/dist/aridhia-queries/useAridhiaQuery.js.map +1 -1
  7. package/dist/assets/icons/emailWithNotification.js +15 -15
  8. package/dist/assets/icons/emailWithNotification.js.map +1 -1
  9. package/dist/assets/icons/emailWithNotification.svg +13 -13
  10. package/dist/components/AccessRequirementList/AccessRequirementList.d.ts.map +1 -1
  11. package/dist/components/AccessRequirementList/AccessRequirementList.js +124 -117
  12. package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
  13. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.d.ts.map +1 -1
  14. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js +1 -1
  15. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js.map +1 -1
  16. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.d.ts.map +1 -1
  17. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js +1 -1
  18. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js.map +1 -1
  19. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.d.ts.map +1 -1
  20. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js +33 -32
  21. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js.map +1 -1
  22. package/dist/components/Aridhia/AridhiaAccessStatus.d.ts.map +1 -1
  23. package/dist/components/Aridhia/AridhiaAccessStatus.js +39 -18
  24. package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
  25. package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.d.ts +32 -0
  26. package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.d.ts.map +1 -0
  27. package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js +285 -0
  28. package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js.map +1 -0
  29. package/dist/components/Aridhia/DarWizard/DarAboutStep.d.ts +4 -0
  30. package/dist/components/Aridhia/DarWizard/DarAboutStep.d.ts.map +1 -0
  31. package/dist/components/Aridhia/DarWizard/DarAboutStep.js +17 -0
  32. package/dist/components/Aridhia/DarWizard/DarAboutStep.js.map +1 -0
  33. package/dist/components/Aridhia/DarWizard/DarCompleteStep.d.ts +27 -0
  34. package/dist/components/Aridhia/DarWizard/DarCompleteStep.d.ts.map +1 -0
  35. package/dist/components/Aridhia/DarWizard/DarCompleteStep.js +96 -0
  36. package/dist/components/Aridhia/DarWizard/DarCompleteStep.js.map +1 -0
  37. package/dist/components/Aridhia/DarWizard/DarDestinationStep.d.ts +28 -0
  38. package/dist/components/Aridhia/DarWizard/DarDestinationStep.d.ts.map +1 -0
  39. package/dist/components/Aridhia/DarWizard/DarDestinationStep.js +128 -0
  40. package/dist/components/Aridhia/DarWizard/DarDestinationStep.js.map +1 -0
  41. package/dist/components/Aridhia/DarWizard/DarProjectStep.d.ts +4 -0
  42. package/dist/components/Aridhia/DarWizard/DarProjectStep.d.ts.map +1 -0
  43. package/dist/components/Aridhia/DarWizard/DarProjectStep.js +17 -0
  44. package/dist/components/Aridhia/DarWizard/DarProjectStep.js.map +1 -0
  45. package/dist/components/Aridhia/DarWizard/DarSectionForm.d.ts +13 -0
  46. package/dist/components/Aridhia/DarWizard/DarSectionForm.d.ts.map +1 -0
  47. package/dist/components/Aridhia/DarWizard/DarSectionForm.js +23 -0
  48. package/dist/components/Aridhia/DarWizard/DarSectionForm.js.map +1 -0
  49. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts +11 -0
  50. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts.map +1 -0
  51. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js +47 -0
  52. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js.map +1 -0
  53. package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.d.ts +16 -0
  54. package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.d.ts.map +1 -0
  55. package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.js +33 -0
  56. package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.js.map +1 -0
  57. package/dist/components/Aridhia/DarWizard/useDarDraft.d.ts +32 -0
  58. package/dist/components/Aridhia/DarWizard/useDarDraft.d.ts.map +1 -0
  59. package/dist/components/Aridhia/DarWizard/useDarDraft.js +44 -0
  60. package/dist/components/Aridhia/DarWizard/useDarDraft.js.map +1 -0
  61. package/dist/components/Aridhia/FairLabelField.d.ts +8 -0
  62. package/dist/components/Aridhia/FairLabelField.d.ts.map +1 -0
  63. package/dist/components/Aridhia/FairLabelField.js +13 -0
  64. package/dist/components/Aridhia/FairLabelField.js.map +1 -0
  65. package/dist/components/Aridhia/fairFormToRjsf.d.ts +36 -0
  66. package/dist/components/Aridhia/fairFormToRjsf.d.ts.map +1 -0
  67. package/dist/components/Aridhia/fairFormToRjsf.js +137 -0
  68. package/dist/components/Aridhia/fairFormToRjsf.js.map +1 -0
  69. package/dist/components/CannedRejectionDialog/CannedRejectionDialog.d.ts.map +1 -1
  70. package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js +2 -2
  71. package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js.map +1 -1
  72. package/dist/components/CardContainer/CardContainer.d.ts.map +1 -1
  73. package/dist/components/CardContainer/CardContainer.js +1 -1
  74. package/dist/components/CardContainer/CardContainer.js.map +1 -1
  75. package/dist/components/ChallengeSubmission/ChallengeSubmission.d.ts.map +1 -1
  76. package/dist/components/ChallengeSubmission/ChallengeSubmission.js +2 -2
  77. package/dist/components/ChallengeSubmission/ChallengeSubmission.js.map +1 -1
  78. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.d.ts.map +1 -1
  79. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js +3 -3
  80. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js.map +1 -1
  81. package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js +1 -1
  82. package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js.map +1 -1
  83. package/dist/components/CreateTableViewWizard/CreateTableViewWizard.js +2 -2
  84. package/dist/components/CreateTableViewWizard/CreateTableViewWizard.js.map +1 -1
  85. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  86. package/dist/components/DataGrid/SynapseGrid.js +121 -117
  87. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  88. package/dist/components/DataGrid/columns/DateTimeColumn.d.ts +21 -1
  89. package/dist/components/DataGrid/columns/DateTimeColumn.d.ts.map +1 -1
  90. package/dist/components/DataGrid/columns/DateTimeColumn.js +73 -29
  91. package/dist/components/DataGrid/columns/DateTimeColumn.js.map +1 -1
  92. package/dist/components/DataGrid/columns/NumberColumn.d.ts +31 -0
  93. package/dist/components/DataGrid/columns/NumberColumn.d.ts.map +1 -0
  94. package/dist/components/DataGrid/columns/NumberColumn.js +27 -0
  95. package/dist/components/DataGrid/columns/NumberColumn.js.map +1 -0
  96. package/dist/components/DataGrid/components/ReorderColumnsButton.d.ts +1 -0
  97. package/dist/components/DataGrid/components/ReorderColumnsButton.d.ts.map +1 -1
  98. package/dist/components/DataGrid/components/ReorderColumnsButton.js +17 -16
  99. package/dist/components/DataGrid/components/ReorderColumnsButton.js.map +1 -1
  100. package/dist/components/DataGrid/components/ReorderColumnsDialog.d.ts +2 -0
  101. package/dist/components/DataGrid/components/ReorderColumnsDialog.d.ts.map +1 -1
  102. package/dist/components/DataGrid/components/ReorderColumnsDialog.js +104 -65
  103. package/dist/components/DataGrid/components/ReorderColumnsDialog.js.map +1 -1
  104. package/dist/components/DataGrid/useDataGridWebsocket.js +1 -1
  105. package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
  106. package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
  107. package/dist/components/DataGrid/utils/columnFactory.js +55 -51
  108. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  109. package/dist/components/DataGrid/utils/computeDefaultColumnOrder.d.ts.map +1 -1
  110. package/dist/components/DataGrid/utils/computeDefaultColumnOrder.js +9 -8
  111. package/dist/components/DataGrid/utils/computeDefaultColumnOrder.js.map +1 -1
  112. package/dist/components/DatasetHosting/DatasetDownloadButton.d.ts +10 -5
  113. package/dist/components/DatasetHosting/DatasetDownloadButton.d.ts.map +1 -1
  114. package/dist/components/DatasetHosting/DatasetDownloadButton.js +66 -74
  115. package/dist/components/DatasetHosting/DatasetDownloadButton.js.map +1 -1
  116. package/dist/components/DatasetHosting/DatasetHosting.d.ts +6 -0
  117. package/dist/components/DatasetHosting/DatasetHosting.d.ts.map +1 -1
  118. package/dist/components/DatasetHosting/DatasetHosting.js +6 -0
  119. package/dist/components/DatasetHosting/DatasetHosting.js.map +1 -1
  120. package/dist/components/DatasetHosting/DatasetHostingAdornment.d.ts +15 -0
  121. package/dist/components/DatasetHosting/DatasetHostingAdornment.d.ts.map +1 -0
  122. package/dist/components/DatasetHosting/DatasetHostingAdornment.js +23 -0
  123. package/dist/components/DatasetHosting/DatasetHostingAdornment.js.map +1 -0
  124. package/dist/components/DatasetHosting/index.d.ts +2 -0
  125. package/dist/components/DatasetHosting/index.d.ts.map +1 -1
  126. package/dist/components/DatasetHosting/index.js +2 -1
  127. package/dist/components/DownloadCart/DownloadCartPage.d.ts.map +1 -1
  128. package/dist/components/DownloadCart/DownloadCartPage.js +1 -1
  129. package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
  130. package/dist/components/DropdownSelect/DropdownSelect.d.ts.map +1 -1
  131. package/dist/components/DropdownSelect/DropdownSelect.js +1 -1
  132. package/dist/components/DropdownSelect/DropdownSelect.js.map +1 -1
  133. package/dist/components/EntityFinder/tree/EntityTree.d.ts.map +1 -1
  134. package/dist/components/EntityFinder/tree/EntityTree.js +1 -1
  135. package/dist/components/EntityFinder/tree/EntityTree.js.map +1 -1
  136. package/dist/components/EntityFinder/tree/VirtualizedTree.js +1 -1
  137. package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
  138. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js +1 -1
  139. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
  140. package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
  141. package/dist/components/GenericCard/TableRowGenericCard.js +176 -170
  142. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  143. package/dist/components/JsonSchemaForm/CustomFormContext.d.ts +9 -0
  144. package/dist/components/JsonSchemaForm/CustomFormContext.d.ts.map +1 -1
  145. package/dist/components/JsonSchemaForm/JsonSchemaForm.d.ts.map +1 -1
  146. package/dist/components/JsonSchemaForm/JsonSchemaForm.js +2 -1
  147. package/dist/components/JsonSchemaForm/JsonSchemaForm.js.map +1 -1
  148. package/dist/components/JsonSchemaForm/templates/ArrayFieldTemplate.d.ts.map +1 -1
  149. package/dist/components/JsonSchemaForm/templates/ArrayFieldTemplate.js +1 -1
  150. package/dist/components/JsonSchemaForm/templates/ArrayFieldTemplate.js.map +1 -1
  151. package/dist/components/JsonSchemaForm/templates/FieldTemplate.d.ts.map +1 -1
  152. package/dist/components/JsonSchemaForm/templates/FieldTemplate.js +6 -6
  153. package/dist/components/JsonSchemaForm/templates/FieldTemplate.js.map +1 -1
  154. package/dist/components/JsonSchemaForm/widgets/DateWidget.d.ts +9 -0
  155. package/dist/components/JsonSchemaForm/widgets/DateWidget.d.ts.map +1 -0
  156. package/dist/components/JsonSchemaForm/widgets/DateWidget.js +23 -0
  157. package/dist/components/JsonSchemaForm/widgets/DateWidget.js.map +1 -0
  158. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.css +1 -1
  159. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts +3 -2
  160. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts.map +1 -1
  161. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js +10 -12
  162. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js.map +1 -1
  163. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.module.js +8 -7
  164. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.module.js.map +1 -1
  165. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.module.scss +12 -2
  166. package/dist/components/Markdown/MarkdownEditor.js +1 -1
  167. package/dist/components/Markdown/MarkdownEditor.js.map +1 -1
  168. package/dist/components/ProvenanceGraph/ProvenanceGraph.d.ts.map +1 -1
  169. package/dist/components/ProvenanceGraph/ProvenanceGraph.js +46 -46
  170. package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
  171. package/dist/components/QueryBuilder/queryBuilderTranslation.js +1 -1
  172. package/dist/components/QueryBuilder/queryBuilderTranslation.js.map +1 -1
  173. package/dist/components/QueryWrapperPlotNav/LastUpdatedOn.js +1 -1
  174. package/dist/components/QueryWrapperPlotNav/LastUpdatedOn.js.map +1 -1
  175. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +1 -1
  176. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
  177. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +27 -25
  178. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
  179. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.d.ts +0 -9
  180. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.d.ts.map +1 -1
  181. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js +23 -31
  182. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js.map +1 -1
  183. package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.d.ts.map +1 -1
  184. package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.js +5 -4
  185. package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.js.map +1 -1
  186. package/dist/components/SchemaDrivenAnnotationEditor/field/SynapseAnnotationsRJSFObjectField.d.ts.map +1 -1
  187. package/dist/components/SchemaDrivenAnnotationEditor/field/SynapseAnnotationsRJSFObjectField.js +6 -5
  188. package/dist/components/SchemaDrivenAnnotationEditor/field/SynapseAnnotationsRJSFObjectField.js.map +1 -1
  189. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +2 -0
  190. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
  191. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +18 -13
  192. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
  193. package/dist/components/StatisticsPlot.d.ts.map +1 -1
  194. package/dist/components/StatisticsPlot.js +1 -1
  195. package/dist/components/StatisticsPlot.js.map +1 -1
  196. package/dist/components/SynapseForm/SynapseFormWrapper.js +1 -1
  197. package/dist/components/SynapseForm/SynapseFormWrapper.js.map +1 -1
  198. package/dist/components/SynapseHomepageV2/HotdropsAndNews.css +1 -1
  199. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js +9 -9
  200. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js.map +1 -1
  201. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.scss +15 -0
  202. package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js +1 -1
  203. package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js.map +1 -1
  204. package/dist/components/SynapseSearchPageResults/SynapseSearchPage.js +1 -1
  205. package/dist/components/SynapseSearchPageResults/SynapseSearchPage.js.map +1 -1
  206. package/dist/components/SynapseTable/SynapseTableRenderers.d.ts.map +1 -1
  207. package/dist/components/SynapseTable/SynapseTableRenderers.js +1 -1
  208. package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
  209. package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts +4 -0
  210. package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts.map +1 -1
  211. package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js +71 -69
  212. package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js.map +1 -1
  213. package/dist/components/SynapseTable/table-top/DownloadOptions.d.ts +4 -0
  214. package/dist/components/SynapseTable/table-top/DownloadOptions.d.ts.map +1 -1
  215. package/dist/components/SynapseTable/table-top/DownloadOptions.js +14 -13
  216. package/dist/components/SynapseTable/table-top/DownloadOptions.js.map +1 -1
  217. package/dist/components/SynapseTable/usePrefetchTableData.js +1 -1
  218. package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
  219. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js +4 -4
  220. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js.map +1 -1
  221. package/dist/components/TanStackTable/TableCellRenderer.d.ts.map +1 -1
  222. package/dist/components/TanStackTable/TableCellRenderer.js +1 -1
  223. package/dist/components/TanStackTable/TableCellRenderer.js.map +1 -1
  224. package/dist/components/TermsAndConditions/TermsAndConditions.js +1 -1
  225. package/dist/components/TermsAndConditions/TermsAndConditions.js.map +1 -1
  226. package/dist/components/Webhook/CreateWebhookModal.d.ts.map +1 -1
  227. package/dist/components/Webhook/CreateWebhookModal.js +1 -1
  228. package/dist/components/Webhook/CreateWebhookModal.js.map +1 -1
  229. package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
  230. package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +172 -63
  231. package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
  232. package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.d.ts +3 -0
  233. package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.d.ts.map +1 -1
  234. package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.js +2 -2
  235. package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.js.map +1 -1
  236. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.d.ts.map +1 -1
  237. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js +10 -8
  238. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js.map +1 -1
  239. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.d.ts.map +1 -1
  240. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js +74 -43
  241. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js.map +1 -1
  242. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.d.ts.map +1 -1
  243. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js +2 -2
  244. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js.map +1 -1
  245. package/dist/components/doi/CreateOrUpdateDoiModal.js +5 -5
  246. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  247. package/dist/components/entity/metadata/EntityModal.js +1 -1
  248. package/dist/components/entity/metadata/EntityModal.js.map +1 -1
  249. package/dist/components/entity/page/action_menu/EntityActionMenu.js +2 -2
  250. package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
  251. package/dist/components/index.js +113 -112
  252. package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
  253. package/dist/components/menu/DropdownMenu.js +1 -1
  254. package/dist/components/menu/DropdownMenu.js.map +1 -1
  255. package/dist/components/row_renderers/Dataset.js +1 -1
  256. package/dist/components/row_renderers/Dataset.js.map +1 -1
  257. package/dist/components/styled/LeftRightPanel.d.ts +8 -0
  258. package/dist/components/styled/LeftRightPanel.d.ts.map +1 -1
  259. package/dist/components/styled/LeftRightPanel.js +10 -1
  260. package/dist/components/styled/LeftRightPanel.js.map +1 -1
  261. package/dist/components/widgets/facet-nav/FacetNavPanel.js +1 -1
  262. package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
  263. package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.d.ts.map +1 -1
  264. package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js +1 -1
  265. package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
  266. package/dist/components/widgets/query-filter/FacetFilterControls.js +1 -1
  267. package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
  268. package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.d.ts.map +1 -1
  269. package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js +1 -1
  270. package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map +1 -1
  271. package/dist/index.js +174 -173
  272. package/dist/index.js.map +1 -1
  273. package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +73 -0
  274. package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -0
  275. package/dist/mocks/msw/handlers/aridhiaHandlers.js +119 -0
  276. package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -0
  277. package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js +1 -1
  278. package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js.map +1 -1
  279. package/dist/mocks/msw/handlers/entityHandlers.d.ts.map +1 -1
  280. package/dist/mocks/msw/handlers/entityHandlers.js +4 -4
  281. package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
  282. package/dist/mocks/msw/handlers/userProfileHandlers.js +2 -2
  283. package/dist/mocks/msw/handlers/userProfileHandlers.js.map +1 -1
  284. package/dist/mocks/msw/handlers.d.ts.map +1 -1
  285. package/dist/mocks/msw/handlers.js +72 -69
  286. package/dist/mocks/msw/handlers.js.map +1 -1
  287. package/dist/style/components/_terms-and-conditions.scss +25 -3
  288. package/dist/style/main.css +1 -1
  289. package/dist/testutils/RjsfFormTestUtils.js +12 -0
  290. package/dist/testutils/RjsfFormTestUtils.js.map +1 -0
  291. package/dist/tsconfig.build.tsbuildinfo +1 -1
  292. package/dist/utils/featureflag/FeatureFlags.d.ts +1 -0
  293. package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
  294. package/dist/utils/featureflag/FeatureFlags.js +1 -1
  295. package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
  296. package/dist/utils/functions/QueryFilterUtils.js +1 -1
  297. package/dist/utils/functions/QueryFilterUtils.js.map +1 -1
  298. package/dist/utils/functions/SqlFunctions.js +1 -1
  299. package/dist/utils/functions/SqlFunctions.js.map +1 -1
  300. package/dist/utils/functions/queryUtils.js +1 -1
  301. package/dist/utils/functions/queryUtils.js.map +1 -1
  302. package/dist/utils/hooks/useDetectSSOCode.d.ts.map +1 -1
  303. package/dist/utils/hooks/useDetectSSOCode.js +1 -1
  304. package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
  305. package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js +1 -1
  306. package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js.map +1 -1
  307. package/dist/utils/jsonschema/SchemaAnnotationUtils.js +1 -1
  308. package/dist/utils/jsonschema/SchemaAnnotationUtils.js.map +1 -1
  309. package/dist/utils/jsonschema/collectTopLevelProperties.d.ts +22 -0
  310. package/dist/utils/jsonschema/collectTopLevelProperties.d.ts.map +1 -0
  311. package/dist/utils/jsonschema/collectTopLevelProperties.js +31 -0
  312. package/dist/utils/jsonschema/collectTopLevelProperties.js.map +1 -0
  313. package/dist/utils/jsonschema/getSchemaPropertyInfo.d.ts.map +1 -1
  314. package/dist/utils/jsonschema/getSchemaPropertyInfo.js +1 -1
  315. package/dist/utils/jsonschema/getSchemaPropertyInfo.js.map +1 -1
  316. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"DownloadCartPage.js","names":[],"sources":["../../../src/components/DownloadCart/DownloadCartPage.tsx"],"sourcesContent":["import styles from './DownloadCartPage.module.scss'\nimport SynapseClient from '@/synapse-client'\nimport { useGetDownloadListStatistics } from '@/synapse-queries/download/useDownloadList'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { DeleteTwoTone } from '@mui/icons-material'\nimport { Button, Tooltip, Typography } from '@mui/material'\nimport {\n AvailableFilter,\n FilesStatisticsResponse,\n} from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport FullWidthAlert from '../FullWidthAlert/FullWidthAlert'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { ProgrammaticInstructionsModal } from '../ProgrammaticInstructionsModal/ProgrammaticInstructionsModal'\nimport AvailableForDownloadTable from './AvailableForDownloadTable'\nimport { CreatePackageV2 } from './CreatePackageV2'\nimport { PYTHON_CLIENT_IMPORT_AND_LOGIN } from './DirectProgrammaticDownload'\nimport { calculateFriendlyFileSize } from '@/utils/functions/calculateFriendlyFileSize'\nimport { DownloadIneligibleForPackagingFilesFromListButton } from './DownloadIneligibleForPackagingFilesFromListButton'\nimport { DownloadListActionsRequired } from './DownloadListActionsRequired'\nimport ComponentCollapse from '../ComponentCollapse'\n\nconst pythonDownloadCode = `${PYTHON_CLIENT_IMPORT_AND_LOGIN}\ndl_list_file_entities = syn.get_download_list()`\n\nconst cliDownloadCode = `synapse get-download-list`\n\nconst filterTabs: { label: string; filter: AvailableFilter }[] = [\n { label: 'All Files', filter: undefined },\n { label: 'Files included in ZIP', filter: 'eligibleForPackaging' },\n { label: 'Files not included in ZIP', filter: 'ineligibleForPackaging' },\n]\n\n/**\n * Show the Download Cart page.\n */\nexport function DownloadCartPage() {\n const { accessToken } = useSynapseContext()\n const [selectedTabIndex, setSelectedTabIndex] = useState<number>(0)\n const [selectedFilterTabIndex, setSelectedFilterTabIndex] =\n useState<number>(0)\n const selectedFilter = filterTabs[selectedFilterTabIndex].filter\n const [isShowingCreatePackageUI, setIsShowingCreatePackageUI] =\n useState<boolean>(false)\n const createPackageRef = useRef<HTMLDivElement>(null)\n // scroll to the CreatePackageV2 component when it is shown so that the user is aware of the next steps after clicking the button to create a package\n useEffect(() => {\n if (isShowingCreatePackageUI) {\n createPackageRef.current?.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n })\n }\n }, [isShowingCreatePackageUI])\n const [isShowingModal, setIsShowingModal] = useState<boolean>(false)\n const [isShowingDownloadSuccessAlert, setIsShowingDownloadSuccessAlert] =\n useState(false)\n const [error, setError] = useState<Error>()\n const {\n data,\n isLoading,\n isError,\n error: newError,\n refetch,\n } = useGetDownloadListStatistics()\n useEffect(() => {\n if (isError && newError) {\n setError(newError)\n }\n }, [isError, newError])\n\n const getFilterCount = (\n data: FilesStatisticsResponse,\n filter: AvailableFilter,\n ) => {\n if (filter === undefined) return data.numberOfFilesAvailableForDownload\n if (filter === 'eligibleForPackaging')\n return data.numberOfFilesAvailableForDownloadAndEligibleForPackaging\n return (\n data.numberOfFilesAvailableForDownload -\n data.numberOfFilesAvailableForDownloadAndEligibleForPackaging\n )\n }\n // SWC-5874: When arriving at the download cart when there are no ARs, the user should start in the Download list\n useEffect(() => {\n if (data && data.numberOfFilesRequiringAction == 0) {\n setSelectedTabIndex(1)\n }\n // also hide the Create Package UI if there are no files available for download\n if (\n data &&\n data.numberOfFilesAvailableForDownloadAndEligibleForPackaging === 0\n ) {\n setIsShowingCreatePackageUI(false)\n }\n }, [data])\n\n if (error) {\n return <ErrorBanner error={error} />\n }\n const clearDownloadList = async () => {\n await SynapseClient.clearDownloadListV2(accessToken)\n refetch()\n }\n return (\n <div className={styles.DownloadCartPage}>\n <div>\n <div className={`${styles.pageHeader}`}>\n <div className=\"container\">\n <div className={styles.grid}>\n <h3 className=\"pageHeaderTitle\">Your Download List</h3>\n <Tooltip\n title=\"Immediately removes all items from your download list\"\n enterNextDelay={300}\n placement=\"right\"\n >\n <Button\n onClick={() => {\n clearDownloadList()\n }}\n variant=\"text\"\n color=\"primary\"\n startIcon={<DeleteTwoTone />}\n >\n Clear Your Download List\n </Button>\n </Tooltip>\n </div>\n </div>\n </div>\n </div>\n <div className={styles.tabsContainer}>\n <div className=\"container\">\n <ul className={styles.navTabs}>\n <li\n className={`${styles.navItem}${\n selectedTabIndex == 0 ? ` ${styles.active}` : ''\n }`}\n aria-selected={selectedTabIndex == 0}\n >\n <button onClick={() => setSelectedTabIndex(0)}>\n Access Actions Required\n {!isError && !isLoading && data && (\n <span className={styles.fileCount}>\n {data.totalNumberOfFiles -\n data.numberOfFilesAvailableForDownload}\n </span>\n )}\n </button>\n </li>\n <li\n className={`${styles.navItem}${\n selectedTabIndex == 1 ? ` ${styles.active}` : ''\n }`}\n aria-selected={selectedTabIndex == 1}\n >\n <button onClick={() => setSelectedTabIndex(1)}>\n Download List\n {!isError && !isLoading && data && (\n <span className={styles.fileCount}>\n {data.numberOfFilesAvailableForDownload}\n </span>\n )}\n </button>\n </li>\n </ul>\n </div>\n </div>\n\n <div\n className={\n /*\n The DownloadListActionsRequired component stores actions in local state to track which actions are completed.\n\n Mount the actions required component and hide it with style to ensure actions stored in component state are persisted as the user switches tabs\n */\n !(selectedTabIndex == 0 && !isError && !isLoading && data)\n ? styles.hidden\n : undefined\n }\n >\n {data?.numberOfFilesRequiringAction &&\n data.numberOfFilesRequiringAction > 0 && (\n // Unmount instead of hiding the DownloadListActionsRequired component when there are 0 actions required\n // The DownloadListActionsRequired cannot discern between a fulfilled action and an action that is no longer required because the\n // file was removed from the download cart.\n // In the typical case where the download cart is cleared, unmounting the component ensures that the actions are cleared out.\n <div>\n <div className=\"container\">\n <DownloadListActionsRequired />\n </div>\n </div>\n )}\n {data?.numberOfFilesRequiringAction === 0 && (\n <div className={styles.placeholder}>\n <div>No actions are currently required.</div>\n </div>\n )}\n </div>\n\n {selectedTabIndex == 1 && !isError && !isLoading && data && (\n <div>\n {data.numberOfFilesAvailableForDownload > 0 && (\n <div className={`container ${styles.DownloadListTabContent}`}>\n <h3 className={`${styles.sectionTitle} pageHeaderTitle`}>\n Bulk Download Options\n {data.sumOfFileSizesAvailableForDownload != null && (\n <Tooltip\n placement=\"right\"\n title={\n <>\n Total file size\n <br />\n Does not include files hosted outside Synapse\n </>\n }\n slotProps={{ tooltip: { sx: { maxWidth: 400 } } }}\n >\n <span className={styles.totalFileSize}>\n {calculateFriendlyFileSize(\n data.sumOfFileSizesAvailableForDownload,\n )}{' '}\n total*\n </span>\n </Tooltip>\n )}\n </h3>\n <div>\n <div className={styles.subSectionOverview}>\n <div className={styles.subSection}>\n <div className={styles.subSectionHeader}>\n <div className={styles.headline}>\n <Typography variant={'headline3'}>\n <IconSvg icon=\"packagableFile\" /> Web Download (.ZIP)\n </Typography>\n </div>\n <div className={styles.subSectionActions}>\n {data.numberOfFilesAvailableForDownloadAndEligibleForPackaging >\n 0 && (\n <Button\n variant=\"contained\"\n onClick={() => {\n setIsShowingCreatePackageUI(true)\n }}\n startIcon={<IconSvg icon=\"download\" wrap={false} />}\n >\n Download Packages\n </Button>\n )}\n {data.numberOfFilesAvailableForDownloadAndEligibleForPackaging ==\n 0 && (\n <Tooltip\n title=\"You cannot create a .zip package because there are no eligible files.\"\n enterNextDelay={300}\n placement=\"top\"\n >\n <span>\n <Button\n variant=\"contained\"\n disabled\n startIcon={\n <IconSvg icon=\"download\" wrap={false} />\n }\n >\n Download Packages\n </Button>\n </span>\n </Tooltip>\n )}\n </div>\n </div>\n <ComponentCollapse\n component={\n <Typography variant={'body1'} component={'div'}>\n Only some files may be eligible for packaging as ZIP.\n Use the Individual Downloads tab, below, to download\n non-packageable files.&nbsp;\n <a\n href=\"https://help.synapse.org/docs/Downloading-Data-From-the-Synapse-UI.2004254837.html\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n More Information.\n </a>\n </Typography>\n }\n collapseBoxSx={{\n backgroundColor: 'transparent',\n p: 0,\n mt: '15px',\n }}\n componentContainerSx={{\n backgroundColor: 'transparent',\n p: 0,\n }}\n iconSx={{ width: '25px', height: '25px' }}\n >\n <Typography\n variant={'body1'}\n component={'div'}\n sx={{ marginBottom: '15px' }}\n >\n <ul>\n <li>Files are bundled into .ZIPs up to 1 GB each.</li>\n <li>\n Larger selections are split into multiple packages.\n </li>\n <li>\n Includes only files stored in Synapse native\n storage.\n </li>\n <li>\n Each package contains a CSV manifest with file\n annotations and metadata.\n </li>\n </ul>\n </Typography>\n </ComponentCollapse>\n </div>\n <div className={styles.subSection}>\n <div className={styles.subSectionHeader}>\n <div className={styles.headline}>\n <Typography variant={'headline3'}>\n <IconSvg icon=\"code\" /> Programmatic Download\n </Typography>\n </div>\n <div className={styles.subSectionActions}>\n <Button\n variant=\"contained\"\n onClick={() => {\n setIsShowingModal(true)\n }}\n startIcon={<IconSvg icon=\"download\" wrap={false} />}\n >\n Get R / Python / CLI Code\n </Button>\n </div>\n </div>\n <ComponentCollapse\n component={\n <Typography variant={'body1'} component={'div'}>\n Use our Python, R, or command line clients to download\n files quickly.&nbsp;\n <a\n href=\"https://help.synapse.org/docs/Downloading-Data-Programmatically.2003796248.html\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n More Information.\n </a>\n </Typography>\n }\n collapseBoxSx={{\n backgroundColor: 'transparent',\n p: 0,\n mt: '15px',\n }}\n componentContainerSx={{\n backgroundColor: 'transparent',\n p: 0,\n }}\n iconSx={{ width: '25px', height: '25px' }}\n >\n <Typography\n variant={'body1'}\n component={'div'}\n sx={{ marginBottom: '15px' }}\n >\n <ul>\n <li>Requires a client (R, Python, or CLI).</li>\n <li>\n No limits on individual file size or total download\n size.\n </li>\n <li>\n Includes files stored both on and off Synapse native\n storage.\n </li>\n <li>\n Downloads include a CSV manifest with file\n annotations and metadata.\n </li>\n </ul>\n </Typography>\n </ComponentCollapse>\n </div>\n {data.numberOfFilesAvailableForDownloadAndEligibleForPackaging <\n data.numberOfFilesAvailableForDownload && (\n <div className={styles.subSection}>\n <div className={styles.subSectionHeader}>\n <div className={styles.headline}>\n <Typography variant={'headline3'}>\n <IconSvg icon=\"multiFile\" /> Multi-file Download\n </Typography>\n </div>\n <div className={styles.subSectionActions}>\n <div className={styles.ineligibleDownloadContainer}>\n <DownloadIneligibleForPackagingFilesFromListButton />\n </div>\n </div>\n </div>\n <ComponentCollapse\n component={\n <Typography variant={'body1'} component={'div'}>\n Files which <strong>aren't</strong> included in a\n ZIP package may be downloaded as a multi-file\n download.&nbsp;\n </Typography>\n }\n collapseBoxSx={{\n backgroundColor: 'transparent',\n p: 0,\n mt: '15px',\n }}\n componentContainerSx={{\n backgroundColor: 'transparent',\n p: 0,\n }}\n iconSx={{ width: '25px', height: '25px' }}\n >\n <Typography\n variant={'body1'}\n component={'div'}\n sx={{ marginBottom: '15px' }}\n >\n Clicking “Start Multi-file Download” initiates a\n download of all files in your Download List that can’t\n be bundled into a ZIP—such as large files or external\n links—in one step. Files are saved one by one with\n clear progress updates, automatic handling of\n duplicate names, and retry support if something fails.\n You can cancel anytime.\n <br />\n <br />\n Note: in some browsers, files download individually to\n your default Downloads folder instead of a selected\n location.\n </Typography>\n </ComponentCollapse>\n </div>\n )}\n </div>\n </div>\n\n <div>\n {isShowingCreatePackageUI && (\n <div ref={createPackageRef}>\n <CreatePackageV2\n onPackageCreation={() => {\n setIsShowingDownloadSuccessAlert(true)\n }}\n />\n </div>\n )}\n <h3 className={`${styles.sectionTitle} pageHeaderTitle`}>\n Download Individual Files\n </h3>\n <div className={styles.tabsContainer}>\n <ul className={styles.navTabs}>\n <li className={styles.navLabel}>View:</li>\n {filterTabs.map((tab, index) => (\n <li\n key={tab.label}\n className={`${styles.navItem}${\n selectedFilterTabIndex === index\n ? ` ${styles.active}`\n : ''\n }`}\n aria-selected={selectedFilterTabIndex === index}\n >\n <button\n onClick={() => setSelectedFilterTabIndex(index)}\n >\n {tab.label}\n {!isError && !isLoading && data && (\n <span className={styles.fileCount}>\n {getFilterCount(data, tab.filter)}\n </span>\n )}\n </button>\n </li>\n ))}\n </ul>\n </div>\n\n <div className={styles.availableForDownloadTableContainer}>\n <AvailableForDownloadTable\n key={selectedFilter ?? 'all'}\n filter={selectedFilter}\n />\n </div>\n </div>\n </div>\n )}\n {data.numberOfFilesAvailableForDownload === 0 && (\n <div className={styles.placeholder}>\n <Typography variant=\"body1Italic\">\n Your Download List is currently empty.\n </Typography>\n </div>\n )}\n </div>\n )}\n <FullWidthAlert\n show={isShowingDownloadSuccessAlert}\n variant=\"success\"\n title=\"Package Created\"\n description=\"A package has been created with eligible files. The items contained in this .zip file have been removed from your list. If your package is over 1GB, you will need to create multiple packages.\"\n autoCloseAfterDelayInSeconds={10}\n onClose={() => {\n setIsShowingDownloadSuccessAlert(false)\n }}\n />\n {isShowingModal && (\n <ProgrammaticInstructionsModal\n show={true}\n onClose={() => setIsShowingModal(false)}\n title=\"Download Programmatically\"\n pythonCode={pythonDownloadCode}\n cliCode={cliDownloadCode}\n // rCode={rDownloadCode}\n />\n )}\n </div>\n )\n}\n\nexport default DownloadCartPage\n"],"mappings":"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"}
1
+ {"version":3,"file":"DownloadCartPage.js","names":[],"sources":["../../../src/components/DownloadCart/DownloadCartPage.tsx"],"sourcesContent":["import styles from './DownloadCartPage.module.scss'\nimport SynapseClient from '@/synapse-client'\nimport { useGetDownloadListStatistics } from '@/synapse-queries/download/useDownloadList'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { DeleteTwoTone } from '@mui/icons-material'\nimport { Button, Tooltip, Typography } from '@mui/material'\nimport {\n AvailableFilter,\n FilesStatisticsResponse,\n} from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport FullWidthAlert from '../FullWidthAlert/FullWidthAlert'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { ProgrammaticInstructionsModal } from '../ProgrammaticInstructionsModal/ProgrammaticInstructionsModal'\nimport AvailableForDownloadTable from './AvailableForDownloadTable'\nimport { CreatePackageV2 } from './CreatePackageV2'\nimport { PYTHON_CLIENT_IMPORT_AND_LOGIN } from './DirectProgrammaticDownload'\nimport { calculateFriendlyFileSize } from '@/utils/functions/calculateFriendlyFileSize'\nimport { DownloadIneligibleForPackagingFilesFromListButton } from './DownloadIneligibleForPackagingFilesFromListButton'\nimport { DownloadListActionsRequired } from './DownloadListActionsRequired'\nimport ComponentCollapse from '../ComponentCollapse'\n\nconst pythonDownloadCode = `${PYTHON_CLIENT_IMPORT_AND_LOGIN}\ndl_list_file_entities = syn.get_download_list()`\n\nconst cliDownloadCode = `synapse get-download-list`\n\nconst filterTabs: { label: string; filter: AvailableFilter }[] = [\n { label: 'All Files', filter: undefined },\n { label: 'Files included in ZIP', filter: 'eligibleForPackaging' },\n { label: 'Files not included in ZIP', filter: 'ineligibleForPackaging' },\n]\n\n/**\n * Show the Download Cart page.\n */\nexport function DownloadCartPage() {\n const { accessToken } = useSynapseContext()\n const [selectedTabIndex, setSelectedTabIndex] = useState<number>(0)\n const [selectedFilterTabIndex, setSelectedFilterTabIndex] =\n useState<number>(0)\n const selectedFilter = filterTabs[selectedFilterTabIndex].filter\n const [isShowingCreatePackageUI, setIsShowingCreatePackageUI] =\n useState<boolean>(false)\n const createPackageRef = useRef<HTMLDivElement>(null)\n // scroll to the CreatePackageV2 component when it is shown so that the user is aware of the next steps after clicking the button to create a package\n useEffect(() => {\n if (isShowingCreatePackageUI) {\n createPackageRef.current?.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n })\n }\n }, [isShowingCreatePackageUI])\n const [isShowingModal, setIsShowingModal] = useState<boolean>(false)\n const [isShowingDownloadSuccessAlert, setIsShowingDownloadSuccessAlert] =\n useState(false)\n const [error, setError] = useState<Error>()\n const {\n data,\n isLoading,\n isError,\n error: newError,\n refetch,\n } = useGetDownloadListStatistics()\n useEffect(() => {\n if (isError && newError) {\n setError(newError)\n }\n }, [isError, newError])\n\n const getFilterCount = (\n data: FilesStatisticsResponse,\n filter: AvailableFilter,\n ) => {\n if (filter === undefined) return data.numberOfFilesAvailableForDownload\n if (filter === 'eligibleForPackaging')\n return data.numberOfFilesAvailableForDownloadAndEligibleForPackaging\n return (\n data.numberOfFilesAvailableForDownload -\n data.numberOfFilesAvailableForDownloadAndEligibleForPackaging\n )\n }\n // SWC-5874: When arriving at the download cart when there are no ARs, the user should start in the Download list\n useEffect(() => {\n if (data?.numberOfFilesRequiringAction == 0) {\n setSelectedTabIndex(1)\n }\n // also hide the Create Package UI if there are no files available for download\n if (data?.numberOfFilesAvailableForDownloadAndEligibleForPackaging === 0) {\n setIsShowingCreatePackageUI(false)\n }\n }, [data])\n\n if (error) {\n return <ErrorBanner error={error} />\n }\n const clearDownloadList = async () => {\n await SynapseClient.clearDownloadListV2(accessToken)\n refetch()\n }\n return (\n <div className={styles.DownloadCartPage}>\n <div>\n <div className={`${styles.pageHeader}`}>\n <div className=\"container\">\n <div className={styles.grid}>\n <h3 className=\"pageHeaderTitle\">Your Download List</h3>\n <Tooltip\n title=\"Immediately removes all items from your download list\"\n enterNextDelay={300}\n placement=\"right\"\n >\n <Button\n onClick={() => {\n clearDownloadList()\n }}\n variant=\"text\"\n color=\"primary\"\n startIcon={<DeleteTwoTone />}\n >\n Clear Your Download List\n </Button>\n </Tooltip>\n </div>\n </div>\n </div>\n </div>\n <div className={styles.tabsContainer}>\n <div className=\"container\">\n <ul className={styles.navTabs}>\n <li\n className={`${styles.navItem}${\n selectedTabIndex == 0 ? ` ${styles.active}` : ''\n }`}\n aria-selected={selectedTabIndex == 0}\n >\n <button onClick={() => setSelectedTabIndex(0)}>\n Access Actions Required\n {!isError && !isLoading && data && (\n <span className={styles.fileCount}>\n {data.totalNumberOfFiles -\n data.numberOfFilesAvailableForDownload}\n </span>\n )}\n </button>\n </li>\n <li\n className={`${styles.navItem}${\n selectedTabIndex == 1 ? ` ${styles.active}` : ''\n }`}\n aria-selected={selectedTabIndex == 1}\n >\n <button onClick={() => setSelectedTabIndex(1)}>\n Download List\n {!isError && !isLoading && data && (\n <span className={styles.fileCount}>\n {data.numberOfFilesAvailableForDownload}\n </span>\n )}\n </button>\n </li>\n </ul>\n </div>\n </div>\n\n <div\n className={\n /*\n The DownloadListActionsRequired component stores actions in local state to track which actions are completed.\n\n Mount the actions required component and hide it with style to ensure actions stored in component state are persisted as the user switches tabs\n */\n !(selectedTabIndex == 0 && !isError && !isLoading && data)\n ? styles.hidden\n : undefined\n }\n >\n {data?.numberOfFilesRequiringAction &&\n data.numberOfFilesRequiringAction > 0 && (\n // Unmount instead of hiding the DownloadListActionsRequired component when there are 0 actions required\n // The DownloadListActionsRequired cannot discern between a fulfilled action and an action that is no longer required because the\n // file was removed from the download cart.\n // In the typical case where the download cart is cleared, unmounting the component ensures that the actions are cleared out.\n <div>\n <div className=\"container\">\n <DownloadListActionsRequired />\n </div>\n </div>\n )}\n {data?.numberOfFilesRequiringAction === 0 && (\n <div className={styles.placeholder}>\n <div>No actions are currently required.</div>\n </div>\n )}\n </div>\n\n {selectedTabIndex == 1 && !isError && !isLoading && data && (\n <div>\n {data.numberOfFilesAvailableForDownload > 0 && (\n <div className={`container ${styles.DownloadListTabContent}`}>\n <h3 className={`${styles.sectionTitle} pageHeaderTitle`}>\n Bulk Download Options\n {data.sumOfFileSizesAvailableForDownload != null && (\n <Tooltip\n placement=\"right\"\n title={\n <>\n Total file size\n <br />\n Does not include files hosted outside Synapse\n </>\n }\n slotProps={{ tooltip: { sx: { maxWidth: 400 } } }}\n >\n <span className={styles.totalFileSize}>\n {calculateFriendlyFileSize(\n data.sumOfFileSizesAvailableForDownload,\n )}{' '}\n total*\n </span>\n </Tooltip>\n )}\n </h3>\n <div>\n <div className={styles.subSectionOverview}>\n <div className={styles.subSection}>\n <div className={styles.subSectionHeader}>\n <div className={styles.headline}>\n <Typography variant={'headline3'}>\n <IconSvg icon=\"packagableFile\" /> Web Download (.ZIP)\n </Typography>\n </div>\n <div className={styles.subSectionActions}>\n {data.numberOfFilesAvailableForDownloadAndEligibleForPackaging >\n 0 && (\n <Button\n variant=\"contained\"\n onClick={() => {\n setIsShowingCreatePackageUI(true)\n }}\n startIcon={<IconSvg icon=\"download\" wrap={false} />}\n >\n Download Packages\n </Button>\n )}\n {data.numberOfFilesAvailableForDownloadAndEligibleForPackaging ==\n 0 && (\n <Tooltip\n title=\"You cannot create a .zip package because there are no eligible files.\"\n enterNextDelay={300}\n placement=\"top\"\n >\n <span>\n <Button\n variant=\"contained\"\n disabled\n startIcon={\n <IconSvg icon=\"download\" wrap={false} />\n }\n >\n Download Packages\n </Button>\n </span>\n </Tooltip>\n )}\n </div>\n </div>\n <ComponentCollapse\n component={\n <Typography variant={'body1'} component={'div'}>\n Only some files may be eligible for packaging as ZIP.\n Use the Individual Downloads tab, below, to download\n non-packageable files.&nbsp;\n <a\n href=\"https://help.synapse.org/docs/Downloading-Data-From-the-Synapse-UI.2004254837.html\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n More Information.\n </a>\n </Typography>\n }\n collapseBoxSx={{\n backgroundColor: 'transparent',\n p: 0,\n mt: '15px',\n }}\n componentContainerSx={{\n backgroundColor: 'transparent',\n p: 0,\n }}\n iconSx={{ width: '25px', height: '25px' }}\n >\n <Typography\n variant={'body1'}\n component={'div'}\n sx={{ marginBottom: '15px' }}\n >\n <ul>\n <li>Files are bundled into .ZIPs up to 1 GB each.</li>\n <li>\n Larger selections are split into multiple packages.\n </li>\n <li>\n Includes only files stored in Synapse native\n storage.\n </li>\n <li>\n Each package contains a CSV manifest with file\n annotations and metadata.\n </li>\n </ul>\n </Typography>\n </ComponentCollapse>\n </div>\n <div className={styles.subSection}>\n <div className={styles.subSectionHeader}>\n <div className={styles.headline}>\n <Typography variant={'headline3'}>\n <IconSvg icon=\"code\" /> Programmatic Download\n </Typography>\n </div>\n <div className={styles.subSectionActions}>\n <Button\n variant=\"contained\"\n onClick={() => {\n setIsShowingModal(true)\n }}\n startIcon={<IconSvg icon=\"download\" wrap={false} />}\n >\n Get R / Python / CLI Code\n </Button>\n </div>\n </div>\n <ComponentCollapse\n component={\n <Typography variant={'body1'} component={'div'}>\n Use our Python, R, or command line clients to download\n files quickly.&nbsp;\n <a\n href=\"https://help.synapse.org/docs/Downloading-Data-Programmatically.2003796248.html\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n More Information.\n </a>\n </Typography>\n }\n collapseBoxSx={{\n backgroundColor: 'transparent',\n p: 0,\n mt: '15px',\n }}\n componentContainerSx={{\n backgroundColor: 'transparent',\n p: 0,\n }}\n iconSx={{ width: '25px', height: '25px' }}\n >\n <Typography\n variant={'body1'}\n component={'div'}\n sx={{ marginBottom: '15px' }}\n >\n <ul>\n <li>Requires a client (R, Python, or CLI).</li>\n <li>\n No limits on individual file size or total download\n size.\n </li>\n <li>\n Includes files stored both on and off Synapse native\n storage.\n </li>\n <li>\n Downloads include a CSV manifest with file\n annotations and metadata.\n </li>\n </ul>\n </Typography>\n </ComponentCollapse>\n </div>\n {data.numberOfFilesAvailableForDownloadAndEligibleForPackaging <\n data.numberOfFilesAvailableForDownload && (\n <div className={styles.subSection}>\n <div className={styles.subSectionHeader}>\n <div className={styles.headline}>\n <Typography variant={'headline3'}>\n <IconSvg icon=\"multiFile\" /> Multi-file Download\n </Typography>\n </div>\n <div className={styles.subSectionActions}>\n <div className={styles.ineligibleDownloadContainer}>\n <DownloadIneligibleForPackagingFilesFromListButton />\n </div>\n </div>\n </div>\n <ComponentCollapse\n component={\n <Typography variant={'body1'} component={'div'}>\n Files which <strong>aren't</strong> included in a\n ZIP package may be downloaded as a multi-file\n download.&nbsp;\n </Typography>\n }\n collapseBoxSx={{\n backgroundColor: 'transparent',\n p: 0,\n mt: '15px',\n }}\n componentContainerSx={{\n backgroundColor: 'transparent',\n p: 0,\n }}\n iconSx={{ width: '25px', height: '25px' }}\n >\n <Typography\n variant={'body1'}\n component={'div'}\n sx={{ marginBottom: '15px' }}\n >\n Clicking “Start Multi-file Download” initiates a\n download of all files in your Download List that can’t\n be bundled into a ZIP—such as large files or external\n links—in one step. Files are saved one by one with\n clear progress updates, automatic handling of\n duplicate names, and retry support if something fails.\n You can cancel anytime.\n <br />\n <br />\n Note: in some browsers, files download individually to\n your default Downloads folder instead of a selected\n location.\n </Typography>\n </ComponentCollapse>\n </div>\n )}\n </div>\n </div>\n\n <div>\n {isShowingCreatePackageUI && (\n <div ref={createPackageRef}>\n <CreatePackageV2\n onPackageCreation={() => {\n setIsShowingDownloadSuccessAlert(true)\n }}\n />\n </div>\n )}\n <h3 className={`${styles.sectionTitle} pageHeaderTitle`}>\n Download Individual Files\n </h3>\n <div className={styles.tabsContainer}>\n <ul className={styles.navTabs}>\n <li className={styles.navLabel}>View:</li>\n {filterTabs.map((tab, index) => (\n <li\n key={tab.label}\n className={`${styles.navItem}${\n selectedFilterTabIndex === index\n ? ` ${styles.active}`\n : ''\n }`}\n aria-selected={selectedFilterTabIndex === index}\n >\n <button\n onClick={() => setSelectedFilterTabIndex(index)}\n >\n {tab.label}\n {!isError && !isLoading && data && (\n <span className={styles.fileCount}>\n {getFilterCount(data, tab.filter)}\n </span>\n )}\n </button>\n </li>\n ))}\n </ul>\n </div>\n\n <div className={styles.availableForDownloadTableContainer}>\n <AvailableForDownloadTable\n key={selectedFilter ?? 'all'}\n filter={selectedFilter}\n />\n </div>\n </div>\n </div>\n )}\n {data.numberOfFilesAvailableForDownload === 0 && (\n <div className={styles.placeholder}>\n <Typography variant=\"body1Italic\">\n Your Download List is currently empty.\n </Typography>\n </div>\n )}\n </div>\n )}\n <FullWidthAlert\n show={isShowingDownloadSuccessAlert}\n variant=\"success\"\n title=\"Package Created\"\n description=\"A package has been created with eligible files. The items contained in this .zip file have been removed from your list. If your package is over 1GB, you will need to create multiple packages.\"\n autoCloseAfterDelayInSeconds={10}\n onClose={() => {\n setIsShowingDownloadSuccessAlert(false)\n }}\n />\n {isShowingModal && (\n <ProgrammaticInstructionsModal\n show={true}\n onClose={() => setIsShowingModal(false)}\n title=\"Download Programmatically\"\n pythonCode={pythonDownloadCode}\n cliCode={cliDownloadCode}\n // rCode={rDownloadCode}\n />\n )}\n </div>\n )\n}\n\nexport default DownloadCartPage\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownSelect.d.ts","sourceRoot":"","sources":["../../../src/components/DropdownSelect/DropdownSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,SAAS,EACV,MAAM,OAAO,CAAA;AACd,OAAO,EAGL,gBAAgB,EAChB,WAAW,EAOZ,MAAM,eAAe,CAAA;AAGtB,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG;IACnD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,aAAa,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;CAC7C,CAAA;AAGD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAuHhE"}
1
+ {"version":3,"file":"DropdownSelect.d.ts","sourceRoot":"","sources":["../../../src/components/DropdownSelect/DropdownSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,SAAS,EACV,MAAM,OAAO,CAAA;AACd,OAAO,EAGL,gBAAgB,EAChB,WAAW,EAOZ,MAAM,eAAe,CAAA;AAGtB,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG;IACnD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,aAAa,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;CAC7C,CAAA;AAGD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAoHhE"}
@@ -9,7 +9,7 @@ function m(m) {
9
9
  }, j = () => {
10
10
  T((e) => !e);
11
11
  }, M = (e) => {
12
- D.current && D.current.contains(e.target) || T(!1);
12
+ D.current?.contains(e.target) || T(!1);
13
13
  };
14
14
  return /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ p(i, {
15
15
  variant: v,
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownSelect.js","names":[],"sources":["../../../src/components/DropdownSelect/DropdownSelect.tsx"],"sourcesContent":["import {\n useRef,\n useState,\n MouseEvent as ReactMouseEvent,\n RefObject,\n} from 'react'\nimport {\n Button,\n ButtonGroup,\n ButtonGroupProps,\n ButtonProps,\n ClickAwayListener,\n Grow,\n MenuItem,\n MenuList,\n Paper,\n Popper,\n} from '@mui/material'\nimport IconSvg from '../IconSvg'\n\nexport type DropdownSelectProps = ButtonGroupProps & {\n options: string[]\n selectedIndex?: number\n setSelectedIndex?: (selectedIndex: number) => void\n onButtonClick?: (selectedIndex: number) => void\n buttonText?: string\n variant?: ButtonProps['variant']\n buttonGroupAriaLabel?: string\n anchorRef?: RefObject<HTMLDivElement | null>\n}\n// Derived from https://mui.com/material-ui/react-button-group/#split-button\n\n/**\n * Renders a button group that acts as a select group\n * @param props\n * @constructor\n */\nexport default function DropdownSelect(props: DropdownSelectProps) {\n const {\n options,\n selectedIndex,\n setSelectedIndex,\n variant = 'contained',\n buttonGroupAriaLabel,\n onButtonClick,\n buttonText,\n anchorRef: externalAnchorRef,\n ...rest\n } = props\n const [open, setOpen] = useState(false)\n const internalAnchorRef = useRef<HTMLDivElement>(null)\n const anchorRef = externalAnchorRef ?? internalAnchorRef\n\n const [selectedIndexLocal, setSelectedIndexLocal] = useState(\n selectedIndex ?? 0,\n )\n\n const handleMenuItemClick = (\n event: ReactMouseEvent<HTMLLIElement, MouseEvent>,\n index: number,\n ) => {\n if (setSelectedIndex) {\n setSelectedIndex(index)\n } else {\n setSelectedIndexLocal(index)\n }\n setOpen(false)\n }\n\n const handleToggle = () => {\n setOpen(prevOpen => !prevOpen)\n }\n\n const handleClose = (event: Event) => {\n if (\n anchorRef.current &&\n anchorRef.current.contains(event.target as HTMLElement)\n ) {\n return\n }\n\n setOpen(false)\n }\n\n return (\n <>\n <ButtonGroup\n variant={variant}\n ref={anchorRef}\n aria-label=\"split button\"\n {...rest}\n >\n <Button\n onClick={() => {\n if (onButtonClick) {\n onButtonClick(selectedIndex ?? selectedIndexLocal)\n } else {\n handleToggle()\n }\n }}\n >\n {buttonText\n ? buttonText\n : options[selectedIndex ?? selectedIndexLocal]}\n </Button>\n <Button\n size=\"small\"\n aria-controls={open ? 'split-button-menu' : undefined}\n aria-expanded={open ? 'true' : undefined}\n aria-label={buttonGroupAriaLabel}\n aria-haspopup=\"menu\"\n onClick={handleToggle}\n sx={{ width: '36px' }}\n >\n <IconSvg icon={'expandMore'} wrap={false} />\n </Button>\n </ButtonGroup>\n <Popper\n sx={{\n zIndex: 10,\n }}\n open={open}\n placement={'bottom-start'}\n anchorEl={anchorRef.current}\n role={undefined}\n transition\n disablePortal\n >\n {({ TransitionProps, placement }) => (\n <Grow\n {...TransitionProps}\n style={{\n transformOrigin:\n placement === 'bottom' ? 'center top' : 'center bottom',\n }}\n >\n <Paper>\n <ClickAwayListener onClickAway={handleClose}>\n <MenuList id=\"split-button-menu\" autoFocusItem>\n {options.map((option, index) => (\n <MenuItem\n key={option}\n selected={index === selectedIndex}\n onClick={event => handleMenuItemClick(event, index)}\n >\n {option}\n </MenuItem>\n ))}\n </MenuList>\n </ClickAwayListener>\n </Paper>\n </Grow>\n )}\n </Popper>\n </>\n )\n}\n"],"mappings":";;;;;AAqCA,SAAwB,EAAe,GAA4B;CACjE,IAAM,EACJ,YACA,kBACA,qBACA,aAAU,aACV,yBACA,kBACA,eACA,WAAW,GACX,GAAG,MACD,GACE,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,IAAoB,EAAuB,IAAI,GAC/C,IAAY,KAAqB,GAEjC,CAAC,GAAoB,KAAyB,EAClD,KAAiB,CACnB,GAEM,KACJ,GACA,MACG;EAMH,AALI,IACF,EAAiB,CAAK,IAEtB,EAAsB,CAAK,GAE7B,EAAQ,EAAK;CACf,GAEM,UAAqB;EACzB,GAAQ,MAAY,CAAC,CAAQ;CAC/B,GAEM,KAAe,MAAiB;EAElC,EAAU,WACV,EAAU,QAAQ,SAAS,EAAM,MAAqB,KAKxD,EAAQ,EAAK;CACf;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACW;EACT,KAAK;EACL,cAAW;EACX,GAAI;YAJN,CAME,kBAAC,GAAD;GACE,eAAe;IACb,AAAI,IACF,EAAc,KAAiB,CAAkB,IAEjD,EAAa;GAEjB;aAEC,KAEG,EAAQ,KAAiB;EACvB,CAAA,GACR,kBAAC,GAAD;GACE,MAAK;GACL,iBAAe,IAAO,sBAAsB,KAAA;GAC5C,iBAAe,IAAO,SAAS,KAAA;GAC/B,cAAY;GACZ,iBAAc;GACd,SAAS;GACT,IAAI,EAAE,OAAO,OAAO;aAEpB,kBAAC,GAAD;IAAS,MAAM;IAAc,MAAM;GAAQ,CAAA;EACrC,CAAA,CACG;KACb,kBAAC,GAAD;EACE,IAAI,EACF,QAAQ,GACV;EACM;EACN,WAAW;EACX,UAAU,EAAU;EACpB,MAAM,KAAA;EACN,YAAA;EACA,eAAA;aAEE,EAAE,oBAAiB,mBACnB,kBAAC,GAAD;GACE,GAAI;GACJ,OAAO,EACL,iBACE,MAAc,WAAW,eAAe,gBAC5C;aAEA,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAmB,aAAa;cAC9B,kBAAC,GAAD;KAAU,IAAG;KAAoB,eAAA;eAC9B,EAAQ,KAAK,GAAQ,MACpB,kBAAC,GAAD;MAEE,UAAU,MAAU;MACpB,UAAS,MAAS,EAAoB,GAAO,CAAK;gBAEjD;KACO,GALH,CAKG,CACX;IACO,CAAA;GACO,CAAA,EACd,CAAA;EACH,CAAA;CAEF,CAAA,CACR,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"DropdownSelect.js","names":[],"sources":["../../../src/components/DropdownSelect/DropdownSelect.tsx"],"sourcesContent":["import {\n useRef,\n useState,\n MouseEvent as ReactMouseEvent,\n RefObject,\n} from 'react'\nimport {\n Button,\n ButtonGroup,\n ButtonGroupProps,\n ButtonProps,\n ClickAwayListener,\n Grow,\n MenuItem,\n MenuList,\n Paper,\n Popper,\n} from '@mui/material'\nimport IconSvg from '../IconSvg'\n\nexport type DropdownSelectProps = ButtonGroupProps & {\n options: string[]\n selectedIndex?: number\n setSelectedIndex?: (selectedIndex: number) => void\n onButtonClick?: (selectedIndex: number) => void\n buttonText?: string\n variant?: ButtonProps['variant']\n buttonGroupAriaLabel?: string\n anchorRef?: RefObject<HTMLDivElement | null>\n}\n// Derived from https://mui.com/material-ui/react-button-group/#split-button\n\n/**\n * Renders a button group that acts as a select group\n * @param props\n * @constructor\n */\nexport default function DropdownSelect(props: DropdownSelectProps) {\n const {\n options,\n selectedIndex,\n setSelectedIndex,\n variant = 'contained',\n buttonGroupAriaLabel,\n onButtonClick,\n buttonText,\n anchorRef: externalAnchorRef,\n ...rest\n } = props\n const [open, setOpen] = useState(false)\n const internalAnchorRef = useRef<HTMLDivElement>(null)\n const anchorRef = externalAnchorRef ?? internalAnchorRef\n\n const [selectedIndexLocal, setSelectedIndexLocal] = useState(\n selectedIndex ?? 0,\n )\n\n const handleMenuItemClick = (\n event: ReactMouseEvent<HTMLLIElement, MouseEvent>,\n index: number,\n ) => {\n if (setSelectedIndex) {\n setSelectedIndex(index)\n } else {\n setSelectedIndexLocal(index)\n }\n setOpen(false)\n }\n\n const handleToggle = () => {\n setOpen(prevOpen => !prevOpen)\n }\n\n const handleClose = (event: Event) => {\n if (anchorRef.current?.contains(event.target as HTMLElement)) {\n return\n }\n\n setOpen(false)\n }\n\n return (\n <>\n <ButtonGroup\n variant={variant}\n ref={anchorRef}\n aria-label=\"split button\"\n {...rest}\n >\n <Button\n onClick={() => {\n if (onButtonClick) {\n onButtonClick(selectedIndex ?? selectedIndexLocal)\n } else {\n handleToggle()\n }\n }}\n >\n {buttonText\n ? buttonText\n : options[selectedIndex ?? selectedIndexLocal]}\n </Button>\n <Button\n size=\"small\"\n aria-controls={open ? 'split-button-menu' : undefined}\n aria-expanded={open ? 'true' : undefined}\n aria-label={buttonGroupAriaLabel}\n aria-haspopup=\"menu\"\n onClick={handleToggle}\n sx={{ width: '36px' }}\n >\n <IconSvg icon={'expandMore'} wrap={false} />\n </Button>\n </ButtonGroup>\n <Popper\n sx={{\n zIndex: 10,\n }}\n open={open}\n placement={'bottom-start'}\n anchorEl={anchorRef.current}\n role={undefined}\n transition\n disablePortal\n >\n {({ TransitionProps, placement }) => (\n <Grow\n {...TransitionProps}\n style={{\n transformOrigin:\n placement === 'bottom' ? 'center top' : 'center bottom',\n }}\n >\n <Paper>\n <ClickAwayListener onClickAway={handleClose}>\n <MenuList id=\"split-button-menu\" autoFocusItem>\n {options.map((option, index) => (\n <MenuItem\n key={option}\n selected={index === selectedIndex}\n onClick={event => handleMenuItemClick(event, index)}\n >\n {option}\n </MenuItem>\n ))}\n </MenuList>\n </ClickAwayListener>\n </Paper>\n </Grow>\n )}\n </Popper>\n </>\n )\n}\n"],"mappings":";;;;;AAqCA,SAAwB,EAAe,GAA4B;CACjE,IAAM,EACJ,YACA,kBACA,qBACA,aAAU,aACV,yBACA,kBACA,eACA,WAAW,GACX,GAAG,MACD,GACE,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,IAAoB,EAAuB,IAAI,GAC/C,IAAY,KAAqB,GAEjC,CAAC,GAAoB,KAAyB,EAClD,KAAiB,CACnB,GAEM,KACJ,GACA,MACG;EAMH,AALI,IACF,EAAiB,CAAK,IAEtB,EAAsB,CAAK,GAE7B,EAAQ,EAAK;CACf,GAEM,UAAqB;EACzB,GAAQ,MAAY,CAAC,CAAQ;CAC/B,GAEM,KAAe,MAAiB;EAChC,EAAU,SAAS,SAAS,EAAM,MAAqB,KAI3D,EAAQ,EAAK;CACf;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACW;EACT,KAAK;EACL,cAAW;EACX,GAAI;YAJN,CAME,kBAAC,GAAD;GACE,eAAe;IACb,AAAI,IACF,EAAc,KAAiB,CAAkB,IAEjD,EAAa;GAEjB;aAEC,KAEG,EAAQ,KAAiB;EACvB,CAAA,GACR,kBAAC,GAAD;GACE,MAAK;GACL,iBAAe,IAAO,sBAAsB,KAAA;GAC5C,iBAAe,IAAO,SAAS,KAAA;GAC/B,cAAY;GACZ,iBAAc;GACd,SAAS;GACT,IAAI,EAAE,OAAO,OAAO;aAEpB,kBAAC,GAAD;IAAS,MAAM;IAAc,MAAM;GAAQ,CAAA;EACrC,CAAA,CACG;KACb,kBAAC,GAAD;EACE,IAAI,EACF,QAAQ,GACV;EACM;EACN,WAAW;EACX,UAAU,EAAU;EACpB,MAAM,KAAA;EACN,YAAA;EACA,eAAA;aAEE,EAAE,oBAAiB,mBACnB,kBAAC,GAAD;GACE,GAAI;GACJ,OAAO,EACL,iBACE,MAAc,WAAW,eAAe,gBAC5C;aAEA,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAmB,aAAa;cAC9B,kBAAC,GAAD;KAAU,IAAG;KAAoB,eAAA;eAC9B,EAAQ,KAAK,GAAQ,MACpB,kBAAC,GAAD;MAEE,UAAU,MAAU;MACpB,UAAS,MAAS,EAAoB,GAAO,CAAK;gBAEjD;KACO,GALH,CAKG,CACX;IACO,CAAA;GACO,CAAA,EACd,CAAA;EACH,CAAA;CAEF,CAAA,CACR,EAAA,CAAA;AAEN"}
@@ -1 +1 @@
1
- {"version":3,"file":"EntityTree.d.ts","sourceRoot":"","sources":["../../../../src/components/EntityFinder/tree/EntityTree.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EAGL,SAAS,EACV,MAAM,iCAAiC,CAAA;AACxC,OAAO,EACL,QAAQ,EACR,cAAc,EAKf,MAAM,OAAO,CAAA;AAId,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,EACL,kCAAkC,EAEnC,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EACL,kBAAkB,EAGnB,MAAM,mBAAmB,CAAA;AAW1B,oBAAY,WAAW;IACrB,eAAe,oBAAoB;IACnC,YAAY,iBAAiB;IAC7B,aAAa,2BAA2B;IACxC,SAAS,iBAAiB;CAC3B;AA0BD;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAGxD,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,mBAAmB,CAAA;IACrC,gBAAgB,EAAE,mBAAmB,CAAA;IACrC,mBAAmB,EAAE,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAClE,YAAY,EAAE,OAAO,CAAA;IACrB,gBAAgB,EAAE,sBAAsB,CAAA;IACxC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;IAC3B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAC7C,2BAA2B,CAAC,EAAE,CAC5B,aAAa,EAAE,kCAAkC,KAC9C,IAAI,CAAA;IACT,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAA;IACtD,mFAAmF;IACnF,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,YAAY,EAAE,kBAAkB,CAAA;IAChC,6CAA6C;IAC7C,eAAe,EAAE,UAAU,EAAE,CAAA;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CAsVhD"}
1
+ {"version":3,"file":"EntityTree.d.ts","sourceRoot":"","sources":["../../../../src/components/EntityFinder/tree/EntityTree.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EAGL,SAAS,EACV,MAAM,iCAAiC,CAAA;AACxC,OAAO,EACL,QAAQ,EACR,cAAc,EAKf,MAAM,OAAO,CAAA;AAId,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,EACL,kCAAkC,EAEnC,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EACL,kBAAkB,EAGnB,MAAM,mBAAmB,CAAA;AAW1B,oBAAY,WAAW;IACrB,eAAe,oBAAoB;IACnC,YAAY,iBAAiB;IAC7B,aAAa,2BAA2B;IACxC,SAAS,iBAAiB;CAC3B;AA0BD;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAGxD,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,mBAAmB,CAAA;IACrC,gBAAgB,EAAE,mBAAmB,CAAA;IACrC,mBAAmB,EAAE,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAClE,YAAY,EAAE,OAAO,CAAA;IACrB,gBAAgB,EAAE,sBAAsB,CAAA;IACxC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;IAC3B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAC7C,2BAA2B,CAAC,EAAE,CAC5B,aAAa,EAAE,kCAAkC,KAC9C,IAAI,CAAA;IACT,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAA;IACtD,mFAAmF;IACnF,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,YAAY,EAAE,kBAAkB,CAAA;IAChC,6CAA6C;IAC7C,eAAe,EAAE,UAAU,EAAE,CAAA;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CAkVhD"}
@@ -64,7 +64,7 @@ function S(S) {
64
64
  refetchInterval: Infinity,
65
65
  throwOnError: !0
66
66
  }), { data: Y } = a(T, {
67
- enabled: !!(w && T && T.match(n)),
67
+ enabled: !!(w && T?.match(n)),
68
68
  refetchInterval: Infinity,
69
69
  throwOnError: !0
70
70
  }), { data: X, isLoading: Z } = ee(w, void 0, {
@@ -1 +1 @@
1
- {"version":3,"file":"EntityTree.js","names":[],"sources":["../../../../src/components/EntityFinder/tree/EntityTree.tsx"],"sourcesContent":["import {\n useGetEntityHeader,\n useGetEntityPath,\n useGetFavorites,\n useGetProjectsInfinite,\n} from '@/synapse-queries'\nimport useGetEntityBundle from '@/synapse-queries/entity/useEntityBundle'\nimport { convertToEntityType } from '@/utils/functions/EntityTypeUtils'\nimport { SYNAPSE_ENTITY_ID_REGEX } from '@/utils/functions/RegularExpressions'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ALL_ENTITY_BUNDLE_FIELDS,\n EntityPath,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport {\n Dispatch,\n SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport DropdownSelect from '../../DropdownSelect/DropdownSelect'\nimport { SynapseSpinner } from '../../LoadingScreen/LoadingScreen'\nimport { displayToast } from '../../ToastMessage/ToastMessage'\nimport { BreadcrumbItem } from '../Breadcrumbs'\nimport { toEntityHeader } from '../details/configurations/ProjectListDetails'\nimport {\n EntityDetailsListDataConfiguration,\n EntityDetailsListDataConfigurationType,\n} from '../details/EntityDetailsList'\nimport { EntityFinderHeader } from '../EntityFinderHeader'\nimport { EntitySelectionMapType } from '../useEntitySelection'\nimport {\n EntityTreeNodeType,\n RootNodeConfiguration,\n VirtualizedTree,\n} from './VirtualizedTree'\n\nconst isEntityIdInPath = (entityId: string, path: EntityPath): boolean => {\n for (const eh of path.path) {\n if (entityId === eh.id) {\n return true\n }\n }\n return false\n}\n\nexport enum FinderScope {\n CURRENT_PROJECT = 'Current Project',\n ALL_PROJECTS = 'All Projects',\n CREATED_BY_ME = 'Projects Created By Me',\n FAVORITES = 'My Favorites',\n}\n\nfunction getScopeOptionDefaultContainer(\n scope: FinderScope,\n): EntityTreeContainer {\n switch (scope) {\n case FinderScope.FAVORITES:\n return 'root'\n case FinderScope.CURRENT_PROJECT:\n case FinderScope.ALL_PROJECTS:\n case FinderScope.CREATED_BY_ME:\n return null\n }\n}\n\nfunction getScopeOptionNodeName(scope: FinderScope): string {\n switch (scope) {\n case FinderScope.CURRENT_PROJECT:\n case FinderScope.ALL_PROJECTS:\n case FinderScope.CREATED_BY_ME:\n return 'Projects'\n case FinderScope.FAVORITES:\n return 'Favorites'\n }\n}\n\n/**\n * Indicates which container is selected when the tree is used to control another component. If 'root', then the top-level entities\n * should be shown in the other component. If a synID, then that entity's children should be shown in the other component. If null,\n * then a selection has not been made.\n */\nexport type EntityTreeContainer = string | 'root' | null\n\n// if the first item is selected (matching the dropdown), then output a configuration. otherwise, output a synId\nexport type EntityTreeProps = {\n initialScope?: FinderScope\n /** To show the current project, projectId must be defined */\n projectId?: string\n initialContainer: EntityTreeContainer\n currentContainer: EntityTreeContainer\n setCurrentContainer: Dispatch<SetStateAction<EntityTreeContainer>>\n showDropdown: boolean\n selectedEntities: EntitySelectionMapType\n visibleTypes?: EntityType[]\n toggleSelection?: (entity: Reference) => void\n setDetailsViewConfiguration?: (\n configuration: EntityDetailsListDataConfiguration,\n ) => void\n setBreadcrumbItems?: (items: BreadcrumbItem[]) => void\n /** Determines whether to show the root node corresponding to the selected scope */\n showScopeAsRootNode?: boolean\n treeNodeType: EntityTreeNodeType\n /** The entity types that may be selected. */\n selectableTypes: EntityType[]\n hideScopeSelector?: boolean\n}\n\n/**\n * The TreeView displays a user's entities hierarchically, allowing a user to quickly dive into an entity tree.\n *\n * The tree view currently can only be used to drive a DetailsView using the `setDetailsViewConfiguration` property.\n */\nexport function EntityTree(props: EntityTreeProps) {\n const {\n initialScope = FinderScope.CURRENT_PROJECT,\n projectId,\n initialContainer = null,\n currentContainer,\n setCurrentContainer,\n visibleTypes = [EntityType.project, EntityType.folder],\n toggleSelection,\n selectedEntities,\n setDetailsViewConfiguration,\n setBreadcrumbItems,\n showScopeAsRootNode = true,\n treeNodeType,\n selectableTypes,\n hideScopeSelector = false,\n } = props\n\n const DEFAULT_CONFIGURATION: EntityDetailsListDataConfiguration = {\n type: EntityDetailsListDataConfigurationType.PROMPT,\n }\n\n const [scope, setScope] = useState(initialScope)\n\n useEffect(() => {\n if (setDetailsViewConfiguration) {\n setDetailsViewConfiguration(DEFAULT_CONFIGURATION)\n }\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const setSelectedId = useCallback(\n (entityId: string) => {\n if (toggleSelection) {\n toggleSelection({ targetId: entityId })\n }\n setCurrentContainer(entityId)\n },\n [setCurrentContainer, toggleSelection],\n )\n\n // For these scopes, use the `useGetProjectsInfinite` hook\n const useProjectData =\n scope === FinderScope.ALL_PROJECTS || scope === FinderScope.CREATED_BY_ME\n\n const {\n data: projectData,\n fetchNextPage: fetchNextPageProjects,\n hasNextPage: hasNextPageProjects,\n isLoading: isLoadingProjects,\n } = useGetProjectsInfinite(\n scope === FinderScope.CREATED_BY_ME\n ? { filter: 'CREATED', sort: 'PROJECT_NAME', sortDirection: 'ASC' }\n : { sort: 'PROJECT_NAME', sortDirection: 'ASC' },\n {\n enabled: useProjectData,\n // Don't refetch the projects. Updating the entity headers will drop all the children that VirtualizedTree has fetched\n refetchInterval: Infinity,\n },\n )\n\n const { data: currentContainerBundle, isSuccess: isSuccessBundle } =\n useGetEntityBundle(currentContainer!, undefined, ALL_ENTITY_BUNDLE_FIELDS, {\n enabled: !!currentContainer && currentContainer !== 'root',\n throwOnError: true,\n })\n\n const { data: favorites, isLoading: isLoadingFavorites } = useGetFavorites(\n 'NAME',\n 'ASC',\n {\n select: data =>\n data.filter(eh => visibleTypes.includes(convertToEntityType(eh.type))),\n // Don't refetch the projects. Updating the entity headers will drop all the children that VirtualizedTree has fetched\n refetchInterval: Infinity,\n throwOnError: true,\n },\n )\n\n const { data: initialContainerPath } = useGetEntityPath(initialContainer!, {\n enabled: !!(\n projectId &&\n initialContainer &&\n initialContainer.match(SYNAPSE_ENTITY_ID_REGEX)\n ),\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n const { data: projectHeader, isLoading: isLoadingProjectHeader } =\n useGetEntityHeader(projectId, undefined, {\n enabled: !!(projectId ?? initialContainerPath?.path[1]?.id),\n refetchInterval: Infinity,\n })\n\n useEffect(() => {\n if (\n FinderScope.CURRENT_PROJECT === scope &&\n projectId &&\n !isLoadingProjectHeader &&\n !projectHeader\n ) {\n // The header wasn't returned, so the user doesn't have access to the current project\n // Let's change the scope to something else\n displayToast(\n `You don't have access to the current project (${projectId}).`,\n 'warning',\n )\n setScope(FinderScope.CREATED_BY_ME)\n }\n }, [isLoadingProjectHeader, projectHeader, projectId, scope])\n\n // Populates the first level of entities in the tree view\n const {\n topLevelEntities,\n isLoading,\n }: {\n topLevelEntities: Pick<EntityFinderHeader, 'name' | 'id' | 'type'>[]\n isLoading: boolean\n } = useMemo(() => {\n let topLevelEntities: Pick<EntityFinderHeader, 'name' | 'id' | 'type'>[] =\n []\n let isLoading: boolean = false\n switch (scope) {\n case FinderScope.ALL_PROJECTS:\n case FinderScope.CREATED_BY_ME:\n if (projectData) {\n topLevelEntities = projectData.pages\n .flatMap(page => page.results)\n .map(toEntityHeader)\n }\n isLoading = isLoadingProjects\n break\n case FinderScope.FAVORITES: {\n topLevelEntities = favorites ?? []\n isLoading = isLoadingFavorites\n break\n }\n case FinderScope.CURRENT_PROJECT:\n if (projectHeader) {\n // use projectHeader as topLevelEntities\n topLevelEntities = [projectHeader]\n isLoading = isLoadingProjectHeader\n }\n break\n default:\n throw new Error('No scope selected')\n }\n return { topLevelEntities, isLoading }\n }, [\n favorites,\n isLoadingFavorites,\n isLoadingProjectHeader,\n isLoadingProjects,\n projectData,\n projectHeader,\n scope,\n ])\n\n // Creates the configuration for the details view and invokes the callback\n useEffect(() => {\n if (setDetailsViewConfiguration || setBreadcrumbItems) {\n let detailsViewConfig: EntityDetailsListDataConfiguration\n let breadcrumbItems: BreadcrumbItem[] = []\n if (currentContainer === null) {\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.PROMPT,\n }\n breadcrumbItems = []\n } else if (currentContainer === 'root') {\n switch (scope) {\n case FinderScope.ALL_PROJECTS:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.USER_PROJECTS,\n }\n break\n case FinderScope.CREATED_BY_ME:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.USER_PROJECTS,\n getProjectParams: {\n filter: 'CREATED',\n },\n }\n break\n case FinderScope.CURRENT_PROJECT:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.HEADER_LIST,\n headerList: topLevelEntities,\n }\n break\n case FinderScope.FAVORITES:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.USER_FAVORITES,\n }\n break\n }\n breadcrumbItems = [\n {\n name: scope,\n isCurrent: true,\n action: () => {\n setCurrentContainer('root')\n },\n },\n ]\n } else {\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.PARENT_CONTAINER,\n parentContainerId: currentContainer,\n }\n if (currentContainerBundle) {\n breadcrumbItems = [\n {\n name: scope,\n isCurrent: false,\n action: () => {\n setCurrentContainer('root')\n },\n },\n ...currentContainerBundle.path.path\n .slice(1) // Remove the root entity, syn4489\n .map(entity => {\n return {\n name: entity.name ?? entity.id,\n isCurrent: entity.id === currentContainer,\n action: () => {\n setCurrentContainer(entity.id)\n },\n }\n }),\n ]\n }\n }\n if (setDetailsViewConfiguration) {\n setDetailsViewConfiguration(detailsViewConfig)\n }\n if (setBreadcrumbItems) {\n setBreadcrumbItems(breadcrumbItems)\n }\n }\n }, [\n scope,\n currentContainer,\n topLevelEntities,\n setDetailsViewConfiguration,\n setBreadcrumbItems,\n currentContainerBundle,\n isSuccessBundle,\n setCurrentContainer,\n ])\n\n const rootNodeConfiguration: RootNodeConfiguration = useMemo(\n () => ({\n show: showScopeAsRootNode,\n nodeText: getScopeOptionNodeName(scope),\n children: topLevelEntities,\n fetchNextPage: async () => {\n await fetchNextPageProjects()\n },\n hasNextPage: useProjectData && hasNextPageProjects && !isLoadingProjects,\n }),\n [\n showScopeAsRootNode,\n scope,\n topLevelEntities,\n useProjectData,\n hasNextPageProjects,\n isLoadingProjects,\n fetchNextPageProjects,\n ],\n )\n\n const shouldAutoExpand = useCallback(\n (entityId: string) => {\n if (entityId === 'root') {\n return true\n } else {\n return !!(\n scope === FinderScope.CURRENT_PROJECT &&\n initialContainerPath &&\n isEntityIdInPath(entityId, initialContainerPath)\n )\n }\n },\n [scope, initialContainerPath],\n )\n\n const filteredOptions = Object.values(FinderScope).filter(\n scopeOption =>\n !(scopeOption === FinderScope.CURRENT_PROJECT && projectId == null),\n )\n\n const selectedIndex = filteredOptions.indexOf(scope)\n\n return (\n <div\n className={`TreeView ${\n treeNodeType === EntityTreeNodeType.SINGLE_PANE\n ? 'SelectTree'\n : 'BrowseTree'\n }`}\n >\n {!hideScopeSelector && (\n <div className=\"Header\" onClick={e => e.stopPropagation()}>\n <DropdownSelect\n variant={'outlined'}\n options={filteredOptions}\n selectedIndex={selectedIndex}\n setSelectedIndex={index => {\n const selectedScope = filteredOptions[index]\n if (scope !== selectedScope) {\n setScope(selectedScope)\n setCurrentContainer(\n getScopeOptionDefaultContainer(selectedScope),\n )\n }\n }}\n size=\"small\"\n fullWidth\n />\n </div>\n )}\n {isLoading ? (\n <div className=\"Placeholder\">\n <SynapseSpinner size={30} />\n </div>\n ) : (\n <div className=\"Tree\" role=\"tree\">\n <VirtualizedTree\n selected={selectedEntities}\n visibleTypes={visibleTypes}\n autoExpand={shouldAutoExpand}\n rootNodeConfiguration={rootNodeConfiguration}\n treeNodeType={treeNodeType}\n selectableTypes={selectableTypes}\n currentContainer={currentContainer}\n setSelectedId={setSelectedId}\n />\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityTree.js","names":[],"sources":["../../../../src/components/EntityFinder/tree/EntityTree.tsx"],"sourcesContent":["import {\n useGetEntityHeader,\n useGetEntityPath,\n useGetFavorites,\n useGetProjectsInfinite,\n} from '@/synapse-queries'\nimport useGetEntityBundle from '@/synapse-queries/entity/useEntityBundle'\nimport { convertToEntityType } from '@/utils/functions/EntityTypeUtils'\nimport { SYNAPSE_ENTITY_ID_REGEX } from '@/utils/functions/RegularExpressions'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ALL_ENTITY_BUNDLE_FIELDS,\n EntityPath,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport {\n Dispatch,\n SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport DropdownSelect from '../../DropdownSelect/DropdownSelect'\nimport { SynapseSpinner } from '../../LoadingScreen/LoadingScreen'\nimport { displayToast } from '../../ToastMessage/ToastMessage'\nimport { BreadcrumbItem } from '../Breadcrumbs'\nimport { toEntityHeader } from '../details/configurations/ProjectListDetails'\nimport {\n EntityDetailsListDataConfiguration,\n EntityDetailsListDataConfigurationType,\n} from '../details/EntityDetailsList'\nimport { EntityFinderHeader } from '../EntityFinderHeader'\nimport { EntitySelectionMapType } from '../useEntitySelection'\nimport {\n EntityTreeNodeType,\n RootNodeConfiguration,\n VirtualizedTree,\n} from './VirtualizedTree'\n\nconst isEntityIdInPath = (entityId: string, path: EntityPath): boolean => {\n for (const eh of path.path) {\n if (entityId === eh.id) {\n return true\n }\n }\n return false\n}\n\nexport enum FinderScope {\n CURRENT_PROJECT = 'Current Project',\n ALL_PROJECTS = 'All Projects',\n CREATED_BY_ME = 'Projects Created By Me',\n FAVORITES = 'My Favorites',\n}\n\nfunction getScopeOptionDefaultContainer(\n scope: FinderScope,\n): EntityTreeContainer {\n switch (scope) {\n case FinderScope.FAVORITES:\n return 'root'\n case FinderScope.CURRENT_PROJECT:\n case FinderScope.ALL_PROJECTS:\n case FinderScope.CREATED_BY_ME:\n return null\n }\n}\n\nfunction getScopeOptionNodeName(scope: FinderScope): string {\n switch (scope) {\n case FinderScope.CURRENT_PROJECT:\n case FinderScope.ALL_PROJECTS:\n case FinderScope.CREATED_BY_ME:\n return 'Projects'\n case FinderScope.FAVORITES:\n return 'Favorites'\n }\n}\n\n/**\n * Indicates which container is selected when the tree is used to control another component. If 'root', then the top-level entities\n * should be shown in the other component. If a synID, then that entity's children should be shown in the other component. If null,\n * then a selection has not been made.\n */\nexport type EntityTreeContainer = string | 'root' | null\n\n// if the first item is selected (matching the dropdown), then output a configuration. otherwise, output a synId\nexport type EntityTreeProps = {\n initialScope?: FinderScope\n /** To show the current project, projectId must be defined */\n projectId?: string\n initialContainer: EntityTreeContainer\n currentContainer: EntityTreeContainer\n setCurrentContainer: Dispatch<SetStateAction<EntityTreeContainer>>\n showDropdown: boolean\n selectedEntities: EntitySelectionMapType\n visibleTypes?: EntityType[]\n toggleSelection?: (entity: Reference) => void\n setDetailsViewConfiguration?: (\n configuration: EntityDetailsListDataConfiguration,\n ) => void\n setBreadcrumbItems?: (items: BreadcrumbItem[]) => void\n /** Determines whether to show the root node corresponding to the selected scope */\n showScopeAsRootNode?: boolean\n treeNodeType: EntityTreeNodeType\n /** The entity types that may be selected. */\n selectableTypes: EntityType[]\n hideScopeSelector?: boolean\n}\n\n/**\n * The TreeView displays a user's entities hierarchically, allowing a user to quickly dive into an entity tree.\n *\n * The tree view currently can only be used to drive a DetailsView using the `setDetailsViewConfiguration` property.\n */\nexport function EntityTree(props: EntityTreeProps) {\n const {\n initialScope = FinderScope.CURRENT_PROJECT,\n projectId,\n initialContainer = null,\n currentContainer,\n setCurrentContainer,\n visibleTypes = [EntityType.project, EntityType.folder],\n toggleSelection,\n selectedEntities,\n setDetailsViewConfiguration,\n setBreadcrumbItems,\n showScopeAsRootNode = true,\n treeNodeType,\n selectableTypes,\n hideScopeSelector = false,\n } = props\n\n const DEFAULT_CONFIGURATION: EntityDetailsListDataConfiguration = {\n type: EntityDetailsListDataConfigurationType.PROMPT,\n }\n\n const [scope, setScope] = useState(initialScope)\n\n useEffect(() => {\n if (setDetailsViewConfiguration) {\n setDetailsViewConfiguration(DEFAULT_CONFIGURATION)\n }\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const setSelectedId = useCallback(\n (entityId: string) => {\n if (toggleSelection) {\n toggleSelection({ targetId: entityId })\n }\n setCurrentContainer(entityId)\n },\n [setCurrentContainer, toggleSelection],\n )\n\n // For these scopes, use the `useGetProjectsInfinite` hook\n const useProjectData =\n scope === FinderScope.ALL_PROJECTS || scope === FinderScope.CREATED_BY_ME\n\n const {\n data: projectData,\n fetchNextPage: fetchNextPageProjects,\n hasNextPage: hasNextPageProjects,\n isLoading: isLoadingProjects,\n } = useGetProjectsInfinite(\n scope === FinderScope.CREATED_BY_ME\n ? { filter: 'CREATED', sort: 'PROJECT_NAME', sortDirection: 'ASC' }\n : { sort: 'PROJECT_NAME', sortDirection: 'ASC' },\n {\n enabled: useProjectData,\n // Don't refetch the projects. Updating the entity headers will drop all the children that VirtualizedTree has fetched\n refetchInterval: Infinity,\n },\n )\n\n const { data: currentContainerBundle, isSuccess: isSuccessBundle } =\n useGetEntityBundle(currentContainer!, undefined, ALL_ENTITY_BUNDLE_FIELDS, {\n enabled: !!currentContainer && currentContainer !== 'root',\n throwOnError: true,\n })\n\n const { data: favorites, isLoading: isLoadingFavorites } = useGetFavorites(\n 'NAME',\n 'ASC',\n {\n select: data =>\n data.filter(eh => visibleTypes.includes(convertToEntityType(eh.type))),\n // Don't refetch the projects. Updating the entity headers will drop all the children that VirtualizedTree has fetched\n refetchInterval: Infinity,\n throwOnError: true,\n },\n )\n\n const { data: initialContainerPath } = useGetEntityPath(initialContainer!, {\n enabled: !!(projectId && initialContainer?.match(SYNAPSE_ENTITY_ID_REGEX)),\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n const { data: projectHeader, isLoading: isLoadingProjectHeader } =\n useGetEntityHeader(projectId, undefined, {\n enabled: !!(projectId ?? initialContainerPath?.path[1]?.id),\n refetchInterval: Infinity,\n })\n\n useEffect(() => {\n if (\n FinderScope.CURRENT_PROJECT === scope &&\n projectId &&\n !isLoadingProjectHeader &&\n !projectHeader\n ) {\n // The header wasn't returned, so the user doesn't have access to the current project\n // Let's change the scope to something else\n displayToast(\n `You don't have access to the current project (${projectId}).`,\n 'warning',\n )\n setScope(FinderScope.CREATED_BY_ME)\n }\n }, [isLoadingProjectHeader, projectHeader, projectId, scope])\n\n // Populates the first level of entities in the tree view\n const {\n topLevelEntities,\n isLoading,\n }: {\n topLevelEntities: Pick<EntityFinderHeader, 'name' | 'id' | 'type'>[]\n isLoading: boolean\n } = useMemo(() => {\n let topLevelEntities: Pick<EntityFinderHeader, 'name' | 'id' | 'type'>[] =\n []\n let isLoading: boolean = false\n switch (scope) {\n case FinderScope.ALL_PROJECTS:\n case FinderScope.CREATED_BY_ME:\n if (projectData) {\n topLevelEntities = projectData.pages\n .flatMap(page => page.results)\n .map(toEntityHeader)\n }\n isLoading = isLoadingProjects\n break\n case FinderScope.FAVORITES: {\n topLevelEntities = favorites ?? []\n isLoading = isLoadingFavorites\n break\n }\n case FinderScope.CURRENT_PROJECT:\n if (projectHeader) {\n // use projectHeader as topLevelEntities\n topLevelEntities = [projectHeader]\n isLoading = isLoadingProjectHeader\n }\n break\n default:\n throw new Error('No scope selected')\n }\n return { topLevelEntities, isLoading }\n }, [\n favorites,\n isLoadingFavorites,\n isLoadingProjectHeader,\n isLoadingProjects,\n projectData,\n projectHeader,\n scope,\n ])\n\n // Creates the configuration for the details view and invokes the callback\n useEffect(() => {\n if (setDetailsViewConfiguration || setBreadcrumbItems) {\n let detailsViewConfig: EntityDetailsListDataConfiguration\n let breadcrumbItems: BreadcrumbItem[] = []\n if (currentContainer === null) {\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.PROMPT,\n }\n breadcrumbItems = []\n } else if (currentContainer === 'root') {\n switch (scope) {\n case FinderScope.ALL_PROJECTS:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.USER_PROJECTS,\n }\n break\n case FinderScope.CREATED_BY_ME:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.USER_PROJECTS,\n getProjectParams: {\n filter: 'CREATED',\n },\n }\n break\n case FinderScope.CURRENT_PROJECT:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.HEADER_LIST,\n headerList: topLevelEntities,\n }\n break\n case FinderScope.FAVORITES:\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.USER_FAVORITES,\n }\n break\n }\n breadcrumbItems = [\n {\n name: scope,\n isCurrent: true,\n action: () => {\n setCurrentContainer('root')\n },\n },\n ]\n } else {\n detailsViewConfig = {\n type: EntityDetailsListDataConfigurationType.PARENT_CONTAINER,\n parentContainerId: currentContainer,\n }\n if (currentContainerBundle) {\n breadcrumbItems = [\n {\n name: scope,\n isCurrent: false,\n action: () => {\n setCurrentContainer('root')\n },\n },\n ...currentContainerBundle.path.path\n .slice(1) // Remove the root entity, syn4489\n .map(entity => {\n return {\n name: entity.name ?? entity.id,\n isCurrent: entity.id === currentContainer,\n action: () => {\n setCurrentContainer(entity.id)\n },\n }\n }),\n ]\n }\n }\n if (setDetailsViewConfiguration) {\n setDetailsViewConfiguration(detailsViewConfig)\n }\n if (setBreadcrumbItems) {\n setBreadcrumbItems(breadcrumbItems)\n }\n }\n }, [\n scope,\n currentContainer,\n topLevelEntities,\n setDetailsViewConfiguration,\n setBreadcrumbItems,\n currentContainerBundle,\n isSuccessBundle,\n setCurrentContainer,\n ])\n\n const rootNodeConfiguration: RootNodeConfiguration = useMemo(\n () => ({\n show: showScopeAsRootNode,\n nodeText: getScopeOptionNodeName(scope),\n children: topLevelEntities,\n fetchNextPage: async () => {\n await fetchNextPageProjects()\n },\n hasNextPage: useProjectData && hasNextPageProjects && !isLoadingProjects,\n }),\n [\n showScopeAsRootNode,\n scope,\n topLevelEntities,\n useProjectData,\n hasNextPageProjects,\n isLoadingProjects,\n fetchNextPageProjects,\n ],\n )\n\n const shouldAutoExpand = useCallback(\n (entityId: string) => {\n if (entityId === 'root') {\n return true\n } else {\n return !!(\n scope === FinderScope.CURRENT_PROJECT &&\n initialContainerPath &&\n isEntityIdInPath(entityId, initialContainerPath)\n )\n }\n },\n [scope, initialContainerPath],\n )\n\n const filteredOptions = Object.values(FinderScope).filter(\n scopeOption =>\n !(scopeOption === FinderScope.CURRENT_PROJECT && projectId == null),\n )\n\n const selectedIndex = filteredOptions.indexOf(scope)\n\n return (\n <div\n className={`TreeView ${\n treeNodeType === EntityTreeNodeType.SINGLE_PANE\n ? 'SelectTree'\n : 'BrowseTree'\n }`}\n >\n {!hideScopeSelector && (\n <div className=\"Header\" onClick={e => e.stopPropagation()}>\n <DropdownSelect\n variant={'outlined'}\n options={filteredOptions}\n selectedIndex={selectedIndex}\n setSelectedIndex={index => {\n const selectedScope = filteredOptions[index]\n if (scope !== selectedScope) {\n setScope(selectedScope)\n setCurrentContainer(\n getScopeOptionDefaultContainer(selectedScope),\n )\n }\n }}\n size=\"small\"\n fullWidth\n />\n </div>\n )}\n {isLoading ? (\n <div className=\"Placeholder\">\n <SynapseSpinner size={30} />\n </div>\n ) : (\n <div className=\"Tree\" role=\"tree\">\n <VirtualizedTree\n selected={selectedEntities}\n visibleTypes={visibleTypes}\n autoExpand={shouldAutoExpand}\n rootNodeConfiguration={rootNodeConfiguration}\n treeNodeType={treeNodeType}\n selectableTypes={selectableTypes}\n currentContainer={currentContainer}\n setSelectedId={setSelectedId}\n />\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
@@ -39,7 +39,7 @@ function M(e) {
39
39
  return k(e) ? !1 : j(e) ? e.hasNextPage : e.children == null || e.childrenNextPageToken != null;
40
40
  }
41
41
  function N(e) {
42
- return k(e) ? !0 : j(e) ? !1 : !n(t(e)) || e.children != null && e.children.length === 0;
42
+ return k(e) ? !0 : j(e) ? !1 : !n(t(e)) || e.children?.length === 0;
43
43
  }
44
44
  function P(e) {
45
45
  return k(e) ? !1 : j(e) ? e.children.length > 0 || e.hasNextPage : !N(e);
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualizedTree.js","names":[],"sources":["../../../../src/components/EntityFinder/tree/VirtualizedTree.tsx"],"sourcesContent":["import React from 'react'\nimport { getEntityChildren } from '@/synapse-client'\nimport { useSynapseContext } from '@/utils'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n getEntityTypeFromHeader,\n isContainerType,\n} from '@/utils/functions/EntityTypeUtils'\nimport { Writable } from '@/utils/types/Writable'\nimport { ChevronRight, ExpandMore } from '@mui/icons-material'\nimport { Skeleton, Tooltip, Typography } from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport { EntityChildrenRequest } from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport dayjs from 'dayjs'\nimport { cloneDeep } from 'lodash-es'\nimport { ReactNode, useCallback, useEffect, useRef, useState } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport AutoSizer from 'react-virtualized-auto-sizer'\nimport {\n TreeWalker,\n TreeWalkerValue,\n VariableSizeNodeData,\n VariableSizeNodePublicState,\n VariableSizeTree,\n} from 'react-vtree'\nimport { NodeComponentProps } from 'react-vtree/dist/es/Tree'\nimport { EntityBadgeIcons } from '../../EntityBadgeIcons'\nimport { EntityTypeIcon } from '../../EntityIcon'\nimport { SynapseSpinner } from '../../LoadingScreen/LoadingScreen'\nimport { UserBadge } from '../../UserCard/UserBadge'\nimport { EntityFinderHeader } from '../EntityFinderHeader'\nimport { EntitySelectionMapType } from '../useEntitySelection'\n\nexport enum EntityTreeNodeType {\n /** The tree component's appearance and interactions will facilitate selection. Nodes will be larger and styles will indicate primary selection */\n SINGLE_PANE,\n /** The tree component's appearance and interactions will facilitate browsing. Nodes will be smaller and styles will indicate secondary selection */\n DUAL_PANE,\n}\n\ntype NodeChildren = Readonly<{\n /** The node's children. If undefined, then children have not been fetched. */\n children?: EntityHeaderNode[]\n /** The token used to fetch the next page of children for this entity. If this property is nullish and children is defined, then all children have been fetched. */\n childrenNextPageToken?: string | null\n}>\n\nexport type EntityHeaderNode = (\n | EntityFinderHeader\n // Only will have a subset of fields if the node is fetched via the entity path:\n | Pick<EntityFinderHeader, 'id' | 'name' | 'type'>\n) &\n NodeChildren\ntype PaginationNode = { __paginationNode: true }\n\ntype TreeNode = EntityHeaderNode | RootNodeConfiguration | PaginationNode\n\nfunction getTreeNodeType(\n node: TreeNode,\n): 'entityHeader' | 'rootNodeConfiguration' | 'pagination' {\n if ('__paginationNode' in node) {\n return 'pagination'\n }\n return 'id' in node ? 'entityHeader' : 'rootNodeConfiguration'\n}\n\nfunction isPaginationNode(node: TreeNode): node is PaginationNode {\n return getTreeNodeType(node) === 'pagination'\n}\n\nfunction isEntityHeaderNode(node: TreeNode): node is EntityHeaderNode {\n return getTreeNodeType(node) === 'entityHeader'\n}\n\nfunction isRootNodeConfiguration(\n node: TreeNode,\n): node is RootNodeConfiguration {\n return getTreeNodeType(node) === 'rootNodeConfiguration'\n}\n\nfunction hasMoreChildren(node: TreeNode) {\n if (isPaginationNode(node)) {\n return false\n } else if (isRootNodeConfiguration(node)) {\n return node.hasNextPage\n }\n\n return node.children == null || node.childrenNextPageToken != null\n}\n\nfunction isLeafNode(node: TreeNode) {\n if (isPaginationNode(node)) {\n return true\n } else if (isRootNodeConfiguration(node)) {\n return false\n } else {\n return (\n // Entity is not a container\n !isContainerType(getEntityTypeFromHeader(node)) ||\n // OR Children have been fetched (nonnull) and there are 0 children\n (node.children != null && node.children.length === 0)\n )\n }\n}\n\nfunction maybeHasChildren(\n node: TreeNode,\n): node is RootNodeConfiguration | EntityHeaderNode {\n if (isPaginationNode(node)) {\n return false\n } else if (isRootNodeConfiguration(node)) {\n return node.children.length > 0 || node.hasNextPage\n } else {\n return !isLeafNode(node)\n }\n}\n\nexport type TreeData = VariableSizeNodeData &\n Readonly<{\n node: TreeNode\n getNextPageOfChildren: () => Promise<void>\n isLeaf: boolean\n nestingLevel: number\n setSelectedId: (entityId: string) => void\n treeNodeType: EntityTreeNodeType\n isSelected: boolean\n isDisabled: boolean\n }>\n\ntype NodeMeta = Readonly<{\n nestingLevel: number\n node: TreeNode\n}>\n\nexport type RootNodeConfiguration = {\n show: boolean\n nodeText: string\n children: EntityHeaderNode[]\n /** If undefined, no more entities to fetch */\n fetchNextPage: () => Promise<void>\n hasNextPage: boolean\n}\n\n/**\n * Converts a TreeNode and related data into a TreeWalkerValue that react-vtree can use to render the tree.\n * Exported for testing purposes only.\n * @param config\n * @returns\n */\nexport const getNodeData = (config: {\n node: TreeNode\n nestingLevel: number\n getNextPageOfChildren: () => Promise<void>\n setSelectedId: (entityId: string) => void\n treeNodeType: EntityTreeNodeType\n selected: EntitySelectionMapType\n selectableTypes: EntityType[]\n autoExpand: (entityId: string) => boolean\n defaultHeight: number\n currentContainer?: string | 'root' | null\n}): TreeWalkerValue<TreeData, NodeMeta> => {\n const {\n node,\n nestingLevel,\n getNextPageOfChildren,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n defaultHeight,\n currentContainer,\n } = config\n\n if (isPaginationNode(node)) {\n throw new Error('Cannot create data for a pagination node')\n }\n\n const id = isRootNodeConfiguration(node) ? 'root' : node.id\n\n const isSelected =\n treeNodeType === EntityTreeNodeType.SINGLE_PANE\n ? selected.has(id)\n : currentContainer === id\n const isDisabled =\n !isRootNodeConfiguration(node) &&\n !selectableTypes.includes(getEntityTypeFromHeader(node))\n\n const isOpenByDefault = autoExpand(id)\n /*\n * If the node is open by default and we haven't fetched its children,\n * fetch the first page (otherwise we won't fetch unless re-toggled)\n */\n if (isOpenByDefault && node.children == null && hasMoreChildren(node)) {\n getNextPageOfChildren()\n }\n\n return {\n data: {\n node,\n getNextPageOfChildren,\n id: id,\n isLeaf: isLeafNode(node),\n isOpenByDefault: isOpenByDefault,\n nestingLevel,\n setSelectedId,\n treeNodeType,\n isSelected,\n isDisabled,\n defaultHeight,\n },\n nestingLevel,\n node,\n }\n}\n\n/**\n * Node component for the react-vtree virtualized tree. Exported only for testing purposes\n */\nexport function Node(\n props: NodeComponentProps<TreeData, VariableSizeNodePublicState<TreeData>>,\n) {\n const {\n data: {\n node,\n getNextPageOfChildren,\n isLeaf,\n id,\n nestingLevel,\n setSelectedId,\n treeNodeType,\n isSelected,\n isDisabled,\n },\n isOpen,\n style,\n setOpen,\n } = props\n\n const [isLoading, setLoading] = useState(false)\n\n const nodeText = isEntityHeaderNode(node) ? (\n <span>{node.name}</span>\n ) : isRootNodeConfiguration(node) ? (\n <span>{node.nodeText}</span>\n ) : (\n // Pagination node\n <Skeleton width={100} />\n )\n\n // We only use this for pagination nodes. If the pagination node comes into view, then immediately call `getNextPageOfChildren`\n const { ref, inView } = useInView()\n\n useEffect(() => {\n if (isPaginationNode(node) && inView) {\n getNextPageOfChildren()\n }\n }, [node, inView, getNextPageOfChildren])\n\n const toggleExpand = useCallback(async () => {\n if (hasMoreChildren(node)) {\n setLoading(true)\n await getNextPageOfChildren()\n await setOpen(!isOpen)\n setLoading(false)\n } else {\n await setOpen(!isOpen)\n }\n }, [getNextPageOfChildren, node, isOpen, setOpen])\n\n /**\n * If in the dual-pane view, expand a node when it becomes selected\n */\n useEffect(() => {\n if (\n treeNodeType === EntityTreeNodeType.DUAL_PANE &&\n isSelected &&\n !isOpen\n ) {\n toggleExpand()\n }\n // Intentionally only toggle the expanded state when isSelected changes, otherwise the node cannot be un-expanded\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [isSelected])\n\n /**\n * If the height is 0, the node is purposefully hidden. Just render a fragment.\n */\n if ('height' in style && style.height === 0) {\n return <></>\n }\n\n let tooltipContent: ReactNode = ''\n if (isEntityHeaderNode(node)) {\n tooltipContent = (\n <div style={{ textAlign: 'center' }}>\n <Typography\n component=\"span\"\n variant=\"smallText1\"\n sx={{\n display: 'inline',\n }}\n >\n {node.name}\n <br />\n <b>ID: </b>\n {node.id}\n {'modifiedBy' in node && (\n <>\n <br />\n <b>Modified By: </b>\n <UserBadge\n userId={node.modifiedBy.toString()}\n showFullName\n disableLink\n showCardOnHover={false}\n />\n </>\n )}\n {'modifiedOn' in node && (\n <>\n <br />\n <b>Modified On: </b>\n {formatDate(dayjs(node.modifiedOn))}\n </>\n )}\n </Typography>\n </div>\n )\n }\n\n const ExpandIcon = isOpen ? ExpandMore : ChevronRight\n\n return (\n <div\n className={`Node ${\n treeNodeType === EntityTreeNodeType.SINGLE_PANE\n ? 'SelectNode'\n : 'BrowseNode'\n }`}\n aria-selected={isSelected}\n aria-disabled={isDisabled}\n onClick={event => {\n event.stopPropagation()\n if (!isDisabled) {\n setSelectedId(id)\n }\n }}\n style={{\n ...style,\n paddingLeft: `${nestingLevel * 20}px`,\n }}\n >\n {!isLeaf && (\n <>\n {isLoading ? (\n <SynapseSpinner size={10} />\n ) : (\n <button\n aria-label={isOpen ? 'Collapse' : 'Expand'}\n onClick={event => {\n event.stopPropagation()\n toggleExpand()\n }}\n >\n <ExpandIcon className=\"ExpandButton\" />\n </button>\n )}\n </>\n )}\n {treeNodeType === EntityTreeNodeType.SINGLE_PANE && ( // SWC-5592\n <div className=\"EntityIcon\">\n {isEntityHeaderNode(node) && (\n <EntityTypeIcon type={getEntityTypeFromHeader(node)} />\n )}\n </div>\n )}\n\n <Tooltip title={tooltipContent} placement=\"right\">\n <div className=\"EntityName\" ref={ref}>\n {nodeText}\n </div>\n </Tooltip>\n\n {treeNodeType === EntityTreeNodeType.SINGLE_PANE && (\n <EntityBadgeIcons\n entityId={id}\n showHasDiscussionThread={false}\n showHasWiki={false}\n showUnlink={false}\n canOpenModal={false}\n />\n )}\n </div>\n )\n}\n\n/**\n * Extracted from the React component for testing purposes\n * @returns a generator function compatible with react-vtree\n */\nexport function getTreeWalkerFunction(\n rootNode: RootNodeConfiguration,\n setSelectedId: VirtualizedTreeProps['setSelectedId'],\n treeNodeType: VirtualizedTreeProps['treeNodeType'],\n selected: VirtualizedTreeProps['selected'],\n selectableTypes: VirtualizedTreeProps['selectableTypes'],\n autoExpand: VirtualizedTreeProps['autoExpand'],\n itemSize: (index?: number) => number,\n currentContainer: VirtualizedTreeProps['currentContainer'],\n fetchNextPageOfChildren: (node: Writable<EntityHeaderNode>) => Promise<void>,\n): TreeWalker<TreeData, NodeMeta> {\n return function* treeWalker() {\n // Step [1]: Define the root node of our tree.\n yield getNodeData({\n node: rootNode,\n nestingLevel: 0,\n getNextPageOfChildren: rootNode.fetchNextPage,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n defaultHeight: itemSize(),\n currentContainer,\n })\n\n while (true) {\n // Step [2]: Get the parent node and nesting level, which will be passed into the Generator.next function by react-vtree.\n // Yielding `undefined` indicates to react-vtree that we've finished iterating children from the last time we were in the loop.\n const parentMeta = yield\n\n if (maybeHasChildren(parentMeta.node)) {\n // Step [3]: Yielding all the known children of the parent\n if (parentMeta.node.children) {\n for (let i = 0; i < parentMeta.node.children.length; i++) {\n const childNode = parentMeta.node.children[i]\n\n yield getNodeData({\n node: childNode,\n nestingLevel: parentMeta.nestingLevel + 1,\n getNextPageOfChildren: () => fetchNextPageOfChildren(childNode),\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n defaultHeight: itemSize(),\n currentContainer,\n })\n }\n }\n\n // Step [4] - If the parent node has more children, render a \"pagination node\" that will fetch more children when it comes into view (via intersection observer)\n if (hasMoreChildren(parentMeta.node)) {\n const paginationNode: PaginationNode = {\n __paginationNode: true,\n }\n const paginationTreeWalkerValue: TreeWalkerValue<TreeData, NodeMeta> =\n {\n data: {\n id: parentMeta.data.id + '-pagination',\n node: paginationNode,\n isOpenByDefault: false,\n getNextPageOfChildren: parentMeta.data.getNextPageOfChildren,\n isLeaf: true,\n isSelected: false,\n defaultHeight: itemSize(),\n isDisabled: true,\n nestingLevel: parentMeta.nestingLevel + 1,\n setSelectedId: () => {},\n treeNodeType,\n },\n nestingLevel: parentMeta.nestingLevel + 1,\n node: {\n __paginationNode: true,\n },\n }\n yield paginationTreeWalkerValue\n }\n }\n }\n }\n}\n\nexport type VirtualizedTreeProps = Readonly<{\n treeNodeType: EntityTreeNodeType\n rootNodeConfiguration: RootNodeConfiguration\n setSelectedId: (entityId: string) => void\n selected: EntitySelectionMapType\n /* currentContainer is the container whose contents are shown on in the right pane in dual-pane configuration, and may only be defined when treeNodeType is DUAL_PANE */\n currentContainer?: string | 'root' | null\n autoExpand: (entityId: string) => boolean\n selectableTypes: EntityType[]\n visibleTypes: EntityType[]\n}>\n\n/**\n * Component that utilizes react-vtree to efficiently display a tree of entities. react-vtree utilizes react-window\n * to only render visible nodes, which eliminates performance issues as seen in SWC-5978.\n */\nexport const VirtualizedTree = (\n props: VirtualizedTreeProps,\n): React.ReactNode => {\n const {\n rootNodeConfiguration,\n setSelectedId,\n treeNodeType,\n selected,\n currentContainer,\n selectableTypes,\n visibleTypes,\n autoExpand,\n } = props\n\n const { accessToken, keyFactory } = useSynapseContext()\n const queryClient = useQueryClient()\n\n const [rootNode, setRootNode] = useState<RootNodeConfiguration>(\n rootNodeConfiguration,\n )\n\n const treeInstance = useRef<VariableSizeTree<TreeData>>(null)\n\n useEffect(() => {\n setRootNode(rootNodeConfiguration)\n }, [rootNodeConfiguration, rootNodeConfiguration.children])\n\n // This function is used by VariableSizeTree to identify the size of each node in the tree.\n const itemSize = useCallback(\n (index?: number) => {\n /**\n * We must have a root node, but we don't always want to show it.\n * In those cases, set the height of the root node to 0.\n */\n if (index === 0 && !rootNodeConfiguration.show) {\n return 0\n }\n /**\n * The height of all other nodes in the tree varies depending on the tree node type.\n */\n return treeNodeType === EntityTreeNodeType.DUAL_PANE ? 30 : 60\n },\n [treeNodeType, rootNodeConfiguration.show],\n )\n\n /**\n * Fetches the next page of children for a given node. After fetching the children, this method will make a deep clone of the\n * full tree, including the new data, and updates the state of the component\n */\n const fetchNextPageOfChildren = useCallback(\n // Because we update the root node with a copy at the end of this function, we can write to the node under update.\n async (node: Writable<EntityHeaderNode>) => {\n // Fetch the children of the node\n const entityChildrenRequest: EntityChildrenRequest = {\n parentId: node.id,\n nextPageToken: node.childrenNextPageToken,\n includeTypes: visibleTypes,\n }\n const children = await queryClient.fetchQuery({\n queryKey: keyFactory.getEntityChildrenQueryKey(\n entityChildrenRequest,\n false,\n ),\n queryFn: () => getEntityChildren(entityChildrenRequest, accessToken),\n })\n // Update the node data -- add the children and store the nextPageToken\n if (node.children) {\n for (const newChild of children.page) {\n // SWC-6751 - Prevent adding duplicate entries in case this function is called twice\n if (!node.children.find(child => child.id == newChild.id)) {\n node.children.push(newChild)\n }\n }\n } else {\n node.children = children.page\n }\n node.childrenNextPageToken = children.nextPageToken\n\n // Ensure the node for which we fetched children is expanded/open\n if (treeInstance.current) {\n await treeInstance.current.recomputeTree({\n [node.id]: {\n open: true,\n },\n })\n }\n\n // cloneDeep is required to re-render the tree with the new children\n setRootNode(cloneDeep(rootNode))\n },\n [visibleTypes, queryClient, keyFactory, rootNode, accessToken],\n )\n\n /**\n * treeWalker is a generator function used by react-vtree to generate the tree structure. The tree is re-built when the function is updated,\n * so the dependencies specified in useCallback are important.\n */\n const memoizedTreeWalker = useCallback(\n getTreeWalkerFunction(\n rootNode,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n itemSize,\n currentContainer,\n fetchNextPageOfChildren,\n ),\n [\n rootNode,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n currentContainer,\n fetchNextPageOfChildren,\n itemSize,\n ],\n )\n\n return (\n <AutoSizer disableWidth>\n {({ height }: { height: number }) => (\n <VariableSizeTree\n ref={treeInstance}\n treeWalker={memoizedTreeWalker}\n itemSize={itemSize}\n height={height}\n async={true}\n width=\"100%\"\n >\n {Node}\n </VariableSizeTree>\n )}\n </AutoSizer>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VirtualizedTree.js","names":[],"sources":["../../../../src/components/EntityFinder/tree/VirtualizedTree.tsx"],"sourcesContent":["import React from 'react'\nimport { getEntityChildren } from '@/synapse-client'\nimport { useSynapseContext } from '@/utils'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n getEntityTypeFromHeader,\n isContainerType,\n} from '@/utils/functions/EntityTypeUtils'\nimport { Writable } from '@/utils/types/Writable'\nimport { ChevronRight, ExpandMore } from '@mui/icons-material'\nimport { Skeleton, Tooltip, Typography } from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport { EntityChildrenRequest } from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport dayjs from 'dayjs'\nimport { cloneDeep } from 'lodash-es'\nimport { ReactNode, useCallback, useEffect, useRef, useState } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport AutoSizer from 'react-virtualized-auto-sizer'\nimport {\n TreeWalker,\n TreeWalkerValue,\n VariableSizeNodeData,\n VariableSizeNodePublicState,\n VariableSizeTree,\n} from 'react-vtree'\nimport { NodeComponentProps } from 'react-vtree/dist/es/Tree'\nimport { EntityBadgeIcons } from '../../EntityBadgeIcons'\nimport { EntityTypeIcon } from '../../EntityIcon'\nimport { SynapseSpinner } from '../../LoadingScreen/LoadingScreen'\nimport { UserBadge } from '../../UserCard/UserBadge'\nimport { EntityFinderHeader } from '../EntityFinderHeader'\nimport { EntitySelectionMapType } from '../useEntitySelection'\n\nexport enum EntityTreeNodeType {\n /** The tree component's appearance and interactions will facilitate selection. Nodes will be larger and styles will indicate primary selection */\n SINGLE_PANE,\n /** The tree component's appearance and interactions will facilitate browsing. Nodes will be smaller and styles will indicate secondary selection */\n DUAL_PANE,\n}\n\ntype NodeChildren = Readonly<{\n /** The node's children. If undefined, then children have not been fetched. */\n children?: EntityHeaderNode[]\n /** The token used to fetch the next page of children for this entity. If this property is nullish and children is defined, then all children have been fetched. */\n childrenNextPageToken?: string | null\n}>\n\nexport type EntityHeaderNode = (\n | EntityFinderHeader\n // Only will have a subset of fields if the node is fetched via the entity path:\n | Pick<EntityFinderHeader, 'id' | 'name' | 'type'>\n) &\n NodeChildren\ntype PaginationNode = { __paginationNode: true }\n\ntype TreeNode = EntityHeaderNode | RootNodeConfiguration | PaginationNode\n\nfunction getTreeNodeType(\n node: TreeNode,\n): 'entityHeader' | 'rootNodeConfiguration' | 'pagination' {\n if ('__paginationNode' in node) {\n return 'pagination'\n }\n return 'id' in node ? 'entityHeader' : 'rootNodeConfiguration'\n}\n\nfunction isPaginationNode(node: TreeNode): node is PaginationNode {\n return getTreeNodeType(node) === 'pagination'\n}\n\nfunction isEntityHeaderNode(node: TreeNode): node is EntityHeaderNode {\n return getTreeNodeType(node) === 'entityHeader'\n}\n\nfunction isRootNodeConfiguration(\n node: TreeNode,\n): node is RootNodeConfiguration {\n return getTreeNodeType(node) === 'rootNodeConfiguration'\n}\n\nfunction hasMoreChildren(node: TreeNode) {\n if (isPaginationNode(node)) {\n return false\n } else if (isRootNodeConfiguration(node)) {\n return node.hasNextPage\n }\n\n return node.children == null || node.childrenNextPageToken != null\n}\n\nfunction isLeafNode(node: TreeNode) {\n if (isPaginationNode(node)) {\n return true\n } else if (isRootNodeConfiguration(node)) {\n return false\n } else {\n return (\n // Entity is not a container\n !isContainerType(getEntityTypeFromHeader(node)) ||\n // OR Children have been fetched (nonnull) and there are 0 children\n node.children?.length === 0\n )\n }\n}\n\nfunction maybeHasChildren(\n node: TreeNode,\n): node is RootNodeConfiguration | EntityHeaderNode {\n if (isPaginationNode(node)) {\n return false\n } else if (isRootNodeConfiguration(node)) {\n return node.children.length > 0 || node.hasNextPage\n } else {\n return !isLeafNode(node)\n }\n}\n\nexport type TreeData = VariableSizeNodeData &\n Readonly<{\n node: TreeNode\n getNextPageOfChildren: () => Promise<void>\n isLeaf: boolean\n nestingLevel: number\n setSelectedId: (entityId: string) => void\n treeNodeType: EntityTreeNodeType\n isSelected: boolean\n isDisabled: boolean\n }>\n\ntype NodeMeta = Readonly<{\n nestingLevel: number\n node: TreeNode\n}>\n\nexport type RootNodeConfiguration = {\n show: boolean\n nodeText: string\n children: EntityHeaderNode[]\n /** If undefined, no more entities to fetch */\n fetchNextPage: () => Promise<void>\n hasNextPage: boolean\n}\n\n/**\n * Converts a TreeNode and related data into a TreeWalkerValue that react-vtree can use to render the tree.\n * Exported for testing purposes only.\n * @param config\n * @returns\n */\nexport const getNodeData = (config: {\n node: TreeNode\n nestingLevel: number\n getNextPageOfChildren: () => Promise<void>\n setSelectedId: (entityId: string) => void\n treeNodeType: EntityTreeNodeType\n selected: EntitySelectionMapType\n selectableTypes: EntityType[]\n autoExpand: (entityId: string) => boolean\n defaultHeight: number\n currentContainer?: string | 'root' | null\n}): TreeWalkerValue<TreeData, NodeMeta> => {\n const {\n node,\n nestingLevel,\n getNextPageOfChildren,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n defaultHeight,\n currentContainer,\n } = config\n\n if (isPaginationNode(node)) {\n throw new Error('Cannot create data for a pagination node')\n }\n\n const id = isRootNodeConfiguration(node) ? 'root' : node.id\n\n const isSelected =\n treeNodeType === EntityTreeNodeType.SINGLE_PANE\n ? selected.has(id)\n : currentContainer === id\n const isDisabled =\n !isRootNodeConfiguration(node) &&\n !selectableTypes.includes(getEntityTypeFromHeader(node))\n\n const isOpenByDefault = autoExpand(id)\n /*\n * If the node is open by default and we haven't fetched its children,\n * fetch the first page (otherwise we won't fetch unless re-toggled)\n */\n if (isOpenByDefault && node.children == null && hasMoreChildren(node)) {\n getNextPageOfChildren()\n }\n\n return {\n data: {\n node,\n getNextPageOfChildren,\n id: id,\n isLeaf: isLeafNode(node),\n isOpenByDefault: isOpenByDefault,\n nestingLevel,\n setSelectedId,\n treeNodeType,\n isSelected,\n isDisabled,\n defaultHeight,\n },\n nestingLevel,\n node,\n }\n}\n\n/**\n * Node component for the react-vtree virtualized tree. Exported only for testing purposes\n */\nexport function Node(\n props: NodeComponentProps<TreeData, VariableSizeNodePublicState<TreeData>>,\n) {\n const {\n data: {\n node,\n getNextPageOfChildren,\n isLeaf,\n id,\n nestingLevel,\n setSelectedId,\n treeNodeType,\n isSelected,\n isDisabled,\n },\n isOpen,\n style,\n setOpen,\n } = props\n\n const [isLoading, setLoading] = useState(false)\n\n const nodeText = isEntityHeaderNode(node) ? (\n <span>{node.name}</span>\n ) : isRootNodeConfiguration(node) ? (\n <span>{node.nodeText}</span>\n ) : (\n // Pagination node\n <Skeleton width={100} />\n )\n\n // We only use this for pagination nodes. If the pagination node comes into view, then immediately call `getNextPageOfChildren`\n const { ref, inView } = useInView()\n\n useEffect(() => {\n if (isPaginationNode(node) && inView) {\n getNextPageOfChildren()\n }\n }, [node, inView, getNextPageOfChildren])\n\n const toggleExpand = useCallback(async () => {\n if (hasMoreChildren(node)) {\n setLoading(true)\n await getNextPageOfChildren()\n await setOpen(!isOpen)\n setLoading(false)\n } else {\n await setOpen(!isOpen)\n }\n }, [getNextPageOfChildren, node, isOpen, setOpen])\n\n /**\n * If in the dual-pane view, expand a node when it becomes selected\n */\n useEffect(() => {\n if (\n treeNodeType === EntityTreeNodeType.DUAL_PANE &&\n isSelected &&\n !isOpen\n ) {\n toggleExpand()\n }\n // Intentionally only toggle the expanded state when isSelected changes, otherwise the node cannot be un-expanded\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [isSelected])\n\n /**\n * If the height is 0, the node is purposefully hidden. Just render a fragment.\n */\n if ('height' in style && style.height === 0) {\n return <></>\n }\n\n let tooltipContent: ReactNode = ''\n if (isEntityHeaderNode(node)) {\n tooltipContent = (\n <div style={{ textAlign: 'center' }}>\n <Typography\n component=\"span\"\n variant=\"smallText1\"\n sx={{\n display: 'inline',\n }}\n >\n {node.name}\n <br />\n <b>ID: </b>\n {node.id}\n {'modifiedBy' in node && (\n <>\n <br />\n <b>Modified By: </b>\n <UserBadge\n userId={node.modifiedBy.toString()}\n showFullName\n disableLink\n showCardOnHover={false}\n />\n </>\n )}\n {'modifiedOn' in node && (\n <>\n <br />\n <b>Modified On: </b>\n {formatDate(dayjs(node.modifiedOn))}\n </>\n )}\n </Typography>\n </div>\n )\n }\n\n const ExpandIcon = isOpen ? ExpandMore : ChevronRight\n\n return (\n <div\n className={`Node ${\n treeNodeType === EntityTreeNodeType.SINGLE_PANE\n ? 'SelectNode'\n : 'BrowseNode'\n }`}\n aria-selected={isSelected}\n aria-disabled={isDisabled}\n onClick={event => {\n event.stopPropagation()\n if (!isDisabled) {\n setSelectedId(id)\n }\n }}\n style={{\n ...style,\n paddingLeft: `${nestingLevel * 20}px`,\n }}\n >\n {!isLeaf && (\n <>\n {isLoading ? (\n <SynapseSpinner size={10} />\n ) : (\n <button\n aria-label={isOpen ? 'Collapse' : 'Expand'}\n onClick={event => {\n event.stopPropagation()\n toggleExpand()\n }}\n >\n <ExpandIcon className=\"ExpandButton\" />\n </button>\n )}\n </>\n )}\n {treeNodeType === EntityTreeNodeType.SINGLE_PANE && ( // SWC-5592\n <div className=\"EntityIcon\">\n {isEntityHeaderNode(node) && (\n <EntityTypeIcon type={getEntityTypeFromHeader(node)} />\n )}\n </div>\n )}\n\n <Tooltip title={tooltipContent} placement=\"right\">\n <div className=\"EntityName\" ref={ref}>\n {nodeText}\n </div>\n </Tooltip>\n\n {treeNodeType === EntityTreeNodeType.SINGLE_PANE && (\n <EntityBadgeIcons\n entityId={id}\n showHasDiscussionThread={false}\n showHasWiki={false}\n showUnlink={false}\n canOpenModal={false}\n />\n )}\n </div>\n )\n}\n\n/**\n * Extracted from the React component for testing purposes\n * @returns a generator function compatible with react-vtree\n */\nexport function getTreeWalkerFunction(\n rootNode: RootNodeConfiguration,\n setSelectedId: VirtualizedTreeProps['setSelectedId'],\n treeNodeType: VirtualizedTreeProps['treeNodeType'],\n selected: VirtualizedTreeProps['selected'],\n selectableTypes: VirtualizedTreeProps['selectableTypes'],\n autoExpand: VirtualizedTreeProps['autoExpand'],\n itemSize: (index?: number) => number,\n currentContainer: VirtualizedTreeProps['currentContainer'],\n fetchNextPageOfChildren: (node: Writable<EntityHeaderNode>) => Promise<void>,\n): TreeWalker<TreeData, NodeMeta> {\n return function* treeWalker() {\n // Step [1]: Define the root node of our tree.\n yield getNodeData({\n node: rootNode,\n nestingLevel: 0,\n getNextPageOfChildren: rootNode.fetchNextPage,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n defaultHeight: itemSize(),\n currentContainer,\n })\n\n while (true) {\n // Step [2]: Get the parent node and nesting level, which will be passed into the Generator.next function by react-vtree.\n // Yielding `undefined` indicates to react-vtree that we've finished iterating children from the last time we were in the loop.\n const parentMeta = yield\n\n if (maybeHasChildren(parentMeta.node)) {\n // Step [3]: Yielding all the known children of the parent\n if (parentMeta.node.children) {\n for (let i = 0; i < parentMeta.node.children.length; i++) {\n const childNode = parentMeta.node.children[i]\n\n yield getNodeData({\n node: childNode,\n nestingLevel: parentMeta.nestingLevel + 1,\n getNextPageOfChildren: () => fetchNextPageOfChildren(childNode),\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n defaultHeight: itemSize(),\n currentContainer,\n })\n }\n }\n\n // Step [4] - If the parent node has more children, render a \"pagination node\" that will fetch more children when it comes into view (via intersection observer)\n if (hasMoreChildren(parentMeta.node)) {\n const paginationNode: PaginationNode = {\n __paginationNode: true,\n }\n const paginationTreeWalkerValue: TreeWalkerValue<TreeData, NodeMeta> =\n {\n data: {\n id: parentMeta.data.id + '-pagination',\n node: paginationNode,\n isOpenByDefault: false,\n getNextPageOfChildren: parentMeta.data.getNextPageOfChildren,\n isLeaf: true,\n isSelected: false,\n defaultHeight: itemSize(),\n isDisabled: true,\n nestingLevel: parentMeta.nestingLevel + 1,\n setSelectedId: () => {},\n treeNodeType,\n },\n nestingLevel: parentMeta.nestingLevel + 1,\n node: {\n __paginationNode: true,\n },\n }\n yield paginationTreeWalkerValue\n }\n }\n }\n }\n}\n\nexport type VirtualizedTreeProps = Readonly<{\n treeNodeType: EntityTreeNodeType\n rootNodeConfiguration: RootNodeConfiguration\n setSelectedId: (entityId: string) => void\n selected: EntitySelectionMapType\n /* currentContainer is the container whose contents are shown on in the right pane in dual-pane configuration, and may only be defined when treeNodeType is DUAL_PANE */\n currentContainer?: string | 'root' | null\n autoExpand: (entityId: string) => boolean\n selectableTypes: EntityType[]\n visibleTypes: EntityType[]\n}>\n\n/**\n * Component that utilizes react-vtree to efficiently display a tree of entities. react-vtree utilizes react-window\n * to only render visible nodes, which eliminates performance issues as seen in SWC-5978.\n */\nexport const VirtualizedTree = (\n props: VirtualizedTreeProps,\n): React.ReactNode => {\n const {\n rootNodeConfiguration,\n setSelectedId,\n treeNodeType,\n selected,\n currentContainer,\n selectableTypes,\n visibleTypes,\n autoExpand,\n } = props\n\n const { accessToken, keyFactory } = useSynapseContext()\n const queryClient = useQueryClient()\n\n const [rootNode, setRootNode] = useState<RootNodeConfiguration>(\n rootNodeConfiguration,\n )\n\n const treeInstance = useRef<VariableSizeTree<TreeData>>(null)\n\n useEffect(() => {\n setRootNode(rootNodeConfiguration)\n }, [rootNodeConfiguration, rootNodeConfiguration.children])\n\n // This function is used by VariableSizeTree to identify the size of each node in the tree.\n const itemSize = useCallback(\n (index?: number) => {\n /**\n * We must have a root node, but we don't always want to show it.\n * In those cases, set the height of the root node to 0.\n */\n if (index === 0 && !rootNodeConfiguration.show) {\n return 0\n }\n /**\n * The height of all other nodes in the tree varies depending on the tree node type.\n */\n return treeNodeType === EntityTreeNodeType.DUAL_PANE ? 30 : 60\n },\n [treeNodeType, rootNodeConfiguration.show],\n )\n\n /**\n * Fetches the next page of children for a given node. After fetching the children, this method will make a deep clone of the\n * full tree, including the new data, and updates the state of the component\n */\n const fetchNextPageOfChildren = useCallback(\n // Because we update the root node with a copy at the end of this function, we can write to the node under update.\n async (node: Writable<EntityHeaderNode>) => {\n // Fetch the children of the node\n const entityChildrenRequest: EntityChildrenRequest = {\n parentId: node.id,\n nextPageToken: node.childrenNextPageToken,\n includeTypes: visibleTypes,\n }\n const children = await queryClient.fetchQuery({\n queryKey: keyFactory.getEntityChildrenQueryKey(\n entityChildrenRequest,\n false,\n ),\n queryFn: () => getEntityChildren(entityChildrenRequest, accessToken),\n })\n // Update the node data -- add the children and store the nextPageToken\n if (node.children) {\n for (const newChild of children.page) {\n // SWC-6751 - Prevent adding duplicate entries in case this function is called twice\n if (!node.children.find(child => child.id == newChild.id)) {\n node.children.push(newChild)\n }\n }\n } else {\n node.children = children.page\n }\n node.childrenNextPageToken = children.nextPageToken\n\n // Ensure the node for which we fetched children is expanded/open\n if (treeInstance.current) {\n await treeInstance.current.recomputeTree({\n [node.id]: {\n open: true,\n },\n })\n }\n\n // cloneDeep is required to re-render the tree with the new children\n setRootNode(cloneDeep(rootNode))\n },\n [visibleTypes, queryClient, keyFactory, rootNode, accessToken],\n )\n\n /**\n * treeWalker is a generator function used by react-vtree to generate the tree structure. The tree is re-built when the function is updated,\n * so the dependencies specified in useCallback are important.\n */\n const memoizedTreeWalker = useCallback(\n getTreeWalkerFunction(\n rootNode,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n itemSize,\n currentContainer,\n fetchNextPageOfChildren,\n ),\n [\n rootNode,\n setSelectedId,\n treeNodeType,\n selected,\n selectableTypes,\n autoExpand,\n currentContainer,\n fetchNextPageOfChildren,\n itemSize,\n ],\n )\n\n return (\n <AutoSizer disableWidth>\n {({ height }: { height: number }) => (\n <VariableSizeTree\n ref={treeInstance}\n treeWalker={memoizedTreeWalker}\n itemSize={itemSize}\n height={height}\n async={true}\n width=\"100%\"\n >\n {Node}\n </VariableSizeTree>\n )}\n </AutoSizer>\n )\n}\n"],"mappings":"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"}
@@ -98,7 +98,7 @@ function M(t) {
98
98
  return e.length > 0 ? e[0] : void 0;
99
99
  } else return;
100
100
  }).filter((e) => e !== void 0)[0];
101
- return e && e.value ? e?.value : "";
101
+ return e?.value ? e?.value : "";
102
102
  }, [y, N?.facets]), H = B.length > 1;
103
103
  return /* @__PURE__ */ D(C, {
104
104
  className: d,
@@ -1 +1 @@
1
- {"version":3,"file":"FacetPlotsCard.js","names":[],"sources":["../../../src/components/FeaturedDataTabs/FacetPlotsCard.tsx"],"sourcesContent":["import { useSynapseContext } from '@/utils/context/SynapseContext'\nimport {\n Box,\n Button,\n Divider,\n Paper,\n Skeleton,\n Typography,\n} from '@mui/material'\nimport {\n ColumnTypeEnum,\n FacetColumnResult,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n} from '@sage-bionetworks/synapse-types'\nimport { useSuspenseQuery } from '@tanstack/react-query'\nimport { times } from 'lodash-es'\nimport Plotly from 'plotly.js-basic-dist'\nimport { Fragment, Suspense, useMemo } from 'react'\nimport Plot from '../Plot/Plot'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { ShowMore } from '../row_renderers/utils'\nimport { SkeletonParagraph, SkeletonTable } from '../Skeleton'\nimport {\n extractPlotDataArray,\n getPlotStyle,\n PlotType,\n} from '../widgets/facet-nav/FacetNavPanel'\nimport { FacetPlotLegendTable } from '../widgets/facet-nav/FacetPlotLegendTable'\nimport { getFacets } from '../widgets/facet-nav/useFacetPlots'\nimport {\n FACET_PLOTS_CARD_CLASSNAME,\n FACET_PLOTS_CARD_PLOT_CONTAINER_CLASSNAME,\n FACET_PLOTS_CARD_TITLE_CONTAINER_CLASSNAME,\n FacetPlotsCardPlotContainer,\n FacetPlotsCardTitleContainer,\n} from './FacetPlotsCardGrid'\nimport { useMeasure } from '@react-hookz/web'\n\nexport type FacetPlotsCardProps = {\n title?: string\n description?: string\n facetsToPlot?: string[]\n detailsPagePath?: string\n plotType?: PlotType\n}\n\nconst layout: Partial<Plotly.Layout> = {\n showlegend: false,\n annotations: [],\n margin: { l: 0, r: 0, b: 0, t: 0, pad: 0 },\n yaxis: {\n visible: false,\n showgrid: false,\n },\n xaxis: {\n visible: false,\n showgrid: false,\n },\n}\n\nfunction LoadingCard(props: { numPlots: number }) {\n const { numPlots } = props\n return (\n <Paper className={FACET_PLOTS_CARD_CLASSNAME}>\n <FacetPlotsCardTitleContainer\n className={FACET_PLOTS_CARD_TITLE_CONTAINER_CLASSNAME}\n >\n <Skeleton width={'60%'} height={'24px'} />\n\n <SkeletonParagraph numRows={5} />\n\n <Skeleton width={'40%'}>\n <Button variant={'contained'}>Explore</Button>\n </Skeleton>\n </FacetPlotsCardTitleContainer>\n {times(numPlots).map(index => (\n <FacetPlotsCardPlotContainer\n key={index}\n className={FACET_PLOTS_CARD_PLOT_CONTAINER_CLASSNAME}\n sx={{\n py: 3,\n gridRow: `plot${index}`,\n }}\n >\n <Skeleton width={'100%'} height={'300px'} />\n <SkeletonTable numRows={4} numCols={2} />\n </FacetPlotsCardPlotContainer>\n ))}\n </Paper>\n )\n}\n\nfunction FacetPlotsCard(props: FacetPlotsCardProps) {\n const {\n title,\n description,\n facetsToPlot,\n detailsPagePath,\n plotType = 'PIE',\n } = props\n const { accessToken } = useSynapseContext()\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n const [plotContainerMeasurements, plotContainerRef] = useMeasure()\n\n const facetDataArray = useMemo(() => {\n if (!facetsToPlot) {\n return []\n }\n\n return getFacets(queryMetadata, facetsToPlot)\n }, [facetsToPlot, queryMetadata])\n\n const currentLayout: Partial<Plotly.Layout> = useMemo(() => {\n return {\n ...layout,\n barmode: plotType === 'STACKED_HORIZONTAL_BAR' ? 'stack' : undefined,\n }\n }, [plotType])\n const maxPlotHeight = plotType === 'STACKED_HORIZONTAL_BAR' ? 50 : 150\n const { data: facetPlotDataArray } = useSuspenseQuery({\n queryKey: ['facetPlotDataArray', facetsToPlot, facetDataArray],\n queryFn: async () => {\n if (!facetsToPlot) {\n return []\n }\n\n const getColumnType = (\n facetToPlot: FacetColumnResult,\n ): ColumnTypeEnum | undefined =>\n queryMetadata.columnModels!.find(\n columnModel => columnModel.name === facetToPlot.columnName,\n )?.columnType as ColumnTypeEnum\n\n return Promise.all(\n facetDataArray.map(async (item, index) => {\n const plotData = await extractPlotDataArray(\n item as FacetColumnResultValues,\n getColumnType(item),\n index + 1, //individual plot rgbIndex\n plotType,\n accessToken,\n )\n return plotData\n }),\n )\n },\n })\n\n const selectedFacetValue = useMemo(() => {\n if (!facetsToPlot) {\n return ''\n }\n\n // If we are showing a facet selection based card, then set the selectedFacetValue. For example, facet column \"study\" with value \"ROSMAP\"\n const selectedFacet: FacetColumnResultValueCount | undefined = queryMetadata\n ?.facets!.map(item => {\n const facetValues: FacetColumnResultValueCount[] = (\n item as FacetColumnResultValues\n ).facetValues\n if (facetValues) {\n const filteredFacetValues: FacetColumnResultValueCount[] =\n facetValues.filter(facetValue => {\n return facetValue.isSelected\n })\n return filteredFacetValues.length > 0\n ? filteredFacetValues[0]\n : undefined\n } else {\n return undefined\n }\n })\n .filter(x => x !== undefined)[0]\n\n if (selectedFacet && selectedFacet.value) {\n return selectedFacet?.value\n }\n return ''\n }, [facetsToPlot, queryMetadata?.facets])\n\n const isShowingMultiplePlots = facetPlotDataArray.length > 1\n const cardTitle =\n title ??\n (isShowingMultiplePlots\n ? selectedFacetValue\n : getColumnDisplayName(facetDataArray[0].columnName))\n return (\n <Paper className={FACET_PLOTS_CARD_CLASSNAME} sx={{ overflow: 'hidden' }}>\n <FacetPlotsCardTitleContainer\n className={FACET_PLOTS_CARD_TITLE_CONTAINER_CLASSNAME}\n >\n <Typography variant={'headline1'}>{cardTitle}</Typography>\n {description && (\n <Typography variant={'body1'} sx={{ color: 'grey.700', my: 2 }}>\n <ShowMore summary={description} maxCharacterCount={200} />\n </Typography>\n )}\n\n {detailsPagePath && selectedFacetValue && (\n <Box sx={{ my: 2 }}>\n <Button\n variant={'contained'}\n href={detailsPagePath}\n color={'secondary'}\n sx={theme => ({\n [theme.breakpoints.down('sm')]: { width: '100%' },\n })}\n >\n Explore {selectedFacetValue}\n </Button>\n </Box>\n )}\n </FacetPlotsCardTitleContainer>\n\n {/* create a plot for every facet to be plotted */}\n {facetPlotDataArray.map((plotData, index) => {\n return (\n <Fragment key={index}>\n <FacetPlotsCardPlotContainer\n className={FACET_PLOTS_CARD_PLOT_CONTAINER_CLASSNAME}\n sx={{\n pt: index === 0 ? 5 : 0,\n gridRow: `plot${index}`,\n }}\n key={index}\n >\n {index != 0 && <Divider sx={{ mt: 2, mb: 4 }} />}\n <Box sx={{ minHeight: '130px' }}>\n <Box\n ref={plotContainerRef}\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <Plot\n key={`${facetsToPlot![index]}-${\n plotContainerMeasurements?.width\n }`}\n layout={currentLayout}\n data={plotData?.data ?? []}\n style={getPlotStyle(\n plotContainerMeasurements?.width,\n plotType,\n maxPlotHeight,\n )}\n config={{ displayModeBar: false }}\n />\n </Box>\n <Box sx={{ mt: 4, width: '100%' }}>\n <FacetPlotLegendTable\n facetName={getColumnDisplayName(\n facetDataArray[index].columnName,\n )}\n labels={plotData?.labels}\n colors={plotData?.colors}\n isExpanded={false}\n linkToFullQuery={detailsPagePath}\n />\n </Box>\n </Box>\n </FacetPlotsCardPlotContainer>\n </Fragment>\n )\n })}\n </Paper>\n )\n}\n\nexport default function FacetPlotsCardWithSuspense(props: FacetPlotsCardProps) {\n return (\n <Suspense\n fallback={<LoadingCard numPlots={(props.facetsToPlot ?? []).length} />}\n >\n <FacetPlotsCard {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FacetPlotsCard.js","names":[],"sources":["../../../src/components/FeaturedDataTabs/FacetPlotsCard.tsx"],"sourcesContent":["import { useSynapseContext } from '@/utils/context/SynapseContext'\nimport {\n Box,\n Button,\n Divider,\n Paper,\n Skeleton,\n Typography,\n} from '@mui/material'\nimport {\n ColumnTypeEnum,\n FacetColumnResult,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n} from '@sage-bionetworks/synapse-types'\nimport { useSuspenseQuery } from '@tanstack/react-query'\nimport { times } from 'lodash-es'\nimport Plotly from 'plotly.js-basic-dist'\nimport { Fragment, Suspense, useMemo } from 'react'\nimport Plot from '../Plot/Plot'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { ShowMore } from '../row_renderers/utils'\nimport { SkeletonParagraph, SkeletonTable } from '../Skeleton'\nimport {\n extractPlotDataArray,\n getPlotStyle,\n PlotType,\n} from '../widgets/facet-nav/FacetNavPanel'\nimport { FacetPlotLegendTable } from '../widgets/facet-nav/FacetPlotLegendTable'\nimport { getFacets } from '../widgets/facet-nav/useFacetPlots'\nimport {\n FACET_PLOTS_CARD_CLASSNAME,\n FACET_PLOTS_CARD_PLOT_CONTAINER_CLASSNAME,\n FACET_PLOTS_CARD_TITLE_CONTAINER_CLASSNAME,\n FacetPlotsCardPlotContainer,\n FacetPlotsCardTitleContainer,\n} from './FacetPlotsCardGrid'\nimport { useMeasure } from '@react-hookz/web'\n\nexport type FacetPlotsCardProps = {\n title?: string\n description?: string\n facetsToPlot?: string[]\n detailsPagePath?: string\n plotType?: PlotType\n}\n\nconst layout: Partial<Plotly.Layout> = {\n showlegend: false,\n annotations: [],\n margin: { l: 0, r: 0, b: 0, t: 0, pad: 0 },\n yaxis: {\n visible: false,\n showgrid: false,\n },\n xaxis: {\n visible: false,\n showgrid: false,\n },\n}\n\nfunction LoadingCard(props: { numPlots: number }) {\n const { numPlots } = props\n return (\n <Paper className={FACET_PLOTS_CARD_CLASSNAME}>\n <FacetPlotsCardTitleContainer\n className={FACET_PLOTS_CARD_TITLE_CONTAINER_CLASSNAME}\n >\n <Skeleton width={'60%'} height={'24px'} />\n\n <SkeletonParagraph numRows={5} />\n\n <Skeleton width={'40%'}>\n <Button variant={'contained'}>Explore</Button>\n </Skeleton>\n </FacetPlotsCardTitleContainer>\n {times(numPlots).map(index => (\n <FacetPlotsCardPlotContainer\n key={index}\n className={FACET_PLOTS_CARD_PLOT_CONTAINER_CLASSNAME}\n sx={{\n py: 3,\n gridRow: `plot${index}`,\n }}\n >\n <Skeleton width={'100%'} height={'300px'} />\n <SkeletonTable numRows={4} numCols={2} />\n </FacetPlotsCardPlotContainer>\n ))}\n </Paper>\n )\n}\n\nfunction FacetPlotsCard(props: FacetPlotsCardProps) {\n const {\n title,\n description,\n facetsToPlot,\n detailsPagePath,\n plotType = 'PIE',\n } = props\n const { accessToken } = useSynapseContext()\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n const [plotContainerMeasurements, plotContainerRef] = useMeasure()\n\n const facetDataArray = useMemo(() => {\n if (!facetsToPlot) {\n return []\n }\n\n return getFacets(queryMetadata, facetsToPlot)\n }, [facetsToPlot, queryMetadata])\n\n const currentLayout: Partial<Plotly.Layout> = useMemo(() => {\n return {\n ...layout,\n barmode: plotType === 'STACKED_HORIZONTAL_BAR' ? 'stack' : undefined,\n }\n }, [plotType])\n const maxPlotHeight = plotType === 'STACKED_HORIZONTAL_BAR' ? 50 : 150\n const { data: facetPlotDataArray } = useSuspenseQuery({\n queryKey: ['facetPlotDataArray', facetsToPlot, facetDataArray],\n queryFn: async () => {\n if (!facetsToPlot) {\n return []\n }\n\n const getColumnType = (\n facetToPlot: FacetColumnResult,\n ): ColumnTypeEnum | undefined =>\n queryMetadata.columnModels!.find(\n columnModel => columnModel.name === facetToPlot.columnName,\n )?.columnType as ColumnTypeEnum\n\n return Promise.all(\n facetDataArray.map(async (item, index) => {\n const plotData = await extractPlotDataArray(\n item as FacetColumnResultValues,\n getColumnType(item),\n index + 1, //individual plot rgbIndex\n plotType,\n accessToken,\n )\n return plotData\n }),\n )\n },\n })\n\n const selectedFacetValue = useMemo(() => {\n if (!facetsToPlot) {\n return ''\n }\n\n // If we are showing a facet selection based card, then set the selectedFacetValue. For example, facet column \"study\" with value \"ROSMAP\"\n const selectedFacet: FacetColumnResultValueCount | undefined = queryMetadata\n ?.facets!.map(item => {\n const facetValues: FacetColumnResultValueCount[] = (\n item as FacetColumnResultValues\n ).facetValues\n if (facetValues) {\n const filteredFacetValues: FacetColumnResultValueCount[] =\n facetValues.filter(facetValue => {\n return facetValue.isSelected\n })\n return filteredFacetValues.length > 0\n ? filteredFacetValues[0]\n : undefined\n } else {\n return undefined\n }\n })\n .filter(x => x !== undefined)[0]\n\n if (selectedFacet?.value) {\n return selectedFacet?.value\n }\n return ''\n }, [facetsToPlot, queryMetadata?.facets])\n\n const isShowingMultiplePlots = facetPlotDataArray.length > 1\n const cardTitle =\n title ??\n (isShowingMultiplePlots\n ? selectedFacetValue\n : getColumnDisplayName(facetDataArray[0].columnName))\n return (\n <Paper className={FACET_PLOTS_CARD_CLASSNAME} sx={{ overflow: 'hidden' }}>\n <FacetPlotsCardTitleContainer\n className={FACET_PLOTS_CARD_TITLE_CONTAINER_CLASSNAME}\n >\n <Typography variant={'headline1'}>{cardTitle}</Typography>\n {description && (\n <Typography variant={'body1'} sx={{ color: 'grey.700', my: 2 }}>\n <ShowMore summary={description} maxCharacterCount={200} />\n </Typography>\n )}\n\n {detailsPagePath && selectedFacetValue && (\n <Box sx={{ my: 2 }}>\n <Button\n variant={'contained'}\n href={detailsPagePath}\n color={'secondary'}\n sx={theme => ({\n [theme.breakpoints.down('sm')]: { width: '100%' },\n })}\n >\n Explore {selectedFacetValue}\n </Button>\n </Box>\n )}\n </FacetPlotsCardTitleContainer>\n\n {/* create a plot for every facet to be plotted */}\n {facetPlotDataArray.map((plotData, index) => {\n return (\n <Fragment key={index}>\n <FacetPlotsCardPlotContainer\n className={FACET_PLOTS_CARD_PLOT_CONTAINER_CLASSNAME}\n sx={{\n pt: index === 0 ? 5 : 0,\n gridRow: `plot${index}`,\n }}\n key={index}\n >\n {index != 0 && <Divider sx={{ mt: 2, mb: 4 }} />}\n <Box sx={{ minHeight: '130px' }}>\n <Box\n ref={plotContainerRef}\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <Plot\n key={`${facetsToPlot![index]}-${\n plotContainerMeasurements?.width\n }`}\n layout={currentLayout}\n data={plotData?.data ?? []}\n style={getPlotStyle(\n plotContainerMeasurements?.width,\n plotType,\n maxPlotHeight,\n )}\n config={{ displayModeBar: false }}\n />\n </Box>\n <Box sx={{ mt: 4, width: '100%' }}>\n <FacetPlotLegendTable\n facetName={getColumnDisplayName(\n facetDataArray[index].columnName,\n )}\n labels={plotData?.labels}\n colors={plotData?.colors}\n isExpanded={false}\n linkToFullQuery={detailsPagePath}\n />\n </Box>\n </Box>\n </FacetPlotsCardPlotContainer>\n </Fragment>\n )\n })}\n </Paper>\n )\n}\n\nexport default function FacetPlotsCardWithSuspense(props: FacetPlotsCardProps) {\n return (\n <Suspense\n fallback={<LoadingCard numPlots={(props.facetsToPlot ?? []).length} />}\n >\n <FacetPlotsCard {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TableRowGenericCard.d.ts","sourceRoot":"","sources":["../../../src/components/GenericCard/TableRowGenericCard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TableRowGenericCard.d.ts","sourceRoot":"","sources":["../../../src/components/GenericCard/TableRowGenericCard.tsx"],"names":[],"mappings":"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"}