synapse-react-client 4.0.9 → 4.0.11

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 (613) hide show
  1. package/dist/SWC.index.d.ts +1 -0
  2. package/dist/SWC.index.d.ts.map +1 -1
  3. package/dist/SWC.index.js +2 -1
  4. package/dist/SWC.index.js.map +1 -1
  5. package/dist/aridhia-queries/aridhiaTokenExchange.js.map +1 -1
  6. package/dist/aridhia-queries/useGetAridhiaRequests.js.map +1 -1
  7. package/dist/assets/icons/CloudWarning.d.ts +5 -0
  8. package/dist/assets/icons/CloudWarning.d.ts.map +1 -0
  9. package/dist/assets/icons/CloudWarning.js +47 -0
  10. package/dist/assets/icons/CloudWarning.js.map +1 -0
  11. package/dist/assets/icons/TasksIcon.d.ts.map +1 -1
  12. package/dist/assets/icons/TasksIcon.js +6 -10
  13. package/dist/assets/icons/TasksIcon.js.map +1 -1
  14. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.d.ts.map +1 -1
  15. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.js +69 -63
  16. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.js.map +1 -1
  17. package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js.map +1 -1
  18. package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
  19. package/dist/components/AccessRequirementList/AccessRequirementListUtils.js.map +1 -1
  20. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsEditor.js.map +1 -1
  21. package/dist/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.js.map +1 -1
  22. package/dist/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.js.map +1 -1
  23. package/dist/components/AccessTokenPage/AccessTokenCard/AccessTokenCard.js.map +1 -1
  24. package/dist/components/AcknowledgementsPage/StudyAcknowledgements.js.map +1 -1
  25. package/dist/components/AclEditor/PermissionLevelMenu.js.map +1 -1
  26. package/dist/components/AclEditor/ResourceAccessAndUserGroupHeader.js.map +1 -1
  27. package/dist/components/AclEditor/useSortResourceAccessList.js.map +1 -1
  28. package/dist/components/AclEditor/useUpdateAcl.js.map +1 -1
  29. package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
  30. package/dist/components/Authentication/AuthenticationMethodSelection.d.ts.map +1 -1
  31. package/dist/components/Authentication/AuthenticationMethodSelection.js +38 -37
  32. package/dist/components/Authentication/AuthenticationMethodSelection.js.map +1 -1
  33. package/dist/components/Authentication/Constants.d.ts +1 -0
  34. package/dist/components/Authentication/Constants.d.ts.map +1 -1
  35. package/dist/components/Authentication/Constants.js +2 -2
  36. package/dist/components/Authentication/Constants.js.map +1 -1
  37. package/dist/components/Authentication/LastLoginInfo.js.map +1 -1
  38. package/dist/components/Authentication/RecoveryCodeForm.js.map +1 -1
  39. package/dist/components/Authentication/RecoveryCodeGrid.js.map +1 -1
  40. package/dist/components/Authentication/RegenerateBackupCodesWarning.js.map +1 -1
  41. package/dist/components/Authentication/Reset2FAWarning.js.map +1 -1
  42. package/dist/components/Authentication/StandaloneLoginForm.js +1 -1
  43. package/dist/components/Authentication/TwoFactorBackupCodes.js.map +1 -1
  44. package/dist/components/Authentication/TwoFactorEnrollmentForm.d.ts.map +1 -1
  45. package/dist/components/Authentication/TwoFactorEnrollmentForm.js +2 -1
  46. package/dist/components/Authentication/TwoFactorEnrollmentForm.js.map +1 -1
  47. package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.js.map +1 -1
  48. package/dist/components/CardContainer/CardContainer.js.map +1 -1
  49. package/dist/components/CardDeck/CardDeck.Mobile.js.map +1 -1
  50. package/dist/components/CardDeck/TableQueryCardDeck.js.map +1 -1
  51. package/dist/components/CertificationQuiz/CertificationQuiz.js.map +1 -1
  52. package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js.map +1 -1
  53. package/dist/components/ChallengeSubmission/ChallengeSubmission.js.map +1 -1
  54. package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js.map +1 -1
  55. package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js.map +1 -1
  56. package/dist/components/ChallengeSubmission/EvaluationQueueList.js.map +1 -1
  57. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.d.ts.map +1 -1
  58. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js +143 -140
  59. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
  60. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js.map +1 -1
  61. package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js.map +1 -1
  62. package/dist/components/ChangePassword/ChangePassword.js.map +1 -1
  63. package/dist/components/ChangePassword/ChangePasswordWithToken.js.map +1 -1
  64. package/dist/components/ChangePassword/useChangePasswordFormState.js +1 -1
  65. package/dist/components/ChangePassword/useChangePasswordFormState.js.map +1 -1
  66. package/dist/components/CitationPopover/CitationPopoverContent.js.map +1 -1
  67. package/dist/components/ColumnFilter/ColumnFilter.js.map +1 -1
  68. package/dist/components/ComponentCollapse.js.map +1 -1
  69. package/dist/components/CookiesNotification/CookiesNotification.js.map +1 -1
  70. package/dist/components/CreateProjectModal/CreateProjectModal.js.map +1 -1
  71. package/dist/components/CreateTableViewWizard/CreateTableViewWizardUtils.js.map +1 -1
  72. package/dist/components/DataGrid/DataGrid.d.ts +0 -1
  73. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
  74. package/dist/components/DataGrid/DataGrid.js +72 -72
  75. package/dist/components/DataGrid/DataGrid.js.map +1 -1
  76. package/dist/components/DataGrid/DataGridWebSocket.d.ts +4 -0
  77. package/dist/components/DataGrid/DataGridWebSocket.d.ts.map +1 -1
  78. package/dist/components/DataGrid/DataGridWebSocket.js +9 -8
  79. package/dist/components/DataGrid/DataGridWebSocket.js.map +1 -1
  80. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  81. package/dist/components/DataGrid/SynapseGrid.js +326 -268
  82. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  83. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts +2 -0
  84. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts.map +1 -1
  85. package/dist/components/DataGrid/columns/AutocompleteColumn.js +124 -67
  86. package/dist/components/DataGrid/columns/AutocompleteColumn.js.map +1 -1
  87. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts +2 -1
  88. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts.map +1 -1
  89. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js +126 -122
  90. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js.map +1 -1
  91. package/dist/components/DataGrid/columns/useGridAutocompleteState.d.ts +58 -0
  92. package/dist/components/DataGrid/columns/useGridAutocompleteState.d.ts.map +1 -0
  93. package/dist/components/DataGrid/columns/useGridAutocompleteState.js +52 -0
  94. package/dist/components/DataGrid/columns/useGridAutocompleteState.js.map +1 -0
  95. package/dist/components/DataGrid/components/ValidationAlert.d.ts +5 -2
  96. package/dist/components/DataGrid/components/ValidationAlert.d.ts.map +1 -1
  97. package/dist/components/DataGrid/components/ValidationAlert.js +429 -24
  98. package/dist/components/DataGrid/components/ValidationAlert.js.map +1 -1
  99. package/dist/components/DataGrid/hooks/useColumnResizeHandles.js.map +1 -1
  100. package/dist/components/DataGrid/hooks/useGetSchemaForGrid.js.map +1 -1
  101. package/dist/components/DataGrid/hooks/useGridUndoRedo.js.map +1 -1
  102. package/dist/components/DataGrid/hooks/useStack.js.map +1 -1
  103. package/dist/components/DataGrid/useCRDTModelView.js.map +1 -1
  104. package/dist/components/DataGrid/useDataGridWebsocket.d.ts +7 -0
  105. package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
  106. package/dist/components/DataGrid/useDataGridWebsocket.js +16 -2
  107. package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
  108. package/dist/components/DataGrid/useInitializeGridConnection.js.map +1 -1
  109. package/dist/components/DataGrid/useMergeGridWithRecordSet.js.map +1 -1
  110. package/dist/components/DataGrid/useMergeGridWithSource.js.map +1 -1
  111. package/dist/components/DataGrid/useMergeGridWithTable.js.map +1 -1
  112. package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
  113. package/dist/components/DataGrid/utils/applyModelChange.d.ts +1 -1
  114. package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
  115. package/dist/components/DataGrid/utils/applyModelChange.js +27 -24
  116. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  117. package/dist/components/DataGrid/utils/columnFactory.d.ts +8 -0
  118. package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
  119. package/dist/components/DataGrid/utils/columnFactory.js +47 -44
  120. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  121. package/dist/components/DataGrid/utils/computeReplicaSelectionModel.js.map +1 -1
  122. package/dist/components/DataGrid/utils/extractColumnValidationMessages.js.map +1 -1
  123. package/dist/components/DataGrid/utils/getCellClassName.d.ts.map +1 -1
  124. package/dist/components/DataGrid/utils/getCellClassName.js +8 -8
  125. package/dist/components/DataGrid/utils/getCellClassName.js.map +1 -1
  126. package/dist/components/DataGrid/utils/getEmptyValue.d.ts +2 -0
  127. package/dist/components/DataGrid/utils/getEmptyValue.d.ts.map +1 -0
  128. package/dist/components/DataGrid/utils/getEmptyValue.js +8 -0
  129. package/dist/components/DataGrid/utils/getEmptyValue.js.map +1 -0
  130. package/dist/components/DataGrid/utils/json-rx/JsonRx.js.map +1 -1
  131. package/dist/components/DataGrid/utils/modelColsToGrid.d.ts.map +1 -1
  132. package/dist/components/DataGrid/utils/modelColsToGrid.js +2 -1
  133. package/dist/components/DataGrid/utils/modelColsToGrid.js.map +1 -1
  134. package/dist/components/DataGrid/utils/modelRowsToGrid.js.map +1 -1
  135. package/dist/components/DataGrid/utils/parseFreeTextUsingJsonSchemaType.js.map +1 -1
  136. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts +32 -0
  137. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts.map +1 -0
  138. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js +22 -0
  139. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js.map +1 -0
  140. package/dist/components/DataGrid/utils/splitPatch.js.map +1 -1
  141. package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
  142. package/dist/components/DirectDownload/DirectDownload.js.map +1 -1
  143. package/dist/components/DirectDownloadButton.js.map +1 -1
  144. package/dist/components/DownloadCart/CreatePackageV2.js.map +1 -1
  145. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.css +1 -0
  146. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.d.ts.map +1 -1
  147. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +199 -132
  148. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
  149. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js +22 -0
  150. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js.map +1 -0
  151. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.scss +170 -0
  152. package/dist/components/DownloadCart/DownloadListActionsRequired.js.map +1 -1
  153. package/dist/components/DownloadCart/DownloadListTable.js.map +1 -1
  154. package/dist/components/DownloadCart/fileNameUtils.js.map +1 -1
  155. package/dist/components/DraggableDialog/DraggableDialog.js.map +1 -1
  156. package/dist/components/DynamicForm/DynamicFormModal.js.map +1 -1
  157. package/dist/components/Ecosystem/TableQueryEcosystem.js.map +1 -1
  158. package/dist/components/EntityAclEditor/EntityAclEditor.d.ts.map +1 -1
  159. package/dist/components/EntityAclEditor/EntityAclEditor.js +103 -103
  160. package/dist/components/EntityAclEditor/EntityAclEditor.js.map +1 -1
  161. package/dist/components/EntityAclEditor/useNotifyNewACLUsers.js.map +1 -1
  162. package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js.map +1 -1
  163. package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
  164. package/dist/components/EntityDownloadButton/EntityDownloadButton.d.ts.map +1 -1
  165. package/dist/components/EntityDownloadButton/EntityDownloadButton.js +1 -0
  166. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  167. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.d.ts.map +1 -1
  168. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js +36 -30
  169. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js.map +1 -1
  170. package/dist/components/EntityFinder/EntityFinder.js.map +1 -1
  171. package/dist/components/EntityFinder/VersionSelectionType.js.map +1 -1
  172. package/dist/components/EntityFinder/details/configurations/EntityChildrenDetails.js.map +1 -1
  173. package/dist/components/EntityFinder/details/configurations/FavoritesDetails.js.map +1 -1
  174. package/dist/components/EntityFinder/details/configurations/ProjectListDetails.js.map +1 -1
  175. package/dist/components/EntityFinder/details/view/DetailsView.js.map +1 -1
  176. package/dist/components/EntityFinder/tree/EntityTree.js.map +1 -1
  177. package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
  178. package/dist/components/EntityFinder/useEntitySelection.js.map +1 -1
  179. package/dist/components/EntityForm/EntityForm.js.map +1 -1
  180. package/dist/components/EntityHeaderTable/EntityHeaderTable.js.map +1 -1
  181. package/dist/components/EntityHeaderTable/Filter.js.map +1 -1
  182. package/dist/components/EntityHeaderTable/useEntityHeaderTableState.js.map +1 -1
  183. package/dist/components/EntitySubjectsSelector/EntitySubjectsSelector.js.map +1 -1
  184. package/dist/components/EntityTreeTable/components/IdColumnHeader.js.map +1 -1
  185. package/dist/components/EntityTreeTable/hooks/useEntityTreeState.js.map +1 -1
  186. package/dist/components/EntityTreeTable/hooks/useTableColumns.js.map +1 -1
  187. package/dist/components/EntityTreeTable/hooks/useTableData.js.map +1 -1
  188. package/dist/components/EntityTreeTable/hooks/useTreeOperationsWithDirectFetch.js.map +1 -1
  189. package/dist/components/EntityUpload/EntityUpload.js.map +1 -1
  190. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.d.ts.map +1 -1
  191. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js +15 -14
  192. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js.map +1 -1
  193. package/dist/components/ExperimentalMode/ExperimentalMode.js.map +1 -1
  194. package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js.map +1 -1
  195. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
  196. package/dist/components/FeaturedDataTabs/QueryPerFacetPlotsCard.js.map +1 -1
  197. package/dist/components/FeaturedDataTabs/SingleQueryFacetPlotsCards.js.map +1 -1
  198. package/dist/components/FeaturedResearch/FeaturedResearch.js.map +1 -1
  199. package/dist/components/FeaturedToolsList/FeaturedToolsList.js.map +1 -1
  200. package/dist/components/FilePreview/FileHandleContentRenderer.js.map +1 -1
  201. package/dist/components/FilePreview/HtmlPreview/HtmlPreview.js.map +1 -1
  202. package/dist/components/FilePreview/PreviewRendererType.js.map +1 -1
  203. package/dist/components/Forum/DiscussionReply.d.ts +1 -0
  204. package/dist/components/Forum/DiscussionReply.d.ts.map +1 -1
  205. package/dist/components/Forum/DiscussionReply.js +19 -19
  206. package/dist/components/Forum/DiscussionReply.js.map +1 -1
  207. package/dist/components/Forum/DiscussionSearchResult.js.map +1 -1
  208. package/dist/components/Forum/DiscussionThread.d.ts +1 -0
  209. package/dist/components/Forum/DiscussionThread.d.ts.map +1 -1
  210. package/dist/components/Forum/DiscussionThread.js +73 -72
  211. package/dist/components/Forum/DiscussionThread.js.map +1 -1
  212. package/dist/components/Forum/ForumTable.js.map +1 -1
  213. package/dist/components/Forum/ForumThreadEditor.js.map +1 -1
  214. package/dist/components/FullTextSearch/FullTextSearchUtils.js.map +1 -1
  215. package/dist/components/GenericCard/BioregistryRules.d.ts.map +1 -1
  216. package/dist/components/GenericCard/BioregistryRules.js +7 -3
  217. package/dist/components/GenericCard/BioregistryRules.js.map +1 -1
  218. package/dist/components/GenericCard/GenericCard.d.ts.map +1 -1
  219. package/dist/components/GenericCard/GenericCard.js +12 -7
  220. package/dist/components/GenericCard/GenericCard.js.map +1 -1
  221. package/dist/components/GenericCard/Linkify.js.map +1 -1
  222. package/dist/components/GenericCard/SynapseCardLabel.js.map +1 -1
  223. package/dist/components/GenericCard/TableRowGenericCard.js +105 -105
  224. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  225. package/dist/components/Goals/Goals.Mobile.js.map +1 -1
  226. package/dist/components/Goals/Goals.js.map +1 -1
  227. package/dist/components/GoalsV2/GoalsV2.Mobile.js.map +1 -1
  228. package/dist/components/GoalsV2/GoalsV2.js.map +1 -1
  229. package/dist/components/GoalsV3/GoalsV3.Mobile.js.map +1 -1
  230. package/dist/components/GoalsV3/GoalsV3.js.map +1 -1
  231. package/dist/components/GoogleMap/SynapseUserMarker.js.map +1 -1
  232. package/dist/components/HasAccess/AccessIcon.js.map +1 -1
  233. package/dist/components/HasAccess/useHasAccess.js.map +1 -1
  234. package/dist/components/HeaderCard/HeaderCardV2.js.map +1 -1
  235. package/dist/components/HeaderCard.d.ts +6 -1
  236. package/dist/components/HeaderCard.d.ts.map +1 -1
  237. package/dist/components/HeaderCard.js +107 -76
  238. package/dist/components/HeaderCard.js.map +1 -1
  239. package/dist/components/HexGrid/HexGrid.js.map +1 -1
  240. package/dist/components/IconList.js.map +1 -1
  241. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  242. package/dist/components/IconSvg/IconSvg.js +2 -1
  243. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  244. package/dist/components/ImageCardGridWithLinks/ImageCardGridWithLinks.js.map +1 -1
  245. package/dist/components/ImageFromSynapseTable.js.map +1 -1
  246. package/dist/components/JSONArrayEditor/useParseCsv.js.map +1 -1
  247. package/dist/components/JsonSchemaForm/templates/ArrayFieldDescriptionTemplate.js.map +1 -1
  248. package/dist/components/JsonSchemaForm/templates/ArrayFieldItemTemplate.js.map +1 -1
  249. package/dist/components/JsonSchemaForm/templates/BaseInputTemplate.js.map +1 -1
  250. package/dist/components/JsonSchemaForm/templates/FieldTemplate.js.map +1 -1
  251. package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js.map +1 -1
  252. package/dist/components/Markdown/MarkdownGithub.js.map +1 -1
  253. package/dist/components/Markdown/MarkdownSynapse.js.map +1 -1
  254. package/dist/components/Markdown/MarkdownUtils.js.map +1 -1
  255. package/dist/components/Markdown/SynapseWikiContext.js.map +1 -1
  256. package/dist/components/Markdown/UserMentionModal.js.map +1 -1
  257. package/dist/components/Markdown/widget/MarkdownProvenanceGraph.js.map +1 -1
  258. package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js.map +1 -1
  259. package/dist/components/ModalDownload/ModalDownload.js.map +1 -1
  260. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.d.ts.map +1 -1
  261. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.js +45 -39
  262. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.js.map +1 -1
  263. package/dist/components/OAuthClientManagement/OAuthManagement.js.map +1 -1
  264. package/dist/components/PageProgress/PageProgress.js.map +1 -1
  265. package/dist/components/Plot/DotPlot.js.map +1 -1
  266. package/dist/components/Plot/Plot.js.map +1 -1
  267. package/dist/components/Plot/SynapsePlot.js.map +1 -1
  268. package/dist/components/Plot/ThemesPlot.js.map +1 -1
  269. package/dist/components/Plot/UpsetPlot.js.map +1 -1
  270. package/dist/components/PortalAclEditor/PortalAclEditor.d.ts.map +1 -1
  271. package/dist/components/PortalAclEditor/PortalAclEditor.js +43 -41
  272. package/dist/components/PortalAclEditor/PortalAclEditor.js.map +1 -1
  273. package/dist/components/PortalFeaturedPartners/PortalFeaturedPartners.js.map +1 -1
  274. package/dist/components/PortalList/CreatePortalModal.js.map +1 -1
  275. package/dist/components/ProgrammaticInstructionsModal/ProgrammaticInstructionsModal.js.map +1 -1
  276. package/dist/components/ProgrammaticTableDownload/ProgrammaticTableDownload.js.map +1 -1
  277. package/dist/components/Programs/Programs.Mobile.js.map +1 -1
  278. package/dist/components/Programs/Programs.js.map +1 -1
  279. package/dist/components/ProvenanceGraph/ProvenanceExternalIcon.js.map +1 -1
  280. package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
  281. package/dist/components/ProvenanceGraph/ProvenanceGraphUtils.js.map +1 -1
  282. package/dist/components/ProvenanceGraph/ProvenanceUtils.js.map +1 -1
  283. package/dist/components/QueryCount/QueryCount.js.map +1 -1
  284. package/dist/components/QueryCountButton/QueryCountButton.js.map +1 -1
  285. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
  286. package/dist/components/QueryWrapper/QueryWrapper.js.map +1 -1
  287. package/dist/components/QueryWrapper/TableQueryUseQueryOptions.js.map +1 -1
  288. package/dist/components/QueryWrapper/TableRowSelectionState.js.map +1 -1
  289. package/dist/components/QueryWrapper/generateEncodedPathAndQueryForSelectedFacetURL.js.map +1 -1
  290. package/dist/components/QueryWrapper/useGetQueryMetadata.js.map +1 -1
  291. package/dist/components/QueryWrapperErrorBoundary.js.map +1 -1
  292. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
  293. package/dist/components/QueryWrapperPlotNav/UseRowSet.js.map +1 -1
  294. package/dist/components/RecentPublicationsGrid/RecentPublicationsGrid.js.map +1 -1
  295. package/dist/components/ReleaseCard/ReleaseCardUtils.js.map +1 -1
  296. package/dist/components/ResizableContainer/hooks/useResizable.js.map +1 -1
  297. package/dist/components/Resources/Resources.Mobile.js.map +1 -1
  298. package/dist/components/Resources/Resources.js.map +1 -1
  299. package/dist/components/RowDataTable/RowDataTableWithQuery.js.map +1 -1
  300. package/dist/components/SageResourcesPopover/SageResourcesPopover.js.map +1 -1
  301. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js.map +1 -1
  302. package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
  303. package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.js.map +1 -1
  304. package/dist/components/SmartLink/SmartButton.js.map +1 -1
  305. package/dist/components/SmartLink/SmartLink.js.map +1 -1
  306. package/dist/components/SourceAppImage.js.map +1 -1
  307. package/dist/components/StandaloneQueryWrapper/StandaloneQueryWrapper.js.map +1 -1
  308. package/dist/components/StatisticsPlot.js.map +1 -1
  309. package/dist/components/StorybookComponentWrapper.js.map +1 -1
  310. package/dist/components/SubsectionRowRenderer/SubsectionRowRenderer.js.map +1 -1
  311. package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js.map +1 -1
  312. package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
  313. package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
  314. package/dist/components/SynapseChat/SynapseChatMessage.js.map +1 -1
  315. package/dist/components/SynapseChat/extractMessageFromTraceEvent.js.map +1 -1
  316. package/dist/components/SynapseForm/StepsSideNav.js.map +1 -1
  317. package/dist/components/SynapseForm/SummaryTable.js.map +1 -1
  318. package/dist/components/SynapseForm/SynapseForm.js +4 -2
  319. package/dist/components/SynapseForm/SynapseForm.js.map +1 -1
  320. package/dist/components/SynapseForm/SynapseFormWrapper.js.map +1 -1
  321. package/dist/components/SynapseHomepageV2/SynapseByTheNumbersItem.js.map +1 -1
  322. package/dist/components/SynapseHomepageV2/SynapseFeatureItem.js.map +1 -1
  323. package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js.map +1 -1
  324. package/dist/components/SynapseHomepageV2/SynapseHomepageSearch.js.map +1 -1
  325. package/dist/components/SynapseHomepageV2/SynapseInActionItem.js.map +1 -1
  326. package/dist/components/SynapseHomepageV2/SynapsePlans.js.map +1 -1
  327. package/dist/components/SynapseHomepageV2/SynapseTrendingProjects.js.map +1 -1
  328. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts +8 -7
  329. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts.map +1 -1
  330. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js +173 -164
  331. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js.map +1 -1
  332. package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js.map +1 -1
  333. package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanel.js.map +1 -1
  334. package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanelUtils.js.map +1 -1
  335. package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js.map +1 -1
  336. package/dist/components/SynapseTable/EntityIDColumnCopyIcon.js.map +1 -1
  337. package/dist/components/SynapseTable/NoContentPlaceholderType.js.map +1 -1
  338. package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js.map +1 -1
  339. package/dist/components/SynapseTable/SynapseTableCell/SynapseTableCell.js.map +1 -1
  340. package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
  341. package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
  342. package/dist/components/SynapseTable/table-top/ColumnSelection.js.map +1 -1
  343. package/dist/components/SynapseTable/table-top/DownloadOptions.js.map +1 -1
  344. package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
  345. package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js.map +1 -1
  346. package/dist/components/TableColumnSchemaEditor/ColumnModelFormFields/DefaultValueField.js.map +1 -1
  347. package/dist/components/TableColumnSchemaEditor/ImportTableColumnsButton.js.map +1 -1
  348. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts +1 -1
  349. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts.map +1 -1
  350. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
  351. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
  352. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js.map +1 -1
  353. package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.js.map +1 -1
  354. package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.js.map +1 -1
  355. package/dist/components/TanStackTable/ColumnHeader.d.ts +1 -0
  356. package/dist/components/TanStackTable/ColumnHeader.d.ts.map +1 -1
  357. package/dist/components/TanStackTable/ColumnHeader.js +8 -8
  358. package/dist/components/TanStackTable/ColumnHeader.js.map +1 -1
  359. package/dist/components/TanStackTable/ColumnHeaderEnumFilter.js.map +1 -1
  360. package/dist/components/TanStackTable/TableBody.js.map +1 -1
  361. package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js.map +1 -1
  362. package/dist/components/TextField/TextField.js.map +1 -1
  363. package/dist/components/TimelinePlot/TimelinePhase.js.map +1 -1
  364. package/dist/components/TimelinePlot/TimelinePlot.js.map +1 -1
  365. package/dist/components/TimelinePlot/TimelinePlotSpeciesSelector.js.map +1 -1
  366. package/dist/components/UserCard/Avatar.js.map +1 -1
  367. package/dist/components/UserCardList/UserCardList.js.map +1 -1
  368. package/dist/components/UserCardList/UserCardListGroups/UserCardListGroups.Mobile.js.map +1 -1
  369. package/dist/components/UserCardList/UserCardListRotate.js.map +1 -1
  370. package/dist/components/UserOrTeamBadge/useUserOrTeam.js.map +1 -1
  371. package/dist/components/UserProfileLinks/UserProjects.js.map +1 -1
  372. package/dist/components/UserSearchBox/UserSearchBox.js.map +1 -1
  373. package/dist/components/Webhook/WebhookDashboard.js.map +1 -1
  374. package/dist/components/WikiMarkdownEditor/WikiMarkdownEditor.js.map +1 -1
  375. package/dist/components/WikiMarkdownEditorButton/WikiMarkdownEditorButton.js.map +1 -1
  376. package/dist/components/dataaccess/AccessApprovalsTable.js.map +1 -1
  377. package/dist/components/dataaccess/AccessRequestSubmissionTable.js.map +1 -1
  378. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.d.ts.map +1 -1
  379. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +157 -148
  380. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js.map +1 -1
  381. package/dist/components/dataaccess/UseAccessRequirementTable.js.map +1 -1
  382. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js.map +1 -1
  383. package/dist/components/doi/CreateOrUpdateDoiModal.d.ts.map +1 -1
  384. package/dist/components/doi/CreateOrUpdateDoiModal.js +20 -19
  385. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  386. package/dist/components/entity/page/CreatedByModifiedBy.js.map +1 -1
  387. package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
  388. package/dist/components/entity/page/title_bar/useDataCiteUsage.js.map +1 -1
  389. package/dist/components/entity/page/title_bar/useGetMentions.js.map +1 -1
  390. package/dist/components/error/ErrorPage.js.map +1 -1
  391. package/dist/components/favorites/FavoritesPage.js.map +1 -1
  392. package/dist/components/file/upload/BasicFileHandleUpload.js.map +1 -1
  393. package/dist/components/layout/SWCHeader.d.ts +9 -0
  394. package/dist/components/layout/SWCHeader.d.ts.map +1 -0
  395. package/dist/components/layout/SWCHeader.js +19 -0
  396. package/dist/components/layout/SWCHeader.js.map +1 -0
  397. package/dist/components/layout/SWCPageLayout.d.ts +9 -0
  398. package/dist/components/layout/SWCPageLayout.d.ts.map +1 -0
  399. package/dist/components/layout/SWCPageLayout.js +14 -0
  400. package/dist/components/layout/SWCPageLayout.js.map +1 -0
  401. package/dist/components/menu/ComplexMenu.js.map +1 -1
  402. package/dist/components/row_renderers/utils/ChipContainer.js.map +1 -1
  403. package/dist/components/styled/StyledPopover.js.map +1 -1
  404. package/dist/components/table/CsvPreview/CsvPreview.js +2 -1
  405. package/dist/components/table/CsvPreview/CsvPreview.js.map +1 -1
  406. package/dist/components/table/CsvPreview/CsvPreviewDialog.js.map +1 -1
  407. package/dist/components/trash/TrashCanList.js.map +1 -1
  408. package/dist/components/widgets/FileHandleLink.js.map +1 -1
  409. package/dist/components/widgets/RangeSlider/RangeSlider.js.map +1 -1
  410. package/dist/components/widgets/SynapseVideo.js.map +1 -1
  411. package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
  412. package/dist/components/widgets/facet-nav/PlotsContainer.js.map +1 -1
  413. package/dist/components/widgets/facet-nav/SelectionCriteriaPills.js.map +1 -1
  414. package/dist/components/widgets/facet-nav/useFacetPlots.js.map +1 -1
  415. package/dist/components/widgets/query-filter/CombinedRangeFacetFilter.js.map +1 -1
  416. package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
  417. package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
  418. package/dist/components/widgets/query-filter/RangeFacetFilter.js.map +1 -1
  419. package/dist/components/widgets/query-filter/RangeFacetFilterUI.js.map +1 -1
  420. package/dist/features/curator/GridPage/components/GridPageTitle.d.ts.map +1 -1
  421. package/dist/features/curator/GridPage/components/GridPageTitle.js +23 -30
  422. package/dist/features/curator/GridPage/components/GridPageTitle.js.map +1 -1
  423. package/dist/features/curator/dashboard/CuratorDashboard.d.ts +2 -0
  424. package/dist/features/curator/dashboard/CuratorDashboard.d.ts.map +1 -0
  425. package/dist/features/curator/dashboard/CuratorDashboard.js +45 -0
  426. package/dist/features/curator/dashboard/CuratorDashboard.js.map +1 -0
  427. package/dist/features/curator/dashboard/components/CurationTaskCard.css +1 -0
  428. package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts +9 -0
  429. package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts.map +1 -0
  430. package/dist/features/curator/dashboard/components/CurationTaskCard.js +106 -0
  431. package/dist/features/curator/dashboard/components/CurationTaskCard.js.map +1 -0
  432. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js +12 -0
  433. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js.map +1 -0
  434. package/dist/features/curator/dashboard/components/CurationTaskCard.module.scss +52 -0
  435. package/dist/features/curator/dashboard/components/NextStepButton.css +1 -0
  436. package/dist/features/curator/dashboard/components/NextStepButton.d.ts +14 -0
  437. package/dist/features/curator/dashboard/components/NextStepButton.d.ts.map +1 -0
  438. package/dist/features/curator/dashboard/components/NextStepButton.js +35 -0
  439. package/dist/features/curator/dashboard/components/NextStepButton.js.map +1 -0
  440. package/dist/features/curator/dashboard/components/NextStepButton.module.js +11 -0
  441. package/dist/features/curator/dashboard/components/NextStepButton.module.js.map +1 -0
  442. package/dist/features/curator/dashboard/components/NextStepButton.module.scss +57 -0
  443. package/dist/features/curator/dashboard/components/UserOrTeamChip.css +1 -1
  444. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.js +1 -1
  445. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.js.map +1 -1
  446. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.scss +5 -5
  447. package/dist/features/curator/dashboard/components/shared.css +1 -0
  448. package/dist/features/curator/dashboard/components/shared.module.js +5 -0
  449. package/dist/features/curator/dashboard/components/shared.module.js.map +1 -0
  450. package/dist/features/curator/dashboard/components/shared.module.scss +8 -0
  451. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts +0 -2
  452. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
  453. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +16 -34
  454. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  455. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts.map +1 -1
  456. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +1 -1
  457. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  458. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js.map +1 -1
  459. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js.map +1 -1
  460. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js.map +1 -1
  461. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js +1 -1
  462. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js.map +1 -1
  463. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts +10 -0
  464. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts.map +1 -0
  465. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js +37 -0
  466. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js.map +1 -0
  467. package/dist/features/entity/metadata-task/utils/constants.d.ts +5 -0
  468. package/dist/features/entity/metadata-task/utils/constants.d.ts.map +1 -0
  469. package/dist/features/entity/metadata-task/utils/constants.js +6 -0
  470. package/dist/features/entity/metadata-task/utils/constants.js.map +1 -0
  471. package/dist/mocks/challenge/mockChallenge.js.map +1 -1
  472. package/dist/mocks/entity/mockDataset.js.map +1 -1
  473. package/dist/mocks/entity/mockDatasetCollection.js.map +1 -1
  474. package/dist/mocks/entity/mockFileEntity.js.map +1 -1
  475. package/dist/mocks/entity/mockFileView.js.map +1 -1
  476. package/dist/mocks/entity/mockGeneratedEntityData.js.map +1 -1
  477. package/dist/mocks/entity/mockProject.js.map +1 -1
  478. package/dist/mocks/entity/mockProjectView.js.map +1 -1
  479. package/dist/mocks/entity/mockRootEntity.js.map +1 -1
  480. package/dist/mocks/entity/mockTableEntity.js.map +1 -1
  481. package/dist/mocks/mockWiki.js.map +1 -1
  482. package/dist/mocks/msw/handlers/asyncJobHandlers.js.map +1 -1
  483. package/dist/mocks/msw/handlers/challengeHandlers.js.map +1 -1
  484. package/dist/mocks/msw/handlers/changePasswordHandlers.js.map +1 -1
  485. package/dist/mocks/msw/handlers/discussionHandlers.js.map +1 -1
  486. package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
  487. package/dist/mocks/msw/handlers/fileHandlers.js.map +1 -1
  488. package/dist/mocks/msw/handlers/gridHandlers.js.map +1 -1
  489. package/dist/mocks/msw/handlers/personalAccessTokenHandlers.js.map +1 -1
  490. package/dist/mocks/msw/handlers/subscriptionHandlers.js.map +1 -1
  491. package/dist/mocks/msw/handlers/teamHandlers.js.map +1 -1
  492. package/dist/mocks/msw/handlers/userProfileHandlers.js.map +1 -1
  493. package/dist/mocks/msw/handlers/wikiHandlers.js.map +1 -1
  494. package/dist/mocks/provenance/mockActivity.js.map +1 -1
  495. package/dist/mocks/query/mockReleaseCardsTableQueryResultBundle.js.map +1 -1
  496. package/dist/ror-client/index.js.map +1 -1
  497. package/dist/style/components/_cards.scss +4 -0
  498. package/dist/style/components/_data-grid-extra.css +1 -1
  499. package/dist/style/components/_data-grid-extra.scss +2 -0
  500. package/dist/style/main.css +1 -1
  501. package/dist/synapse-client/HttpClient.js.map +1 -1
  502. package/dist/synapse-client/SynapseClient.js.map +1 -1
  503. package/dist/synapse-queries/KeyFactory.d.ts +1 -0
  504. package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
  505. package/dist/synapse-queries/KeyFactory.js +3 -0
  506. package/dist/synapse-queries/KeyFactory.js.map +1 -1
  507. package/dist/synapse-queries/QueryMatching.test-utils.js.map +1 -1
  508. package/dist/synapse-queries/auth/useTwoFactorEnrollment.js.map +1 -1
  509. package/dist/synapse-queries/curation/task/useCurationTask.d.ts +1 -1
  510. package/dist/synapse-queries/curation/task/useCurationTask.d.ts.map +1 -1
  511. package/dist/synapse-queries/curation/task/useCurationTask.js +1 -1
  512. package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
  513. package/dist/synapse-queries/dataaccess/useRestrictionInformation.js.map +1 -1
  514. package/dist/synapse-queries/doi/useDOI.js.map +1 -1
  515. package/dist/synapse-queries/download/useDownloadList.js.map +1 -1
  516. package/dist/synapse-queries/entity/useEntity.js.map +1 -1
  517. package/dist/synapse-queries/entity/useEntityBundle.js.map +1 -1
  518. package/dist/synapse-queries/entity/useExportTableQueryToAnalysisPlatform.js.map +1 -1
  519. package/dist/synapse-queries/entity/useExportToTerra.js.map +1 -1
  520. package/dist/synapse-queries/entity/useGetQueryResultBundle.js.map +1 -1
  521. package/dist/synapse-queries/entity/useSchema.js.map +1 -1
  522. package/dist/synapse-queries/file/UploadToS3.js.map +1 -1
  523. package/dist/synapse-queries/file/useDirectUploadToS3.js.map +1 -1
  524. package/dist/synapse-queries/file/useFiles.js.map +1 -1
  525. package/dist/synapse-queries/forum/useReply.js.map +1 -1
  526. package/dist/synapse-queries/forum/useThread.d.ts +1 -0
  527. package/dist/synapse-queries/forum/useThread.d.ts.map +1 -1
  528. package/dist/synapse-queries/forum/useThread.js +19 -12
  529. package/dist/synapse-queries/forum/useThread.js.map +1 -1
  530. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts +2 -0
  531. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts.map +1 -1
  532. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js.map +1 -1
  533. package/dist/synapse-queries/grid/useExportGrid.js.map +1 -1
  534. package/dist/synapse-queries/grid/useGridSession.js.map +1 -1
  535. package/dist/synapse-queries/grid/useImportCsvIntoGrid.js.map +1 -1
  536. package/dist/synapse-queries/subscription/useSubscription.js.map +1 -1
  537. package/dist/synapse-queries/table/useGetCsvPreview.js.map +1 -1
  538. package/dist/synapse-queries/table/useTableUpdateTransaction.js.map +1 -1
  539. package/dist/synapse-queries/team/useTeamMembers.js.map +1 -1
  540. package/dist/synapse-queries/user/useGetUserChallenges.js.map +1 -1
  541. package/dist/synapse-queries/user/useUserBundle.js.map +1 -1
  542. package/dist/synapse-queries/user/useUserGroupHeader.js.map +1 -1
  543. package/dist/testutils/ReactQueryMockUtils.js.map +1 -1
  544. package/dist/theme/ThemeProvider.js.map +1 -1
  545. package/dist/tsconfig.build.tsbuildinfo +1 -1
  546. package/dist/utils/APIConstants.d.ts +1 -0
  547. package/dist/utils/APIConstants.d.ts.map +1 -1
  548. package/dist/utils/APIConstants.js +2 -2
  549. package/dist/utils/APIConstants.js.map +1 -1
  550. package/dist/utils/AppUtils/session/ApplicationSessionManager.d.ts.map +1 -1
  551. package/dist/utils/AppUtils/session/ApplicationSessionManager.js +7 -4
  552. package/dist/utils/AppUtils/session/ApplicationSessionManager.js.map +1 -1
  553. package/dist/utils/AppUtils/session/SynapseSessionManager.js.map +1 -1
  554. package/dist/utils/AppUtils/session/useSessionManager.js.map +1 -1
  555. package/dist/utils/PermissionLevelToAccessType.js.map +1 -1
  556. package/dist/utils/challenge/evaluation/EvaluationUtils.js.map +1 -1
  557. package/dist/utils/context/SynapseContext.js.map +1 -1
  558. package/dist/utils/functions/AccessControlListUtils.d.ts +4 -0
  559. package/dist/utils/functions/AccessControlListUtils.d.ts.map +1 -1
  560. package/dist/utils/functions/AccessControlListUtils.js +12 -1
  561. package/dist/utils/functions/AccessControlListUtils.js.map +1 -1
  562. package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
  563. package/dist/utils/functions/EntityTypeUtils.js +15 -4
  564. package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
  565. package/dist/utils/functions/GridApiUtils.js.map +1 -1
  566. package/dist/utils/functions/QueryFilterUtils.js.map +1 -1
  567. package/dist/utils/functions/RealmUtils.d.ts +4 -0
  568. package/dist/utils/functions/RealmUtils.d.ts.map +1 -1
  569. package/dist/utils/functions/RealmUtils.js +9 -3
  570. package/dist/utils/functions/RealmUtils.js.map +1 -1
  571. package/dist/utils/functions/SanitizeHtmlUtils.js.map +1 -1
  572. package/dist/utils/functions/SanitizeHtmlUtils.test-utils.js.map +1 -1
  573. package/dist/utils/functions/SqlFunctions.js.map +1 -1
  574. package/dist/utils/functions/StringUtils.js.map +1 -1
  575. package/dist/utils/functions/deepLinkingUtils.js.map +1 -1
  576. package/dist/utils/functions/getDataFromFromStorage.js.map +1 -1
  577. package/dist/utils/functions/getEndpoint.js.map +1 -1
  578. package/dist/utils/functions/getUserData.js.map +1 -1
  579. package/dist/utils/functions/queryUtils.js.map +1 -1
  580. package/dist/utils/functions/testDownloadSpeed.js.map +1 -1
  581. package/dist/utils/hooks/useConfirmItems.js.map +1 -1
  582. package/dist/utils/hooks/useCookiePreferences.js.map +1 -1
  583. package/dist/utils/hooks/useCreateShortUrl.js.map +1 -1
  584. package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
  585. package/dist/utils/hooks/useDirectDownloadHandler.js.map +1 -1
  586. package/dist/utils/hooks/useGetGoalData.js.map +1 -1
  587. package/dist/utils/hooks/useGetInfoFromIds.js.map +1 -1
  588. package/dist/utils/hooks/useImageUrlUtils.js.map +1 -1
  589. package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js.map +1 -1
  590. package/dist/utils/hooks/useImmutableTableQuery/useTableQueryReducer.js.map +1 -1
  591. package/dist/utils/hooks/useIsBot.js.map +1 -1
  592. package/dist/utils/hooks/useListState.js.map +1 -1
  593. package/dist/utils/hooks/useLogin.d.ts.map +1 -1
  594. package/dist/utils/hooks/useLogin.js +53 -52
  595. package/dist/utils/hooks/useLogin.js.map +1 -1
  596. package/dist/utils/hooks/useMutuallyExclusiveState.js.map +1 -1
  597. package/dist/utils/hooks/useOverlay.js.map +1 -1
  598. package/dist/utils/hooks/usePreFetchResource.js.map +1 -1
  599. package/dist/utils/hooks/useQuerySearchParam.js.map +1 -1
  600. package/dist/utils/hooks/useScrollFadeTransition.js.map +1 -1
  601. package/dist/utils/hooks/useSet.js.map +1 -1
  602. package/dist/utils/hooks/useSourceAppConfigs.js.map +1 -1
  603. package/dist/utils/hooks/useTableImageUrl.js.map +1 -1
  604. package/dist/utils/hooks/useUploadFileEntity/useCreatePathsAndGetParentId.js.map +1 -1
  605. package/dist/utils/hooks/useUploadFileEntity/useLinkFileEntityToURL.js.map +1 -1
  606. package/dist/utils/hooks/useUploadFileEntity/usePrepareFileEntityUpload.js.map +1 -1
  607. package/dist/utils/hooks/useUploadFileEntity/useTrackFileUploads.js.map +1 -1
  608. package/dist/utils/hooks/useUploadFileEntity/useUploadFileEntities.js.map +1 -1
  609. package/dist/utils/hooks/useUploadFileEntity/useUploadFiles.js.map +1 -1
  610. package/dist/utils/hooks/useUploadFileEntity/willUploadsExceedStorageLimit.js.map +1 -1
  611. package/dist/utils/html/TargetEnum.js.map +1 -1
  612. package/dist/utils/jsonschema/SchemaAnnotationUtils.js.map +1 -1
  613. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"SynapseTableCell.js","names":[],"sources":["../../../../src/components/SynapseTable/SynapseTableCell/SynapseTableCell.tsx"],"sourcesContent":["import { CardLink } from '@/components/CardContainer/CardLink'\nimport { useGetEntity } from '@/synapse-queries'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n isDataset,\n isDatasetCollection,\n isEntityView,\n} from '@/utils/functions/EntityTypeUtils'\nimport { Link, Typography } from '@mui/material'\nimport {\n ColumnModel,\n ColumnType,\n ColumnTypeEnum,\n FileHandleAssociateType,\n Row,\n SelectColumn,\n Table,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { Fragment, memo } from 'react'\nimport { ColumnSpecifiedLink, MarkdownLink } from '../../CardContainerLogic'\nimport {\n EntityImage,\n MapValueToReactComponentConfig,\n} from '../../CardContainerLogic/CardContainerLogic'\nimport DirectDownload from '../../DirectDownload/DirectDownload'\nimport { EntityLink, EntityLinkProps } from '../../EntityLink'\nimport { SynapseCardLabel } from '../../GenericCard'\nimport Linkify from '../../GenericCard/Linkify'\nimport { useQueryContext } from '../../QueryContext'\nimport UserOrTeamBadge from '../../UserOrTeamBadge'\nimport { NOT_SET_DISPLAY_VALUE } from '../SynapseTableConstants'\nimport { isFileViewOrDataset } from '../SynapseTableUtils'\nimport EntityIdList from './EntityIdList'\nimport EvaluationIdRenderer from './EvaluationIdRenderer'\nimport JSONTableCellRenderer from './JSON/JSONTableCellRenderer'\nimport UserIdList from './UserIdList'\n\nexport type SynapseTableCellProps = {\n columnType: ColumnType\n columnValue: string | null\n isBold: string\n columnLinkConfig?:\n | CardLink\n | MarkdownLink\n | ColumnSpecifiedLink\n | EntityImage\n | MapValueToReactComponentConfig\n columnName: string\n selectColumns?: SelectColumn[]\n columnModels?: ColumnModel[]\n rowData: Row['values']\n rowId?: string\n rowVersionNumber?: number\n isRowEntityColumn?: boolean\n}\n\nfunction getDisplayTextFieldForEntityIdColumn(\n columnName: string,\n): EntityLinkProps['displayTextField'] {\n // SWC-7235 - For any table type, if the column is an ENTITYID and the column name is 'id', then display the ID.\n // Otherwise, display the entity name.\n if (columnName.toLowerCase() === 'id') {\n return 'id'\n }\n return 'name'\n}\n\nfunction SynapseTableCell(props: SynapseTableCellProps) {\n const {\n columnType,\n columnValue,\n isBold,\n columnLinkConfig,\n columnName,\n selectColumns,\n columnModels,\n rowData,\n rowId,\n rowVersionNumber,\n isRowEntityColumn,\n } = props\n const { entityId, versionNumber } = useQueryContext()\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n\n if (!columnValue) {\n return (\n <div className=\"SynapseTableCellContent SRC-inactive\">\n {NOT_SET_DISPLAY_VALUE}\n </div>\n )\n }\n\n if (columnLinkConfig) {\n return (\n <SynapseCardLabel\n value={columnValue}\n columnName={columnName}\n selectColumns={selectColumns}\n columnModels={columnModels}\n isHeader={false}\n labelLink={columnLinkConfig}\n rowData={rowData}\n rowId={rowId}\n />\n )\n }\n\n // PORTALS-2095: Special case. If this is an EntityView, and we are rendering the 'id' or 'name' column,\n // and we have a rowId and rowVersionNumber (should always be the case), and our entityIdToHeader map\n // contains the row Synapse ID, then auto-link.\n const tableRowRepresentsEntity =\n entity &&\n (isEntityView(entity) || isDataset(entity) || isDatasetCollection(entity))\n if (\n (tableRowRepresentsEntity || isRowEntityColumn) &&\n (columnName === 'id' || columnName === 'name') &&\n rowId &&\n rowVersionNumber\n ) {\n return (\n <div className=\"SynapseTableCellContent\">\n <EntityLink\n entity={rowId}\n versionNumber={rowVersionNumber}\n className={`${isBold}`}\n showIcon={false}\n displayTextField={columnName}\n />\n </div>\n )\n }\n\n switch (columnType) {\n case ColumnTypeEnum.ENTITYID: {\n const displayTextField = getDisplayTextFieldForEntityIdColumn(columnName)\n return (\n <div className=\"SynapseTableCellContent\">\n <EntityLink\n entity={columnValue}\n className={`${isBold}`}\n displayTextField={displayTextField}\n showIcon={false}\n />\n </div>\n )\n }\n case ColumnTypeEnum.DATE_LIST: {\n const jsonData: number[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n {jsonData.map((val: number, index: number) => {\n return (\n <span key={index} className={isBold}>\n {formatDate(dayjs(Number(val)))}\n {index !== jsonData.length - 1 ? ', ' : ''}\n </span>\n )\n })}{' '}\n </div>\n )\n }\n case ColumnTypeEnum.BOOLEAN_LIST: {\n const jsonData: boolean[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n {jsonData.map((val: boolean, index: number) => {\n return (\n <span key={index} className={isBold}>\n {val ? 'true' : 'false'}\n {index !== jsonData.length - 1 ? ', ' : ''}\n </span>\n )\n })}\n </div>\n )\n }\n case ColumnTypeEnum.FILEHANDLEID: {\n let associatedObjectId = entity!.id!\n let associatedObjectType = FileHandleAssociateType.TableEntity\n if (isFileViewOrDataset(entity) && columnName === 'dataFileHandleId') {\n associatedObjectId = String(rowId)\n associatedObjectType = FileHandleAssociateType.FileEntity\n }\n return (\n <>\n {entity && (\n <div className=\"SynapseTableCellContent\">\n <DirectDownload\n iconSvgPropOverrides={{ sx: { color: 'primary.main' } }}\n associatedObjectId={associatedObjectId}\n associatedObjectType={associatedObjectType}\n fileHandleId={columnValue}\n displayFileName={true}\n />\n </div>\n )}\n </>\n )\n }\n case ColumnTypeEnum.ENTITYID_LIST: {\n const displayTextField = getDisplayTextFieldForEntityIdColumn(columnName)\n const jsonData: string[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n <EntityIdList\n entityIdList={jsonData}\n displayTextField={displayTextField}\n showIcon={false}\n />\n </div>\n )\n }\n case ColumnTypeEnum.USERID_LIST: {\n const jsonData: string[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n <UserIdList userIds={jsonData} />\n </div>\n )\n }\n // handle other list types\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.INTEGER_LIST: {\n const jsonData: string[] = JSON.parse(columnValue)\n return (\n <div className={`SynapseTableCellContent ${isBold}`}>\n {jsonData.map((val: string, index: number) => {\n const textRenderer =\n columnType == ColumnTypeEnum.STRING_LIST ? (\n <Linkify text={val} />\n ) : (\n <>{val}</>\n )\n return (\n <Fragment key={val}>\n {textRenderer}\n {index !== jsonData.length - 1 ? ', ' : ''}\n </Fragment>\n )\n })}\n </div>\n )\n }\n case ColumnTypeEnum.EVALUATIONID: {\n return (\n <div className=\"SynapseTableCellContent\">\n <EvaluationIdRenderer evaluationId={columnValue} />\n </div>\n )\n }\n\n case ColumnTypeEnum.DATE:\n return (\n <div className={`SynapseTableCellContent ${isBold}`}>\n {formatDate(dayjs(Number(columnValue)))}\n </div>\n )\n\n case ColumnTypeEnum.USERID:\n return (\n <div className=\"SynapseTableCellContent\">\n <UserOrTeamBadge principalId={columnValue} />\n </div>\n )\n case ColumnTypeEnum.LINK:\n return (\n <div className=\"SynapseTableCellContent\">\n <Link target=\"_blank\" rel=\"noopener noreferrer\" href={columnValue}>\n {columnValue}\n </Link>\n </div>\n )\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.BOOLEAN:\n case ColumnTypeEnum.MEDIUMTEXT:\n case ColumnTypeEnum.LARGETEXT: {\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography variant={'smallText1'} className={isBold}>\n <Linkify text={columnValue} />\n </Typography>\n </div>\n )\n }\n case ColumnTypeEnum.INTEGER:\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography\n variant={'smallText1'}\n sx={{ textAlign: 'right' }}\n className={isBold}\n >\n {parseInt(columnValue).toLocaleString()}\n </Typography>\n </div>\n )\n case ColumnTypeEnum.DOUBLE:\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography\n variant={'smallText1'}\n sx={{ textAlign: 'right' }}\n className={isBold}\n >\n {parseFloat(columnValue).toLocaleString()}\n </Typography>\n </div>\n )\n case ColumnTypeEnum.JSON:\n return (\n <div className=\"SynapseTableCellContent\">\n <JSONTableCellRenderer value={columnValue} />\n </div>\n )\n default:\n console.warn(\n `ColumnType ${columnType} has unspecified handler. Rendering the column value.`,\n )\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography variant={'smallText1'} className={isBold}>\n {columnValue}\n </Typography>\n </div>\n )\n }\n // We can reach this if we don't get a mapping of IDs to entities or principals.\n // TODO: If we don't have a id:data mapping, we should render a component that can fetch the required data, rather than breaking from the case.\n return (\n <div className={`SynapseTableCellContent ${isBold}`}>{columnValue}</div>\n )\n}\n\nexport default memo(SynapseTableCell)\n"],"mappings":"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"}
