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":"SubmissionPage.js","names":[],"sources":["../../../../src/components/dataaccess/SubmissionPage/SubmissionPage.tsx"],"sourcesContent":["import AccessRequirementList from '@/components/AccessRequirementList/AccessRequirementList'\nimport { CancelDataAccessRequestConfirmationModal } from '@/components/dataaccess/SubmissionPage/CancelDataAccessRequestConfirmationModal'\nimport { ApproveSubmissionConfirmationModal } from '@/components/dataaccess/SubmissionPage/ApproveSubmissionConfirmationModal'\nimport { displayToast } from '@/components/ToastMessage'\nimport {\n useGetAccessRequirementACL,\n useGetAccessRequirements,\n useGetAccessRequirementWikiPageKey,\n} from '@/synapse-queries/dataaccess/useAccessRequirements'\nimport useGetDataAccessSubmission from '@/synapse-queries/dataaccess/useDataAccessSubmission'\nimport { useGetCurrentUserProfile } from '@/synapse-queries/user'\nimport { useGetUserAccessApproval } from '@/synapse-queries/dataaccess/useAccessApprovals'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { ACT_TEAM_ID } from '@/utils/SynapseConstants'\nimport { Button, Grid, Skeleton, Stack, Typography } from '@mui/material'\nimport {\n ACCESS_TYPE,\n FileHandleAssociateType,\n ManagedACTAccessRequirement,\n Submission,\n SubmissionState,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport duration from 'dayjs/plugin/duration'\nimport { isEmpty, toLower, upperFirst } from 'lodash-es'\nimport { Fragment, ReactNode, useMemo, useState } from 'react'\nimport { useNavigate } from 'react-router'\nimport { SynapseErrorBoundary } from '../../error/ErrorBanner'\nimport MarkdownSynapse from '../../Markdown/MarkdownSynapse'\nimport { UserBadge } from '../../UserCard/UserBadge'\nimport UserOrTeamBadge from '../../UserOrTeamBadge/UserOrTeamBadge'\nimport { FileHandleLink } from '../../widgets/FileHandleLink'\nimport RejectDataAccessRequestModal from '../RejectDataAccessRequestModal'\n\ndayjs.extend(duration)\n\nexport type SubmissionPageProps = {\n /** The ID of the submission to view */\n submissionId: string | number\n /** If true, display reviewer controls on the page */\n isReviewer: boolean // There is currently no API to check if a user has review permissions on a specific submission ID\n}\n\nfunction DataAccessSubmissionFileHandleLink(props: {\n submissionId: string\n fileHandleId: string\n}) {\n const { submissionId, fileHandleId } = props\n const fileHandleAssociation = useMemo(\n () => ({\n fileHandleId: fileHandleId,\n associateObjectId: submissionId,\n associateObjectType:\n FileHandleAssociateType.DataAccessSubmissionAttachment,\n }),\n [fileHandleId, submissionId],\n )\n return (\n <FileHandleLink\n key={fileHandleId}\n showDownloadIcon={true}\n fileHandleAssociation={fileHandleAssociation}\n />\n )\n}\n\ntype AccessRequirementWikiType = {\n accessRequirementId: string\n}\n\nfunction AccessRequirementWiki(props: AccessRequirementWikiType) {\n const { data: wikiPageKey } = useGetAccessRequirementWikiPageKey(\n props.accessRequirementId,\n {\n throwOnError: true,\n },\n )\n\n return wikiPageKey ? (\n <div className=\"AccessRequirementWikiContainer\">\n <div className=\"AccessRequirementWikiContent\">\n <Typography variant=\"headline1\">Access Requirement</Typography>\n <hr />\n <MarkdownSynapse\n wikiId={wikiPageKey?.wikiPageId}\n ownerId={wikiPageKey?.ownerObjectId}\n objectType={wikiPageKey?.ownerObjectType}\n />\n </div>\n </div>\n ) : (\n <Skeleton width={'100%'} height={'600px'} />\n )\n}\n\n/**\n * returns true iff the userId is a requester and/or listed on the accessor changes on the submission.\n * @param userId\n * @param submission\n */\nfunction isRequesterOnSubmission(userId: string, submission: Submission) {\n return (\n submission.submittedBy === userId ||\n Boolean(submission.accessorChanges.find(acc => acc.userId === userId))\n )\n}\n\n/**\n * Page for a Data Access Submission. Supports the following user types:\n * - ACT member or other designated reviewer can view, and choose to approve or reject.\n * - Data Access Request submitter can view and modify their own submission.\n * - Data Access Request requester (who is not a submitter) can view their own submission.\n */\nexport default function SubmissionPage(props: SubmissionPageProps) {\n const { submissionId, isReviewer } = props\n const [showRejectionDialog, setShowRejectionDialog] = useState(false)\n\n const { data: currentUserProfile } = useGetCurrentUserProfile()\n\n const { data: submission, isLoading: isLoadingSubmission } =\n useGetDataAccessSubmission(submissionId, {\n throwOnError: true,\n })\n const isRequester = Boolean(\n submission &&\n currentUserProfile &&\n isRequesterOnSubmission(currentUserProfile.ownerId, submission),\n )\n\n const { data: accessApproval, isLoading: isLoadingAccessApproval } =\n useGetUserAccessApproval(String(submissionId), {\n enabled:\n isRequester &&\n submission &&\n submission.state === SubmissionState.APPROVED,\n })\n\n const isExpired = Boolean(\n accessApproval && dayjs(accessApproval.expiredOn).isBefore(dayjs()),\n )\n\n const isSubmitter =\n submission && submission.submittedBy === currentUserProfile?.ownerId\n\n const { data: accessRequirement } =\n useGetAccessRequirements<ManagedACTAccessRequirement>(\n parseInt(submission?.accessRequirementId!),\n { enabled: !!submission },\n )\n\n const { data: acl, isLoading: isLoadingACL } = useGetAccessRequirementACL(\n submission?.accessRequirementId!,\n { enabled: !!submission, throwOnError: true },\n )\n\n const [showUpdateRequestDialog, setShowUpdateRequestDialog] = useState(false)\n const [\n showCancelRequestConfirmationDialog,\n setShowCancelRequestConfirmationDialog,\n ] = useState(false)\n const [showApprovalConfirmation, setShowApprovalConfirmation] =\n useState(false)\n\n const navigate = useNavigate()\n\n const reviewerIds = acl?.resourceAccess\n .filter(ra => ra.accessType.includes(ACCESS_TYPE.REVIEW_SUBMISSIONS))\n .map(ra => ra.principalId)\n\n const displayedSubmissionState: ReactNode = useMemo(() => {\n if (submission && !isLoadingAccessApproval) {\n if (isExpired) {\n return 'Expired'\n }\n return submission.state\n }\n return <Skeleton width={100} />\n }, [isExpired, isLoadingAccessApproval, submission])\n\n return (\n <Grid container={true} spacing={4} className=\"SubmissionPage\">\n {showUpdateRequestDialog && accessRequirement && (\n <AccessRequirementList\n renderAsModal={true}\n accessRequirementFromProps={[accessRequirement]}\n onHide={() => setShowUpdateRequestDialog(false)}\n onSubmissionCreated={submissionId => {\n setShowUpdateRequestDialog(false)\n displayToast('Data access request submitted', 'success', {\n primaryButtonConfig: {\n text: 'View Request',\n onClick: () => {\n navigate('/submissions/' + submissionId)\n },\n },\n })\n }}\n />\n )}\n <ApproveSubmissionConfirmationModal\n open={showApprovalConfirmation}\n onClose={() => {\n setShowApprovalConfirmation(false)\n }}\n submissionId={String(submissionId)}\n />\n {showRejectionDialog && (\n <RejectDataAccessRequestModal\n // Previously, we used a 'key' prop to reset the modal form when it was opened,\n // but removing the key and re-rendering the JSX achieves the same functionality in a more straightforward way.\n submissionId={submissionId}\n open={showRejectionDialog}\n onClose={() => setShowRejectionDialog(false)}\n />\n )}\n <Grid\n className=\"SubmissionSummary\"\n size={{\n xs: 12,\n sm: 4,\n lg: 3,\n }}\n >\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Status\n </Typography>\n <Typography\n variant=\"headline3\"\n sx={{ textTransform: 'uppercase' }}\n gutterBottom\n >\n {displayedSubmissionState}\n </Typography>\n <br />\n {isLoadingSubmission && <Skeleton width={200} />}\n {submission &&\n isReviewer &&\n submission.state === SubmissionState.SUBMITTED && (\n <div className=\"ButtonContainer\">\n <Button\n onClick={() => {\n setShowApprovalConfirmation(true)\n }}\n color=\"success\"\n variant=\"contained\"\n >\n Approve\n </Button>\n <Button\n onClick={() => {\n setShowRejectionDialog(true)\n }}\n color=\"error\"\n variant=\"contained\"\n >\n Reject\n </Button>\n </div>\n )}\n\n {submission && isSubmitter && (\n <div className=\"ButtonContainer\">\n <CancelDataAccessRequestConfirmationModal\n open={showCancelRequestConfirmationDialog}\n submissionId={String(submissionId)}\n accessRequirementId={submission?.accessRequirementId || ''}\n onClose={() => setShowCancelRequestConfirmationDialog(false)}\n />\n {submission.state === SubmissionState.SUBMITTED && (\n <Button\n onClick={() => {\n setShowCancelRequestConfirmationDialog(true)\n }}\n color=\"primary\"\n variant=\"outlined\"\n >\n Cancel Request\n </Button>\n )}\n {submission.state !== SubmissionState.SUBMITTED && (\n <Button\n onClick={() => {\n setShowUpdateRequestDialog(true)\n }}\n color=\"primary\"\n variant=\"outlined\"\n >\n {submission.state === SubmissionState.APPROVED\n ? 'Update'\n : 'Modify'}{' '}\n Request\n </Button>\n )}\n </div>\n )}\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Access Requirement Name\n </Typography>\n\n <Typography variant=\"smallText1\" gutterBottom>\n {accessRequirement?.name ?? <Skeleton width={100} />}\n </Typography>\n <br />\n\n {isReviewer && (\n <>\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Assigned Reviewer\n </Typography>\n <Stack>\n {isLoadingACL && <Skeleton width={100} />}\n {!isLoadingACL &&\n !isEmpty(reviewerIds) &&\n reviewerIds!.map(id => {\n return <UserOrTeamBadge key={id} principalId={id} />\n })}\n {!isLoadingACL && isEmpty(reviewerIds) && (\n <UserOrTeamBadge principalId={ACT_TEAM_ID} />\n )}\n </Stack>\n <br />\n </>\n )}\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Conditions\n </Typography>\n {accessRequirement ? (\n <Typography variant=\"smallText1\" component={'div'} gutterBottom>\n <ul>\n <li>\n Expiration period:{' '}\n {dayjs\n .duration({\n milliseconds: accessRequirement.expirationPeriod,\n })\n .asDays()}{' '}\n day(s)\n {accessRequirement.expirationPeriod === 0 && ' (no expiration)'}\n </li>\n\n {accessRequirement.isCertifiedUserRequired && (\n <li>User must be Certified</li>\n )}\n {accessRequirement.isValidatedProfileRequired && (\n <li>User Profile must be Validated</li>\n )}\n {accessRequirement.isDUCRequired && <li>DUC is required</li>}\n {accessRequirement.isIDURequired && <li>IDU is required</li>}\n {accessRequirement.isIDUPublic && (\n <li>IDU will be made public</li>\n )}\n {accessRequirement.isIRBApprovalRequired && (\n <li>IRB Approval is required</li>\n )}\n {accessRequirement.areOtherAttachmentsRequired && (\n <li>Other attachments are required</li>\n )}\n </ul>\n </Typography>\n ) : (\n <Skeleton width={100} />\n )}\n <br />\n <div className=\"SubmissionSummaryGrid\">\n <Typography variant=\"dataFieldKey\">Submitted By</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n <UserBadge userId={submission.submittedBy} />\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n <Typography variant=\"dataFieldKey\">Submitted On</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n formatDate(dayjs(submission.submittedOn))\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n {isReviewer && (\n <>\n <Typography variant=\"dataFieldKey\">Modified By</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n <UserBadge userId={submission.modifiedBy} />\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n </>\n )}\n <Typography variant=\"dataFieldKey\">Modified On</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n formatDate(dayjs(submission.modifiedOn))\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n <Typography className=\"Key\" variant=\"dataFieldKey\">\n Data Requesters\n {`${submission ? ` (${submission.accessorChanges.length})` : ''}`}\n </Typography>\n {submission ? (\n submission.accessorChanges.map(accessorChange => (\n <Fragment key={accessorChange.userId}>\n <Typography className=\"Key DataAccessor\" variant=\"smallText1\">\n <span style={{ whiteSpace: 'nowrap' }}>\n <UserBadge\n key={accessorChange.userId}\n userId={accessorChange.userId}\n />\n </span>\n </Typography>\n <Typography className=\"Value DataAccessor\" variant=\"smallText1\">\n {upperFirst(\n toLower(\n accessorChange.type.substring(\n 0,\n accessorChange.type.indexOf('_'),\n ),\n ),\n )}\n </Typography>\n </Fragment>\n ))\n ) : (\n <Skeleton width={100} />\n )}\n <Typography className=\"Key\" variant=\"dataFieldKey\">\n Institution\n </Typography>\n <Typography className=\"Value\" variant=\"smallText1\">\n {submission ? (\n submission.researchProjectSnapshot.institution\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n <Typography className=\"Key\" variant=\"dataFieldKey\">\n Project Lead\n </Typography>\n <Typography className=\"Value\" variant=\"smallText1\">\n {submission ? (\n submission.researchProjectSnapshot.projectLead\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n </div>\n </Grid>\n <Grid\n size={{\n xs: 12,\n sm: 8,\n lg: 9,\n }}\n >\n <Stack sx={{ gap: 2 }}>\n <SynapseErrorBoundary>\n {submission ? (\n <AccessRequirementWiki\n accessRequirementId={submission.accessRequirementId}\n />\n ) : (\n <></>\n )}\n </SynapseErrorBoundary>\n {submission?.rejectedReason && (\n <section>\n <Typography variant=\"headline1\" gutterBottom>\n Reason for rejection given by reviewer\n </Typography>\n <hr />\n <Typography\n variant=\"body1\"\n style={{ whiteSpace: 'pre-line' }}\n gutterBottom\n >\n {submission.rejectedReason}\n </Typography>\n </section>\n )}\n <section>\n <Typography variant=\"headline1\">\n Contents of the Access Request\n <hr />\n </Typography>\n <Stack\n sx={{\n gap: 2,\n }}\n >\n {submission?.researchProjectSnapshot\n ?.intendedDataUseStatement && (\n <section>\n <Typography variant=\"headline2\" gutterBottom>\n Intended Data Use Statement\n </Typography>\n <Typography\n variant=\"body1\"\n style={{ whiteSpace: 'pre-line' }}\n gutterBottom\n >\n {\n submission.researchProjectSnapshot\n .intendedDataUseStatement\n }\n </Typography>\n </section>\n )}\n <Typography variant=\"headline2\" gutterBottom>\n Documents\n </Typography>\n {submission?.ducFileHandleId && (\n <section>\n <Typography variant=\"smallText2\">\n Data Use Certificate (DUC)\n </Typography>\n <DataAccessSubmissionFileHandleLink\n submissionId={submission.id}\n fileHandleId={submission.ducFileHandleId}\n />\n </section>\n )}\n {submission?.irbFileHandleId && (\n <section>\n <Typography variant=\"smallText2\" gutterBottom>\n IRB Approval Letter\n </Typography>\n <DataAccessSubmissionFileHandleLink\n submissionId={submission.id}\n fileHandleId={submission.irbFileHandleId}\n />\n </section>\n )}\n {submission?.attachments && (\n <section>\n <Typography variant=\"smallText2\" gutterBottom>\n Other Attachments\n </Typography>\n {submission.attachments.map(fileHandleId => (\n <Fragment key={fileHandleId}>\n <DataAccessSubmissionFileHandleLink\n submissionId={submission.id}\n fileHandleId={fileHandleId}\n />\n <br />\n </Fragment>\n ))}\n </section>\n )}\n </Stack>\n </section>\n </Stack>\n </Grid>\n </Grid>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SubmissionPage.js","names":[],"sources":["../../../../src/components/dataaccess/SubmissionPage/SubmissionPage.tsx"],"sourcesContent":["import AccessRequirementList from '@/components/AccessRequirementList/AccessRequirementList'\nimport { CancelDataAccessRequestConfirmationModal } from '@/components/dataaccess/SubmissionPage/CancelDataAccessRequestConfirmationModal'\nimport { ApproveSubmissionConfirmationModal } from '@/components/dataaccess/SubmissionPage/ApproveSubmissionConfirmationModal'\nimport { displayToast } from '@/components/ToastMessage'\nimport {\n useGetAccessRequirementACL,\n useGetAccessRequirements,\n useGetAccessRequirementWikiPageKey,\n} from '@/synapse-queries/dataaccess/useAccessRequirements'\nimport useGetDataAccessSubmission from '@/synapse-queries/dataaccess/useDataAccessSubmission'\nimport { useGetThreadForSubmission } from '@/synapse-queries/forum/useThread'\nimport { useGetCurrentUserProfile } from '@/synapse-queries/user'\nimport { useGetUserAccessApproval } from '@/synapse-queries/dataaccess/useAccessApprovals'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { ACT_TEAM_ID } from '@/utils/SynapseConstants'\nimport { Button, Grid, Skeleton, Stack, Typography } from '@mui/material'\nimport {\n ACCESS_TYPE,\n FileHandleAssociateType,\n ManagedACTAccessRequirement,\n Submission,\n SubmissionState,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport duration from 'dayjs/plugin/duration'\nimport { isEmpty, toLower, upperFirst } from 'lodash-es'\nimport { Fragment, ReactNode, useMemo, useState } from 'react'\nimport { useNavigate } from 'react-router'\nimport { SynapseErrorBoundary } from '../../error/ErrorBanner'\nimport MarkdownSynapse from '../../Markdown/MarkdownSynapse'\nimport { UserBadge } from '../../UserCard/UserBadge'\nimport UserOrTeamBadge from '../../UserOrTeamBadge/UserOrTeamBadge'\nimport { FileHandleLink } from '../../widgets/FileHandleLink'\nimport RejectDataAccessRequestModal from '../RejectDataAccessRequestModal'\nimport { DiscussionThread } from '@/components/Forum'\n\ndayjs.extend(duration)\n\nexport type SubmissionPageProps = {\n /** The ID of the submission to view */\n submissionId: string | number\n /** If true, display reviewer controls on the page */\n isReviewer: boolean // There is currently no API to check if a user has review permissions on a specific submission ID\n}\n\nconst THREAD_BODY =\n 'Use this thread to communicate with the reviewers about this access request.'\n\nfunction DataAccessSubmissionFileHandleLink(props: {\n submissionId: string\n fileHandleId: string\n}) {\n const { submissionId, fileHandleId } = props\n const fileHandleAssociation = useMemo(\n () => ({\n fileHandleId: fileHandleId,\n associateObjectId: submissionId,\n associateObjectType:\n FileHandleAssociateType.DataAccessSubmissionAttachment,\n }),\n [fileHandleId, submissionId],\n )\n return (\n <FileHandleLink\n key={fileHandleId}\n showDownloadIcon={true}\n fileHandleAssociation={fileHandleAssociation}\n />\n )\n}\n\ntype AccessRequirementWikiType = {\n accessRequirementId: string\n}\n\nfunction AccessRequirementWiki(props: AccessRequirementWikiType) {\n const { data: wikiPageKey } = useGetAccessRequirementWikiPageKey(\n props.accessRequirementId,\n {\n throwOnError: true,\n },\n )\n\n return wikiPageKey ? (\n <div className=\"AccessRequirementWikiContainer\">\n <div className=\"AccessRequirementWikiContent\">\n <Typography variant=\"headline1\">Access Requirement</Typography>\n <hr />\n <MarkdownSynapse\n wikiId={wikiPageKey?.wikiPageId}\n ownerId={wikiPageKey?.ownerObjectId}\n objectType={wikiPageKey?.ownerObjectType}\n />\n </div>\n </div>\n ) : (\n <Skeleton width={'100%'} height={'600px'} />\n )\n}\n\n/**\n * returns true iff the userId is a requester and/or listed on the accessor changes on the submission.\n * @param userId\n * @param submission\n */\nfunction isRequesterOnSubmission(userId: string, submission: Submission) {\n return (\n submission.submittedBy === userId ||\n Boolean(submission.accessorChanges.find(acc => acc.userId === userId))\n )\n}\n\n/**\n * Page for a Data Access Submission. Supports the following user types:\n * - ACT member or other designated reviewer can view, and choose to approve or reject.\n * - Data Access Request submitter can view and modify their own submission.\n * - Data Access Request requester (who is not a submitter) can view their own submission.\n */\nexport default function SubmissionPage(props: SubmissionPageProps) {\n const { submissionId, isReviewer } = props\n const [showRejectionDialog, setShowRejectionDialog] = useState(false)\n\n const { data: currentUserProfile } = useGetCurrentUserProfile()\n\n const { data: submission, isLoading: isLoadingSubmission } =\n useGetDataAccessSubmission(submissionId, {\n throwOnError: true,\n })\n const isRequester = Boolean(\n submission &&\n currentUserProfile &&\n isRequesterOnSubmission(currentUserProfile.ownerId, submission),\n )\n\n const { data: accessApproval, isLoading: isLoadingAccessApproval } =\n useGetUserAccessApproval(String(submissionId), {\n enabled:\n isRequester &&\n submission &&\n submission.state === SubmissionState.APPROVED,\n })\n\n const isExpired = Boolean(\n accessApproval && dayjs(accessApproval.expiredOn).isBefore(dayjs()),\n )\n\n const isSubmitter =\n submission && submission.submittedBy === currentUserProfile?.ownerId\n\n const { data: accessRequirement } =\n useGetAccessRequirements<ManagedACTAccessRequirement>(\n parseInt(submission?.accessRequirementId!),\n { enabled: !!submission },\n )\n\n const { data: acl, isLoading: isLoadingACL } = useGetAccessRequirementACL(\n submission?.accessRequirementId!,\n { enabled: !!submission, throwOnError: true },\n )\n\n const { data: thread } = useGetThreadForSubmission(submissionId)\n\n const [showUpdateRequestDialog, setShowUpdateRequestDialog] = useState(false)\n const [\n showCancelRequestConfirmationDialog,\n setShowCancelRequestConfirmationDialog,\n ] = useState(false)\n const [showApprovalConfirmation, setShowApprovalConfirmation] =\n useState(false)\n\n const navigate = useNavigate()\n\n const reviewerIds = acl?.resourceAccess\n .filter(ra => ra.accessType.includes(ACCESS_TYPE.REVIEW_SUBMISSIONS))\n .map(ra => ra.principalId)\n\n const displayedSubmissionState: ReactNode = useMemo(() => {\n if (submission && !isLoadingAccessApproval) {\n if (isExpired) {\n return 'Expired'\n }\n return submission.state\n }\n return <Skeleton width={100} />\n }, [isExpired, isLoadingAccessApproval, submission])\n\n return (\n <Grid container={true} spacing={4} className=\"SubmissionPage\">\n {showUpdateRequestDialog && accessRequirement && (\n <AccessRequirementList\n renderAsModal={true}\n accessRequirementFromProps={[accessRequirement]}\n onHide={() => setShowUpdateRequestDialog(false)}\n onSubmissionCreated={submissionId => {\n setShowUpdateRequestDialog(false)\n displayToast('Data access request submitted', 'success', {\n primaryButtonConfig: {\n text: 'View Request',\n onClick: () => {\n navigate('/submissions/' + submissionId)\n },\n },\n })\n }}\n />\n )}\n <ApproveSubmissionConfirmationModal\n open={showApprovalConfirmation}\n onClose={() => {\n setShowApprovalConfirmation(false)\n }}\n submissionId={String(submissionId)}\n />\n {showRejectionDialog && (\n <RejectDataAccessRequestModal\n // Previously, we used a 'key' prop to reset the modal form when it was opened,\n // but removing the key and re-rendering the JSX achieves the same functionality in a more straightforward way.\n submissionId={submissionId}\n open={showRejectionDialog}\n onClose={() => setShowRejectionDialog(false)}\n />\n )}\n <Grid\n className=\"SubmissionSummary\"\n size={{\n xs: 12,\n sm: 4,\n lg: 3,\n }}\n >\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Status\n </Typography>\n <Typography\n variant=\"headline3\"\n sx={{ textTransform: 'uppercase' }}\n gutterBottom\n >\n {displayedSubmissionState}\n </Typography>\n <br />\n {isLoadingSubmission && <Skeleton width={200} />}\n {submission &&\n isReviewer &&\n submission.state === SubmissionState.SUBMITTED && (\n <div className=\"ButtonContainer\">\n <Button\n onClick={() => {\n setShowApprovalConfirmation(true)\n }}\n color=\"success\"\n variant=\"contained\"\n >\n Approve\n </Button>\n <Button\n onClick={() => {\n setShowRejectionDialog(true)\n }}\n color=\"error\"\n variant=\"contained\"\n >\n Reject\n </Button>\n </div>\n )}\n\n {submission && isSubmitter && (\n <div className=\"ButtonContainer\">\n <CancelDataAccessRequestConfirmationModal\n open={showCancelRequestConfirmationDialog}\n submissionId={String(submissionId)}\n accessRequirementId={submission?.accessRequirementId || ''}\n onClose={() => setShowCancelRequestConfirmationDialog(false)}\n />\n {submission.state === SubmissionState.SUBMITTED && (\n <Button\n onClick={() => {\n setShowCancelRequestConfirmationDialog(true)\n }}\n color=\"primary\"\n variant=\"outlined\"\n >\n Cancel Request\n </Button>\n )}\n {submission.state !== SubmissionState.SUBMITTED && (\n <Button\n onClick={() => {\n setShowUpdateRequestDialog(true)\n }}\n color=\"primary\"\n variant=\"outlined\"\n >\n {submission.state === SubmissionState.APPROVED\n ? 'Update'\n : 'Modify'}{' '}\n Request\n </Button>\n )}\n </div>\n )}\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Access Requirement Name\n </Typography>\n\n <Typography variant=\"smallText1\" gutterBottom>\n {accessRequirement?.name ?? <Skeleton width={100} />}\n </Typography>\n <br />\n\n {isReviewer && (\n <>\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Assigned Reviewer\n </Typography>\n <Stack>\n {isLoadingACL && <Skeleton width={100} />}\n {!isLoadingACL &&\n !isEmpty(reviewerIds) &&\n reviewerIds!.map(id => {\n return <UserOrTeamBadge key={id} principalId={id} />\n })}\n {!isLoadingACL && isEmpty(reviewerIds) && (\n <UserOrTeamBadge principalId={ACT_TEAM_ID} />\n )}\n </Stack>\n <br />\n </>\n )}\n <Typography variant=\"dataFieldKey\" gutterBottom>\n Conditions\n </Typography>\n {accessRequirement ? (\n <Typography variant=\"smallText1\" component={'div'} gutterBottom>\n <ul>\n <li>\n Expiration period:{' '}\n {dayjs\n .duration({\n milliseconds: accessRequirement.expirationPeriod,\n })\n .asDays()}{' '}\n day(s)\n {accessRequirement.expirationPeriod === 0 && ' (no expiration)'}\n </li>\n\n {accessRequirement.isCertifiedUserRequired && (\n <li>User must be Certified</li>\n )}\n {accessRequirement.isValidatedProfileRequired && (\n <li>User Profile must be Validated</li>\n )}\n {accessRequirement.isDUCRequired && <li>DUC is required</li>}\n {accessRequirement.isIDURequired && <li>IDU is required</li>}\n {accessRequirement.isIDUPublic && (\n <li>IDU will be made public</li>\n )}\n {accessRequirement.isIRBApprovalRequired && (\n <li>IRB Approval is required</li>\n )}\n {accessRequirement.areOtherAttachmentsRequired && (\n <li>Other attachments are required</li>\n )}\n </ul>\n </Typography>\n ) : (\n <Skeleton width={100} />\n )}\n <br />\n <div className=\"SubmissionSummaryGrid\">\n <Typography variant=\"dataFieldKey\">Submitted By</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n <UserBadge userId={submission.submittedBy} />\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n <Typography variant=\"dataFieldKey\">Submitted On</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n formatDate(dayjs(submission.submittedOn))\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n {isReviewer && (\n <>\n <Typography variant=\"dataFieldKey\">Modified By</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n <UserBadge userId={submission.modifiedBy} />\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n </>\n )}\n <Typography variant=\"dataFieldKey\">Modified On</Typography>\n <Typography variant=\"smallText1\">\n {submission ? (\n formatDate(dayjs(submission.modifiedOn))\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n <Typography className=\"Key\" variant=\"dataFieldKey\">\n Data Requesters\n {`${submission ? ` (${submission.accessorChanges.length})` : ''}`}\n </Typography>\n {submission ? (\n submission.accessorChanges.map(accessorChange => (\n <Fragment key={accessorChange.userId}>\n <Typography className=\"Key DataAccessor\" variant=\"smallText1\">\n <span style={{ whiteSpace: 'nowrap' }}>\n <UserBadge\n key={accessorChange.userId}\n userId={accessorChange.userId}\n />\n </span>\n </Typography>\n <Typography className=\"Value DataAccessor\" variant=\"smallText1\">\n {upperFirst(\n toLower(\n accessorChange.type.substring(\n 0,\n accessorChange.type.indexOf('_'),\n ),\n ),\n )}\n </Typography>\n </Fragment>\n ))\n ) : (\n <Skeleton width={100} />\n )}\n <Typography className=\"Key\" variant=\"dataFieldKey\">\n Institution\n </Typography>\n <Typography className=\"Value\" variant=\"smallText1\">\n {submission ? (\n submission.researchProjectSnapshot.institution\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n <Typography className=\"Key\" variant=\"dataFieldKey\">\n Project Lead\n </Typography>\n <Typography className=\"Value\" variant=\"smallText1\">\n {submission ? (\n submission.researchProjectSnapshot.projectLead\n ) : (\n <Skeleton width={100} />\n )}\n </Typography>\n </div>\n </Grid>\n <Grid\n size={{\n xs: 12,\n sm: 8,\n lg: 9,\n }}\n >\n <Stack sx={{ gap: 2 }}>\n <SynapseErrorBoundary>\n {submission ? (\n <AccessRequirementWiki\n accessRequirementId={submission.accessRequirementId}\n />\n ) : (\n <></>\n )}\n </SynapseErrorBoundary>\n {submission?.rejectedReason && (\n <section>\n <Typography variant=\"headline1\" gutterBottom>\n Reason for rejection given by reviewer\n </Typography>\n <hr />\n <Typography\n variant=\"body1\"\n style={{ whiteSpace: 'pre-line' }}\n gutterBottom\n >\n {submission.rejectedReason}\n </Typography>\n </section>\n )}\n <section>\n <Typography variant=\"headline1\">\n Contents of the Access Request\n <hr />\n </Typography>\n <Stack\n sx={{\n gap: 2,\n }}\n >\n {submission?.researchProjectSnapshot\n ?.intendedDataUseStatement && (\n <section>\n <Typography variant=\"headline2\" gutterBottom>\n Intended Data Use Statement\n </Typography>\n <Typography\n variant=\"body1\"\n style={{ whiteSpace: 'pre-line' }}\n gutterBottom\n >\n {\n submission.researchProjectSnapshot\n .intendedDataUseStatement\n }\n </Typography>\n </section>\n )}\n <Typography variant=\"headline2\" gutterBottom>\n Documents\n </Typography>\n {submission?.ducFileHandleId && (\n <section>\n <Typography variant=\"smallText2\">\n Data Use Certificate (DUC)\n </Typography>\n <DataAccessSubmissionFileHandleLink\n submissionId={submission.id}\n fileHandleId={submission.ducFileHandleId}\n />\n </section>\n )}\n {submission?.irbFileHandleId && (\n <section>\n <Typography variant=\"smallText2\" gutterBottom>\n IRB Approval Letter\n </Typography>\n <DataAccessSubmissionFileHandleLink\n submissionId={submission.id}\n fileHandleId={submission.irbFileHandleId}\n />\n </section>\n )}\n {submission?.attachments && (\n <section>\n <Typography variant=\"smallText2\" gutterBottom>\n Other Attachments\n </Typography>\n {submission.attachments.map(fileHandleId => (\n <Fragment key={fileHandleId}>\n <DataAccessSubmissionFileHandleLink\n submissionId={submission.id}\n fileHandleId={fileHandleId}\n />\n <br />\n </Fragment>\n ))}\n </section>\n )}\n </Stack>\n </section>\n {thread?.id && (\n <DiscussionThread\n threadId={thread.id}\n limit={25}\n emptyBodyContent={THREAD_BODY}\n />\n )}\n </Stack>\n </Grid>\n </Grid>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"UseAccessRequirementTable.js","names":[],"sources":["../../../src/components/dataaccess/UseAccessRequirementTable.tsx"],"sourcesContent":["import { useSearchAccessRequirementsInfinite } from '@/synapse-queries'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { PRODUCTION_ENDPOINT_CONFIG } from '@/utils/functions/getEndpoint'\nimport { ACT_TEAM_ID } from '@/utils/SynapseConstants'\nimport { Link, Typography } from '@mui/material'\nimport {\n ACCESS_REQUIREMENT_CONCRETE_TYPE,\n ACCESS_TYPE,\n AccessRequirementSearchRequest,\n AccessRequirementSearchResult,\n AccessRequirementSearchSort,\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SortDirection,\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n} from '@sage-bionetworks/synapse-types'\nimport {\n ColumnFiltersState,\n ColumnSort,\n createColumnHelper,\n getCoreRowModel,\n getFacetedUniqueValues as defaultGetFacetedUniqueValues,\n SortingState,\n Table,\n Updater,\n useReactTable,\n} from '@tanstack/react-table'\nimport dayjs from 'dayjs'\nimport { noop } from 'lodash-es'\nimport { Fragment, useCallback, useMemo, useState } from 'react'\nimport { EntityLink } from '../EntityLink'\nimport ColumnHeader from '../TanStackTable/ColumnHeader'\nimport UserOrTeamBadge from '../UserOrTeamBadge/UserOrTeamBadge'\n\nexport function accessRequirementConcreteTypeValueToDisplayValue(\n accessRequirementConcreteTypeValue: ACCESS_REQUIREMENT_CONCRETE_TYPE,\n) {\n switch (accessRequirementConcreteTypeValue) {\n case TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n case SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE: {\n return SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n }\n case MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n case ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n case LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n default:\n return 'Unknown'\n }\n}\n\nconst ALL_ACCESS_REQUIREMENT_CONCRETE_TYPES = [\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n]\n\nconst isIntegerInput = (v: string): boolean => {\n return /^\\d+$/.test(v)\n}\nconst columnHelper = createColumnHelper<AccessRequirementSearchResult>()\nconst columns = [\n columnHelper.accessor('id', {\n header: props => <ColumnHeader {...props} title={'AR ID'} />,\n cell: ({ getValue }) => (\n <Link\n href={`${\n PRODUCTION_ENDPOINT_CONFIG.PORTAL\n }AccessRequirement:AR_ID=${getValue()}`}\n >\n {getValue()}\n </Link>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('name', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n cell: ({ getValue }) => getValue(),\n enableSorting: true,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('type', {\n header: props => <ColumnHeader {...props} title={'Type'} />,\n cell: ({ getValue }) =>\n accessRequirementConcreteTypeValueToDisplayValue(getValue()),\n enableSorting: false,\n enableColumnFilter: true,\n meta: {\n filterVariant: 'enumeration',\n getDisplayText: accessRequirementConcreteTypeValueToDisplayValue,\n enableMultipleSelect: false,\n },\n }),\n columnHelper.accessor('relatedProjectIds', {\n header: props => <ColumnHeader {...props} title={'Related to Projects'} />,\n cell: ({ getValue }) => (\n <>\n {getValue().map(projectId => (\n <Fragment key={projectId}>\n <EntityLink entity={projectId} />{' '}\n <Typography\n component={'span'}\n variant={'smallText1'}\n sx={{\n color: 'grey.700',\n }}\n >\n ({projectId})\n </Typography>\n <br />\n </Fragment>\n ))}\n </>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('reviewerIds', {\n header: props => <ColumnHeader {...props} title={'Reviewer'} />,\n cell: ({ getValue }) => (\n <>\n {getValue().length === 0 ? (\n <UserOrTeamBadge principalId={ACT_TEAM_ID} />\n ) : (\n getValue().map(reviewerId => (\n <UserOrTeamBadge key={reviewerId} principalId={reviewerId} />\n ))\n )}\n </>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('modifiedOn', {\n header: props => <ColumnHeader {...props} title={'Last Modified'} />,\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('createdOn', {\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n enableSorting: true,\n enableColumnFilter: false,\n }),\n]\nconst DEFAULT_SORTING_STATE: SortingState = [\n {\n desc: true,\n id: 'createdOn',\n },\n]\ntype UseAccessRequirementTableOptions = {\n nameOrID?: string\n relatedProjectId?: string\n reviewerId?: string\n accessType?: ACCESS_TYPE\n typeFilter?: string\n onTypeFilterChange?: (typeFilter: string | undefined) => void\n}\n\nfunction columnSortToAccessRequirementSearchSort(\n columnSort: ColumnSort,\n): AccessRequirementSearchSort {\n const direction: SortDirection = columnSort.desc ? 'DESC' : 'ASC'\n\n if (columnSort.id == 'createdOn') {\n return {\n field: 'CREATED_ON',\n direction,\n }\n } else if (columnSort.id == 'name') {\n return {\n field: 'NAME',\n direction,\n }\n } else {\n throw new Error(\n `Could not map sort field ${columnSort.id} to AccessRequirementSortField`,\n )\n }\n}\n\nfunction getTypeFilterFromColumnFilters(\n columnFilters?: ColumnFiltersState,\n): string | undefined {\n const matchingFilter = (columnFilters || []).find(f => f.id === 'type')\n const filterValues = matchingFilter?.value\n if (filterValues) {\n return (filterValues as string[])[0]\n }\n return undefined\n}\n\nexport function useAccessRequirementTable(\n opts: UseAccessRequirementTableOptions,\n) {\n const {\n nameOrID,\n relatedProjectId,\n reviewerId,\n accessType,\n typeFilter,\n onTypeFilterChange = noop,\n } = opts\n const [sortingState, setSortingState] = useState<SortingState>(\n DEFAULT_SORTING_STATE,\n )\n\n const columnFilters = useMemo(\n () => (typeFilter ? [{ id: 'type', value: [typeFilter] }] : []),\n [typeFilter],\n )\n\n const onColumnFiltersChange = useCallback(\n (updaterOrValue: Updater<ColumnFiltersState>) => {\n const newValue: ColumnFiltersState =\n typeof updaterOrValue === 'function'\n ? updaterOrValue(columnFilters)\n : updaterOrValue\n\n // Unlike the other controls, the type filter control is inside the table. State is still stored in the parent component.\n // When the user updates the filter, this function will fire, so we must propagate changes to the type filter to the parent.\n const typeFilter = getTypeFilterFromColumnFilters(newValue)\n onTypeFilterChange(typeFilter)\n },\n [columnFilters, onTypeFilterChange],\n )\n\n // Map the @tanstack/react-table sort state object to the Synapse API object\n const apiRequestSortState: AccessRequirementSearchRequest['sort'] = useMemo(\n () => sortingState.map(columnSortToAccessRequirementSearchSort),\n [sortingState],\n )\n\n const searchRequest: Omit<AccessRequirementSearchRequest, 'nextPageToken'> =\n useMemo(() => {\n // SWC-6615: If the input string is a single integer, assume it's the AR ID. Otherwise, use as the nameContains field.\n let nameContains: string | undefined = undefined\n let ids: number[] | undefined = undefined\n if (nameOrID !== undefined) {\n const nameOrIDTrimmed = nameOrID.trim()\n if (isIntegerInput(nameOrIDTrimmed)) {\n ids = [Number.parseInt(nameOrIDTrimmed)]\n } else {\n nameContains = nameOrIDTrimmed\n }\n }\n return {\n ids,\n nameContains,\n relatedProjectId,\n reviewerId,\n accessType,\n sort: apiRequestSortState,\n type: typeFilter,\n }\n }, [\n nameOrID,\n relatedProjectId,\n reviewerId,\n accessType,\n apiRequestSortState,\n typeFilter,\n ])\n\n const { data, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } =\n useSearchAccessRequirementsInfinite(searchRequest)\n\n const accessRequirements = useMemo(\n () => data?.pages.flatMap(page => page.results) ?? [],\n [data],\n )\n\n const table: Table<AccessRequirementSearchResult> =\n useReactTable<AccessRequirementSearchResult>({\n data: accessRequirements,\n columns: columns,\n state: {\n sorting: sortingState,\n columnFilters: columnFilters,\n },\n getFacetedUniqueValues: (\n table: Table<AccessRequirementSearchResult>,\n columnId: string,\n ) => {\n if (columnId === 'type') {\n // Hard-code the set of possible access requirement types with count = 0 to indicate that we don't have facet counts.\n return () =>\n new Map(ALL_ACCESS_REQUIREMENT_CONCRETE_TYPES.map(v => [v, 0]))\n }\n return defaultGetFacetedUniqueValues<AccessRequirementSearchResult>()(\n table,\n columnId,\n )\n },\n onSortingChange: setSortingState,\n onColumnFiltersChange: onColumnFiltersChange,\n getRowId: row => row.id,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n manualSorting: true,\n enableMultiSort: false,\n // Sort is required for this API call, so prevent the user from removing the sort.\n enableSortingRemoval: false,\n manualFiltering: true,\n })\n\n return { table, isLoading, hasNextPage, fetchNextPage, isFetchingNextPage }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"UseAccessRequirementTable.js","names":[],"sources":["../../../src/components/dataaccess/UseAccessRequirementTable.tsx"],"sourcesContent":["import { useSearchAccessRequirementsInfinite } from '@/synapse-queries'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { PRODUCTION_ENDPOINT_CONFIG } from '@/utils/functions/getEndpoint'\nimport { ACT_TEAM_ID } from '@/utils/SynapseConstants'\nimport { Link, Typography } from '@mui/material'\nimport {\n ACCESS_REQUIREMENT_CONCRETE_TYPE,\n ACCESS_TYPE,\n AccessRequirementSearchRequest,\n AccessRequirementSearchResult,\n AccessRequirementSearchSort,\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SortDirection,\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE,\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n} from '@sage-bionetworks/synapse-types'\nimport {\n ColumnFiltersState,\n ColumnSort,\n createColumnHelper,\n getCoreRowModel,\n getFacetedUniqueValues as defaultGetFacetedUniqueValues,\n SortingState,\n Table,\n Updater,\n useReactTable,\n} from '@tanstack/react-table'\nimport dayjs from 'dayjs'\nimport { noop } from 'lodash-es'\nimport { Fragment, useCallback, useMemo, useState } from 'react'\nimport { EntityLink } from '../EntityLink'\nimport ColumnHeader from '../TanStackTable/ColumnHeader'\nimport UserOrTeamBadge from '../UserOrTeamBadge/UserOrTeamBadge'\n\nexport function accessRequirementConcreteTypeValueToDisplayValue(\n accessRequirementConcreteTypeValue: ACCESS_REQUIREMENT_CONCRETE_TYPE,\n) {\n switch (accessRequirementConcreteTypeValue) {\n case TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n case SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE: {\n return SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n }\n case MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n case ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n case LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n return LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_DISPLAY_VALUE\n default:\n return 'Unknown'\n }\n}\n\nconst ALL_ACCESS_REQUIREMENT_CONCRETE_TYPES = [\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n]\n\nconst isIntegerInput = (v: string): boolean => {\n return /^\\d+$/.test(v)\n}\nconst columnHelper = createColumnHelper<AccessRequirementSearchResult>()\nconst columns = [\n columnHelper.accessor('id', {\n header: props => <ColumnHeader {...props} title={'AR ID'} />,\n cell: ({ getValue }) => (\n <Link\n href={`${\n PRODUCTION_ENDPOINT_CONFIG.PORTAL\n }AccessRequirement:AR_ID=${getValue()}`}\n >\n {getValue()}\n </Link>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('name', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n cell: ({ getValue }) => getValue(),\n enableSorting: true,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('type', {\n header: props => <ColumnHeader {...props} title={'Type'} />,\n cell: ({ getValue }) =>\n accessRequirementConcreteTypeValueToDisplayValue(getValue()),\n enableSorting: false,\n enableColumnFilter: true,\n meta: {\n filterVariant: 'enumeration',\n getDisplayText: accessRequirementConcreteTypeValueToDisplayValue,\n enableMultipleSelect: false,\n },\n }),\n columnHelper.accessor('relatedProjectIds', {\n header: props => <ColumnHeader {...props} title={'Related to Projects'} />,\n cell: ({ getValue }) => (\n <>\n {getValue().map(projectId => (\n <Fragment key={projectId}>\n <EntityLink entity={projectId} />{' '}\n <Typography\n component={'span'}\n variant={'smallText1'}\n sx={{\n color: 'grey.700',\n }}\n >\n ({projectId})\n </Typography>\n <br />\n </Fragment>\n ))}\n </>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('reviewerIds', {\n header: props => <ColumnHeader {...props} title={'Reviewer'} />,\n cell: ({ getValue }) => (\n <>\n {getValue().length === 0 ? (\n <UserOrTeamBadge principalId={ACT_TEAM_ID} />\n ) : (\n getValue().map(reviewerId => (\n <UserOrTeamBadge key={reviewerId} principalId={reviewerId} />\n ))\n )}\n </>\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('modifiedOn', {\n header: props => <ColumnHeader {...props} title={'Last Modified'} />,\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('createdOn', {\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n enableSorting: true,\n enableColumnFilter: false,\n }),\n]\nconst DEFAULT_SORTING_STATE: SortingState = [\n {\n desc: true,\n id: 'createdOn',\n },\n]\ntype UseAccessRequirementTableOptions = {\n nameOrID?: string\n relatedProjectId?: string\n reviewerId?: string\n accessType?: ACCESS_TYPE\n typeFilter?: string\n onTypeFilterChange?: (typeFilter: string | undefined) => void\n}\n\nfunction columnSortToAccessRequirementSearchSort(\n columnSort: ColumnSort,\n): AccessRequirementSearchSort {\n const direction: SortDirection = columnSort.desc ? 'DESC' : 'ASC'\n\n if (columnSort.id == 'createdOn') {\n return {\n field: 'CREATED_ON',\n direction,\n }\n } else if (columnSort.id == 'name') {\n return {\n field: 'NAME',\n direction,\n }\n } else {\n throw new Error(\n `Could not map sort field ${columnSort.id} to AccessRequirementSortField`,\n )\n }\n}\n\nfunction getTypeFilterFromColumnFilters(\n columnFilters?: ColumnFiltersState,\n): string | undefined {\n const matchingFilter = (columnFilters || []).find(f => f.id === 'type')\n const filterValues = matchingFilter?.value\n if (filterValues) {\n return (filterValues as string[])[0]\n }\n return undefined\n}\n\nexport function useAccessRequirementTable(\n opts: UseAccessRequirementTableOptions,\n) {\n const {\n nameOrID,\n relatedProjectId,\n reviewerId,\n accessType,\n typeFilter,\n onTypeFilterChange = noop,\n } = opts\n const [sortingState, setSortingState] = useState<SortingState>(\n DEFAULT_SORTING_STATE,\n )\n\n const columnFilters = useMemo(\n () => (typeFilter ? [{ id: 'type', value: [typeFilter] }] : []),\n [typeFilter],\n )\n\n const onColumnFiltersChange = useCallback(\n (updaterOrValue: Updater<ColumnFiltersState>) => {\n const newValue: ColumnFiltersState =\n typeof updaterOrValue === 'function'\n ? updaterOrValue(columnFilters)\n : updaterOrValue\n\n // Unlike the other controls, the type filter control is inside the table. State is still stored in the parent component.\n // When the user updates the filter, this function will fire, so we must propagate changes to the type filter to the parent.\n const typeFilter = getTypeFilterFromColumnFilters(newValue)\n onTypeFilterChange(typeFilter)\n },\n [columnFilters, onTypeFilterChange],\n )\n\n // Map the @tanstack/react-table sort state object to the Synapse API object\n const apiRequestSortState: AccessRequirementSearchRequest['sort'] = useMemo(\n () => sortingState.map(columnSortToAccessRequirementSearchSort),\n [sortingState],\n )\n\n const searchRequest: Omit<AccessRequirementSearchRequest, 'nextPageToken'> =\n useMemo(() => {\n // SWC-6615: If the input string is a single integer, assume it's the AR ID. Otherwise, use as the nameContains field.\n let nameContains: string | undefined = undefined\n let ids: number[] | undefined = undefined\n if (nameOrID !== undefined) {\n const nameOrIDTrimmed = nameOrID.trim()\n if (isIntegerInput(nameOrIDTrimmed)) {\n ids = [Number.parseInt(nameOrIDTrimmed)]\n } else {\n nameContains = nameOrIDTrimmed\n }\n }\n return {\n ids,\n nameContains,\n relatedProjectId,\n reviewerId,\n accessType,\n sort: apiRequestSortState,\n type: typeFilter,\n }\n }, [\n nameOrID,\n relatedProjectId,\n reviewerId,\n accessType,\n apiRequestSortState,\n typeFilter,\n ])\n\n const { data, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } =\n useSearchAccessRequirementsInfinite(searchRequest)\n\n const accessRequirements = useMemo(\n () => data?.pages.flatMap(page => page.results) ?? [],\n [data],\n )\n\n const table: Table<AccessRequirementSearchResult> =\n useReactTable<AccessRequirementSearchResult>({\n data: accessRequirements,\n columns: columns,\n state: {\n sorting: sortingState,\n columnFilters: columnFilters,\n },\n getFacetedUniqueValues: (\n table: Table<AccessRequirementSearchResult>,\n columnId: string,\n ) => {\n if (columnId === 'type') {\n // Hard-code the set of possible access requirement types with count = 0 to indicate that we don't have facet counts.\n return () =>\n new Map(ALL_ACCESS_REQUIREMENT_CONCRETE_TYPES.map(v => [v, 0]))\n }\n return defaultGetFacetedUniqueValues<AccessRequirementSearchResult>()(\n table,\n columnId,\n )\n },\n onSortingChange: setSortingState,\n onColumnFiltersChange: onColumnFiltersChange,\n getRowId: row => row.id,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n manualSorting: true,\n enableMultiSort: false,\n // Sort is required for this API call, so prevent the user from removing the sort.\n enableSortingRemoval: false,\n manualFiltering: true,\n })\n\n return { table, isLoading, hasNextPage, fetchNextPage, isFetchingNextPage }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserAccessRequestHistoryTable.js","names":[],"sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.tsx"],"sourcesContent":["import { getSortApiRequestFromTableSortState } from '@/components/dataaccess/UserAccessRequestHistory/SubmissionSortStateTranslator'\nimport InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport { SkeletonTable } from '@/components/Skeleton'\nimport UserOrTeamBadge from '@/components/UserOrTeamBadge/UserOrTeamBadge'\nimport { useSearchAccessSubmissionUserRequestsInfinite } from '@/synapse-queries/dataaccess/useDataAccessSubmission'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { Typography } from '@mui/material'\nimport { UserSubmissionSearchResult } from '@sage-bionetworks/synapse-client'\nimport {\n createColumnHelper,\n getCoreRowModel,\n SortingState,\n useReactTable,\n} from '@tanstack/react-table'\nimport dayjs from 'dayjs'\nimport { upperFirst } from 'lodash-es'\nimport { useMemo, useState } from 'react'\nimport { Link } from 'react-router'\nimport ColumnHeader from '../../TanStackTable/ColumnHeader'\nimport StyledTanStackTable from '../../TanStackTable/StyledTanStackTable'\nimport { USER_ACCESS_HISTORY_SUBMISSION_SUBPATH } from './RouteConstants'\n\nconst columnHelper = createColumnHelper<UserSubmissionSearchResult>()\nconst columns = [\n columnHelper.accessor('accessRequirementName', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('state', {\n header: props => <ColumnHeader {...props} title={'Status'} />,\n enableSorting: false,\n cell: ctx => {\n if (\n ctx.row.original.userAccessApproval &&\n ctx.row.original.userAccessApproval.expiredOn &&\n dayjs(ctx.row.original.userAccessApproval.expiredOn).isBefore(dayjs())\n ) {\n return 'Expired'\n }\n return upperFirst(ctx.getValue()!.toLocaleLowerCase())\n },\n enableColumnFilter: false,\n size: 75,\n }),\n columnHelper.accessor('createdOn', {\n header: props => <ColumnHeader {...props} title={'Date Submitted'} />,\n enableSorting: true,\n cell: ctx => formatDate(dayjs(ctx.getValue())),\n sortDescFirst: true,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: 'expires',\n header: props => <ColumnHeader {...props} title={'Expires'} />,\n enableSorting: false,\n cell: ctx => {\n if (\n ctx.row.original.userAccessApproval &&\n ctx.row.original.userAccessApproval.expiredOn\n ) {\n return formatDate(dayjs(ctx.row.original.userAccessApproval.expiredOn))\n }\n return null\n },\n size: 75,\n enableColumnFilter: false,\n }),\n\n columnHelper.accessor('submitterId', {\n header: props => <ColumnHeader {...props} title={'Submitter'} />,\n enableSorting: false,\n cell: ctx => <UserOrTeamBadge principalId={ctx.getValue()} />,\n enableColumnFilter: false,\n }),\n\n columnHelper.accessor('id', {\n header: props => <ColumnHeader {...props} title={''} />,\n enableSorting: false,\n cell: ctx => (\n <>\n <Link\n to={`/${USER_ACCESS_HISTORY_SUBMISSION_SUBPATH}/${ctx.getValue()}`}\n >\n View Request\n </Link>\n </>\n ),\n size: 95,\n enableColumnFilter: false,\n }),\n]\n\nexport function UserAccessRequestHistoryTable() {\n const [tableSortState, setTableSortState] = useState<SortingState>([\n {\n desc: true,\n id: 'createdOn',\n },\n ])\n\n const {\n data: infiniteData,\n isLoading,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useSearchAccessSubmissionUserRequestsInfinite({\n sort: getSortApiRequestFromTableSortState(tableSortState),\n })\n\n const data = useMemo(\n () => infiniteData?.pages.flatMap(page => page.results || []) || [],\n [infiniteData],\n )\n\n const table = useReactTable({\n data: data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: true,\n columnResizeMode: 'onChange',\n state: {\n sorting: tableSortState,\n },\n onSortingChange: setTableSortState,\n })\n\n const isEmpty = !isLoading && table.getRowModel().rows.length === 0\n\n return (\n <InfiniteTableLayout\n table={<StyledTanStackTable table={table} fullWidth={true} />}\n isLoading={isLoading}\n loader={<SkeletonTable numCols={columns.length} fullWidthCells />}\n isEmpty={isEmpty}\n noResults={\n <Typography variant={'body1'} sx={{ textAlign: 'center', my: 2 }}>\n You have no access requests\n </Typography>\n }\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,IAAM,IAAe,GAAgD,EAC/D,IAAU;CACd,EAAa,SAAS,yBAAyB;EAC7C,SAAQ,MACN,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAA6B,CAAA;EAE/D,eAAe;EACf,oBAAoB;EACrB,CAAC;CACF,EAAa,SAAS,SAAS;EAC7B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAY,CAAA;EAC7D,eAAe;EACf,OAAM,MAEF,EAAI,IAAI,SAAS,sBACjB,EAAI,IAAI,SAAS,mBAAmB,aACpC,EAAM,EAAI,IAAI,SAAS,mBAAmB,UAAU,CAAC,SAAS,GAAO,CAAC,GAE/D,YAEF,EAAW,EAAI,UAAU,CAAE,mBAAmB,CAAC;EAExD,oBAAoB;EACpB,MAAM;EACP,CAAC;CACF,EAAa,SAAS,aAAa;EACjC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAoB,CAAA;EACrE,eAAe;EACf,OAAM,MAAO,EAAW,EAAM,EAAI,UAAU,CAAC,CAAC;EAC9C,eAAe;EACf,oBAAoB;EACrB,CAAC;CACF,EAAa,QAAQ;EACnB,IAAI;EACJ,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAa,CAAA;EAC9D,eAAe;EACf,OAAM,MAEF,EAAI,IAAI,SAAS,sBACjB,EAAI,IAAI,SAAS,mBAAmB,YAE7B,EAAW,EAAM,EAAI,IAAI,SAAS,mBAAmB,UAAU,CAAC,GAElE;EAET,MAAM;EACN,oBAAoB;EACrB,CAAC;CAEF,EAAa,SAAS,eAAe;EACnC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAe,CAAA;EAChE,eAAe;EACf,OAAM,MAAO,kBAAC,GAAD,EAAiB,aAAa,EAAI,UAAU,EAAI,CAAA;EAC7D,oBAAoB;EACrB,CAAC;CAEF,EAAa,SAAS,MAAM;EAC1B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAM,CAAA;EACvD,eAAe;EACf,OAAM,MACJ,kBAAA,GAAA,EAAA,UACE,kBAAC,GAAD;GACE,IAAI,IAAI,EAAuC,GAAG,EAAI,UAAU;aACjE;GAEM,CAAA,EACN,CAAA;EAEL,MAAM;EACN,oBAAoB;EACrB,CAAC;CACH;AAED,SAAgB,IAAgC;CAC9C,IAAM,CAAC,GAAgB,KAAqB,EAAuB,CACjE;EACE,MAAM;EACN,IAAI;EACL,CACF,CAAC,EAEI,EACJ,MAAM,GACN,cACA,gBACA,uBACA,qBACE,EAA8C,EAChD,MAAM,EAAoC,EAAe,EAC1D,CAAC,EAOI,IAAQ,EAAc;EACpB,MANK,QACL,GAAc,MAAM,SAAQ,MAAQ,EAAK,WAAW,EAAE,CAAC,IAAI,EAAE,EACnE,CAAC,EAAa,CACf;EAIC;EACA,iBAAiB,GAAiB;EAClC,eAAe;EACf,kBAAkB;EAClB,OAAO,EACL,SAAS,GACV;EACD,iBAAiB;EAClB,CAAC,EAEI,IAAU,CAAC,KAAa,EAAM,aAAa,CAAC,KAAK,WAAW;AAElE,QACE,kBAAC,GAAD;EACE,OAAO,kBAAC,GAAD;GAA4B;GAAO,WAAW;GAAQ,CAAA;EAClD;EACX,QAAQ,kBAAC,GAAD;GAAe,SAAS,EAAQ;GAAQ,gBAAA;GAAiB,CAAA;EACxD;EACT,WACE,kBAAC,GAAD;GAAY,SAAS;GAAS,IAAI;IAAE,WAAW;IAAU,IAAI;IAAG;aAAE;GAErD,CAAA;EAEF;EACb,8BAA8B;AACvB,MAAe;;EAEF;EACpB,CAAA"}
1
+ {"version":3,"file":"UserAccessRequestHistoryTable.js","names":[],"sources":["../../../../src/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.tsx"],"sourcesContent":["import { getSortApiRequestFromTableSortState } from '@/components/dataaccess/UserAccessRequestHistory/SubmissionSortStateTranslator'\nimport InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport { SkeletonTable } from '@/components/Skeleton'\nimport UserOrTeamBadge from '@/components/UserOrTeamBadge/UserOrTeamBadge'\nimport { useSearchAccessSubmissionUserRequestsInfinite } from '@/synapse-queries/dataaccess/useDataAccessSubmission'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { Typography } from '@mui/material'\nimport { UserSubmissionSearchResult } from '@sage-bionetworks/synapse-client'\nimport {\n createColumnHelper,\n getCoreRowModel,\n SortingState,\n useReactTable,\n} from '@tanstack/react-table'\nimport dayjs from 'dayjs'\nimport { upperFirst } from 'lodash-es'\nimport { useMemo, useState } from 'react'\nimport { Link } from 'react-router'\nimport ColumnHeader from '../../TanStackTable/ColumnHeader'\nimport StyledTanStackTable from '../../TanStackTable/StyledTanStackTable'\nimport { USER_ACCESS_HISTORY_SUBMISSION_SUBPATH } from './RouteConstants'\n\nconst columnHelper = createColumnHelper<UserSubmissionSearchResult>()\nconst columns = [\n columnHelper.accessor('accessRequirementName', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n enableSorting: false,\n enableColumnFilter: false,\n }),\n columnHelper.accessor('state', {\n header: props => <ColumnHeader {...props} title={'Status'} />,\n enableSorting: false,\n cell: ctx => {\n if (\n ctx.row.original.userAccessApproval &&\n ctx.row.original.userAccessApproval.expiredOn &&\n dayjs(ctx.row.original.userAccessApproval.expiredOn).isBefore(dayjs())\n ) {\n return 'Expired'\n }\n return upperFirst(ctx.getValue()!.toLocaleLowerCase())\n },\n enableColumnFilter: false,\n size: 75,\n }),\n columnHelper.accessor('createdOn', {\n header: props => <ColumnHeader {...props} title={'Date Submitted'} />,\n enableSorting: true,\n cell: ctx => formatDate(dayjs(ctx.getValue())),\n sortDescFirst: true,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: 'expires',\n header: props => <ColumnHeader {...props} title={'Expires'} />,\n enableSorting: false,\n cell: ctx => {\n if (\n ctx.row.original.userAccessApproval &&\n ctx.row.original.userAccessApproval.expiredOn\n ) {\n return formatDate(dayjs(ctx.row.original.userAccessApproval.expiredOn))\n }\n return null\n },\n size: 75,\n enableColumnFilter: false,\n }),\n\n columnHelper.accessor('submitterId', {\n header: props => <ColumnHeader {...props} title={'Submitter'} />,\n enableSorting: false,\n cell: ctx => <UserOrTeamBadge principalId={ctx.getValue()} />,\n enableColumnFilter: false,\n }),\n\n columnHelper.accessor('id', {\n header: props => <ColumnHeader {...props} title={''} />,\n enableSorting: false,\n cell: ctx => (\n <>\n <Link\n to={`/${USER_ACCESS_HISTORY_SUBMISSION_SUBPATH}/${ctx.getValue()}`}\n >\n View Request\n </Link>\n </>\n ),\n size: 95,\n enableColumnFilter: false,\n }),\n]\n\nexport function UserAccessRequestHistoryTable() {\n const [tableSortState, setTableSortState] = useState<SortingState>([\n {\n desc: true,\n id: 'createdOn',\n },\n ])\n\n const {\n data: infiniteData,\n isLoading,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useSearchAccessSubmissionUserRequestsInfinite({\n sort: getSortApiRequestFromTableSortState(tableSortState),\n })\n\n const data = useMemo(\n () => infiniteData?.pages.flatMap(page => page.results || []) || [],\n [infiniteData],\n )\n\n const table = useReactTable({\n data: data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: true,\n columnResizeMode: 'onChange',\n state: {\n sorting: tableSortState,\n },\n onSortingChange: setTableSortState,\n })\n\n const isEmpty = !isLoading && table.getRowModel().rows.length === 0\n\n return (\n <InfiniteTableLayout\n table={<StyledTanStackTable table={table} fullWidth={true} />}\n isLoading={isLoading}\n loader={<SkeletonTable numCols={columns.length} fullWidthCells />}\n isEmpty={isEmpty}\n noResults={\n <Typography variant={'body1'} sx={{ textAlign: 'center', my: 2 }}>\n You have no access requests\n </Typography>\n }\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,IAAM,IAAe,GAAgD,EAC/D,IAAU;CACd,EAAa,SAAS,yBAAyB;EAC7C,SAAQ,MACN,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAA6B,CAAA;EAE/D,eAAe;EACf,oBAAoB;EACrB,CAAC;CACF,EAAa,SAAS,SAAS;EAC7B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAY,CAAA;EAC7D,eAAe;EACf,OAAM,MAEF,EAAI,IAAI,SAAS,sBACjB,EAAI,IAAI,SAAS,mBAAmB,aACpC,EAAM,EAAI,IAAI,SAAS,mBAAmB,UAAU,CAAC,SAAS,GAAO,CAAC,GAE/D,YAEF,EAAW,EAAI,UAAU,CAAE,mBAAmB,CAAC;EAExD,oBAAoB;EACpB,MAAM;EACP,CAAC;CACF,EAAa,SAAS,aAAa;EACjC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAoB,CAAA;EACrE,eAAe;EACf,OAAM,MAAO,EAAW,EAAM,EAAI,UAAU,CAAC,CAAC;EAC9C,eAAe;EACf,oBAAoB;EACrB,CAAC;CACF,EAAa,QAAQ;EACnB,IAAI;EACJ,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAa,CAAA;EAC9D,eAAe;EACf,OAAM,MAEF,EAAI,IAAI,SAAS,sBACjB,EAAI,IAAI,SAAS,mBAAmB,YAE7B,EAAW,EAAM,EAAI,IAAI,SAAS,mBAAmB,UAAU,CAAC,GAElE;EAET,MAAM;EACN,oBAAoB;EACrB,CAAC;CAEF,EAAa,SAAS,eAAe;EACnC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAe,CAAA;EAChE,eAAe;EACf,OAAM,MAAO,kBAAC,GAAD,EAAiB,aAAa,EAAI,UAAU,EAAI,CAAA;EAC7D,oBAAoB;EACrB,CAAC;CAEF,EAAa,SAAS,MAAM;EAC1B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAM,CAAA;EACvD,eAAe;EACf,OAAM,MACJ,kBAAA,GAAA,EAAA,UACE,kBAAC,GAAD;GACE,IAAI,IAAI,EAAuC,GAAG,EAAI,UAAU;aACjE;GAEM,CAAA,EACN,CAAA;EAEL,MAAM;EACN,oBAAoB;EACrB,CAAC;CACH;AAED,SAAgB,IAAgC;CAC9C,IAAM,CAAC,GAAgB,KAAqB,EAAuB,CACjE;EACE,MAAM;EACN,IAAI;EACL,CACF,CAAC,EAEI,EACJ,MAAM,GACN,cACA,gBACA,uBACA,qBACE,EAA8C,EAChD,MAAM,EAAoC,EAAe,EAC1D,CAAC,EAOI,IAAQ,EAAc;EACpB,MANK,QACL,GAAc,MAAM,SAAQ,MAAQ,EAAK,WAAW,EAAE,CAAC,IAAI,EAAE,EACnE,CAAC,EAAa,CAIR;EACN;EACA,iBAAiB,GAAiB;EAClC,eAAe;EACf,kBAAkB;EAClB,OAAO,EACL,SAAS,GACV;EACD,iBAAiB;EAClB,CAAC,EAEI,IAAU,CAAC,KAAa,EAAM,aAAa,CAAC,KAAK,WAAW;AAElE,QACE,kBAAC,GAAD;EACE,OAAO,kBAAC,GAAD;GAA4B;GAAO,WAAW;GAAQ,CAAA;EAClD;EACX,QAAQ,kBAAC,GAAD;GAAe,SAAS,EAAQ;GAAQ,gBAAA;GAAiB,CAAA;EACxD;EACT,WACE,kBAAC,GAAD;GAAY,SAAS;GAAS,IAAI;IAAE,WAAW;IAAU,IAAI;IAAG;aAAE;GAErD,CAAA;EAEF;EACb,8BAA8B;AACvB,MAAe;;EAEF;EACpB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CreateOrUpdateDoiModal.d.ts","sourceRoot":"","sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"names":[],"mappings":"AAuCA,OAAO,EACL,aAAa,EAKd,MAAM,kCAAkC,CAAA;AAOzC,MAAM,MAAM,2BAA2B,GAAG;IACxC,iCAAiC;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,yBAAyB;IACzB,UAAU,EAAE,aAAa,CAAA;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAmDD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,2CA4WxE;AAED,eAAe,sBAAsB,CAAA"}
1
+ {"version":3,"file":"CreateOrUpdateDoiModal.d.ts","sourceRoot":"","sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"names":[],"mappings":"AAuCA,OAAO,EACL,aAAa,EAKd,MAAM,kCAAkC,CAAA;AAOzC,MAAM,MAAM,2BAA2B,GAAG;IACxC,iCAAiC;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,yBAAyB;IACzB,UAAU,EAAE,aAAa,CAAA;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAmDD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,2CA+WxE;AAED,eAAe,sBAAsB,CAAA"}
@@ -4,15 +4,15 @@ import { BackendDestinationEnum as te, getEndpoint as ne } from "../../utils/fun
4
4
  import { entityTypeToFriendlyName as re, isDataset as ie, isTable as ae, isVersionableEntity as oe } from "../../utils/functions/EntityTypeUtils.js";
5
5
  import { useGetRealmPrincipals as se } from "../../synapse-queries/realm/useRealmPrincipals.js";
6
6
  import { useGlobalIsEditingContext as ce } from "../../utils/context/GlobalIsEditingContext.js";
7
- import { SynapseSpinner as t } from "../LoadingScreen/LoadingScreen.js";
8
- import n from "../../synapse-queries/entity/useEntityBundle.js";
9
- import { useGetVersions as r } from "../../synapse-queries/entity/useEntity.js";
10
- import { useGetPortal as i } from "../../synapse-queries/portal/usePortal.js";
11
- import { useGetCurrentUserProfile as a } from "../../synapse-queries/user/useUserBundle.js";
12
- import { useCreateOrUpdateDOI as le, useGetDOI as ue } from "../../synapse-queries/doi/useDOI.js";
13
- import { MarkdownPopover as o } from "../Markdown/MarkdownPopover.js";
14
- import { DialogBase as de } from "../DialogBase.js";
15
- import { StyledFormControl as fe } from "../styled/StyledFormControl.js";
7
+ import { SynapseSpinner as le } from "../LoadingScreen/LoadingScreen.js";
8
+ import t from "../../synapse-queries/entity/useEntityBundle.js";
9
+ import { useGetVersions as n } from "../../synapse-queries/entity/useEntity.js";
10
+ import { useGetPortal as r } from "../../synapse-queries/portal/usePortal.js";
11
+ import { useGetCurrentUserProfile as i } from "../../synapse-queries/user/useUserBundle.js";
12
+ import { useCreateOrUpdateDOI as a, useGetDOI as ue } from "../../synapse-queries/doi/useDOI.js";
13
+ import { MarkdownPopover as de } from "../Markdown/MarkdownPopover.js";
14
+ import { DialogBase as fe } from "../DialogBase.js";
15
+ import { StyledFormControl as o } from "../styled/StyledFormControl.js";
16
16
  import pe from "../Dialog/ConfirmCloseWithoutSavingDialog.js";
17
17
  import { doiFormSchema as me, doiFormUiSchema as he } from "./DoiFormSchemas.js";
18
18
  import { PrivateEntityDoiWarning as ge } from "./PrivateEntityDoiWarning.js";
@@ -55,10 +55,10 @@ function E(u) {
55
55
  function I() {
56
56
  Te ? j(!0) : E();
57
57
  }
58
- let [L, R] = l(k), { data: Ee } = i(A, { enabled: !!A }), [z, B] = l({
58
+ let [L, R] = l(k), { data: Ee } = r(A, { enabled: !!A }), [z, B] = l({
59
59
  titles: [""],
60
60
  creators: [""]
61
- }), { data: V, isLoading: De } = a(), { data: H, isLoading: Oe } = n(O, L, {
61
+ }), { data: V, isLoading: De } = i(), { data: H, isLoading: Oe } = t(O, L, {
62
62
  includeEntity: !0,
63
63
  includeBenefactorACL: !0
64
64
  }, {
@@ -73,11 +73,12 @@ function E(u) {
73
73
  }, {
74
74
  staleTime: Infinity,
75
75
  throwOnError: !0
76
- }), G = ye(() => y && W === null && H?.benefactorAcl && U && !ve(H.benefactorAcl.resourceAccess, U), [
76
+ }), G = ye(() => D === v.ENTITY ? y && W === null && H?.benefactorAcl && U && !ve(H.benefactorAcl.resourceAccess, U) : !1, [
77
77
  y,
78
78
  W,
79
79
  H,
80
- U
80
+ U,
81
+ D
81
82
  ]);
82
83
  s(() => {
83
84
  y && !P.current && W !== void 0 && G !== void 0 ? (N(G ? "warning" : "form"), P.current = !0) : y || (N(null), P.current = !1);
@@ -86,7 +87,7 @@ function E(u) {
86
87
  y,
87
88
  W
88
89
  ]);
89
- let K = D === v.ENTITY && H?.entity && oe(H.entity), { data: q } = r(O, void 0, void 0, { enabled: K }), J = c(null), Y = re(H?.entityType ?? b.file), X = `A DOI can be associated with a specific version of this ${Y}.
90
+ let K = D === v.ENTITY && H?.entity && oe(H.entity), { data: q } = n(O, void 0, void 0, { enabled: K }), J = c(null), Y = re(H?.entityType ?? b.file), X = `A DOI can be associated with a specific version of this ${Y}.
90
91
 
91
92
  Versioned DOIs will link to the specified version of the ${Y}.
92
93
 
@@ -97,7 +98,7 @@ function E(u) {
97
98
  X += `\n\nTo create a DOI that will always link to the current set of data in the ${Y},
98
99
  create a new ${e} and mint a DOI for that ${e}.`;
99
100
  }
100
- let { mutate: je, isPending: Me, error: Z } = le({ onSuccess: () => {
101
+ let { mutate: je, isPending: Me, error: Z } = a({ onSuccess: () => {
101
102
  e("The DOI was successfully updated.", "success"), E();
102
103
  } }), Q = Me || De || Oe || Ae || ke, $ = !!(W && w(W));
103
104
  s(() => {
@@ -152,7 +153,7 @@ function E(u) {
152
153
  value: Ee?.name || "",
153
154
  disabled: !0
154
155
  }),
155
- K && /* @__PURE__ */ _(fe, {
156
+ K && /* @__PURE__ */ _(o, {
156
157
  className: "limit-type",
157
158
  fullWidth: !0,
158
159
  sx: { my: 2 },
@@ -164,7 +165,7 @@ function E(u) {
164
165
  justifyContent: "space-between",
165
166
  width: "100%"
166
167
  },
167
- children: [/* @__PURE__ */ g("span", { children: "Version" }), /* @__PURE__ */ g(o, {
168
+ children: [/* @__PURE__ */ g("span", { children: "Version" }), /* @__PURE__ */ g(de, {
168
169
  contentProps: { markdown: X },
169
170
  maxWidth: "350px",
170
171
  children: /* @__PURE__ */ g(x, { className: "HelpButton" })
@@ -234,11 +235,11 @@ function E(u) {
234
235
  onConfirm: () => {
235
236
  j(!1), E();
236
237
  }
237
- }), /* @__PURE__ */ g(de, {
238
+ }), /* @__PURE__ */ g(fe, {
238
239
  open: y,
239
240
  onCancel: I,
240
241
  title: M === "warning" ? "This page is private" : "Create or Update a DOI",
241
- content: M ? /* @__PURE__ */ _(h, { children: [M === "warning" && /* @__PURE__ */ g(ge, {}), M === "form" && Pe] }) : /* @__PURE__ */ g(t, {}),
242
+ content: M ? /* @__PURE__ */ _(h, { children: [M === "warning" && /* @__PURE__ */ g(ge, {}), M === "form" && Pe] }) : /* @__PURE__ */ g(le, {}),
242
243
  actions: /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g(f, {
243
244
  variant: "outlined",
244
245
  disabled: Q,
@@ -1 +1 @@
1
- {"version":3,"file":"CreateOrUpdateDoiModal.js","names":[],"sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"sourcesContent":["import ConfirmCloseWithoutSavingDialog from '@/components/Dialog/ConfirmCloseWithoutSavingDialog'\nimport { DialogBase } from '@/components/DialogBase'\nimport { doiFormSchema, doiFormUiSchema } from '@/components/doi/DoiFormSchemas'\nimport { PrivateEntityDoiWarning } from '@/components/doi/PrivateEntityDoiWarning'\nimport { JsonSchemaForm } from '@/components/JsonSchemaForm/JsonSchemaForm'\nimport { MarkdownPopover } from '@/components/Markdown/MarkdownPopover'\nimport { StyledFormControl } from '@/components/styled/StyledFormControl'\nimport { displayToast } from '@/components/ToastMessage/ToastMessage'\nimport { useCreateOrUpdateDOI, useGetDOI } from '@/synapse-queries/doi/useDOI'\nimport { useGetVersions } from '@/synapse-queries/entity/useEntity'\nimport { useGetEntityBundle } from '@/synapse-queries/entity/useEntityBundle'\nimport { useGetPortal } from '@/synapse-queries/portal/usePortal'\nimport { useGetRealmPrincipals } from '@/synapse-queries/realm/useRealmPrincipals'\nimport { useGetCurrentUserProfile } from '@/synapse-queries/user/useUserBundle'\nimport { useGlobalIsEditingContext } from '@/utils/context/GlobalIsEditingContext'\nimport { isEntityPublic } from '@/utils/functions/AccessControlListUtils'\nimport {\n entityTypeToFriendlyName,\n isDataset,\n isTable,\n isVersionableEntity,\n} from '@/utils/functions/EntityTypeUtils'\nimport {\n BackendDestinationEnum,\n getEndpoint,\n} from '@/utils/functions/getEndpoint'\nimport { DATA_CATALOG_PATH_SEGMENT } from '@/utils/SynapseConstants'\nimport { HelpTwoTone } from '@mui/icons-material'\nimport {\n Alert,\n Button,\n InputLabel,\n Link,\n MenuItem,\n Select,\n TextField,\n Typography,\n} from '@mui/material'\nimport RJSF from '@rjsf/core'\nimport {\n DoiObjectType,\n DoiResourceTypeGeneral,\n DoiResourceTypeResourceTypeGeneralEnum,\n EntityType,\n V2Doi,\n} from '@sage-bionetworks/synapse-client'\nimport { isEmpty } from 'lodash-es'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\ntype CreateOrUpdateDoiModalStep = 'warning' | 'form'\n\nexport type CreateOrUpdateDoiModalProps = {\n /** Whether the dialog is open */\n open: boolean\n /** Callback to call when the dialog is closed */\n onClose: () => void\n /** The type of object */\n objectType: DoiObjectType\n /** The ID of the object */\n objectId: string\n /** The optional version number of the object used to populate the form. */\n defaultVersionNumber?: number\n /** If minting a DOI for a portal, the ID of the portal object in Synapse */\n portalId?: string\n}\n\ntype DoiFormData = {\n titles?: string[]\n creators?: string[]\n resourceTypeGeneral?: DoiResourceTypeResourceTypeGeneralEnum\n publicationYear?: number\n}\n\nfunction getSuggestedResourceTypeGeneral(\n type: EntityType,\n): DoiResourceTypeGeneral {\n if (type === EntityType.project || type === EntityType.folder) {\n return DoiResourceTypeGeneral.Collection\n } else {\n return DoiResourceTypeGeneral.Dataset\n }\n}\n\nfunction convertDoiToFormData(doi: V2Doi): DoiFormData {\n return {\n titles: (doi.titles || []).map(title => title.title!),\n creators: (doi.creators || []).map(creator => creator.creatorName!),\n resourceTypeGeneral: doi.resourceType?.resourceTypeGeneral,\n publicationYear: doi.publicationYear,\n }\n}\n\n/**\n * Returns true if the DOI has fields that are not exposed in the UI, so we can let the user know that any changes\n * may be destructive to hidden fields.\n */\nfunction getWasModifiedViaAPI(doi: V2Doi) {\n if (doi.creators?.some(creator => !isEmpty(creator.nameIdentifiers))) {\n return true\n }\n return false\n}\n\nfunction convertFormDataToDoi(formData: DoiFormData): V2Doi {\n return {\n titles: formData.titles?.map(title => ({ title })) || [],\n creators:\n formData.creators?.map(creator => ({ creatorName: creator })) || [],\n resourceType: {\n resourceTypeGeneral: formData.resourceTypeGeneral,\n },\n publicationYear: formData.publicationYear,\n }\n}\n\nexport function CreateOrUpdateDoiModal(props: CreateOrUpdateDoiModalProps) {\n const {\n open,\n onClose,\n objectType,\n objectId,\n defaultVersionNumber,\n portalId,\n } = props\n\n const [showConfirmCloseModal, setShowConfirmCloseDialog] = useState(false)\n const [currentStep, setCurrentStep] =\n useState<CreateOrUpdateDoiModalStep | null>(null)\n const hasSetInitialStepForThisSession = useRef(false)\n const { isEditing, setIsEditing } = useGlobalIsEditingContext()\n useEffect(() => {\n setIsEditing(open)\n\n return () => {\n setIsEditing(false)\n }\n }, [open, setIsEditing])\n\n function handleClose() {\n if (isEditing) {\n setShowConfirmCloseDialog(true)\n } else {\n onClose()\n }\n }\n\n const [selectedVersionNumber, setSelectedVersionNumber] =\n useState(defaultVersionNumber)\n\n const { data: portal } = useGetPortal(portalId!, {\n enabled: Boolean(portalId),\n })\n\n const [formData, setFormData] = useState<DoiFormData>({\n titles: [''],\n creators: [''],\n })\n const { data: currentUser, isLoading: isLoadingCurrentUser } =\n useGetCurrentUserProfile()\n const { data: entityBundle, isLoading: isLoadingEntity } = useGetEntityBundle(\n objectId,\n selectedVersionNumber,\n {\n includeEntity: true,\n includeBenefactorACL: true,\n },\n {\n enabled: objectType === DoiObjectType.ENTITY,\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n const { data: realmPrincipals, isLoading: isLoadingRealmPrincipals } =\n useGetRealmPrincipals()\n const { data: doi, isLoading: isLoadingDoi } = useGetDOI(\n {\n id: objectId,\n version: selectedVersionNumber,\n type: objectType,\n portalId: portalId,\n },\n {\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n\n const shouldShowWarning = useMemo(() => {\n return (\n open &&\n doi === null && // Creating new DOI\n entityBundle?.benefactorAcl &&\n realmPrincipals &&\n !isEntityPublic(\n entityBundle.benefactorAcl.resourceAccess,\n realmPrincipals,\n )\n )\n }, [open, doi, entityBundle, realmPrincipals])\n\n useEffect(() => {\n if (\n open &&\n !hasSetInitialStepForThisSession.current &&\n doi !== undefined && // Wait for DOI query to resolve before determining step\n shouldShowWarning !== undefined\n ) {\n const newStep = shouldShowWarning ? 'warning' : 'form'\n setCurrentStep(newStep)\n hasSetInitialStepForThisSession.current = true\n } else if (!open) {\n setCurrentStep(null)\n hasSetInitialStepForThisSession.current = false\n }\n }, [shouldShowWarning, open, doi])\n\n const doiCanBeAppliedToVersion =\n objectType === DoiObjectType.ENTITY &&\n entityBundle?.entity &&\n isVersionableEntity(entityBundle.entity)\n\n const { data: entityVersions } = useGetVersions(\n objectId,\n undefined,\n undefined,\n {\n enabled: doiCanBeAppliedToVersion,\n },\n )\n const formRef = useRef<RJSF>(null)\n\n const entityType = entityBundle?.entityType ?? EntityType.file\n const entityTypeDisplay = entityTypeToFriendlyName(entityType)\n let versionHelpMarkdown = `A DOI can be associated with a specific version of this ${entityTypeDisplay}.\n \n Versioned DOIs will link to the specified version of the ${entityTypeDisplay}.\n \n A DOI without a version will always link to the newest version of this ${entityTypeDisplay},\n so the data that someone retrieves using the DOI may change over time.`\n if (entityBundle?.entity && isTable(entityBundle.entity)) {\n const tableVersionCopy = isDataset(entityBundle.entity)\n ? 'version'\n : 'snapshot'\n versionHelpMarkdown += `\\n\\nTo create a DOI that will always link to the current set of data in the ${entityTypeDisplay},\n create a new ${tableVersionCopy} and mint a DOI for that ${tableVersionCopy}.`\n }\n\n const {\n mutate: createOrUpdateDoi,\n isPending: updateIsPending,\n error: updateDoiError,\n } = useCreateOrUpdateDOI({\n onSuccess: () => {\n displayToast('The DOI was successfully updated.', 'success')\n onClose()\n },\n })\n\n const isLoading =\n updateIsPending ||\n isLoadingCurrentUser ||\n isLoadingEntity ||\n isLoadingDoi ||\n isLoadingRealmPrincipals\n\n const wasModifiedViaAPI = Boolean(doi && getWasModifiedViaAPI(doi))\n\n useEffect(() => {\n if (doi) {\n setFormData(convertDoiToFormData(doi))\n }\n // If there is no DOI, then pre-fill the form.\n if (currentUser && entityBundle?.entity && doi === null) {\n const newFormData = {\n titles: [entityBundle.entity.name],\n creators: new Array<string>(),\n resourceTypeGeneral: getSuggestedResourceTypeGeneral(\n entityBundle.entityType,\n ),\n publicationYear: new Date().getFullYear(),\n } satisfies DoiFormData\n if (currentUser.lastName && currentUser.firstName) {\n newFormData.creators.push(\n `${currentUser.lastName}, ${currentUser.firstName}`,\n )\n }\n setFormData(newFormData)\n }\n }, [currentUser, doi, entityBundle])\n\n function onSave() {\n if (formRef.current && formRef.current.validateForm()) {\n const requestDoi: V2Doi = convertFormDataToDoi(formData)\n requestDoi.objectType = objectType\n requestDoi.objectId = objectId\n requestDoi.objectVersion = selectedVersionNumber\n requestDoi.etag = doi?.etag\n requestDoi.portalId = portalId\n createOrUpdateDoi({\n doi: requestDoi,\n concreteType: 'org.sagebionetworks.repo.model.doi.v2.DoiRequest',\n })\n }\n }\n\n const dialogContent = (\n <>\n <Typography variant={'body1'} gutterBottom>\n Minting a DOI allows you to credit contributors and makes it easy to\n cite your work.\n </Typography>\n <Typography variant={'body1'} gutterBottom sx={{ mb: 2 }}>\n Note that while the DOI and its associated metadata will be publicly\n visible outside of Synapse, your data will still adhere to its existing\n access conditions. If your data is private, it will remain restricted,\n but the DOI will still be listed. Resources with DOIs may be added to\n the{' '}\n <Link\n href={`${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}${DATA_CATALOG_PATH_SEGMENT}`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n Synapse Data Catalog\n </Link>\n .\n </Typography>\n {portalId && (\n <TextField\n label={'Publisher'}\n fullWidth\n value={portal?.name || ''}\n disabled\n />\n )}\n {doiCanBeAppliedToVersion && (\n <StyledFormControl className=\"limit-type\" fullWidth sx={{ my: 2 }}>\n <InputLabel\n htmlFor=\"doi-version-select\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <span>Version</span>\n <MarkdownPopover\n contentProps={{ markdown: versionHelpMarkdown }}\n maxWidth=\"350px\"\n >\n <HelpTwoTone className={`HelpButton`} />\n </MarkdownPopover>\n </InputLabel>\n <Select\n id=\"doi-version-select\"\n value={selectedVersionNumber ?? -1}\n onChange={e => {\n if (e.target.value === -1) {\n setSelectedVersionNumber(undefined)\n } else {\n setSelectedVersionNumber(e.target.value)\n }\n }}\n >\n <MenuItem value={-1}>No version</MenuItem>\n {entityVersions &&\n entityVersions.results.map(version => (\n <MenuItem\n key={version.versionNumber}\n value={version.versionNumber}\n >\n Version {version.versionNumber}\n {/* display the version label if it exists & is different from the number itself */}\n {version.versionLabel &&\n version.versionLabel !== String(version.versionNumber)\n ? ` / ${version.versionLabel}`\n : ''}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )}\n <div className=\"JsonSchemaFormContainer\">\n <JsonSchemaForm\n formRef={formRef}\n disabled={isLoading || wasModifiedViaAPI}\n schema={doiFormSchema}\n formData={formData}\n onChange={e => {\n setFormData(e.formData)\n }}\n uiSchema={doiFormUiSchema}\n showErrorList={false}\n />\n </div>\n {doi && (\n <Alert severity={'warning'}>\n <Typography variant={'body1'}>\n A DOI has already been created. Updating the DOI information will\n cause old information to be lost!\n </Typography>\n </Alert>\n )}\n {wasModifiedViaAPI && (\n <Alert severity={'warning'} sx={{ my: 1 }}>\n <Typography variant={'body1'}>\n The metadata for this DOI was modified using a programmatic client,\n so data may be hidden from this view. Any changes may result in\n metadata being lost.\n </Typography>\n </Alert>\n )}\n {updateDoiError && (\n <Alert severity={'error'} sx={{ mt: 1 }}>\n <Typography variant={'body1'}>{updateDoiError.message}</Typography>\n </Alert>\n )}\n </>\n )\n\n const dialogActions = (\n <>\n <Button variant=\"outlined\" disabled={isLoading} onClick={handleClose}>\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n disabled={isLoading}\n onClick={\n currentStep === 'warning'\n ? () => setCurrentStep('form')\n : e => {\n // SWC-7055 - The default action may trigger `beforeunload` and erroneously warn the user about leaving the page.\n e.preventDefault()\n onSave()\n }\n }\n >\n {currentStep === 'warning' ? 'Continue' : 'Save'}\n </Button>\n </>\n )\n\n return (\n <>\n <ConfirmCloseWithoutSavingDialog\n open={showConfirmCloseModal}\n onCancel={() => {\n setShowConfirmCloseDialog(false)\n }}\n onConfirm={() => {\n setShowConfirmCloseDialog(false)\n onClose()\n }}\n />\n <DialogBase\n open={open}\n onCancel={handleClose}\n title={\n currentStep === 'warning'\n ? 'This page is private'\n : 'Create or Update a DOI'\n }\n content={\n !currentStep ? (\n <SynapseSpinner />\n ) : (\n <>\n {currentStep === 'warning' && <PrivateEntityDoiWarning />}\n {currentStep === 'form' && dialogContent}\n </>\n )\n }\n actions={dialogActions}\n />\n </>\n )\n}\n\nexport default CreateOrUpdateDoiModal\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreateOrUpdateDoiModal.js","names":[],"sources":["../../../src/components/doi/CreateOrUpdateDoiModal.tsx"],"sourcesContent":["import ConfirmCloseWithoutSavingDialog from '@/components/Dialog/ConfirmCloseWithoutSavingDialog'\nimport { DialogBase } from '@/components/DialogBase'\nimport { doiFormSchema, doiFormUiSchema } from '@/components/doi/DoiFormSchemas'\nimport { PrivateEntityDoiWarning } from '@/components/doi/PrivateEntityDoiWarning'\nimport { JsonSchemaForm } from '@/components/JsonSchemaForm/JsonSchemaForm'\nimport { MarkdownPopover } from '@/components/Markdown/MarkdownPopover'\nimport { StyledFormControl } from '@/components/styled/StyledFormControl'\nimport { displayToast } from '@/components/ToastMessage/ToastMessage'\nimport { useCreateOrUpdateDOI, useGetDOI } from '@/synapse-queries/doi/useDOI'\nimport { useGetVersions } from '@/synapse-queries/entity/useEntity'\nimport { useGetEntityBundle } from '@/synapse-queries/entity/useEntityBundle'\nimport { useGetPortal } from '@/synapse-queries/portal/usePortal'\nimport { useGetRealmPrincipals } from '@/synapse-queries/realm/useRealmPrincipals'\nimport { useGetCurrentUserProfile } from '@/synapse-queries/user/useUserBundle'\nimport { useGlobalIsEditingContext } from '@/utils/context/GlobalIsEditingContext'\nimport { isEntityPublic } from '@/utils/functions/AccessControlListUtils'\nimport {\n entityTypeToFriendlyName,\n isDataset,\n isTable,\n isVersionableEntity,\n} from '@/utils/functions/EntityTypeUtils'\nimport {\n BackendDestinationEnum,\n getEndpoint,\n} from '@/utils/functions/getEndpoint'\nimport { DATA_CATALOG_PATH_SEGMENT } from '@/utils/SynapseConstants'\nimport { HelpTwoTone } from '@mui/icons-material'\nimport {\n Alert,\n Button,\n InputLabel,\n Link,\n MenuItem,\n Select,\n TextField,\n Typography,\n} from '@mui/material'\nimport RJSF from '@rjsf/core'\nimport {\n DoiObjectType,\n DoiResourceTypeGeneral,\n DoiResourceTypeResourceTypeGeneralEnum,\n EntityType,\n V2Doi,\n} from '@sage-bionetworks/synapse-client'\nimport { isEmpty } from 'lodash-es'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\ntype CreateOrUpdateDoiModalStep = 'warning' | 'form'\n\nexport type CreateOrUpdateDoiModalProps = {\n /** Whether the dialog is open */\n open: boolean\n /** Callback to call when the dialog is closed */\n onClose: () => void\n /** The type of object */\n objectType: DoiObjectType\n /** The ID of the object */\n objectId: string\n /** The optional version number of the object used to populate the form. */\n defaultVersionNumber?: number\n /** If minting a DOI for a portal, the ID of the portal object in Synapse */\n portalId?: string\n}\n\ntype DoiFormData = {\n titles?: string[]\n creators?: string[]\n resourceTypeGeneral?: DoiResourceTypeResourceTypeGeneralEnum\n publicationYear?: number\n}\n\nfunction getSuggestedResourceTypeGeneral(\n type: EntityType,\n): DoiResourceTypeGeneral {\n if (type === EntityType.project || type === EntityType.folder) {\n return DoiResourceTypeGeneral.Collection\n } else {\n return DoiResourceTypeGeneral.Dataset\n }\n}\n\nfunction convertDoiToFormData(doi: V2Doi): DoiFormData {\n return {\n titles: (doi.titles || []).map(title => title.title!),\n creators: (doi.creators || []).map(creator => creator.creatorName!),\n resourceTypeGeneral: doi.resourceType?.resourceTypeGeneral,\n publicationYear: doi.publicationYear,\n }\n}\n\n/**\n * Returns true if the DOI has fields that are not exposed in the UI, so we can let the user know that any changes\n * may be destructive to hidden fields.\n */\nfunction getWasModifiedViaAPI(doi: V2Doi) {\n if (doi.creators?.some(creator => !isEmpty(creator.nameIdentifiers))) {\n return true\n }\n return false\n}\n\nfunction convertFormDataToDoi(formData: DoiFormData): V2Doi {\n return {\n titles: formData.titles?.map(title => ({ title })) || [],\n creators:\n formData.creators?.map(creator => ({ creatorName: creator })) || [],\n resourceType: {\n resourceTypeGeneral: formData.resourceTypeGeneral,\n },\n publicationYear: formData.publicationYear,\n }\n}\n\nexport function CreateOrUpdateDoiModal(props: CreateOrUpdateDoiModalProps) {\n const {\n open,\n onClose,\n objectType,\n objectId,\n defaultVersionNumber,\n portalId,\n } = props\n\n const [showConfirmCloseModal, setShowConfirmCloseDialog] = useState(false)\n const [currentStep, setCurrentStep] =\n useState<CreateOrUpdateDoiModalStep | null>(null)\n const hasSetInitialStepForThisSession = useRef(false)\n const { isEditing, setIsEditing } = useGlobalIsEditingContext()\n useEffect(() => {\n setIsEditing(open)\n\n return () => {\n setIsEditing(false)\n }\n }, [open, setIsEditing])\n\n function handleClose() {\n if (isEditing) {\n setShowConfirmCloseDialog(true)\n } else {\n onClose()\n }\n }\n\n const [selectedVersionNumber, setSelectedVersionNumber] =\n useState(defaultVersionNumber)\n\n const { data: portal } = useGetPortal(portalId!, {\n enabled: Boolean(portalId),\n })\n\n const [formData, setFormData] = useState<DoiFormData>({\n titles: [''],\n creators: [''],\n })\n const { data: currentUser, isLoading: isLoadingCurrentUser } =\n useGetCurrentUserProfile()\n const { data: entityBundle, isLoading: isLoadingEntity } = useGetEntityBundle(\n objectId,\n selectedVersionNumber,\n {\n includeEntity: true,\n includeBenefactorACL: true,\n },\n {\n enabled: objectType === DoiObjectType.ENTITY,\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n const { data: realmPrincipals, isLoading: isLoadingRealmPrincipals } =\n useGetRealmPrincipals()\n const { data: doi, isLoading: isLoadingDoi } = useGetDOI(\n {\n id: objectId,\n version: selectedVersionNumber,\n type: objectType,\n portalId: portalId,\n },\n {\n staleTime: Infinity,\n throwOnError: true,\n },\n )\n\n const shouldShowWarning = useMemo(() => {\n if (objectType !== DoiObjectType.ENTITY) {\n return false\n }\n return (\n open &&\n doi === null && // Creating new DOI\n entityBundle?.benefactorAcl &&\n realmPrincipals &&\n !isEntityPublic(\n entityBundle.benefactorAcl.resourceAccess,\n realmPrincipals,\n )\n )\n }, [open, doi, entityBundle, realmPrincipals, objectType])\n\n useEffect(() => {\n if (\n open &&\n !hasSetInitialStepForThisSession.current &&\n doi !== undefined && // Wait for DOI query to resolve before determining step\n shouldShowWarning !== undefined\n ) {\n const newStep = shouldShowWarning ? 'warning' : 'form'\n setCurrentStep(newStep)\n hasSetInitialStepForThisSession.current = true\n } else if (!open) {\n setCurrentStep(null)\n hasSetInitialStepForThisSession.current = false\n }\n }, [shouldShowWarning, open, doi])\n\n const doiCanBeAppliedToVersion =\n objectType === DoiObjectType.ENTITY &&\n entityBundle?.entity &&\n isVersionableEntity(entityBundle.entity)\n\n const { data: entityVersions } = useGetVersions(\n objectId,\n undefined,\n undefined,\n {\n enabled: doiCanBeAppliedToVersion,\n },\n )\n const formRef = useRef<RJSF>(null)\n\n const entityType = entityBundle?.entityType ?? EntityType.file\n const entityTypeDisplay = entityTypeToFriendlyName(entityType)\n let versionHelpMarkdown = `A DOI can be associated with a specific version of this ${entityTypeDisplay}.\n \n Versioned DOIs will link to the specified version of the ${entityTypeDisplay}.\n \n A DOI without a version will always link to the newest version of this ${entityTypeDisplay},\n so the data that someone retrieves using the DOI may change over time.`\n if (entityBundle?.entity && isTable(entityBundle.entity)) {\n const tableVersionCopy = isDataset(entityBundle.entity)\n ? 'version'\n : 'snapshot'\n versionHelpMarkdown += `\\n\\nTo create a DOI that will always link to the current set of data in the ${entityTypeDisplay},\n create a new ${tableVersionCopy} and mint a DOI for that ${tableVersionCopy}.`\n }\n\n const {\n mutate: createOrUpdateDoi,\n isPending: updateIsPending,\n error: updateDoiError,\n } = useCreateOrUpdateDOI({\n onSuccess: () => {\n displayToast('The DOI was successfully updated.', 'success')\n onClose()\n },\n })\n\n const isLoading =\n updateIsPending ||\n isLoadingCurrentUser ||\n isLoadingEntity ||\n isLoadingDoi ||\n isLoadingRealmPrincipals\n\n const wasModifiedViaAPI = Boolean(doi && getWasModifiedViaAPI(doi))\n\n useEffect(() => {\n if (doi) {\n setFormData(convertDoiToFormData(doi))\n }\n // If there is no DOI, then pre-fill the form.\n if (currentUser && entityBundle?.entity && doi === null) {\n const newFormData = {\n titles: [entityBundle.entity.name],\n creators: new Array<string>(),\n resourceTypeGeneral: getSuggestedResourceTypeGeneral(\n entityBundle.entityType,\n ),\n publicationYear: new Date().getFullYear(),\n } satisfies DoiFormData\n if (currentUser.lastName && currentUser.firstName) {\n newFormData.creators.push(\n `${currentUser.lastName}, ${currentUser.firstName}`,\n )\n }\n setFormData(newFormData)\n }\n }, [currentUser, doi, entityBundle])\n\n function onSave() {\n if (formRef.current && formRef.current.validateForm()) {\n const requestDoi: V2Doi = convertFormDataToDoi(formData)\n requestDoi.objectType = objectType\n requestDoi.objectId = objectId\n requestDoi.objectVersion = selectedVersionNumber\n requestDoi.etag = doi?.etag\n requestDoi.portalId = portalId\n createOrUpdateDoi({\n doi: requestDoi,\n concreteType: 'org.sagebionetworks.repo.model.doi.v2.DoiRequest',\n })\n }\n }\n\n const dialogContent = (\n <>\n <Typography variant={'body1'} gutterBottom>\n Minting a DOI allows you to credit contributors and makes it easy to\n cite your work.\n </Typography>\n <Typography variant={'body1'} gutterBottom sx={{ mb: 2 }}>\n Note that while the DOI and its associated metadata will be publicly\n visible outside of Synapse, your data will still adhere to its existing\n access conditions. If your data is private, it will remain restricted,\n but the DOI will still be listed. Resources with DOIs may be added to\n the{' '}\n <Link\n href={`${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}${DATA_CATALOG_PATH_SEGMENT}`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n Synapse Data Catalog\n </Link>\n .\n </Typography>\n {portalId && (\n <TextField\n label={'Publisher'}\n fullWidth\n value={portal?.name || ''}\n disabled\n />\n )}\n {doiCanBeAppliedToVersion && (\n <StyledFormControl className=\"limit-type\" fullWidth sx={{ my: 2 }}>\n <InputLabel\n htmlFor=\"doi-version-select\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <span>Version</span>\n <MarkdownPopover\n contentProps={{ markdown: versionHelpMarkdown }}\n maxWidth=\"350px\"\n >\n <HelpTwoTone className={`HelpButton`} />\n </MarkdownPopover>\n </InputLabel>\n <Select\n id=\"doi-version-select\"\n value={selectedVersionNumber ?? -1}\n onChange={e => {\n if (e.target.value === -1) {\n setSelectedVersionNumber(undefined)\n } else {\n setSelectedVersionNumber(e.target.value)\n }\n }}\n >\n <MenuItem value={-1}>No version</MenuItem>\n {entityVersions &&\n entityVersions.results.map(version => (\n <MenuItem\n key={version.versionNumber}\n value={version.versionNumber}\n >\n Version {version.versionNumber}\n {/* display the version label if it exists & is different from the number itself */}\n {version.versionLabel &&\n version.versionLabel !== String(version.versionNumber)\n ? ` / ${version.versionLabel}`\n : ''}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )}\n <div className=\"JsonSchemaFormContainer\">\n <JsonSchemaForm\n formRef={formRef}\n disabled={isLoading || wasModifiedViaAPI}\n schema={doiFormSchema}\n formData={formData}\n onChange={e => {\n setFormData(e.formData)\n }}\n uiSchema={doiFormUiSchema}\n showErrorList={false}\n />\n </div>\n {doi && (\n <Alert severity={'warning'}>\n <Typography variant={'body1'}>\n A DOI has already been created. Updating the DOI information will\n cause old information to be lost!\n </Typography>\n </Alert>\n )}\n {wasModifiedViaAPI && (\n <Alert severity={'warning'} sx={{ my: 1 }}>\n <Typography variant={'body1'}>\n The metadata for this DOI was modified using a programmatic client,\n so data may be hidden from this view. Any changes may result in\n metadata being lost.\n </Typography>\n </Alert>\n )}\n {updateDoiError && (\n <Alert severity={'error'} sx={{ mt: 1 }}>\n <Typography variant={'body1'}>{updateDoiError.message}</Typography>\n </Alert>\n )}\n </>\n )\n\n const dialogActions = (\n <>\n <Button variant=\"outlined\" disabled={isLoading} onClick={handleClose}>\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n disabled={isLoading}\n onClick={\n currentStep === 'warning'\n ? () => setCurrentStep('form')\n : e => {\n // SWC-7055 - The default action may trigger `beforeunload` and erroneously warn the user about leaving the page.\n e.preventDefault()\n onSave()\n }\n }\n >\n {currentStep === 'warning' ? 'Continue' : 'Save'}\n </Button>\n </>\n )\n\n return (\n <>\n <ConfirmCloseWithoutSavingDialog\n open={showConfirmCloseModal}\n onCancel={() => {\n setShowConfirmCloseDialog(false)\n }}\n onConfirm={() => {\n setShowConfirmCloseDialog(false)\n onClose()\n }}\n />\n <DialogBase\n open={open}\n onCancel={handleClose}\n title={\n currentStep === 'warning'\n ? 'This page is private'\n : 'Create or Update a DOI'\n }\n content={\n !currentStep ? (\n <SynapseSpinner />\n ) : (\n <>\n {currentStep === 'warning' && <PrivateEntityDoiWarning />}\n {currentStep === 'form' && dialogContent}\n </>\n )\n }\n actions={dialogActions}\n />\n </>\n )\n}\n\nexport default CreateOrUpdateDoiModal\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CreatedByModifiedBy.js","names":[],"sources":["../../../../src/components/entity/page/CreatedByModifiedBy.tsx"],"sourcesContent":["import ConditionalWrapper from '@/components/utils/ConditionalWrapper'\nimport {\n useGetEntity,\n useGetQueryResultBundleWithAsyncStatus,\n} from '@/synapse-queries'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n convertToEntityType,\n entityTypeToFriendlyName,\n isDataset,\n isTable,\n} from '@/utils/functions/EntityTypeUtils'\nimport { BUNDLE_MASK_LAST_UPDATED_ON } from '@/utils/SynapseConstants'\nimport { InfoTwoTone } from '@mui/icons-material'\nimport {\n Box,\n Breadcrumbs,\n Skeleton,\n SxProps,\n Tooltip,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport dayjs from 'dayjs'\nimport { UserBadge } from '../../UserCard/UserBadge'\n\nexport type CreatedByModifiedByProps = {\n entityId: string\n versionNumber?: number\n}\n\nfunction Separator() {\n const theme = useTheme()\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'))\n if (isSmallScreen) {\n return null\n }\n return (\n <Typography variant={'breadcrumb1'} sx={{ color: 'grey.700' }}>\n /\n </Typography>\n )\n}\n\nexport function CreatedByModifiedBy(props: CreatedByModifiedByProps) {\n const { entityId, versionNumber } = props\n const entityIdWithVersion = `${entityId}${\n versionNumber ? `.${versionNumber}` : ''\n }`\n\n const { data: entity } = useGetEntity(entityId, versionNumber)\n\n const { data: tableQueryResult } = useGetQueryResultBundleWithAsyncStatus(\n {\n entityId,\n query: {\n sql: `SELECT * FROM ${entityIdWithVersion} LIMIT 0`,\n },\n partMask: BUNDLE_MASK_LAST_UPDATED_ON,\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n },\n { enabled: !!(entity && isTable(entity)) },\n )\n\n const tableLastRebuilt = tableQueryResult?.responseBody?.lastUpdatedOn\n const friendlyName = entity\n ? entityTypeToFriendlyName(convertToEntityType(entity.concreteType))\n : ''\n\n const datasetCreatedByTooltipText =\n 'This is the user who created this Dataset. ' +\n 'This may not be the same person who generated the files in this Dataset, or who originally uploaded these files to Synapse.'\n\n const tableModifiedOnTooltipText = (\n <>\n <p>\n This is when the configuration of this {friendlyName} was last changed.\n </p>\n <p>Configuration changes may be triggered by (for example):</p>\n <ul>\n <li>Editing the name of the {friendlyName}</li>\n <li>Updating the schema used by the {friendlyName}</li>\n </ul>\n <p>\n This does NOT reflect changes to the data displayed in the the{' '}\n {friendlyName}.\n </p>\n </>\n )\n /*\n If the tooltip text is a string, MUI automatically applies it to aria-label which is more accessible and testable.\n Since this tooltip text is a ReactNode, let's manually create a short string to use for the aria-label.\n */\n const tableModifiedOnAccessibleLabel = `This is when the configuration of this ${friendlyName} was last changed.`\n\n const tableLastUpdatedTooltipText =\n `When data changes, the ${friendlyName} is rebuilt to reflect those changes. ` +\n `This is the last time changes were made to the data.`\n\n const createdByTooltipId = `${entityIdWithVersion}-createdByTooltip`\n const modifiedByTooltipId = `${entityIdWithVersion}-modifiedByTooltip`\n const lastUpdatedTooltipId = `${entityIdWithVersion}-lastUpdatedTooltip`\n\n const iconSx: SxProps = {\n width: '16px',\n height: '16px',\n ml: '4px',\n verticalAlign: 'text-bottom',\n }\n\n return (\n <Box\n sx={theme => ({\n bgcolor: 'grey.100',\n py: '10px',\n [theme.breakpoints.down('sm')]: {\n p: '24px 40px',\n },\n })}\n >\n <Breadcrumbs\n separator={<Separator />}\n sx={theme => ({\n '& .MuiBreadcrumbs-ol': {\n justifyContent: 'center',\n [theme.breakpoints.down('sm')]: {\n gap: '4px',\n },\n },\n })}\n >\n <ConditionalWrapper condition={!entity} wrapper={Skeleton}>\n <Typography\n sx={{ color: 'grey.700' }}\n variant={'breadcrumb1'}\n aria-describedby={createdByTooltipId}\n >\n {friendlyName} created by <UserBadge userId={entity?.createdBy} />{' '}\n on {formatDate(dayjs(entity?.createdOn))}\n {entity && isDataset(entity) && (\n <Tooltip\n id={createdByTooltipId}\n title={datasetCreatedByTooltipText}\n >\n <InfoTwoTone sx={iconSx} />\n </Tooltip>\n )}\n </Typography>\n </ConditionalWrapper>\n <ConditionalWrapper condition={!entity} wrapper={Skeleton}>\n <Typography\n sx={{ color: 'grey.700' }}\n variant={'breadcrumb1'}\n aria-describedby={modifiedByTooltipId}\n >\n {entity && isTable(entity) ? 'Configuration' : friendlyName} last\n modified by <UserBadge userId={entity?.modifiedBy} /> on{' '}\n {formatDate(dayjs(entity?.modifiedOn))}\n {entity && isTable(entity) && (\n <Tooltip\n id={modifiedByTooltipId}\n title={tableModifiedOnTooltipText}\n aria-label={tableModifiedOnAccessibleLabel}\n >\n <InfoTwoTone sx={iconSx} />\n </Tooltip>\n )}\n </Typography>\n </ConditionalWrapper>\n {tableLastRebuilt && (\n <Typography\n sx={{ color: 'grey.700' }}\n variant={'breadcrumb1'}\n aria-describedby={lastUpdatedTooltipId}\n >\n {friendlyName} last rebuilt on {formatDate(dayjs(tableLastRebuilt))}\n <Tooltip\n title={tableLastUpdatedTooltipText}\n id={lastUpdatedTooltipId}\n >\n <InfoTwoTone sx={iconSx} />\n </Tooltip>\n </Typography>\n )}\n </Breadcrumbs>\n </Box>\n )\n}\n\nexport default CreatedByModifiedBy\n"],"mappings":";;;;;;;;;;;;;AAgCA,SAAS,IAAY;AAMnB,QAJsB,EADR,GAAU,CACkB,YAAY,KAAK,KAAK,CAAC,GAExD,OAGP,kBAAC,GAAD;EAAY,SAAS;EAAe,IAAI,EAAE,OAAO,YAAY;YAAE;EAElD,CAAA;;AAIjB,SAAgB,EAAoB,GAAiC;CACnE,IAAM,EAAE,aAAU,qBAAkB,GAC9B,IAAsB,GAAG,IAC7B,IAAgB,IAAI,MAAkB,MAGlC,EAAE,MAAM,MAAW,EAAa,GAAU,EAAc,EAExD,EAAE,MAAM,MAAqB,EACjC;EACE;EACA,OAAO,EACL,KAAK,iBAAiB,EAAoB,WAC3C;EACD,UAAA;EACA,cAAc;EACf,EACD,EAAE,SAAS,CAAC,EAAE,KAAU,EAAQ,EAAO,GAAG,CAC3C,EAEK,IAAmB,GAAkB,cAAc,eACnD,IAAe,IACjB,EAAyB,EAAoB,EAAO,aAAa,CAAC,GAClE,IAME,IACJ,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,KAAD,EAAA,UAAA;GAAG;GACuC;GAAa;GACnD,EAAA,CAAA;EACJ,kBAAC,KAAD,EAAA,UAAG,4DAA4D,CAAA;EAC/D,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAA,CAAI,4BAAyB,EAAkB,EAAA,CAAA,EAC/C,kBAAC,MAAD,EAAA,UAAA,CAAI,oCAAiC,EAAkB,EAAA,CAAA,CACpD,EAAA,CAAA;EACL,kBAAC,KAAD,EAAA,UAAA;GAAG;GAC8D;GAC9D;GAAa;GACZ,EAAA,CAAA;EACH,EAAA,CAAA,EAMC,IAAiC,0CAA0C,EAAa,qBAExF,IACJ,0BAA0B,EAAa,6FAGnC,IAAqB,GAAG,EAAoB,oBAC5C,IAAsB,GAAG,EAAoB,qBAC7C,IAAuB,GAAG,EAAoB,sBAE9C,IAAkB;EACtB,OAAO;EACP,QAAQ;EACR,IAAI;EACJ,eAAe;EAChB;AAED,QACE,kBAAC,GAAD;EACE,KAAI,OAAU;GACZ,SAAS;GACT,IAAI;IACH,EAAM,YAAY,KAAK,KAAK,GAAG,EAC9B,GAAG,aACJ;GACF;YAED,kBAAC,GAAD;GACE,WAAW,kBAAC,GAAD,EAAa,CAAA;GACxB,KAAI,OAAU,EACZ,wBAAwB;IACtB,gBAAgB;KACf,EAAM,YAAY,KAAK,KAAK,GAAG,EAC9B,KAAK,OACN;IACF,EACF;aATH;IAWE,kBAAC,GAAD;KAAoB,WAAW,CAAC;KAAQ,SAAS;eAC/C,kBAAC,GAAD;MACE,IAAI,EAAE,OAAO,YAAY;MACzB,SAAS;MACT,oBAAkB;gBAHpB;OAKG;OAAa;OAAY,kBAAC,GAAD,EAAW,QAAQ,GAAQ,WAAa,CAAA;OAAC;OAAI;OACnE,EAAW,EAAM,GAAQ,UAAU,CAAC;OACvC,KAAU,EAAU,EAAO,IAC1B,kBAAC,GAAD;QACE,IAAI;QACJ,OAAO;kBAEP,kBAAC,GAAD,EAAa,IAAI,GAAU,CAAA;QACnB,CAAA;OAED;;KACM,CAAA;IACrB,kBAAC,GAAD;KAAoB,WAAW,CAAC;KAAQ,SAAS;eAC/C,kBAAC,GAAD;MACE,IAAI,EAAE,OAAO,YAAY;MACzB,SAAS;MACT,oBAAkB;gBAHpB;OAKG,KAAU,EAAQ,EAAO,GAAG,kBAAkB;OAAa;OAChD,kBAAC,GAAD,EAAW,QAAQ,GAAQ,YAAc,CAAA;;OAAI;OACxD,EAAW,EAAM,GAAQ,WAAW,CAAC;OACrC,KAAU,EAAQ,EAAO,IACxB,kBAAC,GAAD;QACE,IAAI;QACJ,OAAO;QACP,cAAY;kBAEZ,kBAAC,GAAD,EAAa,IAAI,GAAU,CAAA;QACnB,CAAA;OAED;;KACM,CAAA;IACpB,KACC,kBAAC,GAAD;KACE,IAAI,EAAE,OAAO,YAAY;KACzB,SAAS;KACT,oBAAkB;eAHpB;MAKG;MAAa;MAAkB,EAAW,EAAM,EAAiB,CAAC;MACnE,kBAAC,GAAD;OACE,OAAO;OACP,IAAI;iBAEJ,kBAAC,GAAD,EAAa,IAAI,GAAU,CAAA;OACnB,CAAA;MACC;;IAEH;;EACV,CAAA"}
1
+ {"version":3,"file":"CreatedByModifiedBy.js","names":[],"sources":["../../../../src/components/entity/page/CreatedByModifiedBy.tsx"],"sourcesContent":["import ConditionalWrapper from '@/components/utils/ConditionalWrapper'\nimport {\n useGetEntity,\n useGetQueryResultBundleWithAsyncStatus,\n} from '@/synapse-queries'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n convertToEntityType,\n entityTypeToFriendlyName,\n isDataset,\n isTable,\n} from '@/utils/functions/EntityTypeUtils'\nimport { BUNDLE_MASK_LAST_UPDATED_ON } from '@/utils/SynapseConstants'\nimport { InfoTwoTone } from '@mui/icons-material'\nimport {\n Box,\n Breadcrumbs,\n Skeleton,\n SxProps,\n Tooltip,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport dayjs from 'dayjs'\nimport { UserBadge } from '../../UserCard/UserBadge'\n\nexport type CreatedByModifiedByProps = {\n entityId: string\n versionNumber?: number\n}\n\nfunction Separator() {\n const theme = useTheme()\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'))\n if (isSmallScreen) {\n return null\n }\n return (\n <Typography variant={'breadcrumb1'} sx={{ color: 'grey.700' }}>\n /\n </Typography>\n )\n}\n\nexport function CreatedByModifiedBy(props: CreatedByModifiedByProps) {\n const { entityId, versionNumber } = props\n const entityIdWithVersion = `${entityId}${\n versionNumber ? `.${versionNumber}` : ''\n }`\n\n const { data: entity } = useGetEntity(entityId, versionNumber)\n\n const { data: tableQueryResult } = useGetQueryResultBundleWithAsyncStatus(\n {\n entityId,\n query: {\n sql: `SELECT * FROM ${entityIdWithVersion} LIMIT 0`,\n },\n partMask: BUNDLE_MASK_LAST_UPDATED_ON,\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n },\n { enabled: !!(entity && isTable(entity)) },\n )\n\n const tableLastRebuilt = tableQueryResult?.responseBody?.lastUpdatedOn\n const friendlyName = entity\n ? entityTypeToFriendlyName(convertToEntityType(entity.concreteType))\n : ''\n\n const datasetCreatedByTooltipText =\n 'This is the user who created this Dataset. ' +\n 'This may not be the same person who generated the files in this Dataset, or who originally uploaded these files to Synapse.'\n\n const tableModifiedOnTooltipText = (\n <>\n <p>\n This is when the configuration of this {friendlyName} was last changed.\n </p>\n <p>Configuration changes may be triggered by (for example):</p>\n <ul>\n <li>Editing the name of the {friendlyName}</li>\n <li>Updating the schema used by the {friendlyName}</li>\n </ul>\n <p>\n This does NOT reflect changes to the data displayed in the the{' '}\n {friendlyName}.\n </p>\n </>\n )\n /*\n If the tooltip text is a string, MUI automatically applies it to aria-label which is more accessible and testable.\n Since this tooltip text is a ReactNode, let's manually create a short string to use for the aria-label.\n */\n const tableModifiedOnAccessibleLabel = `This is when the configuration of this ${friendlyName} was last changed.`\n\n const tableLastUpdatedTooltipText =\n `When data changes, the ${friendlyName} is rebuilt to reflect those changes. ` +\n `This is the last time changes were made to the data.`\n\n const createdByTooltipId = `${entityIdWithVersion}-createdByTooltip`\n const modifiedByTooltipId = `${entityIdWithVersion}-modifiedByTooltip`\n const lastUpdatedTooltipId = `${entityIdWithVersion}-lastUpdatedTooltip`\n\n const iconSx: SxProps = {\n width: '16px',\n height: '16px',\n ml: '4px',\n verticalAlign: 'text-bottom',\n }\n\n return (\n <Box\n sx={theme => ({\n bgcolor: 'grey.100',\n py: '10px',\n [theme.breakpoints.down('sm')]: {\n p: '24px 40px',\n },\n })}\n >\n <Breadcrumbs\n separator={<Separator />}\n sx={theme => ({\n '& .MuiBreadcrumbs-ol': {\n justifyContent: 'center',\n [theme.breakpoints.down('sm')]: {\n gap: '4px',\n },\n },\n })}\n >\n <ConditionalWrapper condition={!entity} wrapper={Skeleton}>\n <Typography\n sx={{ color: 'grey.700' }}\n variant={'breadcrumb1'}\n aria-describedby={createdByTooltipId}\n >\n {friendlyName} created by <UserBadge userId={entity?.createdBy} />{' '}\n on {formatDate(dayjs(entity?.createdOn))}\n {entity && isDataset(entity) && (\n <Tooltip\n id={createdByTooltipId}\n title={datasetCreatedByTooltipText}\n >\n <InfoTwoTone sx={iconSx} />\n </Tooltip>\n )}\n </Typography>\n </ConditionalWrapper>\n <ConditionalWrapper condition={!entity} wrapper={Skeleton}>\n <Typography\n sx={{ color: 'grey.700' }}\n variant={'breadcrumb1'}\n aria-describedby={modifiedByTooltipId}\n >\n {entity && isTable(entity) ? 'Configuration' : friendlyName} last\n modified by <UserBadge userId={entity?.modifiedBy} /> on{' '}\n {formatDate(dayjs(entity?.modifiedOn))}\n {entity && isTable(entity) && (\n <Tooltip\n id={modifiedByTooltipId}\n title={tableModifiedOnTooltipText}\n aria-label={tableModifiedOnAccessibleLabel}\n >\n <InfoTwoTone sx={iconSx} />\n </Tooltip>\n )}\n </Typography>\n </ConditionalWrapper>\n {tableLastRebuilt && (\n <Typography\n sx={{ color: 'grey.700' }}\n variant={'breadcrumb1'}\n aria-describedby={lastUpdatedTooltipId}\n >\n {friendlyName} last rebuilt on {formatDate(dayjs(tableLastRebuilt))}\n <Tooltip\n title={tableLastUpdatedTooltipText}\n id={lastUpdatedTooltipId}\n >\n <InfoTwoTone sx={iconSx} />\n </Tooltip>\n </Typography>\n )}\n </Breadcrumbs>\n </Box>\n )\n}\n\nexport default CreatedByModifiedBy\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EntityActionMenu.js","names":[],"sources":["../../../../../src/components/entity/page/action_menu/EntityActionMenu.tsx"],"sourcesContent":["import { SxProps } from '@mui/material'\nimport { ComplexMenu } from '../../../menu/ComplexMenu'\nimport IconSvg, { IconName } from '../../../IconSvg/IconSvg'\nimport { DropdownMenuItem, DropdownMenuProps } from '../../../menu/DropdownMenu'\nimport { IconSvgButtonProps } from '../../../IconSvgButton'\nimport { MouseEvent } from 'react'\n\n// Represents the two types of dropdown menus that will be displayed on the entity page\ntype EntityActionMenuDropdownMenuType = 'DOWNLOAD' | 'PRIMARY'\n\ntype EntityActionMenuDropdownMenuConfiguration = {\n visible: boolean\n tooltipText?: string\n disabled?: boolean\n}\n\nexport type ActionConfiguration = {\n visible: boolean\n text: string\n disabled?: boolean\n tooltipText?: string\n onClick?: (e: MouseEvent) => void\n href?: string\n}\n\nexport type ActionConfigurationMap = Record<string, ActionConfiguration>\n\nexport type MenuConfigurationMap = Record<\n EntityActionMenuDropdownMenuType,\n EntityActionMenuDropdownMenuConfiguration\n>\n\nexport type ActionViewProps = {\n action: string\n icon?: IconName\n textSx?: SxProps\n iconSx?: SxProps\n}\n\nexport type EntityActionMenuLayout = {\n buttonActions: ActionViewProps[]\n downloadMenuActions: ActionViewProps[][]\n primaryMenuActions: ActionViewProps[][]\n primaryMenuText: string\n primaryMenuEndIcon: IconName\n menuButtonSx?: SxProps\n}\n\nexport type EntityActionMenuProps = {\n /* Maps a unique action string to a dynamic configuration for that particular action */\n actionConfiguration: ActionConfigurationMap\n /* Maps each dropdown menu to a dynamic configuration for that particular menu */\n menuConfiguration: MenuConfigurationMap\n /* Defines the layout of the actions. Typically depends on just the entity type and area. */\n layout: EntityActionMenuLayout\n}\n\n/*\n * All visible actions should be specified in the layout, but this is not guaranteed at compile time.\n * Find all visible actions in the action configuration that are not in the layout.\n */\nfunction getUnmappedActions(\n actionConfiguration: ActionConfigurationMap,\n layout: EntityActionMenuLayout,\n): ActionConfigurationMap {\n return Object.fromEntries(\n Object.entries(actionConfiguration).filter(([action, config]) => {\n // We don't care about actions that are not configured or should not be visible\n if (!config || !config.visible) {\n return false\n }\n\n const allLayoutActions: ActionViewProps[] = [\n ...layout.buttonActions,\n ...layout.primaryMenuActions.flat(),\n ...layout.downloadMenuActions.flat(),\n ]\n // Action is unmapped if it's visible and the layout doesn't have it\n return !allLayoutActions.some(\n layoutAction => layoutAction.action === action,\n )\n }),\n )\n}\n\n/**\n * Given a group of dropdown menu items and an action configuration,\n * return a list of dropdown menu items with non-visible and non-configured actions removed.\n * @param group\n * @param actionConfiguration\n */\nfunction mapAndFilterItemsInMenuGroup(\n group: ActionViewProps[],\n actionConfiguration: ActionConfigurationMap,\n): DropdownMenuItem[] {\n return group.reduce(\n (itemAcc: DropdownMenuItem[], actionViewProps: ActionViewProps) => {\n const configForAction = actionConfiguration[actionViewProps.action]\n // Only show the item if it's configured + visible\n if (configForAction && configForAction.visible) {\n itemAcc.push({\n text: configForAction.text ?? actionViewProps.action,\n onClick: configForAction.onClick,\n href: configForAction.href,\n tooltipText: configForAction.tooltipText,\n disabled: configForAction.disabled,\n icon: actionViewProps.icon,\n textSx: actionViewProps.textSx,\n iconSx: actionViewProps.iconSx,\n })\n }\n return itemAcc\n },\n [],\n )\n}\n\n/**\n * Given a list of groups of dropdown menu actions, returns a list of dropdown menu item\n * groups where non-visible actions have been removed, and groups with no visible actions\n * have been removed.\n * @param menuActions\n * @param actionConfiguration\n */\nfunction mapAndFilterMenuGroups(\n menuActions: ActionViewProps[][],\n actionConfiguration: ActionConfigurationMap,\n): DropdownMenuItem[][] {\n return menuActions.reduce(\n (groupAcc: DropdownMenuItem[][], group: ActionViewProps[]) => {\n const itemGroup = mapAndFilterItemsInMenuGroup(group, actionConfiguration)\n // Only show the group if it contains visible items\n if (itemGroup.length > 0) {\n groupAcc.push(itemGroup)\n }\n return groupAcc\n },\n [],\n )\n}\n\n/**\n * The EntityActionMenu renders a menu that displays the actions that can be invoked on an Entity page.\n */\nexport default function EntityActionMenu(props: EntityActionMenuProps) {\n const { actionConfiguration, menuConfiguration, layout } = props\n\n /*\n * All actions should be specified in the layout, but this is not guaranteed at compile time.\n * Find all visible actions in the action configuration that are not in the layout.\n */\n const unmappedActions = getUnmappedActions(actionConfiguration, layout)\n // Warn if unmapped actions were found and push them on to the layout.\n if (Object.entries(unmappedActions).length > 0) {\n console.warn(\n 'Actions are visible but have not been configured in the layout:',\n Object.entries(unmappedActions).map(entry => entry[0]),\n )\n // Modify the layout: put the unmapped actions in their own group at the top of the menu\n layout.primaryMenuActions.unshift(\n Object.entries(unmappedActions).map(\n (entry): ActionViewProps => ({\n action: entry[0],\n }),\n ),\n )\n }\n\n // Map button actions to an IconButtonConfiguration and omit non-visible actions\n const iconButtonConfigs: IconSvgButtonProps[] = layout.buttonActions.reduce(\n (acc: IconSvgButtonProps[], buttonViewProps: ActionViewProps) => {\n const configForAction = actionConfiguration[buttonViewProps.action]\n if (configForAction && configForAction.visible) {\n let onClick = configForAction.onClick\n if (onClick == null && !configForAction.href) {\n console.warn(`No handler registered for ${buttonViewProps.action}`)\n onClick = () => {\n console.warn(`No handler registered for ${buttonViewProps.action}`)\n }\n }\n acc.push({\n icon: buttonViewProps.icon as IconName,\n onClick: onClick,\n tooltipText: configForAction.text,\n disabled: configForAction.disabled,\n href: configForAction.href,\n })\n }\n return acc\n },\n [],\n )\n\n const downloadMenuConfig: DropdownMenuProps = {\n dropdownButtonText: 'Download Options',\n convertSingleItemToButton: true,\n renderMenuIfNoItems: false,\n buttonTooltip: menuConfiguration.DOWNLOAD.tooltipText,\n buttonProps: {\n disabled: menuConfiguration.DOWNLOAD.disabled,\n endIcon: <IconSvg icon={'download'} wrap={false} />,\n },\n items: mapAndFilterMenuGroups(\n layout.downloadMenuActions,\n actionConfiguration,\n ),\n }\n\n const primaryMenuConfig: DropdownMenuProps = {\n dropdownButtonText: layout.primaryMenuText,\n convertSingleItemToButton: true,\n renderMenuIfNoItems: false,\n buttonProps: {\n endIcon: <IconSvg icon={layout.primaryMenuEndIcon} wrap={false} />,\n },\n items: mapAndFilterMenuGroups(\n layout.primaryMenuActions,\n actionConfiguration,\n ),\n }\n\n return (\n <ComplexMenu\n iconButtons={iconButtonConfigs}\n dropdownMenus={[downloadMenuConfig, primaryMenuConfig]}\n />\n )\n}\n\nexport const EXPORTED_FOR_UNIT_TESTING = {\n getUnmappedActions,\n mapAndFilterItemsInMenuGroup,\n mapAndFilterMenuGroups,\n}\n"],"mappings":";;;;AA6DA,SAAS,EACP,GACA,GACwB;AACxB,QAAO,OAAO,YACZ,OAAO,QAAQ,EAAoB,CAAC,QAAQ,CAAC,GAAQ,OAE/C,CAAC,KAAU,CAAC,EAAO,UACd,KASF,CANqC;EAC1C,GAAG,EAAO;EACV,GAAG,EAAO,mBAAmB,MAAM;EACnC,GAAG,EAAO,oBAAoB,MAAM;EACrC,CAEwB,MACvB,MAAgB,EAAa,WAAW,EACzC,CACD,CACH;;AASH,SAAS,EACP,GACA,GACoB;AACpB,QAAO,EAAM,QACV,GAA6B,MAAqC;EACjE,IAAM,IAAkB,EAAoB,EAAgB;AAc5D,SAZI,KAAmB,EAAgB,WACrC,EAAQ,KAAK;GACX,MAAM,EAAgB,QAAQ,EAAgB;GAC9C,SAAS,EAAgB;GACzB,MAAM,EAAgB;GACtB,aAAa,EAAgB;GAC7B,UAAU,EAAgB;GAC1B,MAAM,EAAgB;GACtB,QAAQ,EAAgB;GACxB,QAAQ,EAAgB;GACzB,CAAC,EAEG;IAET,EAAE,CACH;;AAUH,SAAS,EACP,GACA,GACsB;AACtB,QAAO,EAAY,QAChB,GAAgC,MAA6B;EAC5D,IAAM,IAAY,EAA6B,GAAO,EAAoB;AAK1E,SAHI,EAAU,SAAS,KACrB,EAAS,KAAK,EAAU,EAEnB;IAET,EAAE,CACH;;AAMH,SAAwB,EAAiB,GAA8B;CACrE,IAAM,EAAE,wBAAqB,sBAAmB,cAAW,GAMrD,IAAkB,EAAmB,GAAqB,EAAO;AAsEvE,QApEI,OAAO,QAAQ,EAAgB,CAAC,SAAS,MAC3C,QAAQ,KACN,mEACA,OAAO,QAAQ,EAAgB,CAAC,KAAI,MAAS,EAAM,GAAG,CACvD,EAED,EAAO,mBAAmB,QACxB,OAAO,QAAQ,EAAgB,CAAC,KAC7B,OAA4B,EAC3B,QAAQ,EAAM,IACf,EACF,CACF,GAyDD,kBAAC,GAAD;EACE,aAtD4C,EAAO,cAAc,QAClE,GAA2B,MAAqC;GAC/D,IAAM,IAAkB,EAAoB,EAAgB;AAC5D,OAAI,KAAmB,EAAgB,SAAS;IAC9C,IAAI,IAAU,EAAgB;AAO9B,IANI,KAAW,QAAQ,CAAC,EAAgB,SACtC,QAAQ,KAAK,6BAA6B,EAAgB,SAAS,EACnE,UAAgB;AACd,aAAQ,KAAK,6BAA6B,EAAgB,SAAS;QAGvE,EAAI,KAAK;KACP,MAAM,EAAgB;KACb;KACT,aAAa,EAAgB;KAC7B,UAAU,EAAgB;KAC1B,MAAM,EAAgB;KACvB,CAAC;;AAEJ,UAAO;KAET,EAAE,CACH;EAiCG,eAAe,CA/B2B;GAC5C,oBAAoB;GACpB,2BAA2B;GAC3B,qBAAqB;GACrB,eAAe,EAAkB,SAAS;GAC1C,aAAa;IACX,UAAU,EAAkB,SAAS;IACrC,SAAS,kBAAC,GAAD;KAAS,MAAM;KAAY,MAAM;KAAS,CAAA;IACpD;GACD,OAAO,EACL,EAAO,qBACP,EACD;GACF,EAE4C;GAC3C,oBAAoB,EAAO;GAC3B,2BAA2B;GAC3B,qBAAqB;GACrB,aAAa,EACX,SAAS,kBAAC,GAAD;IAAS,MAAM,EAAO;IAAoB,MAAM;IAAS,CAAA,EACnE;GACD,OAAO,EACL,EAAO,oBACP,EACD;GACF,CAKyD;EACtD,CAAA;;AAIN,IAAa,IAA4B;CACvC;CACA;CACA;CACD"}
1
+ {"version":3,"file":"EntityActionMenu.js","names":[],"sources":["../../../../../src/components/entity/page/action_menu/EntityActionMenu.tsx"],"sourcesContent":["import { SxProps } from '@mui/material'\nimport { ComplexMenu } from '../../../menu/ComplexMenu'\nimport IconSvg, { IconName } from '../../../IconSvg/IconSvg'\nimport { DropdownMenuItem, DropdownMenuProps } from '../../../menu/DropdownMenu'\nimport { IconSvgButtonProps } from '../../../IconSvgButton'\nimport { MouseEvent } from 'react'\n\n// Represents the two types of dropdown menus that will be displayed on the entity page\ntype EntityActionMenuDropdownMenuType = 'DOWNLOAD' | 'PRIMARY'\n\ntype EntityActionMenuDropdownMenuConfiguration = {\n visible: boolean\n tooltipText?: string\n disabled?: boolean\n}\n\nexport type ActionConfiguration = {\n visible: boolean\n text: string\n disabled?: boolean\n tooltipText?: string\n onClick?: (e: MouseEvent) => void\n href?: string\n}\n\nexport type ActionConfigurationMap = Record<string, ActionConfiguration>\n\nexport type MenuConfigurationMap = Record<\n EntityActionMenuDropdownMenuType,\n EntityActionMenuDropdownMenuConfiguration\n>\n\nexport type ActionViewProps = {\n action: string\n icon?: IconName\n textSx?: SxProps\n iconSx?: SxProps\n}\n\nexport type EntityActionMenuLayout = {\n buttonActions: ActionViewProps[]\n downloadMenuActions: ActionViewProps[][]\n primaryMenuActions: ActionViewProps[][]\n primaryMenuText: string\n primaryMenuEndIcon: IconName\n menuButtonSx?: SxProps\n}\n\nexport type EntityActionMenuProps = {\n /* Maps a unique action string to a dynamic configuration for that particular action */\n actionConfiguration: ActionConfigurationMap\n /* Maps each dropdown menu to a dynamic configuration for that particular menu */\n menuConfiguration: MenuConfigurationMap\n /* Defines the layout of the actions. Typically depends on just the entity type and area. */\n layout: EntityActionMenuLayout\n}\n\n/*\n * All visible actions should be specified in the layout, but this is not guaranteed at compile time.\n * Find all visible actions in the action configuration that are not in the layout.\n */\nfunction getUnmappedActions(\n actionConfiguration: ActionConfigurationMap,\n layout: EntityActionMenuLayout,\n): ActionConfigurationMap {\n return Object.fromEntries(\n Object.entries(actionConfiguration).filter(([action, config]) => {\n // We don't care about actions that are not configured or should not be visible\n if (!config || !config.visible) {\n return false\n }\n\n const allLayoutActions: ActionViewProps[] = [\n ...layout.buttonActions,\n ...layout.primaryMenuActions.flat(),\n ...layout.downloadMenuActions.flat(),\n ]\n // Action is unmapped if it's visible and the layout doesn't have it\n return !allLayoutActions.some(\n layoutAction => layoutAction.action === action,\n )\n }),\n )\n}\n\n/**\n * Given a group of dropdown menu items and an action configuration,\n * return a list of dropdown menu items with non-visible and non-configured actions removed.\n * @param group\n * @param actionConfiguration\n */\nfunction mapAndFilterItemsInMenuGroup(\n group: ActionViewProps[],\n actionConfiguration: ActionConfigurationMap,\n): DropdownMenuItem[] {\n return group.reduce(\n (itemAcc: DropdownMenuItem[], actionViewProps: ActionViewProps) => {\n const configForAction = actionConfiguration[actionViewProps.action]\n // Only show the item if it's configured + visible\n if (configForAction && configForAction.visible) {\n itemAcc.push({\n text: configForAction.text ?? actionViewProps.action,\n onClick: configForAction.onClick,\n href: configForAction.href,\n tooltipText: configForAction.tooltipText,\n disabled: configForAction.disabled,\n icon: actionViewProps.icon,\n textSx: actionViewProps.textSx,\n iconSx: actionViewProps.iconSx,\n })\n }\n return itemAcc\n },\n [],\n )\n}\n\n/**\n * Given a list of groups of dropdown menu actions, returns a list of dropdown menu item\n * groups where non-visible actions have been removed, and groups with no visible actions\n * have been removed.\n * @param menuActions\n * @param actionConfiguration\n */\nfunction mapAndFilterMenuGroups(\n menuActions: ActionViewProps[][],\n actionConfiguration: ActionConfigurationMap,\n): DropdownMenuItem[][] {\n return menuActions.reduce(\n (groupAcc: DropdownMenuItem[][], group: ActionViewProps[]) => {\n const itemGroup = mapAndFilterItemsInMenuGroup(group, actionConfiguration)\n // Only show the group if it contains visible items\n if (itemGroup.length > 0) {\n groupAcc.push(itemGroup)\n }\n return groupAcc\n },\n [],\n )\n}\n\n/**\n * The EntityActionMenu renders a menu that displays the actions that can be invoked on an Entity page.\n */\nexport default function EntityActionMenu(props: EntityActionMenuProps) {\n const { actionConfiguration, menuConfiguration, layout } = props\n\n /*\n * All actions should be specified in the layout, but this is not guaranteed at compile time.\n * Find all visible actions in the action configuration that are not in the layout.\n */\n const unmappedActions = getUnmappedActions(actionConfiguration, layout)\n // Warn if unmapped actions were found and push them on to the layout.\n if (Object.entries(unmappedActions).length > 0) {\n console.warn(\n 'Actions are visible but have not been configured in the layout:',\n Object.entries(unmappedActions).map(entry => entry[0]),\n )\n // Modify the layout: put the unmapped actions in their own group at the top of the menu\n layout.primaryMenuActions.unshift(\n Object.entries(unmappedActions).map(\n (entry): ActionViewProps => ({\n action: entry[0],\n }),\n ),\n )\n }\n\n // Map button actions to an IconButtonConfiguration and omit non-visible actions\n const iconButtonConfigs: IconSvgButtonProps[] = layout.buttonActions.reduce(\n (acc: IconSvgButtonProps[], buttonViewProps: ActionViewProps) => {\n const configForAction = actionConfiguration[buttonViewProps.action]\n if (configForAction && configForAction.visible) {\n let onClick = configForAction.onClick\n if (onClick == null && !configForAction.href) {\n console.warn(`No handler registered for ${buttonViewProps.action}`)\n onClick = () => {\n console.warn(`No handler registered for ${buttonViewProps.action}`)\n }\n }\n acc.push({\n icon: buttonViewProps.icon as IconName,\n onClick: onClick,\n tooltipText: configForAction.text,\n disabled: configForAction.disabled,\n href: configForAction.href,\n })\n }\n return acc\n },\n [],\n )\n\n const downloadMenuConfig: DropdownMenuProps = {\n dropdownButtonText: 'Download Options',\n convertSingleItemToButton: true,\n renderMenuIfNoItems: false,\n buttonTooltip: menuConfiguration.DOWNLOAD.tooltipText,\n buttonProps: {\n disabled: menuConfiguration.DOWNLOAD.disabled,\n endIcon: <IconSvg icon={'download'} wrap={false} />,\n },\n items: mapAndFilterMenuGroups(\n layout.downloadMenuActions,\n actionConfiguration,\n ),\n }\n\n const primaryMenuConfig: DropdownMenuProps = {\n dropdownButtonText: layout.primaryMenuText,\n convertSingleItemToButton: true,\n renderMenuIfNoItems: false,\n buttonProps: {\n endIcon: <IconSvg icon={layout.primaryMenuEndIcon} wrap={false} />,\n },\n items: mapAndFilterMenuGroups(\n layout.primaryMenuActions,\n actionConfiguration,\n ),\n }\n\n return (\n <ComplexMenu\n iconButtons={iconButtonConfigs}\n dropdownMenus={[downloadMenuConfig, primaryMenuConfig]}\n />\n )\n}\n\nexport const EXPORTED_FOR_UNIT_TESTING = {\n getUnmappedActions,\n mapAndFilterItemsInMenuGroup,\n mapAndFilterMenuGroups,\n}\n"],"mappings":";;;;AA6DA,SAAS,EACP,GACA,GACwB;AACxB,QAAO,OAAO,YACZ,OAAO,QAAQ,EAAoB,CAAC,QAAQ,CAAC,GAAQ,OAE/C,CAAC,KAAU,CAAC,EAAO,UACd,KASF,CAAC;EALN,GAAG,EAAO;EACV,GAAG,EAAO,mBAAmB,MAAM;EACnC,GAAG,EAAO,oBAAoB,MAAM;EAG9B,CAAiB,MACvB,MAAgB,EAAa,WAAW,EACzC,CACD,CACH;;AASH,SAAS,EACP,GACA,GACoB;AACpB,QAAO,EAAM,QACV,GAA6B,MAAqC;EACjE,IAAM,IAAkB,EAAoB,EAAgB;AAc5D,SAZI,KAAmB,EAAgB,WACrC,EAAQ,KAAK;GACX,MAAM,EAAgB,QAAQ,EAAgB;GAC9C,SAAS,EAAgB;GACzB,MAAM,EAAgB;GACtB,aAAa,EAAgB;GAC7B,UAAU,EAAgB;GAC1B,MAAM,EAAgB;GACtB,QAAQ,EAAgB;GACxB,QAAQ,EAAgB;GACzB,CAAC,EAEG;IAET,EAAE,CACH;;AAUH,SAAS,EACP,GACA,GACsB;AACtB,QAAO,EAAY,QAChB,GAAgC,MAA6B;EAC5D,IAAM,IAAY,EAA6B,GAAO,EAAoB;AAK1E,SAHI,EAAU,SAAS,KACrB,EAAS,KAAK,EAAU,EAEnB;IAET,EAAE,CACH;;AAMH,SAAwB,EAAiB,GAA8B;CACrE,IAAM,EAAE,wBAAqB,sBAAmB,cAAW,GAMrD,IAAkB,EAAmB,GAAqB,EAAO;AAsEvE,QApEI,OAAO,QAAQ,EAAgB,CAAC,SAAS,MAC3C,QAAQ,KACN,mEACA,OAAO,QAAQ,EAAgB,CAAC,KAAI,MAAS,EAAM,GAAG,CACvD,EAED,EAAO,mBAAmB,QACxB,OAAO,QAAQ,EAAgB,CAAC,KAC7B,OAA4B,EAC3B,QAAQ,EAAM,IACf,EACF,CACF,GAyDD,kBAAC,GAAD;EACE,aAtD4C,EAAO,cAAc,QAClE,GAA2B,MAAqC;GAC/D,IAAM,IAAkB,EAAoB,EAAgB;AAC5D,OAAI,KAAmB,EAAgB,SAAS;IAC9C,IAAI,IAAU,EAAgB;AAO9B,IANI,KAAW,QAAQ,CAAC,EAAgB,SACtC,QAAQ,KAAK,6BAA6B,EAAgB,SAAS,EACnE,UAAgB;AACd,aAAQ,KAAK,6BAA6B,EAAgB,SAAS;QAGvE,EAAI,KAAK;KACP,MAAM,EAAgB;KACb;KACT,aAAa,EAAgB;KAC7B,UAAU,EAAgB;KAC1B,MAAM,EAAgB;KACvB,CAAC;;AAEJ,UAAO;KAET,EAAE,CAiCa;EACb,eAAe,CAAC;GA9BlB,oBAAoB;GACpB,2BAA2B;GAC3B,qBAAqB;GACrB,eAAe,EAAkB,SAAS;GAC1C,aAAa;IACX,UAAU,EAAkB,SAAS;IACrC,SAAS,kBAAC,GAAD;KAAS,MAAM;KAAY,MAAM;KAAS,CAAA;IACpD;GACD,OAAO,EACL,EAAO,qBACP,EACD;GAmBiB,EAAoB;GAftC,oBAAoB,EAAO;GAC3B,2BAA2B;GAC3B,qBAAqB;GACrB,aAAa,EACX,SAAS,kBAAC,GAAD;IAAS,MAAM,EAAO;IAAoB,MAAM;IAAS,CAAA,EACnE;GACD,OAAO,EACL,EAAO,oBACP,EACD;GAMqC,CAAkB;EACtD,CAAA;;AAIN,IAAa,IAA4B;CACvC;CACA;CACA;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"useDataCiteUsage.js","names":[],"sources":["../../../../../src/components/entity/page/title_bar/useDataCiteUsage.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { skipToken, useQuery, UseQueryOptions } from '@tanstack/react-query'\n\ntype RestUsage = {\n citationCount: number\n citations: CitingWork[]\n}\n\nexport type CitingWork = {\n id: string // DOI in bare form (e.g., 10.1234/abcd)\n doi: string\n title?: string\n publisher?: string\n publicationYear?: number\n containerTitle?: string\n}\n\nexport const maxCitationCount = 500\n\nexport const getDataCiteUsageQueryKey = (doi?: string) =>\n ['datacite-usage', doi] as const\n\nfunction toBareDoi(idOrUrl: string): string {\n return idOrUrl.replace(/^https?:\\/\\/(dx\\.)?doi\\.org\\//i, '')\n}\n\nasync function fetchCitationsViaGraphQL(signal: AbortSignal, doi: string) {\n const body = JSON.stringify({\n query: `\n query($id: ID!) {\n work(id: $id) {\n citations(first: ${maxCitationCount}) {\n nodes {\n id\n titles { title }\n publisher { name }\n publicationYear\n \n # publication (container) info\n container {\n title\n }\n }\n }\n }\n }\n `,\n variables: { id: `https://doi.org/${doi}` },\n })\n\n const r = await fetch('https://api.datacite.org/graphql', {\n method: 'POST',\n signal,\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body,\n })\n if (!r.ok) throw new Error(`DataCite GraphQL ${r.status}`)\n const json = await r.json()\n const nodes = json?.data?.work?.citations?.nodes ?? []\n return nodes.map((n: any) => {\n const bare = toBareDoi(n?.id ?? '')\n const title =\n Array.isArray(n?.titles) && n.titles.length\n ? n.titles[0]?.title.replaceAll('?', '') // many extended characters are returned as '?'s from DataCite\n : // for example, see https://commons.datacite.org/doi.org/10.1101%2F205807\n undefined\n const publisher = n?.publisher?.name ?? undefined\n const publicationYear = n?.publicationYear ?? undefined\n const containerTitle = n?.container?.title ?? undefined\n\n return {\n id: bare,\n doi: bare,\n title,\n publisher,\n publicationYear,\n containerTitle,\n } as CitingWork\n })\n}\n\nasync function fetchDataCiteUsage(\n signal: AbortSignal,\n doi: string,\n): Promise<RestUsage> {\n const citations: CitingWork[] = await fetchCitationsViaGraphQL(signal, doi)\n if (!citations) {\n throw new Error('No citations found')\n }\n return {\n citationCount: citations.length ?? 0,\n citations,\n }\n}\n\nexport function useDataCiteUsage(\n doi?: string,\n options?: Omit<UseQueryOptions<RestUsage, Error>, 'queryKey' | 'queryFn'>,\n) {\n const key = useMemo(() => getDataCiteUsageQueryKey(doi), [doi])\n return useQuery({\n ...options,\n queryKey: key,\n queryFn: doi\n ? ({ signal }) => {\n return fetchDataCiteUsage(signal, doi)\n }\n : skipToken,\n })\n}\n"],"mappings":";;;AAiBA,IAAa,IAAmB,KAEnB,KAA4B,MACvC,CAAC,kBAAkB,EAAI;AAEzB,SAAS,EAAU,GAAyB;AAC1C,QAAO,EAAQ,QAAQ,kCAAkC,GAAG;;AAG9D,eAAe,EAAyB,GAAqB,GAAa;CACxE,IAAM,IAAO,KAAK,UAAU;EAC1B,OAAO;EAmBP,WAAW,EAAE,IAAI,mBAAmB,KAAO;EAC5C,CAAC,EAEI,IAAI,MAAM,MAAM,oCAAoC;EACxD,QAAQ;EACR;EACA,SAAS;GAAE,gBAAgB;GAAoB,QAAQ;GAAoB;EAC3E;EACD,CAAC;AACF,KAAI,CAAC,EAAE,GAAI,OAAU,MAAM,oBAAoB,EAAE,SAAS;AAG1D,UAFa,MAAM,EAAE,MAAM,GACP,MAAM,MAAM,WAAW,SAAS,EAAE,EACzC,KAAK,MAAW;EAC3B,IAAM,IAAO,EAAU,GAAG,MAAM,GAAG;AAUnC,SAAO;GACL,IAAI;GACJ,KAAK;GACL,OAXA,MAAM,QAAQ,GAAG,OAAO,IAAI,EAAE,OAAO,SACjC,EAAE,OAAO,IAAI,MAAM,WAAW,KAAK,GAAG,GAEtC,KAAA;GASJ,WARgB,GAAG,WAAW,QAAQ,KAAA;GAStC,iBARsB,GAAG,mBAAmB,KAAA;GAS5C,gBARqB,GAAG,WAAW,SAAS,KAAA;GAS7C;GACD;;AAGJ,eAAe,EACb,GACA,GACoB;CACpB,IAAM,IAA0B,MAAM,EAAyB,GAAQ,EAAI;AAC3E,KAAI,CAAC,EACH,OAAU,MAAM,qBAAqB;AAEvC,QAAO;EACL,eAAe,EAAU,UAAU;EACnC;EACD;;AAGH,SAAgB,EACd,GACA,GACA;CACA,IAAM,IAAM,QAAc,EAAyB,EAAI,EAAE,CAAC,EAAI,CAAC;AAC/D,QAAO,EAAS;EACd,GAAG;EACH,UAAU;EACV,SAAS,KACJ,EAAE,gBACM,EAAmB,GAAQ,EAAI,GAExC;EACL,CAAC"}
1
+ {"version":3,"file":"useDataCiteUsage.js","names":[],"sources":["../../../../../src/components/entity/page/title_bar/useDataCiteUsage.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { skipToken, useQuery, UseQueryOptions } from '@tanstack/react-query'\n\ntype RestUsage = {\n citationCount: number\n citations: CitingWork[]\n}\n\nexport type CitingWork = {\n id: string // DOI in bare form (e.g., 10.1234/abcd)\n doi: string\n title?: string\n publisher?: string\n publicationYear?: number\n containerTitle?: string\n}\n\nexport const maxCitationCount = 500\n\nexport const getDataCiteUsageQueryKey = (doi?: string) =>\n ['datacite-usage', doi] as const\n\nfunction toBareDoi(idOrUrl: string): string {\n return idOrUrl.replace(/^https?:\\/\\/(dx\\.)?doi\\.org\\//i, '')\n}\n\nasync function fetchCitationsViaGraphQL(signal: AbortSignal, doi: string) {\n const body = JSON.stringify({\n query: `\n query($id: ID!) {\n work(id: $id) {\n citations(first: ${maxCitationCount}) {\n nodes {\n id\n titles { title }\n publisher { name }\n publicationYear\n \n # publication (container) info\n container {\n title\n }\n }\n }\n }\n }\n `,\n variables: { id: `https://doi.org/${doi}` },\n })\n\n const r = await fetch('https://api.datacite.org/graphql', {\n method: 'POST',\n signal,\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body,\n })\n if (!r.ok) throw new Error(`DataCite GraphQL ${r.status}`)\n const json = await r.json()\n const nodes = json?.data?.work?.citations?.nodes ?? []\n return nodes.map((n: any) => {\n const bare = toBareDoi(n?.id ?? '')\n const title =\n Array.isArray(n?.titles) && n.titles.length\n ? n.titles[0]?.title.replaceAll('?', '') // many extended characters are returned as '?'s from DataCite\n : // for example, see https://commons.datacite.org/doi.org/10.1101%2F205807\n undefined\n const publisher = n?.publisher?.name ?? undefined\n const publicationYear = n?.publicationYear ?? undefined\n const containerTitle = n?.container?.title ?? undefined\n\n return {\n id: bare,\n doi: bare,\n title,\n publisher,\n publicationYear,\n containerTitle,\n } as CitingWork\n })\n}\n\nasync function fetchDataCiteUsage(\n signal: AbortSignal,\n doi: string,\n): Promise<RestUsage> {\n const citations: CitingWork[] = await fetchCitationsViaGraphQL(signal, doi)\n if (!citations) {\n throw new Error('No citations found')\n }\n return {\n citationCount: citations.length ?? 0,\n citations,\n }\n}\n\nexport function useDataCiteUsage(\n doi?: string,\n options?: Omit<UseQueryOptions<RestUsage, Error>, 'queryKey' | 'queryFn'>,\n) {\n const key = useMemo(() => getDataCiteUsageQueryKey(doi), [doi])\n return useQuery({\n ...options,\n queryKey: key,\n queryFn: doi\n ? ({ signal }) => {\n return fetchDataCiteUsage(signal, doi)\n }\n : skipToken,\n })\n}\n"],"mappings":";;;AAiBA,IAAa,IAAmB,KAEnB,KAA4B,MACvC,CAAC,kBAAkB,EAAI;AAEzB,SAAS,EAAU,GAAyB;AAC1C,QAAO,EAAQ,QAAQ,kCAAkC,GAAG;;AAG9D,eAAe,EAAyB,GAAqB,GAAa;CACxE,IAAM,IAAO,KAAK,UAAU;EAC1B,OAAO;EAmBP,WAAW,EAAE,IAAI,mBAAmB,KAAO;EAC5C,CAAC,EAEI,IAAI,MAAM,MAAM,oCAAoC;EACxD,QAAQ;EACR;EACA,SAAS;GAAE,gBAAgB;GAAoB,QAAQ;GAAoB;EAC3E;EACD,CAAC;AACF,KAAI,CAAC,EAAE,GAAI,OAAU,MAAM,oBAAoB,EAAE,SAAS;AAG1D,UADc,MADK,EAAE,MAAM,GACP,MAAM,MAAM,WAAW,SAAS,EAAE,EACzC,KAAK,MAAW;EAC3B,IAAM,IAAO,EAAU,GAAG,MAAM,GAAG;AAUnC,SAAO;GACL,IAAI;GACJ,KAAK;GACL,OAXA,MAAM,QAAQ,GAAG,OAAO,IAAI,EAAE,OAAO,SACjC,EAAE,OAAO,IAAI,MAAM,WAAW,KAAK,GAAG,GAEtC,KAAA;GASJ,WARgB,GAAG,WAAW,QAAQ,KAAA;GAStC,iBARsB,GAAG,mBAAmB,KAAA;GAS5C,gBARqB,GAAG,WAAW,SAAS,KAAA;GAS7C;GACD;;AAGJ,eAAe,EACb,GACA,GACoB;CACpB,IAAM,IAA0B,MAAM,EAAyB,GAAQ,EAAI;AAC3E,KAAI,CAAC,EACH,OAAU,MAAM,qBAAqB;AAEvC,QAAO;EACL,eAAe,EAAU,UAAU;EACnC;EACD;;AAGH,SAAgB,EACd,GACA,GACA;CACA,IAAM,IAAM,QAAc,EAAyB,EAAI,EAAE,CAAC,EAAI,CAAC;AAC/D,QAAO,EAAS;EACd,GAAG;EACH,UAAU;EACV,SAAS,KACJ,EAAE,gBACM,EAAmB,GAAQ,EAAI,GAExC;EACL,CAAC"}