1
+ {"version":3,"file":"SynapseTableCell.js","names":[],"sources":["../../../../src/components/SynapseTable/SynapseTableCell/SynapseTableCell.tsx"],"sourcesContent":["import { CardLink } from '@/components/CardContainer/CardLink'\nimport { useGetEntity } from '@/synapse-queries'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n isDataset,\n isDatasetCollection,\n isEntityView,\n} from '@/utils/functions/EntityTypeUtils'\nimport { Link, Typography } from '@mui/material'\nimport {\n ColumnModel,\n ColumnType,\n ColumnTypeEnum,\n FileHandleAssociateType,\n Row,\n SelectColumn,\n Table,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { Fragment, memo } from 'react'\nimport { ColumnSpecifiedLink, MarkdownLink } from '../../CardContainerLogic'\nimport {\n EntityImage,\n MapValueToReactComponentConfig,\n} from '../../CardContainerLogic/CardContainerLogic'\nimport DirectDownload from '../../DirectDownload/DirectDownload'\nimport { EntityLink, EntityLinkProps } from '../../EntityLink'\nimport { SynapseCardLabel } from '../../GenericCard'\nimport Linkify from '../../GenericCard/Linkify'\nimport { useQueryContext } from '../../QueryContext'\nimport UserOrTeamBadge from '../../UserOrTeamBadge'\nimport { NOT_SET_DISPLAY_VALUE } from '../SynapseTableConstants'\nimport { isFileViewOrDataset } from '../SynapseTableUtils'\nimport EntityIdList from './EntityIdList'\nimport EvaluationIdRenderer from './EvaluationIdRenderer'\nimport JSONTableCellRenderer from './JSON/JSONTableCellRenderer'\nimport UserIdList from './UserIdList'\n\nexport type SynapseTableCellProps = {\n columnType: ColumnType\n columnValue: string | null\n isBold: string\n columnLinkConfig?:\n | CardLink\n | MarkdownLink\n | ColumnSpecifiedLink\n | EntityImage\n | MapValueToReactComponentConfig\n columnName: string\n selectColumns?: SelectColumn[]\n columnModels?: ColumnModel[]\n rowData: Row['values']\n rowId?: string\n rowVersionNumber?: number\n isRowEntityColumn?: boolean\n}\n\nfunction getDisplayTextFieldForEntityIdColumn(\n columnName: string,\n): EntityLinkProps['displayTextField'] {\n // SWC-7235 - For any table type, if the column is an ENTITYID and the column name is 'id', then display the ID.\n // Otherwise, display the entity name.\n if (columnName.toLowerCase() === 'id') {\n return 'id'\n }\n return 'name'\n}\n\nfunction SynapseTableCell(props: SynapseTableCellProps) {\n const {\n columnType,\n columnValue,\n isBold,\n columnLinkConfig,\n columnName,\n selectColumns,\n columnModels,\n rowData,\n rowId,\n rowVersionNumber,\n isRowEntityColumn,\n } = props\n const { entityId, versionNumber } = useQueryContext()\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n\n if (!columnValue) {\n return (\n <div className=\"SynapseTableCellContent SRC-inactive\">\n {NOT_SET_DISPLAY_VALUE}\n </div>\n )\n }\n\n if (columnLinkConfig) {\n return (\n <SynapseCardLabel\n value={columnValue}\n columnName={columnName}\n selectColumns={selectColumns}\n columnModels={columnModels}\n isHeader={false}\n labelLink={columnLinkConfig}\n rowData={rowData}\n rowId={rowId}\n />\n )\n }\n\n // PORTALS-2095: Special case. If this is an EntityView, and we are rendering the 'id' or 'name' column,\n // and we have a rowId and rowVersionNumber (should always be the case), and our entityIdToHeader map\n // contains the row Synapse ID, then auto-link.\n const tableRowRepresentsEntity =\n entity &&\n (isEntityView(entity) || isDataset(entity) || isDatasetCollection(entity))\n if (\n (tableRowRepresentsEntity || isRowEntityColumn) &&\n (columnName === 'id' || columnName === 'name') &&\n rowId &&\n rowVersionNumber\n ) {\n return (\n <div className=\"SynapseTableCellContent\">\n <EntityLink\n entity={rowId}\n versionNumber={rowVersionNumber}\n className={`${isBold}`}\n showIcon={false}\n displayTextField={columnName}\n />\n </div>\n )\n }\n\n switch (columnType) {\n case ColumnTypeEnum.ENTITYID: {\n const displayTextField = getDisplayTextFieldForEntityIdColumn(columnName)\n return (\n <div className=\"SynapseTableCellContent\">\n <EntityLink\n entity={columnValue}\n className={`${isBold}`}\n displayTextField={displayTextField}\n showIcon={false}\n />\n </div>\n )\n }\n case ColumnTypeEnum.DATE_LIST: {\n const jsonData: number[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n {jsonData.map((val: number, index: number) => {\n return (\n <span key={index} className={isBold}>\n {formatDate(dayjs(Number(val)))}\n {index !== jsonData.length - 1 ? ', ' : ''}\n </span>\n )\n })}{' '}\n </div>\n )\n }\n case ColumnTypeEnum.BOOLEAN_LIST: {\n const jsonData: boolean[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n {jsonData.map((val: boolean, index: number) => {\n return (\n <span key={index} className={isBold}>\n {val ? 'true' : 'false'}\n {index !== jsonData.length - 1 ? ', ' : ''}\n </span>\n )\n })}\n </div>\n )\n }\n case ColumnTypeEnum.FILEHANDLEID: {\n let associatedObjectId = entity!.id!\n let associatedObjectType = FileHandleAssociateType.TableEntity\n if (isFileViewOrDataset(entity) && columnName === 'dataFileHandleId') {\n associatedObjectId = String(rowId)\n associatedObjectType = FileHandleAssociateType.FileEntity\n }\n return (\n <>\n {entity && (\n <div className=\"SynapseTableCellContent\">\n <DirectDownload\n iconSvgPropOverrides={{ sx: { color: 'primary.main' } }}\n associatedObjectId={associatedObjectId}\n associatedObjectType={associatedObjectType}\n fileHandleId={columnValue}\n displayFileName={true}\n />\n </div>\n )}\n </>\n )\n }\n case ColumnTypeEnum.ENTITYID_LIST: {\n const displayTextField = getDisplayTextFieldForEntityIdColumn(columnName)\n const jsonData: string[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n <EntityIdList\n entityIdList={jsonData}\n displayTextField={displayTextField}\n showIcon={false}\n />\n </div>\n )\n }\n case ColumnTypeEnum.USERID_LIST: {\n const jsonData: string[] = JSON.parse(columnValue)\n return (\n <div className=\"SynapseTableCellContent\">\n <UserIdList userIds={jsonData} />\n </div>\n )\n }\n // handle other list types\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.INTEGER_LIST: {\n const jsonData: string[] = JSON.parse(columnValue)\n return (\n <div className={`SynapseTableCellContent ${isBold}`}>\n {jsonData.map((val: string, index: number) => {\n const textRenderer =\n columnType == ColumnTypeEnum.STRING_LIST ? (\n <Linkify text={val} />\n ) : (\n <>{val}</>\n )\n return (\n <Fragment key={val}>\n {textRenderer}\n {index !== jsonData.length - 1 ? ', ' : ''}\n </Fragment>\n )\n })}\n </div>\n )\n }\n case ColumnTypeEnum.EVALUATIONID: {\n return (\n <div className=\"SynapseTableCellContent\">\n <EvaluationIdRenderer evaluationId={columnValue} />\n </div>\n )\n }\n\n case ColumnTypeEnum.DATE:\n return (\n <div className={`SynapseTableCellContent ${isBold}`}>\n {formatDate(dayjs(Number(columnValue)))}\n </div>\n )\n\n case ColumnTypeEnum.USERID:\n return (\n <div className=\"SynapseTableCellContent\">\n <UserOrTeamBadge principalId={columnValue} />\n </div>\n )\n case ColumnTypeEnum.LINK:\n return (\n <div className=\"SynapseTableCellContent\">\n <Link target=\"_blank\" rel=\"noopener noreferrer\" href={columnValue}>\n {columnValue}\n </Link>\n </div>\n )\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.BOOLEAN:\n case ColumnTypeEnum.MEDIUMTEXT:\n case ColumnTypeEnum.LARGETEXT: {\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography variant={'smallText1'} className={isBold}>\n <Linkify text={columnValue} />\n </Typography>\n </div>\n )\n }\n case ColumnTypeEnum.INTEGER:\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography\n variant={'smallText1'}\n sx={{ textAlign: 'right' }}\n className={isBold}\n >\n {parseInt(columnValue).toLocaleString()}\n </Typography>\n </div>\n )\n case ColumnTypeEnum.DOUBLE:\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography\n variant={'smallText1'}\n sx={{ textAlign: 'right' }}\n className={isBold}\n >\n {parseFloat(columnValue).toLocaleString()}\n </Typography>\n </div>\n )\n case ColumnTypeEnum.JSON:\n return (\n <div className=\"SynapseTableCellContent\">\n <JSONTableCellRenderer value={columnValue} />\n </div>\n )\n default:\n console.warn(\n `ColumnType ${columnType} has unspecified handler. Rendering the column value.`,\n )\n return (\n <div className=\"SynapseTableCellContent\">\n <Typography variant={'smallText1'} className={isBold}>\n {columnValue}\n </Typography>\n </div>\n )\n }\n // We can reach this if we don't get a mapping of IDs to entities or principals.\n // TODO: If we don't have a id:data mapping, we should render a component that can fetch the required data, rather than breaking from the case.\n return (\n <div className={`SynapseTableCellContent ${isBold}`}>{columnValue}</div>\n )\n}\n\nexport default memo(SynapseTableCell)\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SynapseTableRenderers.js","names":[],"sources":["../../../src/components/SynapseTable/SynapseTableRenderers.tsx"],"sourcesContent":["import { useGetEntityHeader } from '@/synapse-queries'\nimport { Checkbox } from '@mui/material'\nimport {\n ColumnTypeEnum,\n FacetColumnResult,\n FacetColumnResultValues,\n Row,\n} from '@sage-bionetworks/synapse-types'\nimport {\n CellContext,\n createColumnHelper,\n HeaderContext,\n} from '@tanstack/react-table'\nimport { useAtom, useAtomValue } from 'jotai'\nimport { isEqual } from 'lodash-es'\nimport { useCallback } from 'react'\nimport AddToDownloadListV2 from '../AddToDownloadListV2'\nimport FileEntityDirectDownload from '../DirectDownload/FileEntityDirectDownload'\nimport HasAccessV2 from '../HasAccess'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport {\n isRowSelectedAtom,\n selectedRowsAtom,\n} from '../QueryWrapper/TableRowSelectionState'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport ColumnHeader from '../TanStackTable/ColumnHeader'\nimport { EnumFacetFilter } from '../widgets/query-filter/EnumFacetFilter/EnumFacetFilter'\nimport EntityIDColumnCopyIcon from './EntityIDColumnCopyIcon'\nimport SynapseTableCell from './SynapseTableCell'\nimport { useSynapseTableContext } from './SynapseTableContext'\nimport { useInView } from 'react-intersection-observer'\n\n// Add a prefix to these column IDs so they don't collide with actual column names\nconst columnIdPrefix =\n 'org.sagebionetworks.web.client.SynapseTablePredefinedColumn'\n\nconst columnHelper = createColumnHelper<Row>()\n\nfunction RowSelectionCell<TValue = unknown>(props: CellContext<Row, TValue>) {\n const { row, table } = props\n const rowSet = table.options.meta?.rowSet\n\n const isRowSelected = useAtomValue(isRowSelectedAtom)\n const [selectedRows, setSelectedRows] = useAtom(selectedRowsAtom)\n\n return (\n <div>\n <Checkbox\n inputProps={{ 'aria-label': 'Select row' }}\n checked={isRowSelected(row.original, rowSet!.headers)}\n onChange={(_event, checked) => {\n const cloneSelectedRows = [...selectedRows]\n if (checked) {\n cloneSelectedRows.push(row.original)\n } else {\n const index = cloneSelectedRows.findIndex(selectedRow =>\n isEqual(selectedRow, row.original),\n )\n if (index > -1) {\n cloneSelectedRows.splice(index, 1)\n }\n }\n // update context on change\n setSelectedRows(cloneSelectedRows)\n }}\n />\n </div>\n )\n}\n\nexport const rowSelectionColumn = columnHelper.display({\n id: `${columnIdPrefix}.RowSelectionColumn`,\n enableResizing: false,\n cell: RowSelectionCell,\n maxSize: 36,\n meta: {\n textAlign: 'center',\n },\n})\n\nfunction AddToDownloadListCell<TValue = unknown>(\n props: CellContext<Row, TValue>,\n) {\n const entityId = getEntityOrRowId(props)!\n const versionNumberString = getEntityOrRowVersion(props)\n const versionNumber = versionNumberString\n ? parseInt(versionNumberString)\n : undefined\n const { data: entityHeader } = useGetEntityHeader(entityId)\n return (\n <div data-testid={'AddToDownloadListCell'}>\n {entityHeader?.type === 'org.sagebionetworks.repo.model.FileEntity' && (\n <AddToDownloadListV2\n entityId={entityId}\n entityVersionNumber={versionNumber}\n />\n )}\n </div>\n )\n}\n\nexport const addToDownloadListColumn = columnHelper.display({\n id: `${columnIdPrefix}.AddToDownloadListColumn`,\n enableResizing: false,\n cell: AddToDownloadListCell,\n maxSize: 50,\n meta: {\n textAlign: 'center',\n },\n})\n\nfunction DirectDownloadCell<TValue = unknown>(props: CellContext<Row, TValue>) {\n const entityId = getEntityOrRowId(props)!\n const versionNumber = getEntityOrRowVersion(props)\n\n return (\n <div data-testid={'DirectDownloadCell'}>\n <FileEntityDirectDownload\n entityId={entityId}\n entityVersionNumber={versionNumber}\n iconSvgPropOverrides={{ sx: { color: 'primary.main' } }}\n />\n </div>\n )\n}\n\nexport const directDownloadColumn = columnHelper.display({\n id: `${columnIdPrefix}.DirectDownload`,\n enableResizing: false,\n cell: DirectDownloadCell,\n maxSize: 50,\n meta: {\n textAlign: 'center',\n },\n})\n\n/**\n * Given the (tanstack react) Table CellContext, return the rowId of the current Synapse Table Row.\n * If a rowEntityIDColumnName was provided in the table config, then instead return the entityID found in\n * that cell of the current Row.\n */\nfunction getEntityOrRowId<TValue = unknown>(\n props: CellContext<Row, TValue>,\n): string | undefined {\n const { row, table } = props\n const rowEntityIDColumnIndex = table.options.meta?.rowEntityIDColumnIndex\n const entityId =\n rowEntityIDColumnIndex !== undefined\n ? row.original.values[rowEntityIDColumnIndex]!\n : row.original.rowId?.toString()\n return entityId\n}\n\n/**\n * Given the (tanstack react) Table CellContext, return true if the table configuration defines a row entity version column name.\n * This will be used as the entity that represents the current Row.\n * @param props\n * @returns\n */\nfunction isRowEntityColumn<TValue = unknown>(\n props: CellContext<Row, TValue>,\n): boolean {\n const { table } = props\n return table.options.meta?.rowEntityVersionColumnIndex !== undefined\n}\n\n/**\n * Given the (tanstack react) Table CellContext, return the version of the current Synapse Table Row.\n * If a rowEntityVersionColumnName was provided in the table config, then instead return the version found in\n * that cell of the current Row.\n */\nfunction getEntityOrRowVersion<TValue = unknown>(\n props: CellContext<Row, TValue>,\n): string | undefined {\n const { row, table } = props\n const rowEntityVersionColumnIndex =\n table.options.meta?.rowEntityVersionColumnIndex\n const versionNumber =\n rowEntityVersionColumnIndex !== undefined\n ? row.original.values[rowEntityVersionColumnIndex]!\n : row.original.versionNumber?.toString()\n return versionNumber\n}\n\nfunction AccessCell<TValue = unknown>(props: CellContext<Row, TValue>) {\n const { showExternalAccessIcon } = useSynapseTableContext()\n const { ref, inView } = useInView({ triggerOnce: true })\n const entityId = getEntityOrRowId(props)!\n\n // If showExternalAccessIcon is true, defer rendering until the cell is in view to limit simultaneous API calls\n const canRenderAccessIcon =\n !showExternalAccessIcon || (showExternalAccessIcon && inView)\n\n return (\n <div ref={ref} data-testid=\"AccessCell\">\n {canRenderAccessIcon && (\n <HasAccessV2\n key={entityId}\n entityId={entityId}\n showButtonText={false}\n showExternalAccessIcon={showExternalAccessIcon}\n />\n )}\n </div>\n )\n}\n\nexport const accessColumn = columnHelper.display({\n id: `${columnIdPrefix}.Access`,\n enableResizing: false,\n cell: AccessCell,\n maxSize: 50,\n meta: {\n textAlign: 'center',\n },\n})\n\nexport function TableDataColumnHeader(\n props: HeaderContext<Row, string | null>,\n) {\n const { column } = props\n const { lockedColumn } = useQueryContext()\n const { data: queryMetadata } = useGetQueryMetadata()\n const columnModels = queryMetadata?.columnModels ?? []\n const selectColumns = queryMetadata?.selectColumns ?? []\n const selectColumn = selectColumns.find(sc => sc.name === column.id)\n const columnModel = columnModels.find(cm => cm.name === column.id)\n const facets = queryMetadata?.facets ?? []\n const { getColumnDisplayName, getHelpText } = useQueryVisualizationContext()\n\n const displayColumnName = selectColumn\n ? getColumnDisplayName(selectColumn.name)\n : column.id\n const columnHelpText = selectColumn\n ? getHelpText(selectColumn.name)\n : undefined\n // we have to figure out if the current column is a facet selection\n const facetIndex: number = facets.findIndex(\n (facetColumnResult: FacetColumnResult) => {\n return (\n facetColumnResult.columnName === columnModel?.name &&\n // Exclude JSON subcolumn facets, since there may be more than one on a given column\n facetColumnResult.jsonPath == undefined\n )\n },\n )\n // the header must be included in the facets and it has to be enumerable for current rendering capabilities\n const isFacetSelection: boolean =\n facetIndex !== -1 && facets[facetIndex].facetType === 'enumeration'\n const facet = facets[facetIndex] as FacetColumnResultValues\n const isLockedColumn =\n selectColumn &&\n selectColumn.name.toLowerCase() === lockedColumn?.columnName?.toLowerCase() // used in details page to disable filter the column\n const isEntityIDColumn =\n selectColumn &&\n selectColumn.name == 'id' &&\n selectColumn.columnType == ColumnTypeEnum.ENTITYID\n\n // TODO: enableFiltering should be specified on the column, but for now it's easier to override `getCanFilter` here where we have the facet information\n props.column.getCanFilter = useCallback(\n () => Boolean(isFacetSelection && !isLockedColumn && columnModel),\n [isFacetSelection, isLockedColumn, columnModel],\n )\n\n return (\n <ColumnHeader\n {...props}\n title={displayColumnName}\n helpText={columnHelpText}\n filterControl={\n <span>\n <EnumFacetFilter\n containerAs=\"Dropdown\"\n facet={facet}\n defaultShowAllValues={true}\n />\n </span>\n }\n additionalButtons={\n <>{isEntityIDColumn && <EntityIDColumnCopyIcon size={'small'} />}</>\n }\n />\n )\n}\n\nexport function TableDataCell(props: CellContext<Row, string | null>) {\n const { cell, table } = props\n const { data: queryMetadata } = useGetQueryMetadata()\n const entityOrRowId = getEntityOrRowId(props)\n const entityOrRowVersion = getEntityOrRowVersion(props)\n const versionNumber =\n entityOrRowVersion !== undefined ? parseInt(entityOrRowVersion) : undefined\n const selectColumns = table.options.meta?.rowSet?.headers ?? []\n const selectColumn = selectColumns.find(cm => cm.name === cell.column.id)\n const columnModels = queryMetadata?.columnModels ?? []\n const { columnLinks } = useSynapseTableContext()\n if (selectColumn) {\n const columnLinkConfig = (columnLinks ?? []).find(el => {\n return el.matchColumnName === selectColumn.name\n })\n const columnType = selectColumn.columnType\n const isBold = cell.column.getIsSorted() ? 'SRC-boldText' : ''\n return (\n <SynapseTableCell\n key={cell.id}\n columnType={columnType}\n columnValue={cell.getValue()}\n isBold={isBold}\n columnLinkConfig={columnLinkConfig}\n columnName={selectColumn.name}\n rowData={cell.row.original.values}\n selectColumns={selectColumns}\n columnModels={columnModels}\n rowId={entityOrRowId}\n rowVersionNumber={versionNumber}\n isRowEntityColumn={isRowEntityColumn(props)}\n />\n )\n } else return <td key={cell.id}></td>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SynapseTableRenderers.js","names":[],"sources":["../../../src/components/SynapseTable/SynapseTableRenderers.tsx"],"sourcesContent":["import { useGetEntityHeader } from '@/synapse-queries'\nimport { Checkbox } from '@mui/material'\nimport {\n ColumnTypeEnum,\n FacetColumnResult,\n FacetColumnResultValues,\n Row,\n} from '@sage-bionetworks/synapse-types'\nimport {\n CellContext,\n createColumnHelper,\n HeaderContext,\n} from '@tanstack/react-table'\nimport { useAtom, useAtomValue } from 'jotai'\nimport { isEqual } from 'lodash-es'\nimport { useCallback } from 'react'\nimport AddToDownloadListV2 from '../AddToDownloadListV2'\nimport FileEntityDirectDownload from '../DirectDownload/FileEntityDirectDownload'\nimport HasAccessV2 from '../HasAccess'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport {\n isRowSelectedAtom,\n selectedRowsAtom,\n} from '../QueryWrapper/TableRowSelectionState'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport ColumnHeader from '../TanStackTable/ColumnHeader'\nimport { EnumFacetFilter } from '../widgets/query-filter/EnumFacetFilter/EnumFacetFilter'\nimport EntityIDColumnCopyIcon from './EntityIDColumnCopyIcon'\nimport SynapseTableCell from './SynapseTableCell'\nimport { useSynapseTableContext } from './SynapseTableContext'\nimport { useInView } from 'react-intersection-observer'\n\n// Add a prefix to these column IDs so they don't collide with actual column names\nconst columnIdPrefix =\n 'org.sagebionetworks.web.client.SynapseTablePredefinedColumn'\n\nconst columnHelper = createColumnHelper<Row>()\n\nfunction RowSelectionCell<TValue = unknown>(props: CellContext<Row, TValue>) {\n const { row, table } = props\n const rowSet = table.options.meta?.rowSet\n\n const isRowSelected = useAtomValue(isRowSelectedAtom)\n const [selectedRows, setSelectedRows] = useAtom(selectedRowsAtom)\n\n return (\n <div>\n <Checkbox\n inputProps={{ 'aria-label': 'Select row' }}\n checked={isRowSelected(row.original, rowSet!.headers)}\n onChange={(_event, checked) => {\n const cloneSelectedRows = [...selectedRows]\n if (checked) {\n cloneSelectedRows.push(row.original)\n } else {\n const index = cloneSelectedRows.findIndex(selectedRow =>\n isEqual(selectedRow, row.original),\n )\n if (index > -1) {\n cloneSelectedRows.splice(index, 1)\n }\n }\n // update context on change\n setSelectedRows(cloneSelectedRows)\n }}\n />\n </div>\n )\n}\n\nexport const rowSelectionColumn = columnHelper.display({\n id: `${columnIdPrefix}.RowSelectionColumn`,\n enableResizing: false,\n cell: RowSelectionCell,\n maxSize: 36,\n meta: {\n textAlign: 'center',\n },\n})\n\nfunction AddToDownloadListCell<TValue = unknown>(\n props: CellContext<Row, TValue>,\n) {\n const entityId = getEntityOrRowId(props)!\n const versionNumberString = getEntityOrRowVersion(props)\n const versionNumber = versionNumberString\n ? parseInt(versionNumberString)\n : undefined\n const { data: entityHeader } = useGetEntityHeader(entityId)\n return (\n <div data-testid={'AddToDownloadListCell'}>\n {entityHeader?.type === 'org.sagebionetworks.repo.model.FileEntity' && (\n <AddToDownloadListV2\n entityId={entityId}\n entityVersionNumber={versionNumber}\n />\n )}\n </div>\n )\n}\n\nexport const addToDownloadListColumn = columnHelper.display({\n id: `${columnIdPrefix}.AddToDownloadListColumn`,\n enableResizing: false,\n cell: AddToDownloadListCell,\n maxSize: 50,\n meta: {\n textAlign: 'center',\n },\n})\n\nfunction DirectDownloadCell<TValue = unknown>(props: CellContext<Row, TValue>) {\n const entityId = getEntityOrRowId(props)!\n const versionNumber = getEntityOrRowVersion(props)\n\n return (\n <div data-testid={'DirectDownloadCell'}>\n <FileEntityDirectDownload\n entityId={entityId}\n entityVersionNumber={versionNumber}\n iconSvgPropOverrides={{ sx: { color: 'primary.main' } }}\n />\n </div>\n )\n}\n\nexport const directDownloadColumn = columnHelper.display({\n id: `${columnIdPrefix}.DirectDownload`,\n enableResizing: false,\n cell: DirectDownloadCell,\n maxSize: 50,\n meta: {\n textAlign: 'center',\n },\n})\n\n/**\n * Given the (tanstack react) Table CellContext, return the rowId of the current Synapse Table Row.\n * If a rowEntityIDColumnName was provided in the table config, then instead return the entityID found in\n * that cell of the current Row.\n */\nfunction getEntityOrRowId<TValue = unknown>(\n props: CellContext<Row, TValue>,\n): string | undefined {\n const { row, table } = props\n const rowEntityIDColumnIndex = table.options.meta?.rowEntityIDColumnIndex\n const entityId =\n rowEntityIDColumnIndex !== undefined\n ? row.original.values[rowEntityIDColumnIndex]!\n : row.original.rowId?.toString()\n return entityId\n}\n\n/**\n * Given the (tanstack react) Table CellContext, return true if the table configuration defines a row entity version column name.\n * This will be used as the entity that represents the current Row.\n * @param props\n * @returns\n */\nfunction isRowEntityColumn<TValue = unknown>(\n props: CellContext<Row, TValue>,\n): boolean {\n const { table } = props\n return table.options.meta?.rowEntityVersionColumnIndex !== undefined\n}\n\n/**\n * Given the (tanstack react) Table CellContext, return the version of the current Synapse Table Row.\n * If a rowEntityVersionColumnName was provided in the table config, then instead return the version found in\n * that cell of the current Row.\n */\nfunction getEntityOrRowVersion<TValue = unknown>(\n props: CellContext<Row, TValue>,\n): string | undefined {\n const { row, table } = props\n const rowEntityVersionColumnIndex =\n table.options.meta?.rowEntityVersionColumnIndex\n const versionNumber =\n rowEntityVersionColumnIndex !== undefined\n ? row.original.values[rowEntityVersionColumnIndex]!\n : row.original.versionNumber?.toString()\n return versionNumber\n}\n\nfunction AccessCell<TValue = unknown>(props: CellContext<Row, TValue>) {\n const { showExternalAccessIcon } = useSynapseTableContext()\n const { ref, inView } = useInView({ triggerOnce: true })\n const entityId = getEntityOrRowId(props)!\n\n // If showExternalAccessIcon is true, defer rendering until the cell is in view to limit simultaneous API calls\n const canRenderAccessIcon =\n !showExternalAccessIcon || (showExternalAccessIcon && inView)\n\n return (\n <div ref={ref} data-testid=\"AccessCell\">\n {canRenderAccessIcon && (\n <HasAccessV2\n key={entityId}\n entityId={entityId}\n showButtonText={false}\n showExternalAccessIcon={showExternalAccessIcon}\n />\n )}\n </div>\n )\n}\n\nexport const accessColumn = columnHelper.display({\n id: `${columnIdPrefix}.Access`,\n enableResizing: false,\n cell: AccessCell,\n maxSize: 50,\n meta: {\n textAlign: 'center',\n },\n})\n\nexport function TableDataColumnHeader(\n props: HeaderContext<Row, string | null>,\n) {\n const { column } = props\n const { lockedColumn } = useQueryContext()\n const { data: queryMetadata } = useGetQueryMetadata()\n const columnModels = queryMetadata?.columnModels ?? []\n const selectColumns = queryMetadata?.selectColumns ?? []\n const selectColumn = selectColumns.find(sc => sc.name === column.id)\n const columnModel = columnModels.find(cm => cm.name === column.id)\n const facets = queryMetadata?.facets ?? []\n const { getColumnDisplayName, getHelpText } = useQueryVisualizationContext()\n\n const displayColumnName = selectColumn\n ? getColumnDisplayName(selectColumn.name)\n : column.id\n const columnHelpText = selectColumn\n ? getHelpText(selectColumn.name)\n : undefined\n // we have to figure out if the current column is a facet selection\n const facetIndex: number = facets.findIndex(\n (facetColumnResult: FacetColumnResult) => {\n return (\n facetColumnResult.columnName === columnModel?.name &&\n // Exclude JSON subcolumn facets, since there may be more than one on a given column\n facetColumnResult.jsonPath == undefined\n )\n },\n )\n // the header must be included in the facets and it has to be enumerable for current rendering capabilities\n const isFacetSelection: boolean =\n facetIndex !== -1 && facets[facetIndex].facetType === 'enumeration'\n const facet = facets[facetIndex] as FacetColumnResultValues\n const isLockedColumn =\n selectColumn &&\n selectColumn.name.toLowerCase() === lockedColumn?.columnName?.toLowerCase() // used in details page to disable filter the column\n const isEntityIDColumn =\n selectColumn &&\n selectColumn.name == 'id' &&\n selectColumn.columnType == ColumnTypeEnum.ENTITYID\n\n // TODO: enableFiltering should be specified on the column, but for now it's easier to override `getCanFilter` here where we have the facet information\n props.column.getCanFilter = useCallback(\n () => Boolean(isFacetSelection && !isLockedColumn && columnModel),\n [isFacetSelection, isLockedColumn, columnModel],\n )\n\n return (\n <ColumnHeader\n {...props}\n title={displayColumnName}\n helpText={columnHelpText}\n filterControl={\n <span>\n <EnumFacetFilter\n containerAs=\"Dropdown\"\n facet={facet}\n defaultShowAllValues={true}\n />\n </span>\n }\n additionalButtons={\n <>{isEntityIDColumn && <EntityIDColumnCopyIcon size={'small'} />}</>\n }\n />\n )\n}\n\nexport function TableDataCell(props: CellContext<Row, string | null>) {\n const { cell, table } = props\n const { data: queryMetadata } = useGetQueryMetadata()\n const entityOrRowId = getEntityOrRowId(props)\n const entityOrRowVersion = getEntityOrRowVersion(props)\n const versionNumber =\n entityOrRowVersion !== undefined ? parseInt(entityOrRowVersion) : undefined\n const selectColumns = table.options.meta?.rowSet?.headers ?? []\n const selectColumn = selectColumns.find(cm => cm.name === cell.column.id)\n const columnModels = queryMetadata?.columnModels ?? []\n const { columnLinks } = useSynapseTableContext()\n if (selectColumn) {\n const columnLinkConfig = (columnLinks ?? []).find(el => {\n return el.matchColumnName === selectColumn.name\n })\n const columnType = selectColumn.columnType\n const isBold = cell.column.getIsSorted() ? 'SRC-boldText' : ''\n return (\n <SynapseTableCell\n key={cell.id}\n columnType={columnType}\n columnValue={cell.getValue()}\n isBold={isBold}\n columnLinkConfig={columnLinkConfig}\n columnName={selectColumn.name}\n rowData={cell.row.original.values}\n selectColumns={selectColumns}\n columnModels={columnModels}\n rowId={entityOrRowId}\n rowVersionNumber={versionNumber}\n isRowEntityColumn={isRowEntityColumn(props)}\n />\n )\n } else return <td key={cell.id}></td>\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DatasetItemsEditor.js","names":[],"sources":["../../../../src/components/SynapseTable/datasets/DatasetItemsEditor.tsx"],"sourcesContent":["import React from 'react'\nimport WideButton from '@/components/styled/WideButton'\nimport { datasetItemToReference } from '@/components/SynapseTable/datasets/DatasetEditorUtils'\nimport {\n useGetEntity,\n useGetEntityPath,\n useUpdateEntity,\n} from '@/synapse-queries'\nimport { RequiredProperties } from '@/utils'\nimport {\n convertToEntityType,\n entityTypeToFriendlyName,\n isDataset,\n isDatasetCollection,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useSet } from '@/utils/hooks'\nimport AddCircleTwoToneIcon from '@mui/icons-material/AddCircleTwoTone'\nimport {\n Alert,\n Button,\n Checkbox,\n Skeleton,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n EntityRef,\n EntityRefCollectionView,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport {\n createColumnHelper,\n getCoreRowModel,\n Table,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { isEqual, upperFirst } from 'lodash-es'\nimport pluralize from 'pluralize'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { CreatedOnCell } from '../../EntityFinder/details/view/table/CreatedOnCell'\nimport { EntityBadgeIconsCell } from '../../EntityFinder/details/view/table/EntityBadgeIconsCell'\nimport { EntityNameCell } from '../../EntityFinder/details/view/table/EntityNameCell'\nimport { ModifiedByCell } from '../../EntityFinder/details/view/table/ModifiedByCell'\nimport { ModifiedOnCell } from '../../EntityFinder/details/view/table/ModifiedOnCell'\nimport { ParentProjectCell } from '../../EntityFinder/details/view/table/ParentProjectCell'\nimport { EntityFinderModal } from '../../EntityFinder/EntityFinderModal'\nimport { FinderScope } from '../../EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '../../EntityFinder/VersionSelectionType'\nimport { BlockingLoader } from '../../LoadingScreen/LoadingScreen'\nimport { SkeletonTable } from '../../Skeleton'\nimport WarningDialog from '../../SynapseForm/WarningDialog'\nimport ColumnHeader from '../../TanStackTable/ColumnHeader'\nimport StyledVirtualTanStackTable from '../../TanStackTable/StyledVirtualTanStackTable'\nimport { displayToast } from '../../ToastMessage'\nimport { DatasetEditorCheckboxCell } from './DatasetEditorCheckboxCell'\nimport { DatasetEditorVersionCell } from './DatasetEditorVersionCell'\nimport { EntityFetchErrorCell } from './EntityFetchErrorCell'\n\nexport type DatasetItemsEditorTableData = EntityRef & {\n isSelected: boolean\n setSelected: (value: boolean) => void\n}\n\nenum DatasetItemsEditorColumn {\n ERROR_STATE = 'errorState',\n SELECTED = 'isSelected',\n NAME = 'name',\n ENTITY_ID = 'entityId',\n BADGES = 'badges',\n VERSION = 'version',\n CREATED_ON = 'createdOn',\n MODIFIED_ON = 'modifieddOn',\n MODIFIED_BY = 'modifiedBy',\n PROJECT = 'project',\n}\n\nconst columnHelper = createColumnHelper<DatasetItemsEditorTableData>()\nfunction getColumns(\n opts: SelectAllCheckboxRendererProps & {\n changeVersionOnItem: (entityId: string, newVersion: number) => void\n },\n) {\n const {\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n } = opts\n return [\n columnHelper.display({\n id: DatasetItemsEditorColumn.ERROR_STATE,\n minSize: 35,\n maxSize: 35,\n size: 35,\n enableResizing: false,\n header: () => null,\n cell: EntityFetchErrorCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.SELECTED,\n minSize: 40,\n maxSize: 40,\n size: 40,\n enableResizing: false,\n header: () => (\n <SelectAllCheckboxRenderer\n datasetToUpdate={datasetToUpdate}\n selectedIds={selectedIds}\n clearSelectedIds={clearSelectedIds}\n addSelectedId={addSelectedId}\n allItemsAreSelected={allItemsAreSelected}\n />\n ),\n cell: DatasetEditorCheckboxCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.NAME,\n minSize: 50,\n size: 300,\n header: props => <ColumnHeader {...props} title={'Name'} />,\n cell: EntityNameCell,\n }),\n columnHelper.accessor(DatasetItemsEditorColumn.ENTITY_ID, {\n minSize: 50,\n size: 130,\n header: props => <ColumnHeader {...props} title={'ID'} />,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.BADGES,\n minSize: 80,\n size: 80,\n enableResizing: true,\n cell: EntityBadgeIconsCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.VERSION,\n minSize: 150,\n size: 150,\n header: props => <ColumnHeader {...props} title={'Version'} />,\n cell: props => (\n <DatasetEditorVersionCell\n {...props}\n toggleSelection={datasetItem => {\n changeVersionOnItem(datasetItem.entityId, datasetItem.versionNumber)\n }}\n />\n ),\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.CREATED_ON,\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n size: 220,\n minSize: 170,\n cell: CreatedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_ON,\n header: props => <ColumnHeader {...props} title={'Modified On'} />,\n size: 220,\n minSize: 170,\n cell: ModifiedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_BY,\n header: props => <ColumnHeader {...props} title={'Modified By'} />,\n size: 250,\n enableResizing: true,\n cell: ModifiedByCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.PROJECT,\n header: props => <ColumnHeader {...props} title={'Size'} />,\n size: 300,\n cell: ParentProjectCell,\n }),\n ]\n}\n\nfunction getSelectableTypes(entity: EntityRefCollectionView) {\n if (isDataset(entity)) {\n return [EntityType.file]\n } else if (isDatasetCollection(entity)) {\n return [EntityType.dataset]\n } else {\n console.error(\n 'Cannot determine selectable types for entity type: ' +\n entity.concreteType,\n )\n return []\n }\n}\n\nexport function getCopy(entity?: EntityRefCollectionView) {\n const displayName = entity\n ? entityTypeToFriendlyName(convertToEntityType(entity.concreteType))\n : 'Collection'\n let itemName = 'Item'\n let currentVersionName = 'Current Version'\n if (entity && isDataset(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.file)\n currentVersionName = 'Draft'\n } else if (entity && isDatasetCollection(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.dataset)\n }\n\n const entityFinderPopover =\n entity && isDataset(entity)\n ? `Use the left pane to browse projects and folders. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple folders. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n : `Use the left pane to browse projects. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple projects. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n\n return {\n ADD_ITEMS: `Add ${pluralize(itemName)}`,\n ADD_ITEMS_TO: `Add ${pluralize(itemName)} to ${displayName}`,\n REMOVE_ITEMS: `Remove ${pluralize(itemName)}`,\n NO_ITEMS_IN_THIS_DATASET: `No ${pluralize(\n itemName,\n )} in this ${displayName}`,\n SAVE_TO_CONTINUE: `Save the ${displayName} to continue`,\n CREATE_VERSION_TO_FREEZE: `Create a Version of this ${displayName} to freeze it in its current state`,\n ENTITY_SAVED: `${displayName} Saved`,\n SAVE_CHANGES: `Save changes to ${currentVersionName}`,\n ENTITY_FINDER_POPOVER: entityFinderPopover,\n ENTITY_FINDER_PROMPT: `Find ${pluralize(\n itemName,\n )} to add to the ${displayName}.`,\n PRECONDITION_FAILED_MESSAGE: `Re-retrieve the ${displayName} to get the latest changes. Your current changes will be lost.`,\n PRECONDITION_FAILED_TITLE: `${displayName} updated since last fetched`,\n PRECONDITION_FAILED_ACTION: `Retrieve ${displayName}`,\n NO_CHANGES_MADE: `You have not made any changes to the ${displayName}.`,\n }\n}\n\nfunction getDataSetDifference(\n oldDataSet: EntityRef[],\n changedItems: EntityRef[],\n) {\n const unchangedItems = oldDataSet.filter(\n oldItem =>\n !changedItems.find(newItem => newItem.entityId === oldItem.entityId),\n )\n const deletedItems = [...unchangedItems]\n const { updatedItems, newItems } = changedItems.reduce(\n (results, result) => {\n const oldItem = oldDataSet.find(old => old.entityId === result.entityId)\n if (oldItem) {\n if (result.versionNumber !== oldItem.versionNumber) {\n results['updatedItems'].push(result)\n } else {\n unchangedItems.push(result)\n }\n } else {\n results['newItems'].push(result)\n }\n return results\n },\n { updatedItems: [], newItems: [] } as {\n updatedItems: EntityRef[]\n newItems: EntityRef[]\n },\n )\n\n return { unchangedItems, updatedItems, newItems, deletedItems }\n}\n\nfunction getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate?: RequiredProperties<\n EntityRefCollectionView,\n 'items'\n >,\n datasetToUpdate?: RequiredProperties<EntityRefCollectionView, 'items'>,\n) {\n const { updatedItems, newItems, deletedItems } = getDataSetDifference(\n previousDatasetToUpdate?.items ?? [],\n datasetToUpdate?.items!,\n )\n let toastTitle = ''\n\n // \"X items(s) deleted\"\n if (deletedItems.length > 0) {\n toastTitle += `${deletedItems.length} Item${\n deletedItems.length === 1 ? '' : 's'\n } removed`\n } else {\n // \"Y item(s) added\"\n toastTitle += `${newItems.length} Item${\n newItems.length === 1 ? '' : 's'\n } added`\n\n // \"and Z item(s) updated\", only shown if there are updated items\n if (updatedItems.length > 0) {\n toastTitle += ` and ${updatedItems.length} Item${\n updatedItems.length === 1 ? '' : 's'\n } updated`\n }\n }\n return toastTitle\n}\n\nexport type DatasetItemsEditorProps = {\n /* The synId of the EntityRefCollectionView to modify */\n entityId: string\n /** Callback invoked when the editor changes state to contain un/saved changes. */\n onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void\n onSave?: () => void\n onClose?: () => void\n}\n\nconst ROW_HEIGHT = 48\n\ntype SelectAllCheckboxRendererProps = {\n datasetToUpdate: RequiredProperties<EntityRefCollectionView, 'items'>\n selectedIds: Omit<Set<string>, 'add' | 'delete' | 'clear'>\n addSelectedId: (...items: string[]) => void\n clearSelectedIds: () => void\n allItemsAreSelected: boolean\n}\n\nconst SelectAllCheckboxRenderer = (\n props: SelectAllCheckboxRendererProps,\n): React.ReactNode => {\n const {\n datasetToUpdate,\n clearSelectedIds,\n allItemsAreSelected,\n addSelectedId,\n } = props\n const isChecked = allItemsAreSelected\n\n return (\n <Checkbox\n inputProps={{ 'aria-label': 'Select All' }}\n checked={isChecked}\n disabled={datasetToUpdate.items.length === 0}\n onChange={() => {\n if (isChecked) {\n clearSelectedIds()\n } else {\n addSelectedId(...datasetToUpdate.items.map(item => item.entityId))\n }\n }}\n />\n )\n}\n\nfunction NoItemsPlaceholder(props: {\n titleCopy: string\n buttonCopy: string\n onButtonClick: () => void\n}) {\n const { titleCopy, buttonCopy, onButtonClick } = props\n return (\n <div className=\"NoItemsPlaceholder\">\n <Typography variant={'headline3'}>{titleCopy}</Typography>\n <WideButton\n variant=\"contained\"\n color=\"primary\"\n onClick={onButtonClick}\n startIcon={<AddCircleTwoToneIcon />}\n sx={{ mt: 2 }}\n >\n {buttonCopy}\n </WideButton>\n </div>\n )\n}\n\nexport function DatasetItemsEditor(props: DatasetItemsEditorProps) {\n const { entityId, onSave, onClose, onUnsavedChangesChange } = props\n const [showEntityFinder, setShowEntityFinder] = useState<boolean>(false)\n const [showWarningDialog, setShowWarningDialog] = useState<boolean>(false)\n\n // The current 'client state' of dataset that the user is currently editing. Updates to this state are not saved until the user clicks 'Save'.\n const [datasetToUpdate, setDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // The previous value of the datasetToUpdate variable. This is used to calculate a summary of bulk actions since the last update to the unsaved dataset state.\n const [previousDatasetToUpdate, setPreviousDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // Stores the `close` function that will be used to hide the last toast that prompted the user to save\n const [onCloseLastSavePromptToast, setOnCloseLastSavePromptToast] = useState<\n { close: () => void } | undefined\n >()\n\n const { data: datasetOnServer, refetch: refetchDataset } = useGetEntity<\n RequiredProperties<EntityRefCollectionView, 'items'>\n >(entityId, undefined, {\n staleTime: Infinity,\n })\n\n const hasChangedSinceLastSave = Boolean(\n datasetOnServer &&\n datasetToUpdate &&\n !isEqual(datasetOnServer, datasetToUpdate),\n )\n\n const {\n ADD_ITEMS,\n ADD_ITEMS_TO,\n REMOVE_ITEMS,\n NO_ITEMS_IN_THIS_DATASET,\n SAVE_TO_CONTINUE,\n CREATE_VERSION_TO_FREEZE,\n ENTITY_SAVED,\n SAVE_CHANGES,\n PRECONDITION_FAILED_TITLE,\n PRECONDITION_FAILED_MESSAGE,\n PRECONDITION_FAILED_ACTION,\n ENTITY_FINDER_POPOVER,\n ENTITY_FINDER_PROMPT,\n NO_CHANGES_MADE,\n } = useMemo(() => getCopy(datasetOnServer), [datasetOnServer])\n\n useEffect(() => {\n if (datasetOnServer) {\n // SWC-5876: Dataset Items may be undefined. This has the same inherent meaning as the empty list, so we'll just change it to save us some null checks.\n if (datasetOnServer.items == null) {\n datasetOnServer.items = []\n }\n setDatasetToUpdate(datasetOnServer)\n }\n }, [datasetOnServer])\n\n const {\n set: selectedIds,\n add: addSelectedId,\n remove: removeSelectedId,\n clear: clearSelectedIds,\n } = useSet<string>()\n const allItemsAreSelected = Boolean(\n datasetToUpdate && datasetToUpdate.items.length === selectedIds.size,\n )\n\n useEffect(() => {\n if (datasetToUpdate && datasetOnServer && onUnsavedChangesChange) {\n onUnsavedChangesChange(hasChangedSinceLastSave)\n }\n }, [\n datasetOnServer,\n datasetToUpdate,\n hasChangedSinceLastSave,\n onUnsavedChangesChange,\n ])\n\n // We get the project ID to show the \"Current Project\" context in the Entity Finder.\n const { data: path } = useGetEntityPath(entityId)\n const projectId = path?.path[1]?.id\n\n const { mutate, isPending: updateIsPending } =\n useUpdateEntity<EntityRefCollectionView>({\n onMutate: () => {\n // Close existing toast that prompted the user to save\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n setOnCloseLastSavePromptToast(undefined)\n }\n },\n onSuccess: () => {\n // The query should automatically be invalidated, but just in case\n void refetchDataset()\n\n if (onSave) {\n onSave()\n } else {\n // If onSave isn't specified, push a generic toast message.\n displayToast(CREATE_VERSION_TO_FREEZE, 'success', {\n title: ENTITY_SAVED,\n })\n }\n },\n onError: error => {\n if (error.status === 412) {\n displayToast(PRECONDITION_FAILED_MESSAGE, 'warning', {\n title: PRECONDITION_FAILED_TITLE,\n primaryButtonConfig: {\n text: PRECONDITION_FAILED_ACTION,\n onClick: () => {\n void refetchDataset()\n },\n },\n })\n } else {\n displayToast(error.reason, 'danger', {\n title: 'An Error Occurred',\n })\n }\n },\n })\n\n useEffect(() => {\n // When changes are made (but not saved) to the datasetToUpdate, show a notification that summarizes the change and prompts the user to save\n if (\n previousDatasetToUpdate &&\n datasetToUpdate &&\n !isEqual(previousDatasetToUpdate.items, datasetToUpdate.items) &&\n !updateIsPending\n ) {\n const toastMessageTitle = getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate,\n datasetToUpdate,\n )\n // Replace existing toast that prompts the user to save before showing the new one\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n }\n const onCloseToast = displayToast(SAVE_TO_CONTINUE, 'info', {\n title: toastMessageTitle,\n primaryButtonConfig: {\n text: SAVE_CHANGES,\n onClick: () => mutate(datasetToUpdate),\n },\n })\n setOnCloseLastSavePromptToast({ close: onCloseToast })\n }\n setPreviousDatasetToUpdate(datasetToUpdate)\n // Only run when datasetToUpdate changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [datasetToUpdate])\n\n const tableData = useMemo(\n () =>\n datasetToUpdate?.items.map(\n (item: EntityRef): DatasetItemsEditorTableData => {\n return {\n ...item,\n isSelected: selectedIds.has(item.entityId),\n setSelected: (value: boolean) => {\n return value\n ? addSelectedId(item.entityId)\n : removeSelectedId(item.entityId)\n },\n }\n },\n ) ?? [],\n [addSelectedId, datasetToUpdate?.items, removeSelectedId, selectedIds],\n )\n\n function addItemsToDataset(itemsToAdd: Reference[]) {\n setDatasetToUpdate(datasetToUpdate => {\n if (datasetToUpdate) {\n const refToDatasetItem = itemsToAdd.map(item => ({\n entityId: item.targetId,\n versionNumber: item.targetVersionNumber!,\n }))\n const { unchangedItems, updatedItems, newItems } = getDataSetDifference(\n datasetToUpdate.items,\n refToDatasetItem,\n )\n\n if (updatedItems.length == 0 && newItems.length == 0) {\n // No items were added or updated, so don't update the state variable.\n return datasetToUpdate\n }\n\n const items = [...unchangedItems, ...updatedItems, ...newItems]\n\n return {\n ...datasetToUpdate,\n items: items,\n }\n } else {\n console.warn(\n 'Cannot add items to the Collection because it is undefined. The Collection may not have been fetched yet.',\n )\n return datasetToUpdate\n }\n })\n clearSelectedIds()\n }\n\n function removeSelectedItemsFromDataset() {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.filter(\n datasetItem => !selectedIds.has(datasetItem.entityId),\n ),\n }))\n clearSelectedIds()\n }\n\n function changeVersionOnItem(entityId: string, newVersion: number) {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.map(datasetItem =>\n datasetItem.entityId === entityId\n ? { entityId: entityId, versionNumber: newVersion }\n : datasetItem,\n ),\n }))\n }\n\n const selectableTypes: EntityType[] | undefined = useMemo(() => {\n if (datasetOnServer) {\n return getSelectableTypes(datasetOnServer)\n } else {\n return undefined\n }\n }, [datasetOnServer])\n\n const columns = useMemo(() => {\n if (!datasetToUpdate) {\n return []\n }\n return getColumns({\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n })\n }, [\n addSelectedId,\n allItemsAreSelected,\n clearSelectedIds,\n datasetToUpdate,\n selectedIds,\n ])\n\n const table: Table<DatasetItemsEditorTableData> =\n useReactTable<DatasetItemsEditorTableData>({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n // There are no backend sort controls. The server only provides ID/version, and a dataset could be up to 10k items,\n // so client side sorting is non-trivial. We may consider fetching all entity headers upon user request.\n enableSorting: false,\n })\n\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n const rowVirtualizer = useVirtualizer({\n count: tableData?.length ?? 0,\n estimateSize: () => ROW_HEIGHT, // estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? element => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const datasetItemsAsEntityFinderRef = useMemo(\n () => datasetToUpdate?.items.map(datasetItemToReference),\n [datasetToUpdate],\n )\n\n return (\n <div className=\"DatasetEditor\">\n <EntityFinderModal\n initialSelected={datasetItemsAsEntityFinderRef}\n configuration={{\n projectId: projectId,\n selectMultiple: true,\n initialScope: FinderScope.CURRENT_PROJECT,\n initialContainer: projectId ?? null,\n selectableTypes: selectableTypes,\n versionSelection: VersionSelectionType.REQUIRED,\n }}\n titleHelpPopoverProps={{\n markdownText: ENTITY_FINDER_POPOVER,\n helpUrl: 'https://help.synapse.org/docs/Datasets.2611281979.html',\n placement: 'right',\n }}\n promptCopy={ENTITY_FINDER_PROMPT}\n show={showEntityFinder}\n title={ADD_ITEMS_TO}\n confirmButtonCopy={'Apply changes'}\n onConfirm={items => {\n addItemsToDataset(items)\n setShowEntityFinder(false)\n }}\n onCancel={() => setShowEntityFinder(false)}\n />\n <WarningDialog\n title=\"Unsaved Changes\"\n content=\"Any unsaved changes will be lost. Are you sure you want to close the editor?\"\n confirmButtonText=\"Close Editor\"\n onConfirm={() => {\n if (onClose) {\n setShowWarningDialog(false)\n if (onUnsavedChangesChange) {\n onUnsavedChangesChange(false)\n }\n onClose()\n }\n }}\n open={showWarningDialog}\n onConfirmCallbackArgs={[]}\n onCancel={() => setShowWarningDialog(false)}\n />\n\n <div className=\"DatasetEditorTopBottomPanel\">\n <BlockingLoader show={updateIsPending} />\n <div className=\"ItemCount\">\n {datasetToUpdate ? (\n <Typography variant=\"headline3\">\n {datasetToUpdate.items.length === 0\n ? 'No'\n : datasetToUpdate.items.length.toLocaleString()}{' '}\n File\n {datasetToUpdate.items.length !== 1 && 's'}\n </Typography>\n ) : (\n <Skeleton variant=\"rectangular\" width={200} />\n )}\n </div>\n\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={datasetToUpdate == null}\n onClick={() => setShowEntityFinder(true)}\n >\n {ADD_ITEMS}\n </Button>\n <Button\n disabled={selectedIds.size === 0}\n variant=\"outlined\"\n color=\"primary\"\n onClick={removeSelectedItemsFromDataset}\n >\n {REMOVE_ITEMS}\n </Button>\n </div>\n <div className=\"DatasetEditorTableContainer\">\n {datasetToUpdate && datasetToUpdate.items.length === 0 && (\n <NoItemsPlaceholder\n titleCopy={NO_ITEMS_IN_THIS_DATASET}\n buttonCopy={ADD_ITEMS}\n onButtonClick={() => setShowEntityFinder(true)}\n />\n )}\n {datasetToUpdate && datasetToUpdate.items.length > 0 && (\n <StyledVirtualTanStackTable<DatasetItemsEditorTableData>\n styledTableContainerProps={{\n className: 'DatasetEditorTable',\n ref: tableContainerRef,\n height: '350px',\n }}\n table={table}\n rowVirtualizer={rowVirtualizer}\n slotProps={{\n Tr: {\n className: `DatasetEditorRow`,\n style: {\n height: `${ROW_HEIGHT}px`,\n maxHeight: `${ROW_HEIGHT}px`,\n },\n },\n }}\n />\n )}\n {!datasetToUpdate && (\n <SkeletonTable\n className=\"DatasetItemsEditorSkeleton\"\n numRows={8}\n numCols={6}\n rowHeight={`${ROW_HEIGHT}px`}\n />\n )}\n </div>\n <div className=\"DatasetEditorTopBottomPanel\">\n {hasChangedSinceLastSave && (\n <Alert severity=\"warning\">You have unsaved changes</Alert>\n )}\n <Button\n variant=\"outlined\"\n color=\"primary\"\n onClick={() => {\n if (hasChangedSinceLastSave) {\n setShowWarningDialog(true)\n } else if (onClose) {\n onClose()\n }\n }}\n >\n Cancel\n </Button>\n\n <Tooltip title={!hasChangedSinceLastSave && NO_CHANGES_MADE}>\n <div>\n <Button\n disabled={!datasetToUpdate || !hasChangedSinceLastSave}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => mutate(datasetToUpdate!)}\n >\n Save\n </Button>\n </div>\n </Tooltip>\n </div>\n </div>\n )\n}\n\nexport default DatasetItemsEditor\n"],"mappings":"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"}
1
+ {"version":3,"file":"DatasetItemsEditor.js","names":[],"sources":["../../../../src/components/SynapseTable/datasets/DatasetItemsEditor.tsx"],"sourcesContent":["import React from 'react'\nimport WideButton from '@/components/styled/WideButton'\nimport { datasetItemToReference } from '@/components/SynapseTable/datasets/DatasetEditorUtils'\nimport {\n useGetEntity,\n useGetEntityPath,\n useUpdateEntity,\n} from '@/synapse-queries'\nimport { RequiredProperties } from '@/utils'\nimport {\n convertToEntityType,\n entityTypeToFriendlyName,\n isDataset,\n isDatasetCollection,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useSet } from '@/utils/hooks'\nimport AddCircleTwoToneIcon from '@mui/icons-material/AddCircleTwoTone'\nimport {\n Alert,\n Button,\n Checkbox,\n Skeleton,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n EntityRef,\n EntityRefCollectionView,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport {\n createColumnHelper,\n getCoreRowModel,\n Table,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { isEqual, upperFirst } from 'lodash-es'\nimport pluralize from 'pluralize'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { CreatedOnCell } from '../../EntityFinder/details/view/table/CreatedOnCell'\nimport { EntityBadgeIconsCell } from '../../EntityFinder/details/view/table/EntityBadgeIconsCell'\nimport { EntityNameCell } from '../../EntityFinder/details/view/table/EntityNameCell'\nimport { ModifiedByCell } from '../../EntityFinder/details/view/table/ModifiedByCell'\nimport { ModifiedOnCell } from '../../EntityFinder/details/view/table/ModifiedOnCell'\nimport { ParentProjectCell } from '../../EntityFinder/details/view/table/ParentProjectCell'\nimport { EntityFinderModal } from '../../EntityFinder/EntityFinderModal'\nimport { FinderScope } from '../../EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '../../EntityFinder/VersionSelectionType'\nimport { BlockingLoader } from '../../LoadingScreen/LoadingScreen'\nimport { SkeletonTable } from '../../Skeleton'\nimport WarningDialog from '../../SynapseForm/WarningDialog'\nimport ColumnHeader from '../../TanStackTable/ColumnHeader'\nimport StyledVirtualTanStackTable from '../../TanStackTable/StyledVirtualTanStackTable'\nimport { displayToast } from '../../ToastMessage'\nimport { DatasetEditorCheckboxCell } from './DatasetEditorCheckboxCell'\nimport { DatasetEditorVersionCell } from './DatasetEditorVersionCell'\nimport { EntityFetchErrorCell } from './EntityFetchErrorCell'\n\nexport type DatasetItemsEditorTableData = EntityRef & {\n isSelected: boolean\n setSelected: (value: boolean) => void\n}\n\nenum DatasetItemsEditorColumn {\n ERROR_STATE = 'errorState',\n SELECTED = 'isSelected',\n NAME = 'name',\n ENTITY_ID = 'entityId',\n BADGES = 'badges',\n VERSION = 'version',\n CREATED_ON = 'createdOn',\n MODIFIED_ON = 'modifieddOn',\n MODIFIED_BY = 'modifiedBy',\n PROJECT = 'project',\n}\n\nconst columnHelper = createColumnHelper<DatasetItemsEditorTableData>()\nfunction getColumns(\n opts: SelectAllCheckboxRendererProps & {\n changeVersionOnItem: (entityId: string, newVersion: number) => void\n },\n) {\n const {\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n } = opts\n return [\n columnHelper.display({\n id: DatasetItemsEditorColumn.ERROR_STATE,\n minSize: 35,\n maxSize: 35,\n size: 35,\n enableResizing: false,\n header: () => null,\n cell: EntityFetchErrorCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.SELECTED,\n minSize: 40,\n maxSize: 40,\n size: 40,\n enableResizing: false,\n header: () => (\n <SelectAllCheckboxRenderer\n datasetToUpdate={datasetToUpdate}\n selectedIds={selectedIds}\n clearSelectedIds={clearSelectedIds}\n addSelectedId={addSelectedId}\n allItemsAreSelected={allItemsAreSelected}\n />\n ),\n cell: DatasetEditorCheckboxCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.NAME,\n minSize: 50,\n size: 300,\n header: props => <ColumnHeader {...props} title={'Name'} />,\n cell: EntityNameCell,\n }),\n columnHelper.accessor(DatasetItemsEditorColumn.ENTITY_ID, {\n minSize: 50,\n size: 130,\n header: props => <ColumnHeader {...props} title={'ID'} />,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.BADGES,\n minSize: 80,\n size: 80,\n enableResizing: true,\n cell: EntityBadgeIconsCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.VERSION,\n minSize: 150,\n size: 150,\n header: props => <ColumnHeader {...props} title={'Version'} />,\n cell: props => (\n <DatasetEditorVersionCell\n {...props}\n toggleSelection={datasetItem => {\n changeVersionOnItem(datasetItem.entityId, datasetItem.versionNumber)\n }}\n />\n ),\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.CREATED_ON,\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n size: 220,\n minSize: 170,\n cell: CreatedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_ON,\n header: props => <ColumnHeader {...props} title={'Modified On'} />,\n size: 220,\n minSize: 170,\n cell: ModifiedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_BY,\n header: props => <ColumnHeader {...props} title={'Modified By'} />,\n size: 250,\n enableResizing: true,\n cell: ModifiedByCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.PROJECT,\n header: props => <ColumnHeader {...props} title={'Size'} />,\n size: 300,\n cell: ParentProjectCell,\n }),\n ]\n}\n\nfunction getSelectableTypes(entity: EntityRefCollectionView) {\n if (isDataset(entity)) {\n return [EntityType.file]\n } else if (isDatasetCollection(entity)) {\n return [EntityType.dataset]\n } else {\n console.error(\n 'Cannot determine selectable types for entity type: ' +\n entity.concreteType,\n )\n return []\n }\n}\n\nexport function getCopy(entity?: EntityRefCollectionView) {\n const displayName = entity\n ? entityTypeToFriendlyName(convertToEntityType(entity.concreteType))\n : 'Collection'\n let itemName = 'Item'\n let currentVersionName = 'Current Version'\n if (entity && isDataset(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.file)\n currentVersionName = 'Draft'\n } else if (entity && isDatasetCollection(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.dataset)\n }\n\n const entityFinderPopover =\n entity && isDataset(entity)\n ? `Use the left pane to browse projects and folders. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple folders. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n : `Use the left pane to browse projects. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple projects. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n\n return {\n ADD_ITEMS: `Add ${pluralize(itemName)}`,\n ADD_ITEMS_TO: `Add ${pluralize(itemName)} to ${displayName}`,\n REMOVE_ITEMS: `Remove ${pluralize(itemName)}`,\n NO_ITEMS_IN_THIS_DATASET: `No ${pluralize(\n itemName,\n )} in this ${displayName}`,\n SAVE_TO_CONTINUE: `Save the ${displayName} to continue`,\n CREATE_VERSION_TO_FREEZE: `Create a Version of this ${displayName} to freeze it in its current state`,\n ENTITY_SAVED: `${displayName} Saved`,\n SAVE_CHANGES: `Save changes to ${currentVersionName}`,\n ENTITY_FINDER_POPOVER: entityFinderPopover,\n ENTITY_FINDER_PROMPT: `Find ${pluralize(\n itemName,\n )} to add to the ${displayName}.`,\n PRECONDITION_FAILED_MESSAGE: `Re-retrieve the ${displayName} to get the latest changes. Your current changes will be lost.`,\n PRECONDITION_FAILED_TITLE: `${displayName} updated since last fetched`,\n PRECONDITION_FAILED_ACTION: `Retrieve ${displayName}`,\n NO_CHANGES_MADE: `You have not made any changes to the ${displayName}.`,\n }\n}\n\nfunction getDataSetDifference(\n oldDataSet: EntityRef[],\n changedItems: EntityRef[],\n) {\n const unchangedItems = oldDataSet.filter(\n oldItem =>\n !changedItems.find(newItem => newItem.entityId === oldItem.entityId),\n )\n const deletedItems = [...unchangedItems]\n const { updatedItems, newItems } = changedItems.reduce(\n (results, result) => {\n const oldItem = oldDataSet.find(old => old.entityId === result.entityId)\n if (oldItem) {\n if (result.versionNumber !== oldItem.versionNumber) {\n results['updatedItems'].push(result)\n } else {\n unchangedItems.push(result)\n }\n } else {\n results['newItems'].push(result)\n }\n return results\n },\n { updatedItems: [], newItems: [] } as {\n updatedItems: EntityRef[]\n newItems: EntityRef[]\n },\n )\n\n return { unchangedItems, updatedItems, newItems, deletedItems }\n}\n\nfunction getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate?: RequiredProperties<\n EntityRefCollectionView,\n 'items'\n >,\n datasetToUpdate?: RequiredProperties<EntityRefCollectionView, 'items'>,\n) {\n const { updatedItems, newItems, deletedItems } = getDataSetDifference(\n previousDatasetToUpdate?.items ?? [],\n datasetToUpdate?.items!,\n )\n let toastTitle = ''\n\n // \"X items(s) deleted\"\n if (deletedItems.length > 0) {\n toastTitle += `${deletedItems.length} Item${\n deletedItems.length === 1 ? '' : 's'\n } removed`\n } else {\n // \"Y item(s) added\"\n toastTitle += `${newItems.length} Item${\n newItems.length === 1 ? '' : 's'\n } added`\n\n // \"and Z item(s) updated\", only shown if there are updated items\n if (updatedItems.length > 0) {\n toastTitle += ` and ${updatedItems.length} Item${\n updatedItems.length === 1 ? '' : 's'\n } updated`\n }\n }\n return toastTitle\n}\n\nexport type DatasetItemsEditorProps = {\n /* The synId of the EntityRefCollectionView to modify */\n entityId: string\n /** Callback invoked when the editor changes state to contain un/saved changes. */\n onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void\n onSave?: () => void\n onClose?: () => void\n}\n\nconst ROW_HEIGHT = 48\n\ntype SelectAllCheckboxRendererProps = {\n datasetToUpdate: RequiredProperties<EntityRefCollectionView, 'items'>\n selectedIds: Omit<Set<string>, 'add' | 'delete' | 'clear'>\n addSelectedId: (...items: string[]) => void\n clearSelectedIds: () => void\n allItemsAreSelected: boolean\n}\n\nconst SelectAllCheckboxRenderer = (\n props: SelectAllCheckboxRendererProps,\n): React.ReactNode => {\n const {\n datasetToUpdate,\n clearSelectedIds,\n allItemsAreSelected,\n addSelectedId,\n } = props\n const isChecked = allItemsAreSelected\n\n return (\n <Checkbox\n inputProps={{ 'aria-label': 'Select All' }}\n checked={isChecked}\n disabled={datasetToUpdate.items.length === 0}\n onChange={() => {\n if (isChecked) {\n clearSelectedIds()\n } else {\n addSelectedId(...datasetToUpdate.items.map(item => item.entityId))\n }\n }}\n />\n )\n}\n\nfunction NoItemsPlaceholder(props: {\n titleCopy: string\n buttonCopy: string\n onButtonClick: () => void\n}) {\n const { titleCopy, buttonCopy, onButtonClick } = props\n return (\n <div className=\"NoItemsPlaceholder\">\n <Typography variant={'headline3'}>{titleCopy}</Typography>\n <WideButton\n variant=\"contained\"\n color=\"primary\"\n onClick={onButtonClick}\n startIcon={<AddCircleTwoToneIcon />}\n sx={{ mt: 2 }}\n >\n {buttonCopy}\n </WideButton>\n </div>\n )\n}\n\nexport function DatasetItemsEditor(props: DatasetItemsEditorProps) {\n const { entityId, onSave, onClose, onUnsavedChangesChange } = props\n const [showEntityFinder, setShowEntityFinder] = useState<boolean>(false)\n const [showWarningDialog, setShowWarningDialog] = useState<boolean>(false)\n\n // The current 'client state' of dataset that the user is currently editing. Updates to this state are not saved until the user clicks 'Save'.\n const [datasetToUpdate, setDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // The previous value of the datasetToUpdate variable. This is used to calculate a summary of bulk actions since the last update to the unsaved dataset state.\n const [previousDatasetToUpdate, setPreviousDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // Stores the `close` function that will be used to hide the last toast that prompted the user to save\n const [onCloseLastSavePromptToast, setOnCloseLastSavePromptToast] = useState<\n { close: () => void } | undefined\n >()\n\n const { data: datasetOnServer, refetch: refetchDataset } = useGetEntity<\n RequiredProperties<EntityRefCollectionView, 'items'>\n >(entityId, undefined, {\n staleTime: Infinity,\n })\n\n const hasChangedSinceLastSave = Boolean(\n datasetOnServer &&\n datasetToUpdate &&\n !isEqual(datasetOnServer, datasetToUpdate),\n )\n\n const {\n ADD_ITEMS,\n ADD_ITEMS_TO,\n REMOVE_ITEMS,\n NO_ITEMS_IN_THIS_DATASET,\n SAVE_TO_CONTINUE,\n CREATE_VERSION_TO_FREEZE,\n ENTITY_SAVED,\n SAVE_CHANGES,\n PRECONDITION_FAILED_TITLE,\n PRECONDITION_FAILED_MESSAGE,\n PRECONDITION_FAILED_ACTION,\n ENTITY_FINDER_POPOVER,\n ENTITY_FINDER_PROMPT,\n NO_CHANGES_MADE,\n } = useMemo(() => getCopy(datasetOnServer), [datasetOnServer])\n\n useEffect(() => {\n if (datasetOnServer) {\n // SWC-5876: Dataset Items may be undefined. This has the same inherent meaning as the empty list, so we'll just change it to save us some null checks.\n if (datasetOnServer.items == null) {\n datasetOnServer.items = []\n }\n setDatasetToUpdate(datasetOnServer)\n }\n }, [datasetOnServer])\n\n const {\n set: selectedIds,\n add: addSelectedId,\n remove: removeSelectedId,\n clear: clearSelectedIds,\n } = useSet<string>()\n const allItemsAreSelected = Boolean(\n datasetToUpdate && datasetToUpdate.items.length === selectedIds.size,\n )\n\n useEffect(() => {\n if (datasetToUpdate && datasetOnServer && onUnsavedChangesChange) {\n onUnsavedChangesChange(hasChangedSinceLastSave)\n }\n }, [\n datasetOnServer,\n datasetToUpdate,\n hasChangedSinceLastSave,\n onUnsavedChangesChange,\n ])\n\n // We get the project ID to show the \"Current Project\" context in the Entity Finder.\n const { data: path } = useGetEntityPath(entityId)\n const projectId = path?.path[1]?.id\n\n const { mutate, isPending: updateIsPending } =\n useUpdateEntity<EntityRefCollectionView>({\n onMutate: () => {\n // Close existing toast that prompted the user to save\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n setOnCloseLastSavePromptToast(undefined)\n }\n },\n onSuccess: () => {\n // The query should automatically be invalidated, but just in case\n void refetchDataset()\n\n if (onSave) {\n onSave()\n } else {\n // If onSave isn't specified, push a generic toast message.\n displayToast(CREATE_VERSION_TO_FREEZE, 'success', {\n title: ENTITY_SAVED,\n })\n }\n },\n onError: error => {\n if (error.status === 412) {\n displayToast(PRECONDITION_FAILED_MESSAGE, 'warning', {\n title: PRECONDITION_FAILED_TITLE,\n primaryButtonConfig: {\n text: PRECONDITION_FAILED_ACTION,\n onClick: () => {\n void refetchDataset()\n },\n },\n })\n } else {\n displayToast(error.reason, 'danger', {\n title: 'An Error Occurred',\n })\n }\n },\n })\n\n useEffect(() => {\n // When changes are made (but not saved) to the datasetToUpdate, show a notification that summarizes the change and prompts the user to save\n if (\n previousDatasetToUpdate &&\n datasetToUpdate &&\n !isEqual(previousDatasetToUpdate.items, datasetToUpdate.items) &&\n !updateIsPending\n ) {\n const toastMessageTitle = getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate,\n datasetToUpdate,\n )\n // Replace existing toast that prompts the user to save before showing the new one\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n }\n const onCloseToast = displayToast(SAVE_TO_CONTINUE, 'info', {\n title: toastMessageTitle,\n primaryButtonConfig: {\n text: SAVE_CHANGES,\n onClick: () => mutate(datasetToUpdate),\n },\n })\n setOnCloseLastSavePromptToast({ close: onCloseToast })\n }\n setPreviousDatasetToUpdate(datasetToUpdate)\n // Only run when datasetToUpdate changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [datasetToUpdate])\n\n const tableData = useMemo(\n () =>\n datasetToUpdate?.items.map(\n (item: EntityRef): DatasetItemsEditorTableData => {\n return {\n ...item,\n isSelected: selectedIds.has(item.entityId),\n setSelected: (value: boolean) => {\n return value\n ? addSelectedId(item.entityId)\n : removeSelectedId(item.entityId)\n },\n }\n },\n ) ?? [],\n [addSelectedId, datasetToUpdate?.items, removeSelectedId, selectedIds],\n )\n\n function addItemsToDataset(itemsToAdd: Reference[]) {\n setDatasetToUpdate(datasetToUpdate => {\n if (datasetToUpdate) {\n const refToDatasetItem = itemsToAdd.map(item => ({\n entityId: item.targetId,\n versionNumber: item.targetVersionNumber!,\n }))\n const { unchangedItems, updatedItems, newItems } = getDataSetDifference(\n datasetToUpdate.items,\n refToDatasetItem,\n )\n\n if (updatedItems.length == 0 && newItems.length == 0) {\n // No items were added or updated, so don't update the state variable.\n return datasetToUpdate\n }\n\n const items = [...unchangedItems, ...updatedItems, ...newItems]\n\n return {\n ...datasetToUpdate,\n items: items,\n }\n } else {\n console.warn(\n 'Cannot add items to the Collection because it is undefined. The Collection may not have been fetched yet.',\n )\n return datasetToUpdate\n }\n })\n clearSelectedIds()\n }\n\n function removeSelectedItemsFromDataset() {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.filter(\n datasetItem => !selectedIds.has(datasetItem.entityId),\n ),\n }))\n clearSelectedIds()\n }\n\n function changeVersionOnItem(entityId: string, newVersion: number) {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.map(datasetItem =>\n datasetItem.entityId === entityId\n ? { entityId: entityId, versionNumber: newVersion }\n : datasetItem,\n ),\n }))\n }\n\n const selectableTypes: EntityType[] | undefined = useMemo(() => {\n if (datasetOnServer) {\n return getSelectableTypes(datasetOnServer)\n } else {\n return undefined\n }\n }, [datasetOnServer])\n\n const columns = useMemo(() => {\n if (!datasetToUpdate) {\n return []\n }\n return getColumns({\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n })\n }, [\n addSelectedId,\n allItemsAreSelected,\n clearSelectedIds,\n datasetToUpdate,\n selectedIds,\n ])\n\n const table: Table<DatasetItemsEditorTableData> =\n useReactTable<DatasetItemsEditorTableData>({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n // There are no backend sort controls. The server only provides ID/version, and a dataset could be up to 10k items,\n // so client side sorting is non-trivial. We may consider fetching all entity headers upon user request.\n enableSorting: false,\n })\n\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n const rowVirtualizer = useVirtualizer({\n count: tableData?.length ?? 0,\n estimateSize: () => ROW_HEIGHT, // estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? element => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const datasetItemsAsEntityFinderRef = useMemo(\n () => datasetToUpdate?.items.map(datasetItemToReference),\n [datasetToUpdate],\n )\n\n return (\n <div className=\"DatasetEditor\">\n <EntityFinderModal\n initialSelected={datasetItemsAsEntityFinderRef}\n configuration={{\n projectId: projectId,\n selectMultiple: true,\n initialScope: FinderScope.CURRENT_PROJECT,\n initialContainer: projectId ?? null,\n selectableTypes: selectableTypes,\n versionSelection: VersionSelectionType.REQUIRED,\n }}\n titleHelpPopoverProps={{\n markdownText: ENTITY_FINDER_POPOVER,\n helpUrl: 'https://help.synapse.org/docs/Datasets.2611281979.html',\n placement: 'right',\n }}\n promptCopy={ENTITY_FINDER_PROMPT}\n show={showEntityFinder}\n title={ADD_ITEMS_TO}\n confirmButtonCopy={'Apply changes'}\n onConfirm={items => {\n addItemsToDataset(items)\n setShowEntityFinder(false)\n }}\n onCancel={() => setShowEntityFinder(false)}\n />\n <WarningDialog\n title=\"Unsaved Changes\"\n content=\"Any unsaved changes will be lost. Are you sure you want to close the editor?\"\n confirmButtonText=\"Close Editor\"\n onConfirm={() => {\n if (onClose) {\n setShowWarningDialog(false)\n if (onUnsavedChangesChange) {\n onUnsavedChangesChange(false)\n }\n onClose()\n }\n }}\n open={showWarningDialog}\n onConfirmCallbackArgs={[]}\n onCancel={() => setShowWarningDialog(false)}\n />\n\n <div className=\"DatasetEditorTopBottomPanel\">\n <BlockingLoader show={updateIsPending} />\n <div className=\"ItemCount\">\n {datasetToUpdate ? (\n <Typography variant=\"headline3\">\n {datasetToUpdate.items.length === 0\n ? 'No'\n : datasetToUpdate.items.length.toLocaleString()}{' '}\n File\n {datasetToUpdate.items.length !== 1 && 's'}\n </Typography>\n ) : (\n <Skeleton variant=\"rectangular\" width={200} />\n )}\n </div>\n\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={datasetToUpdate == null}\n onClick={() => setShowEntityFinder(true)}\n >\n {ADD_ITEMS}\n </Button>\n <Button\n disabled={selectedIds.size === 0}\n variant=\"outlined\"\n color=\"primary\"\n onClick={removeSelectedItemsFromDataset}\n >\n {REMOVE_ITEMS}\n </Button>\n </div>\n <div className=\"DatasetEditorTableContainer\">\n {datasetToUpdate && datasetToUpdate.items.length === 0 && (\n <NoItemsPlaceholder\n titleCopy={NO_ITEMS_IN_THIS_DATASET}\n buttonCopy={ADD_ITEMS}\n onButtonClick={() => setShowEntityFinder(true)}\n />\n )}\n {datasetToUpdate && datasetToUpdate.items.length > 0 && (\n <StyledVirtualTanStackTable<DatasetItemsEditorTableData>\n styledTableContainerProps={{\n className: 'DatasetEditorTable',\n ref: tableContainerRef,\n height: '350px',\n }}\n table={table}\n rowVirtualizer={rowVirtualizer}\n slotProps={{\n Tr: {\n className: `DatasetEditorRow`,\n style: {\n height: `${ROW_HEIGHT}px`,\n maxHeight: `${ROW_HEIGHT}px`,\n },\n },\n }}\n />\n )}\n {!datasetToUpdate && (\n <SkeletonTable\n className=\"DatasetItemsEditorSkeleton\"\n numRows={8}\n numCols={6}\n rowHeight={`${ROW_HEIGHT}px`}\n />\n )}\n </div>\n <div className=\"DatasetEditorTopBottomPanel\">\n {hasChangedSinceLastSave && (\n <Alert severity=\"warning\">You have unsaved changes</Alert>\n )}\n <Button\n variant=\"outlined\"\n color=\"primary\"\n onClick={() => {\n if (hasChangedSinceLastSave) {\n setShowWarningDialog(true)\n } else if (onClose) {\n onClose()\n }\n }}\n >\n Cancel\n </Button>\n\n <Tooltip title={!hasChangedSinceLastSave && NO_CHANGES_MADE}>\n <div>\n <Button\n disabled={!datasetToUpdate || !hasChangedSinceLastSave}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => mutate(datasetToUpdate!)}\n >\n Save\n </Button>\n </div>\n </Tooltip>\n </div>\n </div>\n )\n}\n\nexport default DatasetItemsEditor\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnSelection.js","names":[],"sources":["../../../../src/components/SynapseTable/table-top/ColumnSelection.tsx"],"sourcesContent":["import { MenuItem } from '@mui/material'\nimport { SelectColumn } from '@sage-bionetworks/synapse-types'\nimport { CSSProperties } from 'react'\nimport IconSvg from '../../IconSvg/IconSvg'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { ElementWithTooltip } from '../../widgets/ElementWithTooltip'\n\ntype ColumnSelectionProps = {\n headers?: SelectColumn[]\n isColumnSelected: string[]\n onChange?: () => void\n toggleColumnSelection: (name: string) => void\n darkTheme?: boolean\n}\n\nexport function ColumnSelection(props: ColumnSelectionProps) {\n const { headers, isColumnSelected, toggleColumnSelection, darkTheme } = props\n\n const { getColumnDisplayName } = useQueryVisualizationContext()\n return (\n <ElementWithTooltip\n tooltipText={'Show/Hide Columns'}\n icon={darkTheme ? 'columnsdark' : 'columns'}\n darkTheme={darkTheme}\n menuItems={headers?.map(header => {\n const { name } = header\n const isCurrentColumnSelected = isColumnSelected.includes(name)\n const iconStyle: CSSProperties = {\n width: '11px',\n marginRight: '10px',\n visibility: isCurrentColumnSelected ? undefined : 'hidden',\n }\n const maybeShowPrimaryColor = isCurrentColumnSelected\n ? 'SRC-primary-text-color'\n : ''\n return (\n <MenuItem onClick={() => toggleColumnSelection(name)} key={name}>\n <span className={maybeShowPrimaryColor} style={iconStyle}>\n <IconSvg icon=\"check\" sx={{ width: '14px' }} />\n </span>\n {getColumnDisplayName(name)}\n </MenuItem>\n )\n })}\n />\n )\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,EAAgB,GAA6B;CAC3D,IAAM,EAAE,YAAS,qBAAkB,0BAAuB,iBAAc,GAElE,EAAE,4BAAyB,GAA8B;AAC/D,QACE,kBAAC,GAAD;EACE,aAAa;EACb,MAAM,IAAY,gBAAgB;EACvB;EACX,WAAW,GAAS,KAAI,MAAU;GAChC,IAAM,EAAE,YAAS,GACX,IAA0B,EAAiB,SAAS,EAAK;AAS/D,UACE,kBAAC,GAAD;IAAU,eAAe,EAAsB,EAAK;cAApD,CACE,kBAAC,QAAD;KAAM,WALoB,IAC1B,2BACA;KAGwC,OAVX;MAC/B,OAAO;MACP,aAAa;MACb,YAAY,IAA0B,KAAA,IAAY;MACnD;eAOK,kBAAC,GAAD;MAAS,MAAK;MAAQ,IAAI,EAAE,OAAO,QAAQ;MAAI,CAAA;KAC1C,CAAA,EACN,EAAqB,EAAK,CAClB;MALgD,EAKhD;IAEb;EACF,CAAA"}
1
+ {"version":3,"file":"ColumnSelection.js","names":[],"sources":["../../../../src/components/SynapseTable/table-top/ColumnSelection.tsx"],"sourcesContent":["import { MenuItem } from '@mui/material'\nimport { SelectColumn } from '@sage-bionetworks/synapse-types'\nimport { CSSProperties } from 'react'\nimport IconSvg from '../../IconSvg/IconSvg'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { ElementWithTooltip } from '../../widgets/ElementWithTooltip'\n\ntype ColumnSelectionProps = {\n headers?: SelectColumn[]\n isColumnSelected: string[]\n onChange?: () => void\n toggleColumnSelection: (name: string) => void\n darkTheme?: boolean\n}\n\nexport function ColumnSelection(props: ColumnSelectionProps) {\n const { headers, isColumnSelected, toggleColumnSelection, darkTheme } = props\n\n const { getColumnDisplayName } = useQueryVisualizationContext()\n return (\n <ElementWithTooltip\n tooltipText={'Show/Hide Columns'}\n icon={darkTheme ? 'columnsdark' : 'columns'}\n darkTheme={darkTheme}\n menuItems={headers?.map(header => {\n const { name } = header\n const isCurrentColumnSelected = isColumnSelected.includes(name)\n const iconStyle: CSSProperties = {\n width: '11px',\n marginRight: '10px',\n visibility: isCurrentColumnSelected ? undefined : 'hidden',\n }\n const maybeShowPrimaryColor = isCurrentColumnSelected\n ? 'SRC-primary-text-color'\n : ''\n return (\n <MenuItem onClick={() => toggleColumnSelection(name)} key={name}>\n <span className={maybeShowPrimaryColor} style={iconStyle}>\n <IconSvg icon=\"check\" sx={{ width: '14px' }} />\n </span>\n {getColumnDisplayName(name)}\n </MenuItem>\n )\n })}\n />\n )\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,EAAgB,GAA6B;CAC3D,IAAM,EAAE,YAAS,qBAAkB,0BAAuB,iBAAc,GAElE,EAAE,4BAAyB,GAA8B;AAC/D,QACE,kBAAC,GAAD;EACE,aAAa;EACb,MAAM,IAAY,gBAAgB;EACvB;EACX,WAAW,GAAS,KAAI,MAAU;GAChC,IAAM,EAAE,YAAS,GACX,IAA0B,EAAiB,SAAS,EAAK;AAS/D,UACE,kBAAC,GAAD;IAAU,eAAe,EAAsB,EAAK;cAApD,CACE,kBAAC,QAAD;KAAM,WALoB,IAC1B,2BACA;KAGwC,OAAO;MATjD,OAAO;MACP,aAAa;MACb,YAAY,IAA0B,KAAA,IAAY;MAOD;eAC7C,kBAAC,GAAD;MAAS,MAAK;MAAQ,IAAI,EAAE,OAAO,QAAQ;MAAI,CAAA;KAC1C,CAAA,EACN,EAAqB,EAAK,CAClB;MALgD,EAKhD;IAEb;EACF,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"DownloadOptions.js","names":[],"sources":["../../../../src/components/SynapseTable/table-top/DownloadOptions.tsx"],"sourcesContent":["import { useGetEntity } from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { isDataset } from '@/utils/functions/EntityTypeUtils'\nimport { canTableQueryBeAddedToDownloadList } from '@/utils/functions/queryUtils'\nimport { MenuItem, Tooltip } from '@mui/material'\nimport { Table } from '@sage-bionetworks/synapse-types'\nimport { ReactNode, useMemo, useState } from 'react'\nimport ModalDownload from '../../ModalDownload/ModalDownload'\nimport ProgrammaticTableDownload from '../../ProgrammaticTableDownload/ProgrammaticTableDownload'\nimport { useQueryContext } from '../../QueryContext'\nimport {\n useHasSelectedRowsAtomValue,\n useSelectedRowsAtomValue,\n} from '../../QueryWrapper/TableRowSelectionState'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { ElementWithTooltip } from '../../widgets/ElementWithTooltip'\nimport { getFileColumnModelId } from '../SynapseTableUtils'\nimport { getNumberOfResultsToAddToDownloadListCopy } from '../TopLevelControls/TopLevelControlsUtils'\nimport { DownloadLoginModal } from './DownloadLoginModal'\n\nexport type DownloadOptionsProps = {\n onDownloadFiles: () => void\n darkTheme?: boolean\n}\n\nexport function DownloadOptions(props: DownloadOptionsProps) {\n const { isAuthenticated } = useSynapseContext()\n const {\n entityId,\n versionNumber,\n getCurrentQueryRequest,\n hasResettableFilters,\n } = useQueryContext()\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const selectedRows = useSelectedRowsAtomValue()\n const hasSelectedRows = useHasSelectedRowsAtomValue()\n\n const queryBundleRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n\n const [showLoginModal, setShowLoginModal] = useState(false)\n const [showExportMetadata, setShowExportMetadata] = useState(false)\n const [showProgrammaticOptions, setShowProgrammaticOptions] = useState(false)\n const { onDownloadFiles, darkTheme = true } = props\n\n const fileColumnId = getFileColumnModelId(queryMetadata?.columnModels)\n\n const showAddQueryToDownloadList = canTableQueryBeAddedToDownloadList(\n entity,\n fileColumnId,\n )\n\n // SWC-5878 - Disable downloading a \"Draft\" dataset\n const disableDownload = entity && isDataset(entity) && entity.isLatestVersion\n\n const downloadMenuItems: ReactNode[] = useMemo(() => {\n const downloadMenuItems = []\n if (showAddQueryToDownloadList) {\n downloadMenuItems.push(\n <Tooltip\n key={'add-to-download-list'}\n title={\n disableDownload\n ? 'A draft version of a dataset cannot be added to the Download Cart'\n : null\n }\n placement=\"left\"\n enterNextDelay={300}\n describeChild={true}\n >\n <MenuItem\n className={disableDownload ? 'ignoreLink' : undefined}\n disabled={disableDownload}\n // If disabled, add pointer-events-auto so the tooltip still works\n style={disableDownload ? { pointerEvents: 'auto' } : {}}\n onClick={() =>\n isAuthenticated ? onDownloadFiles() : setShowLoginModal(true)\n }\n >\n {getNumberOfResultsToAddToDownloadListCopy(\n hasResettableFilters,\n hasSelectedRows,\n selectedRows,\n queryMetadata?.queryCount,\n 'file',\n )}\n </MenuItem>\n </Tooltip>,\n )\n }\n downloadMenuItems.push(\n <MenuItem\n key={'export-table'}\n onClick={() => {\n setShowExportMetadata(true)\n }}\n >\n Export Table\n </MenuItem>,\n )\n downloadMenuItems.push(\n <Tooltip\n key={'programmatic-options'}\n title={\n disableDownload\n ? 'A draft version of a dataset cannot be downloaded programmatically'\n : null\n }\n placement=\"left\"\n enterNextDelay={300}\n describeChild={true}\n >\n <MenuItem\n className={disableDownload ? 'ignoreLink' : undefined}\n disabled={disableDownload}\n // If disabled, add pointer-events-auto so the tooltip still works\n style={disableDownload ? { pointerEvents: 'auto' } : {}}\n onClick={() => setShowProgrammaticOptions(true)}\n >\n Programmatic Options\n </MenuItem>\n </Tooltip>,\n )\n return downloadMenuItems\n }, [\n isAuthenticated,\n disableDownload,\n hasResettableFilters,\n hasSelectedRows,\n onDownloadFiles,\n queryMetadata?.queryCount,\n selectedRows,\n showAddQueryToDownloadList,\n ])\n\n return (\n <>\n <ElementWithTooltip\n tooltipText={'Download Options'}\n size=\"lg\"\n darkTheme={darkTheme}\n icon={'download'}\n menuItems={downloadMenuItems}\n />\n {showLoginModal && (\n <DownloadLoginModal\n showModal={showLoginModal}\n onHide={() => setShowLoginModal(false)}\n ></DownloadLoginModal>\n )}\n {\n // modal can render anywhere, this is not a particular location\n showExportMetadata && (\n <ModalDownload\n onClose={() => setShowExportMetadata(false)}\n queryBundleRequest={queryBundleRequest}\n />\n )\n }\n {showProgrammaticOptions && queryMetadata && (\n <ProgrammaticTableDownload\n onHide={() => setShowProgrammaticOptions(false)}\n queryBundleRequest={queryBundleRequest}\n ></ProgrammaticTableDownload>\n )}\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,EAAgB,GAA6B;CAC3D,IAAM,EAAE,uBAAoB,GAAmB,EACzC,EACJ,aACA,kBACA,2BACA,4BACE,GAAiB,EACf,EAAE,MAAM,MAAW,EAAoB,GAAU,EAAc,EAC/D,EAAE,MAAM,MAAkB,GAAqB,EAE/C,IAAe,GAA0B,EACzC,IAAkB,GAA6B,EAE/C,IAAqB,QACnB,GAAwB,EAC9B,CAAC,EAAuB,CACzB,EAEK,CAAC,GAAgB,KAAqB,EAAS,GAAM,EACrD,CAAC,GAAoB,KAAyB,EAAS,GAAM,EAC7D,CAAC,GAAyB,KAA8B,EAAS,GAAM,EACvE,EAAE,oBAAiB,eAAY,OAAS,GAIxC,IAA6B,EACjC,GAHmB,EAAqB,GAAe,aAAa,CAKrE,EAGK,IAAkB,KAAU,EAAU,EAAO,IAAI,EAAO;AAkF9D,QACE,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,GAAD;GACE,aAAa;GACb,MAAK;GACM;GACX,MAAM;GACN,WAvFiC,QAAc;IACnD,IAAM,IAAoB,EAAE;AAmE5B,WAlEI,KACF,EAAkB,KAChB,kBAAC,GAAD;KAEE,OACE,IACI,sEACA;KAEN,WAAU;KACV,gBAAgB;KAChB,eAAe;eAEf,kBAAC,GAAD;MACE,WAAW,IAAkB,eAAe,KAAA;MAC5C,UAAU;MAEV,OAAO,IAAkB,EAAE,eAAe,QAAQ,GAAG,EAAE;MACvD,eACE,IAAkB,GAAiB,GAAG,EAAkB,GAAK;gBAG9D,EACC,GACA,GACA,GACA,GAAe,YACf,OACD;MACQ,CAAA;KACH,EA3BH,uBA2BG,CACX,EAEH,EAAkB,KAChB,kBAAC,GAAD;KAEE,eAAe;AACb,QAAsB,GAAK;;eAE9B;KAEU,EANJ,eAMI,CACZ,EACD,EAAkB,KAChB,kBAAC,GAAD;KAEE,OACE,IACI,uEACA;KAEN,WAAU;KACV,gBAAgB;KAChB,eAAe;eAEf,kBAAC,GAAD;MACE,WAAW,IAAkB,eAAe,KAAA;MAC5C,UAAU;MAEV,OAAO,IAAkB,EAAE,eAAe,QAAQ,GAAG,EAAE;MACvD,eAAe,EAA2B,GAAK;gBAChD;MAEU,CAAA;KACH,EAnBH,uBAmBG,CACX,EACM;MACN;IACD;IACA;IACA;IACA;IACA;IACA,GAAe;IACf;IACA;IACD,CAAC;GAUI,CAAA;EACD,KACC,kBAAC,GAAD;GACE,WAAW;GACX,cAAc,EAAkB,GAAM;GAClB,CAAA;EAItB,KACE,kBAAC,GAAD;GACE,eAAe,EAAsB,GAAM;GACvB;GACpB,CAAA;EAGL,KAA2B,KAC1B,kBAAC,GAAD;GACE,cAAc,EAA2B,GAAM;GAC3B;GACO,CAAA;EAE9B,EAAA,CAAA"}
1
+ {"version":3,"file":"DownloadOptions.js","names":[],"sources":["../../../../src/components/SynapseTable/table-top/DownloadOptions.tsx"],"sourcesContent":["import { useGetEntity } from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { isDataset } from '@/utils/functions/EntityTypeUtils'\nimport { canTableQueryBeAddedToDownloadList } from '@/utils/functions/queryUtils'\nimport { MenuItem, Tooltip } from '@mui/material'\nimport { Table } from '@sage-bionetworks/synapse-types'\nimport { ReactNode, useMemo, useState } from 'react'\nimport ModalDownload from '../../ModalDownload/ModalDownload'\nimport ProgrammaticTableDownload from '../../ProgrammaticTableDownload/ProgrammaticTableDownload'\nimport { useQueryContext } from '../../QueryContext'\nimport {\n useHasSelectedRowsAtomValue,\n useSelectedRowsAtomValue,\n} from '../../QueryWrapper/TableRowSelectionState'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { ElementWithTooltip } from '../../widgets/ElementWithTooltip'\nimport { getFileColumnModelId } from '../SynapseTableUtils'\nimport { getNumberOfResultsToAddToDownloadListCopy } from '../TopLevelControls/TopLevelControlsUtils'\nimport { DownloadLoginModal } from './DownloadLoginModal'\n\nexport type DownloadOptionsProps = {\n onDownloadFiles: () => void\n darkTheme?: boolean\n}\n\nexport function DownloadOptions(props: DownloadOptionsProps) {\n const { isAuthenticated } = useSynapseContext()\n const {\n entityId,\n versionNumber,\n getCurrentQueryRequest,\n hasResettableFilters,\n } = useQueryContext()\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const selectedRows = useSelectedRowsAtomValue()\n const hasSelectedRows = useHasSelectedRowsAtomValue()\n\n const queryBundleRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n\n const [showLoginModal, setShowLoginModal] = useState(false)\n const [showExportMetadata, setShowExportMetadata] = useState(false)\n const [showProgrammaticOptions, setShowProgrammaticOptions] = useState(false)\n const { onDownloadFiles, darkTheme = true } = props\n\n const fileColumnId = getFileColumnModelId(queryMetadata?.columnModels)\n\n const showAddQueryToDownloadList = canTableQueryBeAddedToDownloadList(\n entity,\n fileColumnId,\n )\n\n // SWC-5878 - Disable downloading a \"Draft\" dataset\n const disableDownload = entity && isDataset(entity) && entity.isLatestVersion\n\n const downloadMenuItems: ReactNode[] = useMemo(() => {\n const downloadMenuItems = []\n if (showAddQueryToDownloadList) {\n downloadMenuItems.push(\n <Tooltip\n key={'add-to-download-list'}\n title={\n disableDownload\n ? 'A draft version of a dataset cannot be added to the Download Cart'\n : null\n }\n placement=\"left\"\n enterNextDelay={300}\n describeChild={true}\n >\n <MenuItem\n className={disableDownload ? 'ignoreLink' : undefined}\n disabled={disableDownload}\n // If disabled, add pointer-events-auto so the tooltip still works\n style={disableDownload ? { pointerEvents: 'auto' } : {}}\n onClick={() =>\n isAuthenticated ? onDownloadFiles() : setShowLoginModal(true)\n }\n >\n {getNumberOfResultsToAddToDownloadListCopy(\n hasResettableFilters,\n hasSelectedRows,\n selectedRows,\n queryMetadata?.queryCount,\n 'file',\n )}\n </MenuItem>\n </Tooltip>,\n )\n }\n downloadMenuItems.push(\n <MenuItem\n key={'export-table'}\n onClick={() => {\n setShowExportMetadata(true)\n }}\n >\n Export Table\n </MenuItem>,\n )\n downloadMenuItems.push(\n <Tooltip\n key={'programmatic-options'}\n title={\n disableDownload\n ? 'A draft version of a dataset cannot be downloaded programmatically'\n : null\n }\n placement=\"left\"\n enterNextDelay={300}\n describeChild={true}\n >\n <MenuItem\n className={disableDownload ? 'ignoreLink' : undefined}\n disabled={disableDownload}\n // If disabled, add pointer-events-auto so the tooltip still works\n style={disableDownload ? { pointerEvents: 'auto' } : {}}\n onClick={() => setShowProgrammaticOptions(true)}\n >\n Programmatic Options\n </MenuItem>\n </Tooltip>,\n )\n return downloadMenuItems\n }, [\n isAuthenticated,\n disableDownload,\n hasResettableFilters,\n hasSelectedRows,\n onDownloadFiles,\n queryMetadata?.queryCount,\n selectedRows,\n showAddQueryToDownloadList,\n ])\n\n return (\n <>\n <ElementWithTooltip\n tooltipText={'Download Options'}\n size=\"lg\"\n darkTheme={darkTheme}\n icon={'download'}\n menuItems={downloadMenuItems}\n />\n {showLoginModal && (\n <DownloadLoginModal\n showModal={showLoginModal}\n onHide={() => setShowLoginModal(false)}\n ></DownloadLoginModal>\n )}\n {\n // modal can render anywhere, this is not a particular location\n showExportMetadata && (\n <ModalDownload\n onClose={() => setShowExportMetadata(false)}\n queryBundleRequest={queryBundleRequest}\n />\n )\n }\n {showProgrammaticOptions && queryMetadata && (\n <ProgrammaticTableDownload\n onHide={() => setShowProgrammaticOptions(false)}\n queryBundleRequest={queryBundleRequest}\n ></ProgrammaticTableDownload>\n )}\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,EAAgB,GAA6B;CAC3D,IAAM,EAAE,uBAAoB,GAAmB,EACzC,EACJ,aACA,kBACA,2BACA,4BACE,GAAiB,EACf,EAAE,MAAM,MAAW,EAAoB,GAAU,EAAc,EAC/D,EAAE,MAAM,MAAkB,GAAqB,EAE/C,IAAe,GAA0B,EACzC,IAAkB,GAA6B,EAE/C,IAAqB,QACnB,GAAwB,EAC9B,CAAC,EAAuB,CACzB,EAEK,CAAC,GAAgB,KAAqB,EAAS,GAAM,EACrD,CAAC,GAAoB,KAAyB,EAAS,GAAM,EAC7D,CAAC,GAAyB,KAA8B,EAAS,GAAM,EACvE,EAAE,oBAAiB,eAAY,OAAS,GAIxC,IAA6B,EACjC,GAHmB,EAAqB,GAAe,aAIvD,CACD,EAGK,IAAkB,KAAU,EAAU,EAAO,IAAI,EAAO;AAkF9D,QACE,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,GAAD;GACE,aAAa;GACb,MAAK;GACM;GACX,MAAM;GACN,WAvFiC,QAAc;IACnD,IAAM,IAAoB,EAAE;AAmE5B,WAlEI,KACF,EAAkB,KAChB,kBAAC,GAAD;KAEE,OACE,IACI,sEACA;KAEN,WAAU;KACV,gBAAgB;KAChB,eAAe;eAEf,kBAAC,GAAD;MACE,WAAW,IAAkB,eAAe,KAAA;MAC5C,UAAU;MAEV,OAAO,IAAkB,EAAE,eAAe,QAAQ,GAAG,EAAE;MACvD,eACE,IAAkB,GAAiB,GAAG,EAAkB,GAAK;gBAG9D,EACC,GACA,GACA,GACA,GAAe,YACf,OACD;MACQ,CAAA;KACH,EA3BH,uBA2BG,CACX,EAEH,EAAkB,KAChB,kBAAC,GAAD;KAEE,eAAe;AACb,QAAsB,GAAK;;eAE9B;KAEU,EANJ,eAMI,CACZ,EACD,EAAkB,KAChB,kBAAC,GAAD;KAEE,OACE,IACI,uEACA;KAEN,WAAU;KACV,gBAAgB;KAChB,eAAe;eAEf,kBAAC,GAAD;MACE,WAAW,IAAkB,eAAe,KAAA;MAC5C,UAAU;MAEV,OAAO,IAAkB,EAAE,eAAe,QAAQ,GAAG,EAAE;MACvD,eAAe,EAA2B,GAAK;gBAChD;MAEU,CAAA;KACH,EAnBH,uBAmBG,CACX,EACM;MACN;IACD;IACA;IACA;IACA;IACA;IACA,GAAe;IACf;IACA;IACD,CASgB;GACX,CAAA;EACD,KACC,kBAAC,GAAD;GACE,WAAW;GACX,cAAc,EAAkB,GAAM;GAClB,CAAA;EAItB,KACE,kBAAC,GAAD;GACE,eAAe,EAAsB,GAAM;GACvB;GACpB,CAAA;EAGL,KAA2B,KAC1B,kBAAC,GAAD;GACE,cAAc,EAA2B,GAAM;GAC3B;GACO,CAAA;EAE9B,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePrefetchTableData.js","names":[],"sources":["../../../src/components/SynapseTable/usePrefetchTableData.ts"],"sourcesContent":["import {\n useGetEntity,\n useGetEntityHeaders,\n useGetFileBatch,\n useGetRestrictionInformationBatch,\n useGetUserGroupHeaders,\n} from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { getFieldIndex, getTypeIndices } from '@/utils/functions/queryUtils'\nimport { goToPage as transformQueryToGoToPage } from '@/utils/hooks/useImmutableTableQuery/TableQueryReducerActions'\nimport {\n ColumnTypeEnum,\n FileHandleAssociateType,\n FileHandleAssociation,\n QueryBundleRequest,\n ReferenceList,\n RestrictableObjectType,\n RowSet,\n Table,\n} from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { cloneDeep } from 'lodash-es'\nimport { useCallback, useMemo } from 'react'\nimport { useQueryContext } from '../QueryContext'\nimport { getTableQueryUseQueryOptions } from '../QueryWrapper/TableQueryUseQueryOptions'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport {\n isEntityViewOrDatasetOrCollection,\n isFileViewOrDataset,\n} from './SynapseTableUtils'\n\nfunction usePrefetchFileHandleData(rowSet: RowSet) {\n const { entityId, versionNumber } = useQueryContext()\n\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const fileHandleIdColumnIndices = getTypeIndices(\n ColumnTypeEnum.FILEHANDLEID,\n queryMetadata?.selectColumns,\n )\n\n let fileHandlesToPrefetch: FileHandleAssociation[] = []\n\n // Now add all IDs from the entity ID columns\n if (entity && rowSet && queryMetadata && queryMetadata.selectColumns) {\n fileHandlesToPrefetch = rowSet.rows.reduce(\n (prev: FileHandleAssociation[], curr) => {\n fileHandleIdColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value) {\n const selectColumn = queryMetadata?.selectColumns![index]\n if (\n isFileViewOrDataset(entity) &&\n selectColumn.name === 'dataFileHandleId'\n ) {\n // The association is the entity\n prev.push({\n fileHandleId: value,\n associateObjectId: String(curr.rowId),\n associateObjectType: FileHandleAssociateType.FileEntity,\n })\n } else {\n // The association is the table entity\n prev.push({\n fileHandleId: value,\n associateObjectId: entity.id!,\n associateObjectType: FileHandleAssociateType.TableEntity,\n })\n }\n }\n })\n return prev\n },\n\n fileHandlesToPrefetch,\n )\n }\n\n return useGetFileBatch(\n {\n requestedFiles: fileHandlesToPrefetch,\n includeFileHandles: true,\n includePreSignedURLs: false,\n includePreviewPreSignedURLs: false,\n },\n {\n enabled: fileHandlesToPrefetch.length > 0,\n },\n )\n}\n\nfunction useGetEntitiesInTable(rowSet: RowSet) {\n const { entityId, versionNumber } = useQueryContext()\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n const { data: queryMetadata } = useGetQueryMetadata()\n\n let entitiesInTable: ReferenceList = []\n\n // If this is a file view/dataset, collect all the row IDs; they correspond to entities that we'll end up fetching\n if (entity && isEntityViewOrDatasetOrCollection(entity)) {\n entitiesInTable = rowSet.rows.reduce((prev: ReferenceList, curr) => {\n const { rowId, versionNumber } = curr\n if (rowId) {\n prev.push({\n targetId: `syn${rowId}`,\n targetVersionNumber: versionNumber,\n })\n }\n return prev\n }, entitiesInTable)\n }\n\n let entityIdColumnIndices = getTypeIndices(\n ColumnTypeEnum.ENTITYID,\n queryMetadata?.selectColumns,\n )\n\n if (entity && isEntityViewOrDatasetOrCollection(entity)) {\n // If this is a view/dataset, we don't need to fetch the entities in the entity ID column\n // Collecting the row IDs in the last step was sufficient\n const idColumnIndex = getFieldIndex('id', queryMetadata)\n entityIdColumnIndices = entityIdColumnIndices.filter(\n index => index !== idColumnIndex,\n )\n }\n\n const entityIdListColumnIndices = getTypeIndices(\n ColumnTypeEnum.ENTITYID_LIST,\n queryMetadata?.selectColumns,\n )\n\n entitiesInTable = rowSet.rows.reduce((prev: ReferenceList, curr) => {\n // Get all IDs from the entity ID columns\n entityIdColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (\n value &&\n !prev.find(e => e.targetId === value && e.targetVersionNumber == null)\n ) {\n prev.push({ targetId: value })\n }\n })\n // Get all IDs from the entity ID list columns\n entityIdListColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value) {\n const ids = JSON.parse(value) as string[]\n ids.forEach(id => {\n if (\n id &&\n !prev.find(e => e.targetId === id && e.targetVersionNumber == null)\n ) {\n prev.push({ targetId: id })\n }\n })\n }\n })\n\n return prev\n }, entitiesInTable)\n\n return entitiesInTable\n}\n\nfunction usePrefetchEntityData(entitiesToPrefetch: ReferenceList) {\n return useGetEntityHeaders(entitiesToPrefetch, {\n enabled: entitiesToPrefetch.length > 0,\n })\n}\n\nfunction usePrefetchUserGroupHeaderData(rowSet: RowSet) {\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const userIdColumnIndices = getTypeIndices(\n ColumnTypeEnum.USERID,\n queryMetadata?.selectColumns,\n )\n\n const userIdListColumnIndices = getTypeIndices(\n ColumnTypeEnum.USERID_LIST,\n queryMetadata?.selectColumns,\n )\n\n const principalIdsToPrefetch: string[] = rowSet.rows.reduce(\n (prev: string[], curr) => {\n // Add all IDs from the USERID columns\n userIdColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value && !prev.includes(value)) {\n prev.push(value)\n }\n })\n // Add all IDs from the USERID_LIST columns\n userIdListColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value) {\n const userIds = JSON.parse(value) as number[]\n userIds.forEach(userId => {\n if (!prev.includes(String(userId))) {\n prev.push(String(userId))\n }\n })\n }\n })\n return prev\n },\n [],\n )\n\n return useGetUserGroupHeaders(principalIdsToPrefetch, {\n enabled: principalIdsToPrefetch.length > 0,\n })\n}\n\nfunction usePrefetchEntityRestrictionData(entitiesToPrefetch: ReferenceList) {\n // This information only varies by entity ID, not version number. The restriction information is the same for all versions.\n const uniqueEntityIds = useMemo(() => {\n const entityIds = entitiesToPrefetch.map(e => e.targetId)\n // Dedupe the list in case there were duplicates, e.g. there were multiple versions of the same entity\n return Array.from(new Set(entityIds))\n }, [entitiesToPrefetch])\n\n return useGetRestrictionInformationBatch(\n {\n objectIds: uniqueEntityIds,\n restrictableObjectType: RestrictableObjectType.ENTITY,\n },\n {\n enabled: entitiesToPrefetch.length > 0,\n },\n )\n}\n\n/**\n * Uses react-query to prefetch data rendered by SynapseTable. Each SynapseTableCell instance load data to render rich\n * content (e.g. entity data) for the cell based on its column type. This hook uses react-query hooks that will\n * fetch and de-normalize batch requests, so when the SynapseTableCell component renders, the data is already loaded\n * in the cache. In practice, this avoids Synapse backend throttling and 'waterfall' content rendering.\n */\nexport function usePrefetchResourcesInTable(rowSet: RowSet): {\n dataHasBeenPrefetched: boolean\n} {\n const entitiesToPrefetch = useGetEntitiesInTable(rowSet)\n const { isLoading: isLoadingEntityData } =\n usePrefetchEntityData(entitiesToPrefetch)\n const { isLoading: isLoadingEntityRestrictionData } =\n usePrefetchEntityRestrictionData(entitiesToPrefetch)\n const { isLoading: isLoadingFileHandleData } =\n usePrefetchFileHandleData(rowSet)\n const { isLoading: isLoadingUserGroupData } =\n usePrefetchUserGroupHeaderData(rowSet)\n\n return {\n dataHasBeenPrefetched:\n !isLoadingEntityData &&\n !isLoadingEntityRestrictionData &&\n !isLoadingFileHandleData &&\n !isLoadingUserGroupData,\n }\n}\n\n/**\n * Uses react-query to prefetch an entire page of row data.\n *\n * @returns A function that will prefetch the data for a given page number.\n */\nexport function usePrefetchTableRows(): (pageNumber: number) => Promise<void> {\n const { keyFactory, accessToken } = useSynapseContext()\n const { currentQueryRequest } = useQueryContext()\n const queryClient = useQueryClient()\n\n // locked column does not matter for row data\n const lockedColumn = undefined\n return useCallback(\n (pageNumber: number) => {\n // Get the query for the next page\n const queryWithUpdatedPage = transformQueryToGoToPage(\n { type: 'goToPage', pageNumber },\n cloneDeep(currentQueryRequest) as QueryBundleRequest,\n )\n\n // Transform the query into UseQueryOptions\n const { rowDataQueryOptions } = getTableQueryUseQueryOptions(\n queryWithUpdatedPage,\n lockedColumn,\n keyFactory,\n accessToken,\n )\n\n // Finally, prefetch the data\n return queryClient.prefetchQuery(rowDataQueryOptions)\n },\n [accessToken, currentQueryRequest, keyFactory, lockedColumn, queryClient],\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"usePrefetchTableData.js","names":[],"sources":["../../../src/components/SynapseTable/usePrefetchTableData.ts"],"sourcesContent":["import {\n useGetEntity,\n useGetEntityHeaders,\n useGetFileBatch,\n useGetRestrictionInformationBatch,\n useGetUserGroupHeaders,\n} from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { getFieldIndex, getTypeIndices } from '@/utils/functions/queryUtils'\nimport { goToPage as transformQueryToGoToPage } from '@/utils/hooks/useImmutableTableQuery/TableQueryReducerActions'\nimport {\n ColumnTypeEnum,\n FileHandleAssociateType,\n FileHandleAssociation,\n QueryBundleRequest,\n ReferenceList,\n RestrictableObjectType,\n RowSet,\n Table,\n} from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { cloneDeep } from 'lodash-es'\nimport { useCallback, useMemo } from 'react'\nimport { useQueryContext } from '../QueryContext'\nimport { getTableQueryUseQueryOptions } from '../QueryWrapper/TableQueryUseQueryOptions'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport {\n isEntityViewOrDatasetOrCollection,\n isFileViewOrDataset,\n} from './SynapseTableUtils'\n\nfunction usePrefetchFileHandleData(rowSet: RowSet) {\n const { entityId, versionNumber } = useQueryContext()\n\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const fileHandleIdColumnIndices = getTypeIndices(\n ColumnTypeEnum.FILEHANDLEID,\n queryMetadata?.selectColumns,\n )\n\n let fileHandlesToPrefetch: FileHandleAssociation[] = []\n\n // Now add all IDs from the entity ID columns\n if (entity && rowSet && queryMetadata && queryMetadata.selectColumns) {\n fileHandlesToPrefetch = rowSet.rows.reduce(\n (prev: FileHandleAssociation[], curr) => {\n fileHandleIdColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value) {\n const selectColumn = queryMetadata?.selectColumns![index]\n if (\n isFileViewOrDataset(entity) &&\n selectColumn.name === 'dataFileHandleId'\n ) {\n // The association is the entity\n prev.push({\n fileHandleId: value,\n associateObjectId: String(curr.rowId),\n associateObjectType: FileHandleAssociateType.FileEntity,\n })\n } else {\n // The association is the table entity\n prev.push({\n fileHandleId: value,\n associateObjectId: entity.id!,\n associateObjectType: FileHandleAssociateType.TableEntity,\n })\n }\n }\n })\n return prev\n },\n\n fileHandlesToPrefetch,\n )\n }\n\n return useGetFileBatch(\n {\n requestedFiles: fileHandlesToPrefetch,\n includeFileHandles: true,\n includePreSignedURLs: false,\n includePreviewPreSignedURLs: false,\n },\n {\n enabled: fileHandlesToPrefetch.length > 0,\n },\n )\n}\n\nfunction useGetEntitiesInTable(rowSet: RowSet) {\n const { entityId, versionNumber } = useQueryContext()\n const { data: entity } = useGetEntity<Table>(entityId, versionNumber)\n const { data: queryMetadata } = useGetQueryMetadata()\n\n let entitiesInTable: ReferenceList = []\n\n // If this is a file view/dataset, collect all the row IDs; they correspond to entities that we'll end up fetching\n if (entity && isEntityViewOrDatasetOrCollection(entity)) {\n entitiesInTable = rowSet.rows.reduce((prev: ReferenceList, curr) => {\n const { rowId, versionNumber } = curr\n if (rowId) {\n prev.push({\n targetId: `syn${rowId}`,\n targetVersionNumber: versionNumber,\n })\n }\n return prev\n }, entitiesInTable)\n }\n\n let entityIdColumnIndices = getTypeIndices(\n ColumnTypeEnum.ENTITYID,\n queryMetadata?.selectColumns,\n )\n\n if (entity && isEntityViewOrDatasetOrCollection(entity)) {\n // If this is a view/dataset, we don't need to fetch the entities in the entity ID column\n // Collecting the row IDs in the last step was sufficient\n const idColumnIndex = getFieldIndex('id', queryMetadata)\n entityIdColumnIndices = entityIdColumnIndices.filter(\n index => index !== idColumnIndex,\n )\n }\n\n const entityIdListColumnIndices = getTypeIndices(\n ColumnTypeEnum.ENTITYID_LIST,\n queryMetadata?.selectColumns,\n )\n\n entitiesInTable = rowSet.rows.reduce((prev: ReferenceList, curr) => {\n // Get all IDs from the entity ID columns\n entityIdColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (\n value &&\n !prev.find(e => e.targetId === value && e.targetVersionNumber == null)\n ) {\n prev.push({ targetId: value })\n }\n })\n // Get all IDs from the entity ID list columns\n entityIdListColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value) {\n const ids = JSON.parse(value) as string[]\n ids.forEach(id => {\n if (\n id &&\n !prev.find(e => e.targetId === id && e.targetVersionNumber == null)\n ) {\n prev.push({ targetId: id })\n }\n })\n }\n })\n\n return prev\n }, entitiesInTable)\n\n return entitiesInTable\n}\n\nfunction usePrefetchEntityData(entitiesToPrefetch: ReferenceList) {\n return useGetEntityHeaders(entitiesToPrefetch, {\n enabled: entitiesToPrefetch.length > 0,\n })\n}\n\nfunction usePrefetchUserGroupHeaderData(rowSet: RowSet) {\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const userIdColumnIndices = getTypeIndices(\n ColumnTypeEnum.USERID,\n queryMetadata?.selectColumns,\n )\n\n const userIdListColumnIndices = getTypeIndices(\n ColumnTypeEnum.USERID_LIST,\n queryMetadata?.selectColumns,\n )\n\n const principalIdsToPrefetch: string[] = rowSet.rows.reduce(\n (prev: string[], curr) => {\n // Add all IDs from the USERID columns\n userIdColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value && !prev.includes(value)) {\n prev.push(value)\n }\n })\n // Add all IDs from the USERID_LIST columns\n userIdListColumnIndices.forEach(index => {\n const value = curr.values[index]\n if (value) {\n const userIds = JSON.parse(value) as number[]\n userIds.forEach(userId => {\n if (!prev.includes(String(userId))) {\n prev.push(String(userId))\n }\n })\n }\n })\n return prev\n },\n [],\n )\n\n return useGetUserGroupHeaders(principalIdsToPrefetch, {\n enabled: principalIdsToPrefetch.length > 0,\n })\n}\n\nfunction usePrefetchEntityRestrictionData(entitiesToPrefetch: ReferenceList) {\n // This information only varies by entity ID, not version number. The restriction information is the same for all versions.\n const uniqueEntityIds = useMemo(() => {\n const entityIds = entitiesToPrefetch.map(e => e.targetId)\n // Dedupe the list in case there were duplicates, e.g. there were multiple versions of the same entity\n return Array.from(new Set(entityIds))\n }, [entitiesToPrefetch])\n\n return useGetRestrictionInformationBatch(\n {\n objectIds: uniqueEntityIds,\n restrictableObjectType: RestrictableObjectType.ENTITY,\n },\n {\n enabled: entitiesToPrefetch.length > 0,\n },\n )\n}\n\n/**\n * Uses react-query to prefetch data rendered by SynapseTable. Each SynapseTableCell instance load data to render rich\n * content (e.g. entity data) for the cell based on its column type. This hook uses react-query hooks that will\n * fetch and de-normalize batch requests, so when the SynapseTableCell component renders, the data is already loaded\n * in the cache. In practice, this avoids Synapse backend throttling and 'waterfall' content rendering.\n */\nexport function usePrefetchResourcesInTable(rowSet: RowSet): {\n dataHasBeenPrefetched: boolean\n} {\n const entitiesToPrefetch = useGetEntitiesInTable(rowSet)\n const { isLoading: isLoadingEntityData } =\n usePrefetchEntityData(entitiesToPrefetch)\n const { isLoading: isLoadingEntityRestrictionData } =\n usePrefetchEntityRestrictionData(entitiesToPrefetch)\n const { isLoading: isLoadingFileHandleData } =\n usePrefetchFileHandleData(rowSet)\n const { isLoading: isLoadingUserGroupData } =\n usePrefetchUserGroupHeaderData(rowSet)\n\n return {\n dataHasBeenPrefetched:\n !isLoadingEntityData &&\n !isLoadingEntityRestrictionData &&\n !isLoadingFileHandleData &&\n !isLoadingUserGroupData,\n }\n}\n\n/**\n * Uses react-query to prefetch an entire page of row data.\n *\n * @returns A function that will prefetch the data for a given page number.\n */\nexport function usePrefetchTableRows(): (pageNumber: number) => Promise<void> {\n const { keyFactory, accessToken } = useSynapseContext()\n const { currentQueryRequest } = useQueryContext()\n const queryClient = useQueryClient()\n\n // locked column does not matter for row data\n const lockedColumn = undefined\n return useCallback(\n (pageNumber: number) => {\n // Get the query for the next page\n const queryWithUpdatedPage = transformQueryToGoToPage(\n { type: 'goToPage', pageNumber },\n cloneDeep(currentQueryRequest) as QueryBundleRequest,\n )\n\n // Transform the query into UseQueryOptions\n const { rowDataQueryOptions } = getTableQueryUseQueryOptions(\n queryWithUpdatedPage,\n lockedColumn,\n keyFactory,\n accessToken,\n )\n\n // Finally, prefetch the data\n return queryClient.prefetchQuery(rowDataQueryOptions)\n },\n [accessToken, currentQueryRequest, keyFactory, lockedColumn, queryClient],\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA+BA,SAAS,EAA0B,GAAgB;CACjD,IAAM,EAAE,aAAU,qBAAkB,GAAiB,EAE/C,EAAE,MAAM,MAAW,EAAoB,GAAU,EAAc,EAC/D,EAAE,MAAM,MAAkB,GAAqB,EAE/C,IAA4B,EAChC,EAAe,cACf,GAAe,cAChB,EAEG,IAAiD,EAAE;AAqCvD,QAlCI,KAAU,KAAU,KAAiB,EAAc,kBACrD,IAAwB,EAAO,KAAK,QACjC,GAA+B,OAC9B,EAA0B,SAAQ,MAAS;EACzC,IAAM,IAAQ,EAAK,OAAO;AAC1B,MAAI,GAAO;GACT,IAAM,IAAe,GAAe,cAAe;AACnD,GACE,EAAoB,EAAO,IAC3B,EAAa,SAAS,qBAGtB,EAAK,KAAK;IACR,cAAc;IACd,mBAAmB,OAAO,EAAK,MAAM;IACrC,qBAAqB,EAAwB;IAC9C,CAAC,GAGF,EAAK,KAAK;IACR,cAAc;IACd,mBAAmB,EAAO;IAC1B,qBAAqB,EAAwB;IAC9C,CAAC;;GAGN,EACK,IAGT,EACD,GAGI,EACL;EACE,gBAAgB;EAChB,oBAAoB;EACpB,sBAAsB;EACtB,6BAA6B;EAC9B,EACD,EACE,SAAS,EAAsB,SAAS,GACzC,CACF;;AAGH,SAAS,EAAsB,GAAgB;CAC7C,IAAM,EAAE,aAAU,qBAAkB,GAAiB,EAC/C,EAAE,MAAM,MAAW,EAAoB,GAAU,EAAc,EAC/D,EAAE,MAAM,MAAkB,GAAqB,EAEjD,IAAiC,EAAE;AAGvC,CAAI,KAAU,EAAkC,EAAO,KACrD,IAAkB,EAAO,KAAK,QAAQ,GAAqB,MAAS;EAClE,IAAM,EAAE,UAAO,qBAAkB;AAOjC,SANI,KACF,EAAK,KAAK;GACR,UAAU,MAAM;GAChB,qBAAqB;GACtB,CAAC,EAEG;IACN,EAAgB;CAGrB,IAAI,IAAwB,EAC1B,EAAe,UACf,GAAe,cAChB;AAED,KAAI,KAAU,EAAkC,EAAO,EAAE;EAGvD,IAAM,IAAgB,EAAc,MAAM,EAAc;AACxD,MAAwB,EAAsB,QAC5C,MAAS,MAAU,EACpB;;CAGH,IAAM,IAA4B,EAChC,EAAe,eACf,GAAe,cAChB;AAgCD,QA9BA,IAAkB,EAAO,KAAK,QAAQ,GAAqB,OAEzD,EAAsB,SAAQ,MAAS;EACrC,IAAM,IAAQ,EAAK,OAAO;AAC1B,EACE,KACA,CAAC,EAAK,MAAK,MAAK,EAAE,aAAa,KAAS,EAAE,uBAAuB,KAAK,IAEtE,EAAK,KAAK,EAAE,UAAU,GAAO,CAAC;GAEhC,EAEF,EAA0B,SAAQ,MAAS;EACzC,IAAM,IAAQ,EAAK,OAAO;AAC1B,EAAI,KACU,KAAK,MAAM,EACvB,CAAI,SAAQ,MAAM;AAChB,GACE,KACA,CAAC,EAAK,MAAK,MAAK,EAAE,aAAa,KAAM,EAAE,uBAAuB,KAAK,IAEnE,EAAK,KAAK,EAAE,UAAU,GAAI,CAAC;IAE7B;GAEJ,EAEK,IACN,EAAgB,EAEZ;;AAGT,SAAS,EAAsB,GAAmC;AAChE,QAAO,EAAoB,GAAoB,EAC7C,SAAS,EAAmB,SAAS,GACtC,CAAC;;AAGJ,SAAS,EAA+B,GAAgB;CACtD,IAAM,EAAE,MAAM,MAAkB,GAAqB,EAE/C,IAAsB,EAC1B,EAAe,QACf,GAAe,cAChB,EAEK,IAA0B,EAC9B,EAAe,aACf,GAAe,cAChB,EAEK,IAAmC,EAAO,KAAK,QAClD,GAAgB,OAEf,EAAoB,SAAQ,MAAS;EACnC,IAAM,IAAQ,EAAK,OAAO;AAC1B,EAAI,KAAS,CAAC,EAAK,SAAS,EAAM,IAChC,EAAK,KAAK,EAAM;GAElB,EAEF,EAAwB,SAAQ,MAAS;EACvC,IAAM,IAAQ,EAAK,OAAO;AAC1B,EAAI,KACc,KAAK,MAAM,EAC3B,CAAQ,SAAQ,MAAU;AACxB,GAAK,EAAK,SAAS,OAAO,EAAO,CAAC,IAChC,EAAK,KAAK,OAAO,EAAO,CAAC;IAE3B;GAEJ,EACK,IAET,EAAE,CACH;AAED,QAAO,EAAuB,GAAwB,EACpD,SAAS,EAAuB,SAAS,GAC1C,CAAC;;AAGJ,SAAS,EAAiC,GAAmC;AAQ3E,QAAO,EACL;EACE,WARoB,QAAc;GACpC,IAAM,IAAY,EAAmB,KAAI,MAAK,EAAE,SAAS;AAEzD,UAAO,MAAM,KAAK,IAAI,IAAI,EAAU,CAAC;KACpC,CAAC,EAAmB,CAIR;EACX,wBAAwB,EAAuB;EAChD,EACD,EACE,SAAS,EAAmB,SAAS,GACtC,CACF;;AASH,SAAgB,EAA4B,GAE1C;CACA,IAAM,IAAqB,EAAsB,EAAO,EAClD,EAAE,WAAW,MACjB,EAAsB,EAAmB,EACrC,EAAE,WAAW,MACjB,EAAiC,EAAmB,EAChD,EAAE,WAAW,MACjB,EAA0B,EAAO,EAC7B,EAAE,WAAW,MACjB,EAA+B,EAAO;AAExC,QAAO,EACL,uBACE,CAAC,KACD,CAAC,KACD,CAAC,KACD,CAAC,GACJ;;AAQH,SAAgB,IAA8D;CAC5E,IAAM,EAAE,eAAY,mBAAgB,GAAmB,EACjD,EAAE,2BAAwB,GAAiB,EAC3C,IAAc,GAAgB;AAIpC,QAAO,GACJ,MAAuB;EAQtB,IAAM,EAAE,2BAAwB,EANH,EAC3B;GAAE,MAAM;GAAY;GAAY,EAChC,EAAU,EAAoB,CAK9B,EACA,QACA,GACA,EACD;AAGD,SAAO,EAAY,cAAc,EAAoB;IAEvD;EAAC;EAAa;EAAqB;EAAY;EAAc;EAAY,CAC1E"}