synapse-react-client 4.0.9 → 4.0.10

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 (543) 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/TasksIcon.d.ts.map +1 -1
  8. package/dist/assets/icons/TasksIcon.js +6 -10
  9. package/dist/assets/icons/TasksIcon.js.map +1 -1
  10. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.d.ts.map +1 -1
  11. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.js +69 -63
  12. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.js.map +1 -1
  13. package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js.map +1 -1
  14. package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
  15. package/dist/components/AccessRequirementList/AccessRequirementListUtils.js.map +1 -1
  16. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsEditor.js.map +1 -1
  17. package/dist/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.js.map +1 -1
  18. package/dist/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.js.map +1 -1
  19. package/dist/components/AccessTokenPage/AccessTokenCard/AccessTokenCard.js.map +1 -1
  20. package/dist/components/AcknowledgementsPage/StudyAcknowledgements.js.map +1 -1
  21. package/dist/components/AclEditor/PermissionLevelMenu.js.map +1 -1
  22. package/dist/components/AclEditor/ResourceAccessAndUserGroupHeader.js.map +1 -1
  23. package/dist/components/AclEditor/useSortResourceAccessList.js.map +1 -1
  24. package/dist/components/AclEditor/useUpdateAcl.js.map +1 -1
  25. package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
  26. package/dist/components/Authentication/AuthenticationMethodSelection.d.ts.map +1 -1
  27. package/dist/components/Authentication/AuthenticationMethodSelection.js +38 -37
  28. package/dist/components/Authentication/AuthenticationMethodSelection.js.map +1 -1
  29. package/dist/components/Authentication/Constants.d.ts +1 -0
  30. package/dist/components/Authentication/Constants.d.ts.map +1 -1
  31. package/dist/components/Authentication/Constants.js +2 -2
  32. package/dist/components/Authentication/Constants.js.map +1 -1
  33. package/dist/components/Authentication/LastLoginInfo.js.map +1 -1
  34. package/dist/components/Authentication/RecoveryCodeForm.js.map +1 -1
  35. package/dist/components/Authentication/RecoveryCodeGrid.js.map +1 -1
  36. package/dist/components/Authentication/RegenerateBackupCodesWarning.js.map +1 -1
  37. package/dist/components/Authentication/Reset2FAWarning.js.map +1 -1
  38. package/dist/components/Authentication/StandaloneLoginForm.js +1 -1
  39. package/dist/components/Authentication/TwoFactorBackupCodes.js.map +1 -1
  40. package/dist/components/Authentication/TwoFactorEnrollmentForm.d.ts.map +1 -1
  41. package/dist/components/Authentication/TwoFactorEnrollmentForm.js +2 -1
  42. package/dist/components/Authentication/TwoFactorEnrollmentForm.js.map +1 -1
  43. package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.js.map +1 -1
  44. package/dist/components/CardContainer/CardContainer.js.map +1 -1
  45. package/dist/components/CardDeck/CardDeck.Mobile.js.map +1 -1
  46. package/dist/components/CardDeck/TableQueryCardDeck.js.map +1 -1
  47. package/dist/components/CertificationQuiz/CertificationQuiz.js.map +1 -1
  48. package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js.map +1 -1
  49. package/dist/components/ChallengeSubmission/ChallengeSubmission.js.map +1 -1
  50. package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js.map +1 -1
  51. package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js.map +1 -1
  52. package/dist/components/ChallengeSubmission/EvaluationQueueList.js.map +1 -1
  53. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
  54. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js.map +1 -1
  55. package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js.map +1 -1
  56. package/dist/components/ChangePassword/ChangePassword.js.map +1 -1
  57. package/dist/components/ChangePassword/ChangePasswordWithToken.js.map +1 -1
  58. package/dist/components/ChangePassword/useChangePasswordFormState.js +1 -1
  59. package/dist/components/ChangePassword/useChangePasswordFormState.js.map +1 -1
  60. package/dist/components/CitationPopover/CitationPopoverContent.js.map +1 -1
  61. package/dist/components/ColumnFilter/ColumnFilter.js.map +1 -1
  62. package/dist/components/ComponentCollapse.js.map +1 -1
  63. package/dist/components/CookiesNotification/CookiesNotification.js.map +1 -1
  64. package/dist/components/CreateProjectModal/CreateProjectModal.js.map +1 -1
  65. package/dist/components/CreateTableViewWizard/CreateTableViewWizardUtils.js.map +1 -1
  66. package/dist/components/DataGrid/DataGrid.d.ts +0 -1
  67. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
  68. package/dist/components/DataGrid/DataGrid.js +72 -72
  69. package/dist/components/DataGrid/DataGrid.js.map +1 -1
  70. package/dist/components/DataGrid/DataGridWebSocket.d.ts +4 -0
  71. package/dist/components/DataGrid/DataGridWebSocket.d.ts.map +1 -1
  72. package/dist/components/DataGrid/DataGridWebSocket.js +9 -8
  73. package/dist/components/DataGrid/DataGridWebSocket.js.map +1 -1
  74. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  75. package/dist/components/DataGrid/SynapseGrid.js +326 -268
  76. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  77. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts +2 -0
  78. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts.map +1 -1
  79. package/dist/components/DataGrid/columns/AutocompleteColumn.js +113 -67
  80. package/dist/components/DataGrid/columns/AutocompleteColumn.js.map +1 -1
  81. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts +2 -1
  82. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts.map +1 -1
  83. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js +126 -122
  84. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js.map +1 -1
  85. package/dist/components/DataGrid/columns/useGridAutocompleteState.d.ts +58 -0
  86. package/dist/components/DataGrid/columns/useGridAutocompleteState.d.ts.map +1 -0
  87. package/dist/components/DataGrid/columns/useGridAutocompleteState.js +52 -0
  88. package/dist/components/DataGrid/columns/useGridAutocompleteState.js.map +1 -0
  89. package/dist/components/DataGrid/components/ValidationAlert.d.ts +5 -2
  90. package/dist/components/DataGrid/components/ValidationAlert.d.ts.map +1 -1
  91. package/dist/components/DataGrid/components/ValidationAlert.js +429 -24
  92. package/dist/components/DataGrid/components/ValidationAlert.js.map +1 -1
  93. package/dist/components/DataGrid/hooks/useColumnResizeHandles.js.map +1 -1
  94. package/dist/components/DataGrid/hooks/useGetSchemaForGrid.js.map +1 -1
  95. package/dist/components/DataGrid/hooks/useGridUndoRedo.js.map +1 -1
  96. package/dist/components/DataGrid/hooks/useStack.js.map +1 -1
  97. package/dist/components/DataGrid/useCRDTModelView.js.map +1 -1
  98. package/dist/components/DataGrid/useDataGridWebsocket.d.ts +7 -0
  99. package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
  100. package/dist/components/DataGrid/useDataGridWebsocket.js +16 -2
  101. package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
  102. package/dist/components/DataGrid/useInitializeGridConnection.js.map +1 -1
  103. package/dist/components/DataGrid/useMergeGridWithRecordSet.js.map +1 -1
  104. package/dist/components/DataGrid/useMergeGridWithSource.js.map +1 -1
  105. package/dist/components/DataGrid/useMergeGridWithTable.js.map +1 -1
  106. package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
  107. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  108. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  109. package/dist/components/DataGrid/utils/computeReplicaSelectionModel.js.map +1 -1
  110. package/dist/components/DataGrid/utils/extractColumnValidationMessages.js.map +1 -1
  111. package/dist/components/DataGrid/utils/getCellClassName.d.ts.map +1 -1
  112. package/dist/components/DataGrid/utils/getCellClassName.js +8 -8
  113. package/dist/components/DataGrid/utils/getCellClassName.js.map +1 -1
  114. package/dist/components/DataGrid/utils/json-rx/JsonRx.js.map +1 -1
  115. package/dist/components/DataGrid/utils/modelRowsToGrid.js.map +1 -1
  116. package/dist/components/DataGrid/utils/parseFreeTextUsingJsonSchemaType.js.map +1 -1
  117. package/dist/components/DataGrid/utils/splitPatch.js.map +1 -1
  118. package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
  119. package/dist/components/DirectDownload/DirectDownload.js.map +1 -1
  120. package/dist/components/DirectDownloadButton.js.map +1 -1
  121. package/dist/components/DownloadCart/CreatePackageV2.js.map +1 -1
  122. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
  123. package/dist/components/DownloadCart/DownloadListActionsRequired.js.map +1 -1
  124. package/dist/components/DownloadCart/DownloadListTable.js.map +1 -1
  125. package/dist/components/DownloadCart/fileNameUtils.js.map +1 -1
  126. package/dist/components/DraggableDialog/DraggableDialog.js.map +1 -1
  127. package/dist/components/DynamicForm/DynamicFormModal.js.map +1 -1
  128. package/dist/components/Ecosystem/TableQueryEcosystem.js.map +1 -1
  129. package/dist/components/EntityAclEditor/EntityAclEditor.d.ts.map +1 -1
  130. package/dist/components/EntityAclEditor/EntityAclEditor.js +103 -103
  131. package/dist/components/EntityAclEditor/EntityAclEditor.js.map +1 -1
  132. package/dist/components/EntityAclEditor/useNotifyNewACLUsers.js.map +1 -1
  133. package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js.map +1 -1
  134. package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
  135. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  136. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.d.ts.map +1 -1
  137. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js +36 -30
  138. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js.map +1 -1
  139. package/dist/components/EntityFinder/EntityFinder.js.map +1 -1
  140. package/dist/components/EntityFinder/VersionSelectionType.js.map +1 -1
  141. package/dist/components/EntityFinder/details/configurations/EntityChildrenDetails.js.map +1 -1
  142. package/dist/components/EntityFinder/details/configurations/FavoritesDetails.js.map +1 -1
  143. package/dist/components/EntityFinder/details/configurations/ProjectListDetails.js.map +1 -1
  144. package/dist/components/EntityFinder/details/view/DetailsView.js.map +1 -1
  145. package/dist/components/EntityFinder/tree/EntityTree.js.map +1 -1
  146. package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
  147. package/dist/components/EntityFinder/useEntitySelection.js.map +1 -1
  148. package/dist/components/EntityForm/EntityForm.js.map +1 -1
  149. package/dist/components/EntityHeaderTable/EntityHeaderTable.js.map +1 -1
  150. package/dist/components/EntityHeaderTable/Filter.js.map +1 -1
  151. package/dist/components/EntityHeaderTable/useEntityHeaderTableState.js.map +1 -1
  152. package/dist/components/EntitySubjectsSelector/EntitySubjectsSelector.js.map +1 -1
  153. package/dist/components/EntityTreeTable/components/IdColumnHeader.js.map +1 -1
  154. package/dist/components/EntityTreeTable/hooks/useEntityTreeState.js.map +1 -1
  155. package/dist/components/EntityTreeTable/hooks/useTableColumns.js.map +1 -1
  156. package/dist/components/EntityTreeTable/hooks/useTableData.js.map +1 -1
  157. package/dist/components/EntityTreeTable/hooks/useTreeOperationsWithDirectFetch.js.map +1 -1
  158. package/dist/components/EntityUpload/EntityUpload.js.map +1 -1
  159. package/dist/components/ExperimentalMode/ExperimentalMode.js.map +1 -1
  160. package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js.map +1 -1
  161. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
  162. package/dist/components/FeaturedDataTabs/QueryPerFacetPlotsCard.js.map +1 -1
  163. package/dist/components/FeaturedDataTabs/SingleQueryFacetPlotsCards.js.map +1 -1
  164. package/dist/components/FeaturedResearch/FeaturedResearch.js.map +1 -1
  165. package/dist/components/FeaturedToolsList/FeaturedToolsList.js.map +1 -1
  166. package/dist/components/FilePreview/FileHandleContentRenderer.js.map +1 -1
  167. package/dist/components/FilePreview/HtmlPreview/HtmlPreview.js.map +1 -1
  168. package/dist/components/FilePreview/PreviewRendererType.js.map +1 -1
  169. package/dist/components/Forum/DiscussionReply.js.map +1 -1
  170. package/dist/components/Forum/DiscussionSearchResult.js.map +1 -1
  171. package/dist/components/Forum/ForumTable.js.map +1 -1
  172. package/dist/components/Forum/ForumThreadEditor.js.map +1 -1
  173. package/dist/components/FullTextSearch/FullTextSearchUtils.js.map +1 -1
  174. package/dist/components/GenericCard/GenericCard.d.ts.map +1 -1
  175. package/dist/components/GenericCard/GenericCard.js +12 -7
  176. package/dist/components/GenericCard/GenericCard.js.map +1 -1
  177. package/dist/components/GenericCard/Linkify.js.map +1 -1
  178. package/dist/components/GenericCard/SynapseCardLabel.js.map +1 -1
  179. package/dist/components/GenericCard/TableRowGenericCard.js +105 -105
  180. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  181. package/dist/components/Goals/Goals.Mobile.js.map +1 -1
  182. package/dist/components/Goals/Goals.js.map +1 -1
  183. package/dist/components/GoalsV2/GoalsV2.Mobile.js.map +1 -1
  184. package/dist/components/GoalsV2/GoalsV2.js.map +1 -1
  185. package/dist/components/GoalsV3/GoalsV3.Mobile.js.map +1 -1
  186. package/dist/components/GoalsV3/GoalsV3.js.map +1 -1
  187. package/dist/components/GoogleMap/SynapseUserMarker.js.map +1 -1
  188. package/dist/components/HasAccess/AccessIcon.js.map +1 -1
  189. package/dist/components/HasAccess/useHasAccess.js.map +1 -1
  190. package/dist/components/HeaderCard/HeaderCardV2.js.map +1 -1
  191. package/dist/components/HeaderCard.d.ts +6 -1
  192. package/dist/components/HeaderCard.d.ts.map +1 -1
  193. package/dist/components/HeaderCard.js +107 -76
  194. package/dist/components/HeaderCard.js.map +1 -1
  195. package/dist/components/HexGrid/HexGrid.js.map +1 -1
  196. package/dist/components/IconList.js.map +1 -1
  197. package/dist/components/ImageCardGridWithLinks/ImageCardGridWithLinks.js.map +1 -1
  198. package/dist/components/ImageFromSynapseTable.js.map +1 -1
  199. package/dist/components/JSONArrayEditor/useParseCsv.js.map +1 -1
  200. package/dist/components/JsonSchemaForm/templates/ArrayFieldDescriptionTemplate.js.map +1 -1
  201. package/dist/components/JsonSchemaForm/templates/ArrayFieldItemTemplate.js.map +1 -1
  202. package/dist/components/JsonSchemaForm/templates/BaseInputTemplate.js.map +1 -1
  203. package/dist/components/JsonSchemaForm/templates/FieldTemplate.js.map +1 -1
  204. package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js.map +1 -1
  205. package/dist/components/Markdown/MarkdownGithub.js.map +1 -1
  206. package/dist/components/Markdown/MarkdownSynapse.js.map +1 -1
  207. package/dist/components/Markdown/MarkdownUtils.js.map +1 -1
  208. package/dist/components/Markdown/SynapseWikiContext.js.map +1 -1
  209. package/dist/components/Markdown/UserMentionModal.js.map +1 -1
  210. package/dist/components/Markdown/widget/MarkdownProvenanceGraph.js.map +1 -1
  211. package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js.map +1 -1
  212. package/dist/components/ModalDownload/ModalDownload.js.map +1 -1
  213. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.d.ts.map +1 -1
  214. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.js +45 -39
  215. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.js.map +1 -1
  216. package/dist/components/OAuthClientManagement/OAuthManagement.js.map +1 -1
  217. package/dist/components/PageProgress/PageProgress.js.map +1 -1
  218. package/dist/components/Plot/DotPlot.js.map +1 -1
  219. package/dist/components/Plot/Plot.js.map +1 -1
  220. package/dist/components/Plot/SynapsePlot.js.map +1 -1
  221. package/dist/components/Plot/ThemesPlot.js.map +1 -1
  222. package/dist/components/Plot/UpsetPlot.js.map +1 -1
  223. package/dist/components/PortalAclEditor/PortalAclEditor.d.ts.map +1 -1
  224. package/dist/components/PortalAclEditor/PortalAclEditor.js +43 -41
  225. package/dist/components/PortalAclEditor/PortalAclEditor.js.map +1 -1
  226. package/dist/components/PortalFeaturedPartners/PortalFeaturedPartners.js.map +1 -1
  227. package/dist/components/PortalList/CreatePortalModal.js.map +1 -1
  228. package/dist/components/ProgrammaticInstructionsModal/ProgrammaticInstructionsModal.js.map +1 -1
  229. package/dist/components/ProgrammaticTableDownload/ProgrammaticTableDownload.js.map +1 -1
  230. package/dist/components/Programs/Programs.Mobile.js.map +1 -1
  231. package/dist/components/Programs/Programs.js.map +1 -1
  232. package/dist/components/ProvenanceGraph/ProvenanceExternalIcon.js.map +1 -1
  233. package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
  234. package/dist/components/ProvenanceGraph/ProvenanceGraphUtils.js.map +1 -1
  235. package/dist/components/ProvenanceGraph/ProvenanceUtils.js.map +1 -1
  236. package/dist/components/QueryCount/QueryCount.js.map +1 -1
  237. package/dist/components/QueryCountButton/QueryCountButton.js.map +1 -1
  238. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
  239. package/dist/components/QueryWrapper/QueryWrapper.js.map +1 -1
  240. package/dist/components/QueryWrapper/TableQueryUseQueryOptions.js.map +1 -1
  241. package/dist/components/QueryWrapper/TableRowSelectionState.js.map +1 -1
  242. package/dist/components/QueryWrapper/generateEncodedPathAndQueryForSelectedFacetURL.js.map +1 -1
  243. package/dist/components/QueryWrapper/useGetQueryMetadata.js.map +1 -1
  244. package/dist/components/QueryWrapperErrorBoundary.js.map +1 -1
  245. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
  246. package/dist/components/QueryWrapperPlotNav/UseRowSet.js.map +1 -1
  247. package/dist/components/RecentPublicationsGrid/RecentPublicationsGrid.js.map +1 -1
  248. package/dist/components/ReleaseCard/ReleaseCardUtils.js.map +1 -1
  249. package/dist/components/ResizableContainer/hooks/useResizable.js.map +1 -1
  250. package/dist/components/Resources/Resources.Mobile.js.map +1 -1
  251. package/dist/components/Resources/Resources.js.map +1 -1
  252. package/dist/components/RowDataTable/RowDataTableWithQuery.js.map +1 -1
  253. package/dist/components/SageResourcesPopover/SageResourcesPopover.js.map +1 -1
  254. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js.map +1 -1
  255. package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
  256. package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.js.map +1 -1
  257. package/dist/components/SmartLink/SmartButton.js.map +1 -1
  258. package/dist/components/SmartLink/SmartLink.js.map +1 -1
  259. package/dist/components/SourceAppImage.js.map +1 -1
  260. package/dist/components/StandaloneQueryWrapper/StandaloneQueryWrapper.js.map +1 -1
  261. package/dist/components/StatisticsPlot.js.map +1 -1
  262. package/dist/components/StorybookComponentWrapper.js.map +1 -1
  263. package/dist/components/SubsectionRowRenderer/SubsectionRowRenderer.js.map +1 -1
  264. package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js.map +1 -1
  265. package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
  266. package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
  267. package/dist/components/SynapseChat/SynapseChatMessage.js.map +1 -1
  268. package/dist/components/SynapseChat/extractMessageFromTraceEvent.js.map +1 -1
  269. package/dist/components/SynapseForm/StepsSideNav.js.map +1 -1
  270. package/dist/components/SynapseForm/SummaryTable.js.map +1 -1
  271. package/dist/components/SynapseForm/SynapseForm.js +4 -2
  272. package/dist/components/SynapseForm/SynapseForm.js.map +1 -1
  273. package/dist/components/SynapseForm/SynapseFormWrapper.js.map +1 -1
  274. package/dist/components/SynapseHomepageV2/SynapseByTheNumbersItem.js.map +1 -1
  275. package/dist/components/SynapseHomepageV2/SynapseFeatureItem.js.map +1 -1
  276. package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js.map +1 -1
  277. package/dist/components/SynapseHomepageV2/SynapseHomepageSearch.js.map +1 -1
  278. package/dist/components/SynapseHomepageV2/SynapseInActionItem.js.map +1 -1
  279. package/dist/components/SynapseHomepageV2/SynapsePlans.js.map +1 -1
  280. package/dist/components/SynapseHomepageV2/SynapseTrendingProjects.js.map +1 -1
  281. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts +8 -7
  282. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts.map +1 -1
  283. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js +173 -164
  284. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js.map +1 -1
  285. package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js.map +1 -1
  286. package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanel.js.map +1 -1
  287. package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanelUtils.js.map +1 -1
  288. package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js.map +1 -1
  289. package/dist/components/SynapseTable/EntityIDColumnCopyIcon.js.map +1 -1
  290. package/dist/components/SynapseTable/NoContentPlaceholderType.js.map +1 -1
  291. package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js.map +1 -1
  292. package/dist/components/SynapseTable/SynapseTableCell/SynapseTableCell.js.map +1 -1
  293. package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
  294. package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
  295. package/dist/components/SynapseTable/table-top/ColumnSelection.js.map +1 -1
  296. package/dist/components/SynapseTable/table-top/DownloadOptions.js.map +1 -1
  297. package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
  298. package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js.map +1 -1
  299. package/dist/components/TableColumnSchemaEditor/ColumnModelFormFields/DefaultValueField.js.map +1 -1
  300. package/dist/components/TableColumnSchemaEditor/ImportTableColumnsButton.js.map +1 -1
  301. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts +1 -1
  302. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts.map +1 -1
  303. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
  304. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
  305. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js.map +1 -1
  306. package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.js.map +1 -1
  307. package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.js.map +1 -1
  308. package/dist/components/TanStackTable/ColumnHeader.d.ts +1 -0
  309. package/dist/components/TanStackTable/ColumnHeader.d.ts.map +1 -1
  310. package/dist/components/TanStackTable/ColumnHeader.js +8 -8
  311. package/dist/components/TanStackTable/ColumnHeader.js.map +1 -1
  312. package/dist/components/TanStackTable/ColumnHeaderEnumFilter.js.map +1 -1
  313. package/dist/components/TanStackTable/TableBody.js.map +1 -1
  314. package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js.map +1 -1
  315. package/dist/components/TextField/TextField.js.map +1 -1
  316. package/dist/components/TimelinePlot/TimelinePhase.js.map +1 -1
  317. package/dist/components/TimelinePlot/TimelinePlot.js.map +1 -1
  318. package/dist/components/TimelinePlot/TimelinePlotSpeciesSelector.js.map +1 -1
  319. package/dist/components/UserCard/Avatar.js.map +1 -1
  320. package/dist/components/UserCardList/UserCardList.js.map +1 -1
  321. package/dist/components/UserCardList/UserCardListGroups/UserCardListGroups.Mobile.js.map +1 -1
  322. package/dist/components/UserCardList/UserCardListRotate.js.map +1 -1
  323. package/dist/components/UserOrTeamBadge/useUserOrTeam.js.map +1 -1
  324. package/dist/components/UserProfileLinks/UserProjects.js.map +1 -1
  325. package/dist/components/UserSearchBox/UserSearchBox.js.map +1 -1
  326. package/dist/components/Webhook/WebhookDashboard.js.map +1 -1
  327. package/dist/components/WikiMarkdownEditor/WikiMarkdownEditor.js.map +1 -1
  328. package/dist/components/WikiMarkdownEditorButton/WikiMarkdownEditorButton.js.map +1 -1
  329. package/dist/components/dataaccess/AccessApprovalsTable.js.map +1 -1
  330. package/dist/components/dataaccess/AccessRequestSubmissionTable.js.map +1 -1
  331. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js.map +1 -1
  332. package/dist/components/dataaccess/UseAccessRequirementTable.js.map +1 -1
  333. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js.map +1 -1
  334. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  335. package/dist/components/entity/page/CreatedByModifiedBy.js.map +1 -1
  336. package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
  337. package/dist/components/entity/page/title_bar/useDataCiteUsage.js.map +1 -1
  338. package/dist/components/entity/page/title_bar/useGetMentions.js.map +1 -1
  339. package/dist/components/error/ErrorPage.js.map +1 -1
  340. package/dist/components/favorites/FavoritesPage.js.map +1 -1
  341. package/dist/components/file/upload/BasicFileHandleUpload.js.map +1 -1
  342. package/dist/components/layout/SWCHeader.d.ts +9 -0
  343. package/dist/components/layout/SWCHeader.d.ts.map +1 -0
  344. package/dist/components/layout/SWCHeader.js +19 -0
  345. package/dist/components/layout/SWCHeader.js.map +1 -0
  346. package/dist/components/layout/SWCPageLayout.d.ts +9 -0
  347. package/dist/components/layout/SWCPageLayout.d.ts.map +1 -0
  348. package/dist/components/layout/SWCPageLayout.js +14 -0
  349. package/dist/components/layout/SWCPageLayout.js.map +1 -0
  350. package/dist/components/menu/ComplexMenu.js.map +1 -1
  351. package/dist/components/row_renderers/utils/ChipContainer.js.map +1 -1
  352. package/dist/components/styled/StyledPopover.js.map +1 -1
  353. package/dist/components/table/CsvPreview/CsvPreview.js +2 -1
  354. package/dist/components/table/CsvPreview/CsvPreview.js.map +1 -1
  355. package/dist/components/table/CsvPreview/CsvPreviewDialog.js.map +1 -1
  356. package/dist/components/trash/TrashCanList.js.map +1 -1
  357. package/dist/components/widgets/FileHandleLink.js.map +1 -1
  358. package/dist/components/widgets/RangeSlider/RangeSlider.js.map +1 -1
  359. package/dist/components/widgets/SynapseVideo.js.map +1 -1
  360. package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
  361. package/dist/components/widgets/facet-nav/PlotsContainer.js.map +1 -1
  362. package/dist/components/widgets/facet-nav/SelectionCriteriaPills.js.map +1 -1
  363. package/dist/components/widgets/facet-nav/useFacetPlots.js.map +1 -1
  364. package/dist/components/widgets/query-filter/CombinedRangeFacetFilter.js.map +1 -1
  365. package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
  366. package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
  367. package/dist/components/widgets/query-filter/RangeFacetFilter.js.map +1 -1
  368. package/dist/components/widgets/query-filter/RangeFacetFilterUI.js.map +1 -1
  369. package/dist/features/curator/GridPage/components/GridPageTitle.d.ts.map +1 -1
  370. package/dist/features/curator/GridPage/components/GridPageTitle.js +23 -30
  371. package/dist/features/curator/GridPage/components/GridPageTitle.js.map +1 -1
  372. package/dist/features/curator/dashboard/CuratorDashboard.d.ts +2 -0
  373. package/dist/features/curator/dashboard/CuratorDashboard.d.ts.map +1 -0
  374. package/dist/features/curator/dashboard/CuratorDashboard.js +45 -0
  375. package/dist/features/curator/dashboard/CuratorDashboard.js.map +1 -0
  376. package/dist/features/curator/dashboard/components/CurationTaskCard.css +1 -0
  377. package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts +9 -0
  378. package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts.map +1 -0
  379. package/dist/features/curator/dashboard/components/CurationTaskCard.js +106 -0
  380. package/dist/features/curator/dashboard/components/CurationTaskCard.js.map +1 -0
  381. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js +12 -0
  382. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js.map +1 -0
  383. package/dist/features/curator/dashboard/components/CurationTaskCard.module.scss +52 -0
  384. package/dist/features/curator/dashboard/components/NextStepButton.css +1 -0
  385. package/dist/features/curator/dashboard/components/NextStepButton.d.ts +14 -0
  386. package/dist/features/curator/dashboard/components/NextStepButton.d.ts.map +1 -0
  387. package/dist/features/curator/dashboard/components/NextStepButton.js +35 -0
  388. package/dist/features/curator/dashboard/components/NextStepButton.js.map +1 -0
  389. package/dist/features/curator/dashboard/components/NextStepButton.module.js +11 -0
  390. package/dist/features/curator/dashboard/components/NextStepButton.module.js.map +1 -0
  391. package/dist/features/curator/dashboard/components/NextStepButton.module.scss +57 -0
  392. package/dist/features/curator/dashboard/components/UserOrTeamChip.css +1 -1
  393. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.js +1 -1
  394. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.js.map +1 -1
  395. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.scss +5 -5
  396. package/dist/features/curator/dashboard/components/shared.css +1 -0
  397. package/dist/features/curator/dashboard/components/shared.module.js +5 -0
  398. package/dist/features/curator/dashboard/components/shared.module.js.map +1 -0
  399. package/dist/features/curator/dashboard/components/shared.module.scss +8 -0
  400. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts +0 -2
  401. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
  402. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +16 -34
  403. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  404. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  405. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js.map +1 -1
  406. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js.map +1 -1
  407. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js.map +1 -1
  408. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js +1 -1
  409. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js.map +1 -1
  410. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts +10 -0
  411. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts.map +1 -0
  412. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js +37 -0
  413. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js.map +1 -0
  414. package/dist/features/entity/metadata-task/utils/constants.d.ts +5 -0
  415. package/dist/features/entity/metadata-task/utils/constants.d.ts.map +1 -0
  416. package/dist/features/entity/metadata-task/utils/constants.js +6 -0
  417. package/dist/features/entity/metadata-task/utils/constants.js.map +1 -0
  418. package/dist/mocks/challenge/mockChallenge.js.map +1 -1
  419. package/dist/mocks/entity/mockDataset.js.map +1 -1
  420. package/dist/mocks/entity/mockDatasetCollection.js.map +1 -1
  421. package/dist/mocks/entity/mockFileEntity.js.map +1 -1
  422. package/dist/mocks/entity/mockFileView.js.map +1 -1
  423. package/dist/mocks/entity/mockGeneratedEntityData.js.map +1 -1
  424. package/dist/mocks/entity/mockProject.js.map +1 -1
  425. package/dist/mocks/entity/mockProjectView.js.map +1 -1
  426. package/dist/mocks/entity/mockRootEntity.js.map +1 -1
  427. package/dist/mocks/entity/mockTableEntity.js.map +1 -1
  428. package/dist/mocks/mockWiki.js.map +1 -1
  429. package/dist/mocks/msw/handlers/asyncJobHandlers.js.map +1 -1
  430. package/dist/mocks/msw/handlers/challengeHandlers.js.map +1 -1
  431. package/dist/mocks/msw/handlers/changePasswordHandlers.js.map +1 -1
  432. package/dist/mocks/msw/handlers/discussionHandlers.js.map +1 -1
  433. package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
  434. package/dist/mocks/msw/handlers/fileHandlers.js.map +1 -1
  435. package/dist/mocks/msw/handlers/gridHandlers.js.map +1 -1
  436. package/dist/mocks/msw/handlers/personalAccessTokenHandlers.js.map +1 -1
  437. package/dist/mocks/msw/handlers/subscriptionHandlers.js.map +1 -1
  438. package/dist/mocks/msw/handlers/teamHandlers.js.map +1 -1
  439. package/dist/mocks/msw/handlers/userProfileHandlers.js.map +1 -1
  440. package/dist/mocks/msw/handlers/wikiHandlers.js.map +1 -1
  441. package/dist/mocks/provenance/mockActivity.js.map +1 -1
  442. package/dist/mocks/query/mockReleaseCardsTableQueryResultBundle.js.map +1 -1
  443. package/dist/ror-client/index.js.map +1 -1
  444. package/dist/style/components/_cards.scss +4 -0
  445. package/dist/style/components/_data-grid-extra.css +1 -1
  446. package/dist/style/components/_data-grid-extra.scss +2 -0
  447. package/dist/style/main.css +1 -1
  448. package/dist/synapse-client/HttpClient.js.map +1 -1
  449. package/dist/synapse-client/SynapseClient.js.map +1 -1
  450. package/dist/synapse-queries/QueryMatching.test-utils.js.map +1 -1
  451. package/dist/synapse-queries/auth/useTwoFactorEnrollment.js.map +1 -1
  452. package/dist/synapse-queries/curation/task/useCurationTask.d.ts +1 -1
  453. package/dist/synapse-queries/curation/task/useCurationTask.d.ts.map +1 -1
  454. package/dist/synapse-queries/curation/task/useCurationTask.js +1 -1
  455. package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
  456. package/dist/synapse-queries/dataaccess/useRestrictionInformation.js.map +1 -1
  457. package/dist/synapse-queries/doi/useDOI.js.map +1 -1
  458. package/dist/synapse-queries/download/useDownloadList.js.map +1 -1
  459. package/dist/synapse-queries/entity/useEntity.js.map +1 -1
  460. package/dist/synapse-queries/entity/useEntityBundle.js.map +1 -1
  461. package/dist/synapse-queries/entity/useExportTableQueryToAnalysisPlatform.js.map +1 -1
  462. package/dist/synapse-queries/entity/useExportToTerra.js.map +1 -1
  463. package/dist/synapse-queries/entity/useGetQueryResultBundle.js.map +1 -1
  464. package/dist/synapse-queries/entity/useSchema.js.map +1 -1
  465. package/dist/synapse-queries/file/UploadToS3.js.map +1 -1
  466. package/dist/synapse-queries/file/useDirectUploadToS3.js.map +1 -1
  467. package/dist/synapse-queries/file/useFiles.js.map +1 -1
  468. package/dist/synapse-queries/forum/useReply.js.map +1 -1
  469. package/dist/synapse-queries/forum/useThread.js.map +1 -1
  470. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts +2 -0
  471. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts.map +1 -1
  472. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js.map +1 -1
  473. package/dist/synapse-queries/grid/useExportGrid.js.map +1 -1
  474. package/dist/synapse-queries/grid/useGridSession.js.map +1 -1
  475. package/dist/synapse-queries/grid/useImportCsvIntoGrid.js.map +1 -1
  476. package/dist/synapse-queries/subscription/useSubscription.js.map +1 -1
  477. package/dist/synapse-queries/table/useGetCsvPreview.js.map +1 -1
  478. package/dist/synapse-queries/table/useTableUpdateTransaction.js.map +1 -1
  479. package/dist/synapse-queries/team/useTeamMembers.js.map +1 -1
  480. package/dist/synapse-queries/user/useGetUserChallenges.js.map +1 -1
  481. package/dist/synapse-queries/user/useUserBundle.js.map +1 -1
  482. package/dist/synapse-queries/user/useUserGroupHeader.js.map +1 -1
  483. package/dist/testutils/ReactQueryMockUtils.js.map +1 -1
  484. package/dist/theme/ThemeProvider.js.map +1 -1
  485. package/dist/tsconfig.build.tsbuildinfo +1 -1
  486. package/dist/utils/AppUtils/session/SynapseSessionManager.js.map +1 -1
  487. package/dist/utils/AppUtils/session/useSessionManager.js.map +1 -1
  488. package/dist/utils/PermissionLevelToAccessType.js.map +1 -1
  489. package/dist/utils/challenge/evaluation/EvaluationUtils.js.map +1 -1
  490. package/dist/utils/context/SynapseContext.js.map +1 -1
  491. package/dist/utils/functions/AccessControlListUtils.d.ts +4 -0
  492. package/dist/utils/functions/AccessControlListUtils.d.ts.map +1 -1
  493. package/dist/utils/functions/AccessControlListUtils.js +12 -1
  494. package/dist/utils/functions/AccessControlListUtils.js.map +1 -1
  495. package/dist/utils/functions/GridApiUtils.js.map +1 -1
  496. package/dist/utils/functions/QueryFilterUtils.js.map +1 -1
  497. package/dist/utils/functions/RealmUtils.d.ts +4 -0
  498. package/dist/utils/functions/RealmUtils.d.ts.map +1 -1
  499. package/dist/utils/functions/RealmUtils.js +9 -3
  500. package/dist/utils/functions/RealmUtils.js.map +1 -1
  501. package/dist/utils/functions/SanitizeHtmlUtils.js.map +1 -1
  502. package/dist/utils/functions/SanitizeHtmlUtils.test-utils.js.map +1 -1
  503. package/dist/utils/functions/SqlFunctions.js.map +1 -1
  504. package/dist/utils/functions/StringUtils.js.map +1 -1
  505. package/dist/utils/functions/deepLinkingUtils.js.map +1 -1
  506. package/dist/utils/functions/getDataFromFromStorage.js.map +1 -1
  507. package/dist/utils/functions/getEndpoint.js.map +1 -1
  508. package/dist/utils/functions/getUserData.js.map +1 -1
  509. package/dist/utils/functions/queryUtils.js.map +1 -1
  510. package/dist/utils/functions/testDownloadSpeed.js.map +1 -1
  511. package/dist/utils/hooks/useConfirmItems.js.map +1 -1
  512. package/dist/utils/hooks/useCookiePreferences.js.map +1 -1
  513. package/dist/utils/hooks/useCreateShortUrl.js.map +1 -1
  514. package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
  515. package/dist/utils/hooks/useDirectDownloadHandler.js.map +1 -1
  516. package/dist/utils/hooks/useGetGoalData.js.map +1 -1
  517. package/dist/utils/hooks/useGetInfoFromIds.js.map +1 -1
  518. package/dist/utils/hooks/useImageUrlUtils.js.map +1 -1
  519. package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js.map +1 -1
  520. package/dist/utils/hooks/useImmutableTableQuery/useTableQueryReducer.js.map +1 -1
  521. package/dist/utils/hooks/useIsBot.js.map +1 -1
  522. package/dist/utils/hooks/useListState.js.map +1 -1
  523. package/dist/utils/hooks/useLogin.d.ts.map +1 -1
  524. package/dist/utils/hooks/useLogin.js +53 -52
  525. package/dist/utils/hooks/useLogin.js.map +1 -1
  526. package/dist/utils/hooks/useMutuallyExclusiveState.js.map +1 -1
  527. package/dist/utils/hooks/useOverlay.js.map +1 -1
  528. package/dist/utils/hooks/usePreFetchResource.js.map +1 -1
  529. package/dist/utils/hooks/useQuerySearchParam.js.map +1 -1
  530. package/dist/utils/hooks/useScrollFadeTransition.js.map +1 -1
  531. package/dist/utils/hooks/useSet.js.map +1 -1
  532. package/dist/utils/hooks/useSourceAppConfigs.js.map +1 -1
  533. package/dist/utils/hooks/useTableImageUrl.js.map +1 -1
  534. package/dist/utils/hooks/useUploadFileEntity/useCreatePathsAndGetParentId.js.map +1 -1
  535. package/dist/utils/hooks/useUploadFileEntity/useLinkFileEntityToURL.js.map +1 -1
  536. package/dist/utils/hooks/useUploadFileEntity/usePrepareFileEntityUpload.js.map +1 -1
  537. package/dist/utils/hooks/useUploadFileEntity/useTrackFileUploads.js.map +1 -1
  538. package/dist/utils/hooks/useUploadFileEntity/useUploadFileEntities.js.map +1 -1
  539. package/dist/utils/hooks/useUploadFileEntity/useUploadFiles.js.map +1 -1
  540. package/dist/utils/hooks/useUploadFileEntity/willUploadsExceedStorageLimit.js.map +1 -1
  541. package/dist/utils/html/TargetEnum.js.map +1 -1
  542. package/dist/utils/jsonschema/SchemaAnnotationUtils.js.map +1 -1
  543. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"UserProjects.js","names":[],"sources":["../../../src/components/UserProfileLinks/UserProjects.tsx"],"sourcesContent":["import { useGetUserProjectsInfinite } from '@/synapse-queries/user/useGetUserProjects'\nimport { PRODUCTION_ENDPOINT_CONFIG } from '@/utils/functions/getEndpoint'\nimport {\n GetProjectsParameters,\n ProjectHeader,\n} from '@sage-bionetworks/synapse-types'\nimport { useEffect } from 'react'\nimport { useErrorHandler } from 'react-error-boundary'\nimport { useInView } from 'react-intersection-observer'\nimport { SkeletonTable } from '../Skeleton/SkeletonTable'\n\nexport type UserProjectsProps = {\n userId: string\n}\n\nexport default function UserProjects({ userId }: UserProjectsProps) {\n const handleError = useErrorHandler()\n // Load the next page when this ref comes into view.\n const { ref, inView } = useInView()\n const getProjectsParameters: GetProjectsParameters = {}\n const {\n data,\n status,\n isFetching,\n isLoading,\n hasNextPage,\n fetchNextPage,\n isError,\n error: newError,\n } = useGetUserProjectsInfinite(userId, getProjectsParameters)\n\n useEffect(() => {\n if (isError && newError) {\n handleError(newError)\n }\n }, [isError, newError, handleError])\n\n useEffect(() => {\n if (\n status === 'success' &&\n !isFetching &&\n hasNextPage &&\n fetchNextPage &&\n inView\n ) {\n fetchNextPage()\n }\n }, [status, isFetching, hasNextPage, fetchNextPage, inView])\n\n const allRows = data?.pages.flatMap(page => page.results) ?? []\n\n return (\n <>\n {allRows.length > 0 && (\n <>\n {allRows.map((item: ProjectHeader) => {\n if (item) {\n // another option would be to use an EntityLink\n return (\n <p key={`user-project-list-item-${item.id}`}>\n <a\n target=\"_self\"\n rel=\"noopener noreferrer\"\n href={`${PRODUCTION_ENDPOINT_CONFIG.PORTAL}Synapse:${item.id}`}\n >\n {item.name}\n </a>\n </p>\n )\n } else return false\n })}\n {/* To trigger loading the next page */}\n <div ref={ref} />\n </>\n )}\n {!isFetching && allRows.length == 0 && <div>Empty</div>}\n {isLoading && <SkeletonTable numRows={5} numCols={1} />}\n </>\n )\n}\n"],"mappings":";;;;;;;;AAeA,SAAwB,EAAa,EAAE,aAA6B;CAClE,IAAM,IAAc,GAAiB,EAE/B,EAAE,QAAK,cAAW,GAAW,EAE7B,EACJ,SACA,WACA,eACA,cACA,gBACA,kBACA,YACA,OAAO,MACL,EAA2B,GAVsB,EAAE,CAUM;AAQ7D,CANA,QAAgB;AACd,EAAI,KAAW,KACb,EAAY,EAAS;IAEtB;EAAC;EAAS;EAAU;EAAY,CAAC,EAEpC,QAAgB;AACd,EACE,MAAW,aACX,CAAC,KACD,KACA,KACA,KAEA,GAAe;IAEhB;EAAC;EAAQ;EAAY;EAAa;EAAe;EAAO,CAAC;CAE5D,IAAM,IAAU,GAAM,MAAM,SAAQ,MAAQ,EAAK,QAAQ,IAAI,EAAE;AAE/D,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,EAAQ,SAAS,KAChB,kBAAA,GAAA,EAAA,UAAA,CACG,EAAQ,KAAK,MACR,IAGA,kBAAC,KAAD,EAAA,UACE,kBAAC,KAAD;GACE,QAAO;GACP,KAAI;GACJ,MAAM,GAAG,EAA2B,OAAO,UAAU,EAAK;aAEzD,EAAK;GACJ,CAAA,EACF,EARI,0BAA0B,EAAK,KAQnC,GAEM,GACd,EAEF,kBAAC,OAAD,EAAU,QAAO,CAAA,CAChB,EAAA,CAAA;EAEJ,CAAC,KAAc,EAAQ,UAAU,KAAK,kBAAC,OAAD,EAAA,UAAK,SAAW,CAAA;EACtD,KAAa,kBAAC,GAAD;GAAe,SAAS;GAAG,SAAS;GAAK,CAAA;EACtD,EAAA,CAAA"}
1
+ {"version":3,"file":"UserProjects.js","names":[],"sources":["../../../src/components/UserProfileLinks/UserProjects.tsx"],"sourcesContent":["import { useGetUserProjectsInfinite } from '@/synapse-queries/user/useGetUserProjects'\nimport { PRODUCTION_ENDPOINT_CONFIG } from '@/utils/functions/getEndpoint'\nimport {\n GetProjectsParameters,\n ProjectHeader,\n} from '@sage-bionetworks/synapse-types'\nimport { useEffect } from 'react'\nimport { useErrorHandler } from 'react-error-boundary'\nimport { useInView } from 'react-intersection-observer'\nimport { SkeletonTable } from '../Skeleton/SkeletonTable'\n\nexport type UserProjectsProps = {\n userId: string\n}\n\nexport default function UserProjects({ userId }: UserProjectsProps) {\n const handleError = useErrorHandler()\n // Load the next page when this ref comes into view.\n const { ref, inView } = useInView()\n const getProjectsParameters: GetProjectsParameters = {}\n const {\n data,\n status,\n isFetching,\n isLoading,\n hasNextPage,\n fetchNextPage,\n isError,\n error: newError,\n } = useGetUserProjectsInfinite(userId, getProjectsParameters)\n\n useEffect(() => {\n if (isError && newError) {\n handleError(newError)\n }\n }, [isError, newError, handleError])\n\n useEffect(() => {\n if (\n status === 'success' &&\n !isFetching &&\n hasNextPage &&\n fetchNextPage &&\n inView\n ) {\n fetchNextPage()\n }\n }, [status, isFetching, hasNextPage, fetchNextPage, inView])\n\n const allRows = data?.pages.flatMap(page => page.results) ?? []\n\n return (\n <>\n {allRows.length > 0 && (\n <>\n {allRows.map((item: ProjectHeader) => {\n if (item) {\n // another option would be to use an EntityLink\n return (\n <p key={`user-project-list-item-${item.id}`}>\n <a\n target=\"_self\"\n rel=\"noopener noreferrer\"\n href={`${PRODUCTION_ENDPOINT_CONFIG.PORTAL}Synapse:${item.id}`}\n >\n {item.name}\n </a>\n </p>\n )\n } else return false\n })}\n {/* To trigger loading the next page */}\n <div ref={ref} />\n </>\n )}\n {!isFetching && allRows.length == 0 && <div>Empty</div>}\n {isLoading && <SkeletonTable numRows={5} numCols={1} />}\n </>\n )\n}\n"],"mappings":";;;;;;;;AAeA,SAAwB,EAAa,EAAE,aAA6B;CAClE,IAAM,IAAc,GAAiB,EAE/B,EAAE,QAAK,cAAW,GAAW,EAE7B,EACJ,SACA,WACA,eACA,cACA,gBACA,kBACA,YACA,OAAO,MACL,EAA2B,GAAQ,EAAA,CAAsB;AAQ7D,CANA,QAAgB;AACd,EAAI,KAAW,KACb,EAAY,EAAS;IAEtB;EAAC;EAAS;EAAU;EAAY,CAAC,EAEpC,QAAgB;AACd,EACE,MAAW,aACX,CAAC,KACD,KACA,KACA,KAEA,GAAe;IAEhB;EAAC;EAAQ;EAAY;EAAa;EAAe;EAAO,CAAC;CAE5D,IAAM,IAAU,GAAM,MAAM,SAAQ,MAAQ,EAAK,QAAQ,IAAI,EAAE;AAE/D,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,EAAQ,SAAS,KAChB,kBAAA,GAAA,EAAA,UAAA,CACG,EAAQ,KAAK,MACR,IAGA,kBAAC,KAAD,EAAA,UACE,kBAAC,KAAD;GACE,QAAO;GACP,KAAI;GACJ,MAAM,GAAG,EAA2B,OAAO,UAAU,EAAK;aAEzD,EAAK;GACJ,CAAA,EACF,EARI,0BAA0B,EAAK,KAQnC,GAEM,GACd,EAEF,kBAAC,OAAD,EAAU,QAAO,CAAA,CAChB,EAAA,CAAA;EAEJ,CAAC,KAAc,EAAQ,UAAU,KAAK,kBAAC,OAAD,EAAA,UAAK,SAAW,CAAA;EACtD,KAAa,kBAAC,GAAD;GAAe,SAAS;GAAG,SAAS;GAAK,CAAA;EACtD,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserSearchBox.js","names":[],"sources":["../../../src/components/UserSearchBox/UserSearchBox.tsx"],"sourcesContent":["import {\n useGetUserGroupHeader,\n useSearchUserGroupHeaders,\n} from '@/synapse-queries'\nimport { useDebouncedEffect } from '@/utils/hooks/useDebouncedEffect'\nimport { Autocomplete, Box, Skeleton, TextField } from '@mui/material'\nimport { TYPE_FILTER, UserGroupHeader } from '@sage-bionetworks/synapse-types'\nimport { useMemo, useState } from 'react'\nimport UserOrTeamBadge from '../UserOrTeamBadge/UserOrTeamBadge'\n\nexport type UserSearchBoxProps = {\n /* id for the input element, for associating with a <label> */\n inputId?: string\n /* The initial principal ID (uncontrolled). Ignored if `value` is provided. */\n defaultValue?: string\n onChange?: (\n principalId: string | null,\n header: UserGroupHeader | null,\n ) => void\n typeFilter?: TYPE_FILTER\n filterPredicate?: (item: UserGroupHeader) => boolean\n placeholder?: string\n autoFocus?: boolean\n /**\n * The principal ID of the currently selected user or team.\n * - `undefined`: uncontrolled — the component manages its own selection state\n * - `null`: controlled with no selection (clears the field)\n * - string: controlled with the given principal ID selected\n */\n value?: string | null\n}\n\n/**\n * Autocomplete component used to search for and select a user or team.\n */\nfunction UserSearchBox(props: UserSearchBoxProps) {\n const {\n inputId,\n defaultValue = null,\n onChange,\n filterPredicate,\n typeFilter,\n placeholder,\n autoFocus = false,\n value: valueProp,\n } = props\n\n const isControlled = valueProp !== undefined\n\n const [inputValue, setInputValue] = useState('')\n const [debouncedInput, setDebouncedInput] = useState('')\n useDebouncedEffect(\n () => {\n setDebouncedInput(inputValue)\n },\n [inputValue],\n 500,\n )\n\n // Tracks whether the dropdown is open, used to toggle between badge display\n // and text-input search mode.\n const [isSearching, setIsSearching] = useState(false)\n\n // Resolve defaultValue principalId → UserGroupHeader for the initial uncontrolled state\n const { data: defaultUserGroupHeader, isLoading: isLoadingDefaultValue } =\n useGetUserGroupHeader(defaultValue ?? '', {\n enabled: !!defaultValue && !isControlled,\n })\n\n // Resolve controlled string principalId → UserGroupHeader\n const controlledPrincipalId =\n isControlled && typeof valueProp === 'string' ? valueProp : null\n\n const {\n data: resolvedControlledHeader,\n isLoading: isLoadingControlledValue,\n } = useGetUserGroupHeader(controlledPrincipalId ?? '', {\n enabled: !!controlledPrincipalId,\n })\n\n // Internal state for uncontrolled mode.\n // undefined = user hasn't interacted yet → falls back to defaultUserGroupHeader\n // null = user explicitly cleared the selection\n // header = user's current selection\n const [internalValue, setInternalValue] = useState<\n UserGroupHeader | null | undefined\n >(undefined)\n\n const controlledValue =\n typeof valueProp === 'string' ? resolvedControlledHeader ?? null : null\n const uncontrolledValue =\n internalValue !== undefined ? internalValue : defaultUserGroupHeader ?? null\n const resolvedValue: UserGroupHeader | null = isControlled\n ? controlledValue\n : uncontrolledValue\n\n // Show the badge in the input field when a value is selected and the user\n // is not actively searching.\n const showBadge = resolvedValue !== null && !isSearching\n\n const isSearchEnabled = !!debouncedInput\n const { data, isLoading } = useSearchUserGroupHeaders(\n debouncedInput,\n typeFilter,\n {\n enabled: isSearchEnabled,\n },\n )\n\n const options = useMemo(\n () => (data ?? []).filter(filterPredicate ?? (() => true)),\n [data, filterPredicate],\n )\n\n const placeholderText = useMemo(() => {\n if (placeholder !== undefined) {\n return placeholder\n } else if (typeFilter == TYPE_FILTER.USERS_ONLY) {\n return 'Name (first and last)'\n } else if (typeFilter == TYPE_FILTER.TEAMS_ONLY) {\n return 'Team name'\n } else {\n return 'Name (first and last) or team name'\n }\n }, [placeholder, typeFilter])\n\n if (isLoadingDefaultValue || isLoadingControlledValue) {\n return <Skeleton width=\"100%\" />\n }\n\n return (\n <Autocomplete<UserGroupHeader, false, false, false>\n id={inputId}\n value={resolvedValue}\n inputValue={inputValue}\n onInputChange={(_event, newInputValue, reason) => {\n if (reason === 'selectOption' || reason === 'reset') {\n // After an option is selected/removed, clear the input text so it's ready for the next search.\n setInputValue('')\n } else {\n setInputValue(newInputValue)\n }\n }}\n // When a value is selected, clicking the badge area should re-open the search.\n openOnFocus={resolvedValue !== null}\n onOpen={() => {\n setIsSearching(true)\n }}\n onClose={() => setIsSearching(false)}\n options={options}\n filterOptions={x => x}\n loading={isLoading || inputValue !== debouncedInput}\n isOptionEqualToValue={(option, val) => option.ownerId === val.ownerId}\n getOptionLabel={option => option.userName}\n renderOption={(optionProps, option) => (\n <li {...optionProps} key={option.ownerId}>\n <UserOrTeamBadge\n userGroupHeader={option}\n disableHref\n showFullName\n showCardOnHover={false}\n />\n </li>\n )}\n renderInput={({\n inputProps: inputPropsFromParams,\n InputProps: InputPropsFromParams,\n ...params\n }) => (\n <TextField\n {...params}\n placeholder={showBadge ? undefined : placeholderText}\n autoFocus={autoFocus}\n slotProps={{\n htmlInput: {\n ...inputPropsFromParams,\n // While the badge is displayed, hide the underlying input text and cursor.\n // Merge custom styles with parent styles to preserve mouse selection and other behaviors.\n style: {\n ...inputPropsFromParams.style,\n ...(showBadge ? { color: 'transparent' } : {}),\n },\n },\n input: {\n ...InputPropsFromParams,\n startAdornment: showBadge ? (\n <Box sx={{ ml: 1 }}>\n <UserOrTeamBadge\n userGroupHeader={resolvedValue}\n disableHref\n showFullName\n showCardOnHover={false}\n />\n </Box>\n ) : undefined,\n },\n }}\n />\n )}\n onChange={(_event, newValue) => {\n if (!isControlled) {\n setInternalValue(newValue)\n }\n onChange?.(\n newValue?.ownerId != null ? newValue.ownerId.toString() : null,\n newValue ?? null,\n )\n }}\n noOptionsText={\n isLoading || inputValue !== debouncedInput ? 'Loading…' : 'No options'\n }\n clearOnEscape\n />\n )\n}\n\nexport default UserSearchBox\n"],"mappings":";;;;;;;;;AAmCA,SAAS,EAAc,GAA2B;CAChD,IAAM,EACJ,YACA,kBAAe,MACf,aACA,oBACA,eACA,gBACA,eAAY,IACZ,OAAO,MACL,GAEE,IAAe,MAAc,KAAA,GAE7B,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAgB,KAAqB,EAAS,GAAG;AACxD,SACQ;AACJ,IAAkB,EAAW;IAE/B,CAAC,EAAW,EACZ,IACD;CAID,IAAM,CAAC,GAAa,KAAkB,EAAS,GAAM,EAG/C,EAAE,MAAM,GAAwB,WAAW,MAC/C,EAAsB,KAAgB,IAAI,EACxC,SAAS,CAAC,CAAC,KAAgB,CAAC,GAC7B,CAAC,EAGE,IACJ,KAAgB,OAAO,KAAc,WAAW,IAAY,MAExD,EACJ,MAAM,GACN,WAAW,MACT,EAAsB,KAAyB,IAAI,EACrD,SAAS,CAAC,CAAC,GACZ,CAAC,EAMI,CAAC,GAAe,KAAoB,EAExC,KAAA,EAAU,EAMN,IAAwC,IAH5C,OAAO,KAAc,WAAW,KAA4B,OAAO,OAEnE,MAAkB,KAAA,IAA4B,KAA0B,OAA1C,GAO1B,IAAY,MAAkB,QAAQ,CAAC,GAGvC,EAAE,SAAM,iBAAc,EAC1B,GACA,GACA,EACE,SALoB,CAAC,CAAC,GAMvB,CACF,EAEK,IAAU,SACP,KAAQ,EAAE,EAAE,OAAO,YAA0B,IAAM,EAC1D,CAAC,GAAM,EAAgB,CACxB,EAEK,IAAkB,QAClB,MAAgB,KAAA,IAET,KAAc,EAAY,aAC5B,0BACE,KAAc,EAAY,aAC5B,cAEA,uCANA,GAQR,CAAC,GAAa,EAAW,CAAC;AAM7B,QAJI,KAAyB,IACpB,kBAAC,GAAD,EAAU,OAAM,QAAS,CAAA,GAIhC,kBAAC,GAAD;EACE,IAAI;EACJ,OAAO;EACK;EACZ,gBAAgB,GAAQ,GAAe,MAAW;AAChD,GAEE,EAFE,MAAW,kBAAkB,MAAW,UAE5B,KAEA,EAAc;;EAIhC,aAAa,MAAkB;EAC/B,cAAc;AACZ,KAAe,GAAK;;EAEtB,eAAe,EAAe,GAAM;EAC3B;EACT,gBAAe,MAAK;EACpB,SAAS,KAAa,MAAe;EACrC,uBAAuB,GAAQ,MAAQ,EAAO,YAAY,EAAI;EAC9D,iBAAgB,MAAU,EAAO;EACjC,eAAe,GAAa,MAC1B,kBAAC,MAAD;GAAI,GAAI;GAAa,KAAK,EAAO;GAO5B,EANH,kBAAC,GAAD;GACE,iBAAiB;GACjB,aAAA;GACA,cAAA;GACA,iBAAiB;GACjB,CAAA,CACC;EAEP,cAAc,EACZ,YAAY,GACZ,YAAY,GACZ,GAAG,QAEH,kBAAC,GAAD;GACE,GAAI;GACJ,aAAa,IAAY,KAAA,IAAY;GAC1B;GACX,WAAW;IACT,WAAW;KACT,GAAG;KAGH,OAAO;MACL,GAAG,EAAqB;MACxB,GAAI,IAAY,EAAE,OAAO,eAAe,GAAG,EAAE;MAC9C;KACF;IACD,OAAO;KACL,GAAG;KACH,gBAAgB,IACd,kBAAC,GAAD;MAAK,IAAI,EAAE,IAAI,GAAG;gBAChB,kBAAC,GAAD;OACE,iBAAiB;OACjB,aAAA;OACA,cAAA;OACA,iBAAiB;OACjB,CAAA;MACE,CAAA,GACJ,KAAA;KACL;IACF;GACD,CAAA;EAEJ,WAAW,GAAQ,MAAa;AAI9B,GAHK,KACH,EAAiB,EAAS,EAE5B,IACE,GAAU,WAAW,OAAqC,OAA9B,EAAS,QAAQ,UAAU,EACvD,KAAY,KACb;;EAEH,eACE,KAAa,MAAe,IAAiB,aAAa;EAE5D,eAAA;EACA,CAAA"}
1
+ {"version":3,"file":"UserSearchBox.js","names":[],"sources":["../../../src/components/UserSearchBox/UserSearchBox.tsx"],"sourcesContent":["import {\n useGetUserGroupHeader,\n useSearchUserGroupHeaders,\n} from '@/synapse-queries'\nimport { useDebouncedEffect } from '@/utils/hooks/useDebouncedEffect'\nimport { Autocomplete, Box, Skeleton, TextField } from '@mui/material'\nimport { TYPE_FILTER, UserGroupHeader } from '@sage-bionetworks/synapse-types'\nimport { useMemo, useState } from 'react'\nimport UserOrTeamBadge from '../UserOrTeamBadge/UserOrTeamBadge'\n\nexport type UserSearchBoxProps = {\n /* id for the input element, for associating with a <label> */\n inputId?: string\n /* The initial principal ID (uncontrolled). Ignored if `value` is provided. */\n defaultValue?: string\n onChange?: (\n principalId: string | null,\n header: UserGroupHeader | null,\n ) => void\n typeFilter?: TYPE_FILTER\n filterPredicate?: (item: UserGroupHeader) => boolean\n placeholder?: string\n autoFocus?: boolean\n /**\n * The principal ID of the currently selected user or team.\n * - `undefined`: uncontrolled — the component manages its own selection state\n * - `null`: controlled with no selection (clears the field)\n * - string: controlled with the given principal ID selected\n */\n value?: string | null\n}\n\n/**\n * Autocomplete component used to search for and select a user or team.\n */\nfunction UserSearchBox(props: UserSearchBoxProps) {\n const {\n inputId,\n defaultValue = null,\n onChange,\n filterPredicate,\n typeFilter,\n placeholder,\n autoFocus = false,\n value: valueProp,\n } = props\n\n const isControlled = valueProp !== undefined\n\n const [inputValue, setInputValue] = useState('')\n const [debouncedInput, setDebouncedInput] = useState('')\n useDebouncedEffect(\n () => {\n setDebouncedInput(inputValue)\n },\n [inputValue],\n 500,\n )\n\n // Tracks whether the dropdown is open, used to toggle between badge display\n // and text-input search mode.\n const [isSearching, setIsSearching] = useState(false)\n\n // Resolve defaultValue principalId → UserGroupHeader for the initial uncontrolled state\n const { data: defaultUserGroupHeader, isLoading: isLoadingDefaultValue } =\n useGetUserGroupHeader(defaultValue ?? '', {\n enabled: !!defaultValue && !isControlled,\n })\n\n // Resolve controlled string principalId → UserGroupHeader\n const controlledPrincipalId =\n isControlled && typeof valueProp === 'string' ? valueProp : null\n\n const {\n data: resolvedControlledHeader,\n isLoading: isLoadingControlledValue,\n } = useGetUserGroupHeader(controlledPrincipalId ?? '', {\n enabled: !!controlledPrincipalId,\n })\n\n // Internal state for uncontrolled mode.\n // undefined = user hasn't interacted yet → falls back to defaultUserGroupHeader\n // null = user explicitly cleared the selection\n // header = user's current selection\n const [internalValue, setInternalValue] = useState<\n UserGroupHeader | null | undefined\n >(undefined)\n\n const controlledValue =\n typeof valueProp === 'string' ? resolvedControlledHeader ?? null : null\n const uncontrolledValue =\n internalValue !== undefined ? internalValue : defaultUserGroupHeader ?? null\n const resolvedValue: UserGroupHeader | null = isControlled\n ? controlledValue\n : uncontrolledValue\n\n // Show the badge in the input field when a value is selected and the user\n // is not actively searching.\n const showBadge = resolvedValue !== null && !isSearching\n\n const isSearchEnabled = !!debouncedInput\n const { data, isLoading } = useSearchUserGroupHeaders(\n debouncedInput,\n typeFilter,\n {\n enabled: isSearchEnabled,\n },\n )\n\n const options = useMemo(\n () => (data ?? []).filter(filterPredicate ?? (() => true)),\n [data, filterPredicate],\n )\n\n const placeholderText = useMemo(() => {\n if (placeholder !== undefined) {\n return placeholder\n } else if (typeFilter == TYPE_FILTER.USERS_ONLY) {\n return 'Name (first and last)'\n } else if (typeFilter == TYPE_FILTER.TEAMS_ONLY) {\n return 'Team name'\n } else {\n return 'Name (first and last) or team name'\n }\n }, [placeholder, typeFilter])\n\n if (isLoadingDefaultValue || isLoadingControlledValue) {\n return <Skeleton width=\"100%\" />\n }\n\n return (\n <Autocomplete<UserGroupHeader, false, false, false>\n id={inputId}\n value={resolvedValue}\n inputValue={inputValue}\n onInputChange={(_event, newInputValue, reason) => {\n if (reason === 'selectOption' || reason === 'reset') {\n // After an option is selected/removed, clear the input text so it's ready for the next search.\n setInputValue('')\n } else {\n setInputValue(newInputValue)\n }\n }}\n // When a value is selected, clicking the badge area should re-open the search.\n openOnFocus={resolvedValue !== null}\n onOpen={() => {\n setIsSearching(true)\n }}\n onClose={() => setIsSearching(false)}\n options={options}\n filterOptions={x => x}\n loading={isLoading || inputValue !== debouncedInput}\n isOptionEqualToValue={(option, val) => option.ownerId === val.ownerId}\n getOptionLabel={option => option.userName}\n renderOption={(optionProps, option) => (\n <li {...optionProps} key={option.ownerId}>\n <UserOrTeamBadge\n userGroupHeader={option}\n disableHref\n showFullName\n showCardOnHover={false}\n />\n </li>\n )}\n renderInput={({\n inputProps: inputPropsFromParams,\n InputProps: InputPropsFromParams,\n ...params\n }) => (\n <TextField\n {...params}\n placeholder={showBadge ? undefined : placeholderText}\n autoFocus={autoFocus}\n slotProps={{\n htmlInput: {\n ...inputPropsFromParams,\n // While the badge is displayed, hide the underlying input text and cursor.\n // Merge custom styles with parent styles to preserve mouse selection and other behaviors.\n style: {\n ...inputPropsFromParams.style,\n ...(showBadge ? { color: 'transparent' } : {}),\n },\n },\n input: {\n ...InputPropsFromParams,\n startAdornment: showBadge ? (\n <Box sx={{ ml: 1 }}>\n <UserOrTeamBadge\n userGroupHeader={resolvedValue}\n disableHref\n showFullName\n showCardOnHover={false}\n />\n </Box>\n ) : undefined,\n },\n }}\n />\n )}\n onChange={(_event, newValue) => {\n if (!isControlled) {\n setInternalValue(newValue)\n }\n onChange?.(\n newValue?.ownerId != null ? newValue.ownerId.toString() : null,\n newValue ?? null,\n )\n }}\n noOptionsText={\n isLoading || inputValue !== debouncedInput ? 'Loading…' : 'No options'\n }\n clearOnEscape\n />\n )\n}\n\nexport default UserSearchBox\n"],"mappings":";;;;;;;;;AAmCA,SAAS,EAAc,GAA2B;CAChD,IAAM,EACJ,YACA,kBAAe,MACf,aACA,oBACA,eACA,gBACA,eAAY,IACZ,OAAO,MACL,GAEE,IAAe,MAAc,KAAA,GAE7B,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAgB,KAAqB,EAAS,GAAG;AACxD,SACQ;AACJ,IAAkB,EAAW;IAE/B,CAAC,EAAW,EACZ,IACD;CAID,IAAM,CAAC,GAAa,KAAkB,EAAS,GAAM,EAG/C,EAAE,MAAM,GAAwB,WAAW,MAC/C,EAAsB,KAAgB,IAAI,EACxC,SAAS,CAAC,CAAC,KAAgB,CAAC,GAC7B,CAAC,EAGE,IACJ,KAAgB,OAAO,KAAc,WAAW,IAAY,MAExD,EACJ,MAAM,GACN,WAAW,MACT,EAAsB,KAAyB,IAAI,EACrD,SAAS,CAAC,CAAC,GACZ,CAAC,EAMI,CAAC,GAAe,KAAoB,EAExC,KAAA,EAAU,EAMN,IAAwC,IAH5C,OAAO,KAAc,WAAW,KAA4B,OAAO,OAEnE,MAAkB,KAAA,IAA4B,KAA0B,OAA1C,GAO1B,IAAY,MAAkB,QAAQ,CAAC,GAGvC,EAAE,SAAM,iBAAc,EAC1B,GACA,GACA,EACE,SAAS,CALY,CAAC,GAMvB,CACF,EAEK,IAAU,SACP,KAAQ,EAAE,EAAE,OAAO,YAA0B,IAAM,EAC1D,CAAC,GAAM,EAAgB,CACxB,EAEK,IAAkB,QAClB,MAAgB,KAAA,IAET,KAAc,EAAY,aAC5B,0BACE,KAAc,EAAY,aAC5B,cAEA,uCANA,GAQR,CAAC,GAAa,EAAW,CAAC;AAM7B,QAJI,KAAyB,IACpB,kBAAC,GAAD,EAAU,OAAM,QAAS,CAAA,GAIhC,kBAAC,GAAD;EACE,IAAI;EACJ,OAAO;EACK;EACZ,gBAAgB,GAAQ,GAAe,MAAW;AAChD,GAEE,EAFE,MAAW,kBAAkB,MAAW,UAE5B,KAEA,EAAc;;EAIhC,aAAa,MAAkB;EAC/B,cAAc;AACZ,KAAe,GAAK;;EAEtB,eAAe,EAAe,GAAM;EAC3B;EACT,gBAAe,MAAK;EACpB,SAAS,KAAa,MAAe;EACrC,uBAAuB,GAAQ,MAAQ,EAAO,YAAY,EAAI;EAC9D,iBAAgB,MAAU,EAAO;EACjC,eAAe,GAAa,MAC1B,kBAAC,MAAD;GAAI,GAAI;GAAa,KAAK,EAAO;GAO5B,EANH,kBAAC,GAAD;GACE,iBAAiB;GACjB,aAAA;GACA,cAAA;GACA,iBAAiB;GACjB,CAAA,CACC;EAEP,cAAc,EACZ,YAAY,GACZ,YAAY,GACZ,GAAG,QAEH,kBAAC,GAAD;GACE,GAAI;GACJ,aAAa,IAAY,KAAA,IAAY;GAC1B;GACX,WAAW;IACT,WAAW;KACT,GAAG;KAGH,OAAO;MACL,GAAG,EAAqB;MACxB,GAAI,IAAY,EAAE,OAAO,eAAe,GAAG,EAAE;MAC9C;KACF;IACD,OAAO;KACL,GAAG;KACH,gBAAgB,IACd,kBAAC,GAAD;MAAK,IAAI,EAAE,IAAI,GAAG;gBAChB,kBAAC,GAAD;OACE,iBAAiB;OACjB,aAAA;OACA,cAAA;OACA,iBAAiB;OACjB,CAAA;MACE,CAAA,GACJ,KAAA;KACL;IACF;GACD,CAAA;EAEJ,WAAW,GAAQ,MAAa;AAI9B,GAHK,KACH,EAAiB,EAAS,EAE5B,IACE,GAAU,WAAW,OAAqC,OAA9B,EAAS,QAAQ,UAAU,EACvD,KAAY,KACb;;EAEH,eACE,KAAa,MAAe,IAAiB,aAAa;EAE5D,eAAA;EACA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookDashboard.js","names":[],"sources":["../../../src/components/Webhook/WebhookDashboard.tsx"],"sourcesContent":["import InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport {\n useGetWebhooksInfinite,\n useResendVerificationCode,\n} from '@/synapse-queries/webhook/useWebhook'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { AddCircleTwoTone } from '@mui/icons-material'\nimport {\n Box,\n Button,\n Link,\n Stack,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport {\n SynapseObjectType,\n Webhook,\n WebhookVerificationStatus,\n} from '@sage-bionetworks/synapse-client'\nimport {\n createColumnHelper,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport dayjs from 'dayjs'\nimport { upperFirst } from 'lodash-es'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { EntityLink } from '../EntityLink'\nimport { HelpPopover } from '../HelpPopover/HelpPopover'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport StyledTanStackTable from '../TanStackTable/StyledTanStackTable'\nimport CreateWebhookModal from './CreateWebhookModal'\nimport { WebhookVerificationDialog } from './WebhookVerificationDialog'\n\nconst WEBHOOK_CAN_RESEND_CODE_STATES: WebhookVerificationStatus[] = [\n WebhookVerificationStatus.FAILED,\n WebhookVerificationStatus.REVOKED,\n]\n\nconst columnHelper = createColumnHelper<Webhook>()\n\nfunction getWebhookTableColumns(\n onClickVerifyWebhook: (webhook: Webhook) => void,\n onClickResendVerificationCode: (webhook: Webhook) => void,\n onClickEditWebhook: (webhook: Webhook) => void,\n) {\n return [\n columnHelper.accessor('id', {\n header: 'ID',\n size: 75,\n cell: ctx => ctx.cell.getValue(),\n }),\n columnHelper.display({\n header: 'Object',\n cell: ctx => {\n if (ctx.row.original.objectType === SynapseObjectType.ENTITY) {\n return (\n <>\n <EntityLink entity={ctx.row.original.objectId!} /> (syn\n {ctx.row.original.objectId})\n </>\n )\n }\n return `${ctx.row.original.objectType}: ${ctx.row.original.objectId}`\n },\n }),\n columnHelper.accessor('eventTypes', {\n header: 'Event Type(s)',\n cell: ctx => (\n <Stack>\n {Array.from<string>(ctx.cell.getValue()!)\n .map(s => s.toLowerCase())\n .map(upperFirst)\n .map(val => (\n <span key={val}>{val}</span>\n ))}\n </Stack>\n ),\n }),\n columnHelper.accessor('isEnabled', {\n header: 'Enabled',\n size: 10,\n cell: ctx => (ctx.cell.getValue() ? 'Yes' : 'No'),\n }),\n columnHelper.accessor('createdOn', {\n header: 'Created On',\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n }),\n columnHelper.accessor('modifiedOn', {\n header: 'Modified On',\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n }),\n columnHelper.accessor('verificationStatus', {\n header: 'Verification Status',\n cell: ctx => (\n <Stack\n sx={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: 1,\n }}\n >\n {ctx.row.original.verificationStatus === 'PENDING' && (\n // useEffect above will trigger a refetch until this resolves\n <SynapseSpinner size={20} />\n )}\n {ctx.row.original.verificationStatus !==\n WebhookVerificationStatus.PENDING &&\n upperFirst(\n (ctx.row.original.verificationStatus || '')\n .toLowerCase()\n .replaceAll('_', ' '),\n )}\n {ctx.row.original.verificationMsg && (\n <HelpPopover markdownText={ctx.row.original.verificationMsg} />\n )}\n </Stack>\n ),\n }),\n columnHelper.display({\n id: 'actions',\n header: 'Actions',\n size: 10,\n meta: {\n textAlign: 'right',\n },\n cell: ctx => (\n <Stack\n sx={{\n flexDirection: 'row',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: 2,\n }}\n >\n {ctx.row.original.verificationStatus ===\n WebhookVerificationStatus.CODE_SENT && (\n <Button\n variant={'outlined'}\n onClick={() => {\n onClickVerifyWebhook(ctx.row.original)\n }}\n >\n Verify code\n </Button>\n )}\n\n {WEBHOOK_CAN_RESEND_CODE_STATES.includes(\n ctx.row.original.verificationStatus as WebhookVerificationStatus,\n ) && (\n <Button\n variant={'outlined'}\n onClick={() => {\n onClickResendVerificationCode(ctx.row.original)\n }}\n >\n Resend code\n </Button>\n )}\n <Button\n size=\"small\"\n variant=\"contained\"\n onClick={() => {\n onClickEditWebhook(ctx.row.original)\n }}\n >\n Edit\n </Button>\n </Stack>\n ),\n }),\n ]\n}\n\nexport default function WebhookDashboard() {\n const [showCreateModal, setShowCreateModal] = useState(false)\n const [showVerificationDialog, setShowVerificationDialog] = useState(false)\n const [webhookToUpdate, setWebhookToUpdate] = useState<Webhook | undefined>(\n undefined,\n )\n\n const theme = useTheme()\n const hideOptionalColumns = useMediaQuery(theme.breakpoints.down('md'))\n\n const {\n data: infiniteData,\n refetch,\n hasNextPage,\n fetchNextPage,\n isFetchingNextPage,\n isLoading,\n } = useGetWebhooksInfinite()\n const webhooks = useMemo(\n () => infiniteData?.pages.flatMap(page => page.page!) ?? [],\n [infiniteData],\n )\n\n // If the Webhook verification status is PENDING, Synapse may not have sent the verification code, or may have not reported a response.\n // Refetch on an interval to check if the verification status has changed.\n useEffect(() => {\n let intervalId: NodeJS.Timeout\n if (webhooks.some(webhook => webhook.verificationStatus === 'PENDING')) {\n intervalId = setInterval(() => {\n void refetch()\n }, 2500)\n }\n return () => clearInterval(intervalId)\n }, [refetch, webhooks])\n\n const { mutate: resendVerificationCode } = useResendVerificationCode()\n\n const onClickVerifyWebhook = useCallback((webhook: Webhook) => {\n setWebhookToUpdate(webhook)\n setShowVerificationDialog(true)\n }, [])\n const onClickEditWebhook = useCallback((webhook: Webhook) => {\n setWebhookToUpdate(webhook)\n setShowCreateModal(true)\n }, [])\n const onClickResendVerificationCode = useCallback(\n (webhook: Webhook) => {\n resendVerificationCode(webhook.id!)\n },\n [resendVerificationCode],\n )\n\n const columns = useMemo(\n () =>\n getWebhookTableColumns(\n onClickVerifyWebhook,\n onClickResendVerificationCode,\n onClickEditWebhook,\n ),\n [onClickEditWebhook, onClickResendVerificationCode, onClickVerifyWebhook],\n )\n\n const webhookTable = useReactTable<Webhook>({\n data: webhooks,\n columns: columns,\n state: {\n columnVisibility: {\n createdOn: !hideOptionalColumns,\n modifiedOn: !hideOptionalColumns,\n },\n },\n getCoreRowModel: getCoreRowModel(),\n })\n\n const isEmpty = !isLoading && webhookTable.getRowModel().rows.length === 0\n\n return (\n <div>\n <WebhookVerificationDialog\n key={webhookToUpdate?.id}\n open={showVerificationDialog}\n onClose={() => setShowVerificationDialog(false)}\n webhookId={webhookToUpdate?.id!}\n />\n <Typography variant={'headline3'}>Webhook Dashboard</Typography>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n my: 2,\n gap: 3,\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n }}\n >\n <div>\n <Typography variant={'body1'} gutterBottom>\n Webhooks can be used to programmatically receive alerts that are\n triggered by events in Synapse. A webhook can specify a Synapse\n entity to receive events related to that entity. For entities that\n represent a container (folder and project), matching events are\n published to the webhook endpoint for any entity in its hierarchy.\n </Typography>\n <Typography variant={'body1'} gutterBottom>\n For more information, see the{' '}\n <Link\n href={\n 'http://dev.release.rest.doc.sagebase.org.s3-website-us-east-1.amazonaws.com/index.html#org.sagebionetworks.repo.web.controller.WebhookController'\n }\n target={'blank'}\n >\n Synapse API REST Docs section on Webhooks\n </Link>\n .\n </Typography>\n </div>\n <Button\n size=\"large\"\n variant=\"contained\"\n startIcon={<AddCircleTwoTone />}\n onClick={() => {\n setWebhookToUpdate(undefined)\n setShowCreateModal(true)\n }}\n sx={{ flexShrink: 0 }}\n >\n Create Webhook\n </Button>\n <CreateWebhookModal\n initialData={webhookToUpdate}\n open={showCreateModal}\n onClose={() => setShowCreateModal(false)}\n />\n </Box>\n <InfiniteTableLayout\n table={<StyledTanStackTable table={webhookTable} />}\n isLoading={isLoading}\n noResults={\n <Typography variant=\"body1\">\n You have not created any webhooks. Click &quot;Create Webhook&quot;\n above to begin.\n </Typography>\n }\n isEmpty={isEmpty}\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"WebhookDashboard.js","names":[],"sources":["../../../src/components/Webhook/WebhookDashboard.tsx"],"sourcesContent":["import InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport {\n useGetWebhooksInfinite,\n useResendVerificationCode,\n} from '@/synapse-queries/webhook/useWebhook'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { AddCircleTwoTone } from '@mui/icons-material'\nimport {\n Box,\n Button,\n Link,\n Stack,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport {\n SynapseObjectType,\n Webhook,\n WebhookVerificationStatus,\n} from '@sage-bionetworks/synapse-client'\nimport {\n createColumnHelper,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport dayjs from 'dayjs'\nimport { upperFirst } from 'lodash-es'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { EntityLink } from '../EntityLink'\nimport { HelpPopover } from '../HelpPopover/HelpPopover'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport StyledTanStackTable from '../TanStackTable/StyledTanStackTable'\nimport CreateWebhookModal from './CreateWebhookModal'\nimport { WebhookVerificationDialog } from './WebhookVerificationDialog'\n\nconst WEBHOOK_CAN_RESEND_CODE_STATES: WebhookVerificationStatus[] = [\n WebhookVerificationStatus.FAILED,\n WebhookVerificationStatus.REVOKED,\n]\n\nconst columnHelper = createColumnHelper<Webhook>()\n\nfunction getWebhookTableColumns(\n onClickVerifyWebhook: (webhook: Webhook) => void,\n onClickResendVerificationCode: (webhook: Webhook) => void,\n onClickEditWebhook: (webhook: Webhook) => void,\n) {\n return [\n columnHelper.accessor('id', {\n header: 'ID',\n size: 75,\n cell: ctx => ctx.cell.getValue(),\n }),\n columnHelper.display({\n header: 'Object',\n cell: ctx => {\n if (ctx.row.original.objectType === SynapseObjectType.ENTITY) {\n return (\n <>\n <EntityLink entity={ctx.row.original.objectId!} /> (syn\n {ctx.row.original.objectId})\n </>\n )\n }\n return `${ctx.row.original.objectType}: ${ctx.row.original.objectId}`\n },\n }),\n columnHelper.accessor('eventTypes', {\n header: 'Event Type(s)',\n cell: ctx => (\n <Stack>\n {Array.from<string>(ctx.cell.getValue()!)\n .map(s => s.toLowerCase())\n .map(upperFirst)\n .map(val => (\n <span key={val}>{val}</span>\n ))}\n </Stack>\n ),\n }),\n columnHelper.accessor('isEnabled', {\n header: 'Enabled',\n size: 10,\n cell: ctx => (ctx.cell.getValue() ? 'Yes' : 'No'),\n }),\n columnHelper.accessor('createdOn', {\n header: 'Created On',\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n }),\n columnHelper.accessor('modifiedOn', {\n header: 'Modified On',\n cell: ({ getValue }) => formatDate(dayjs(getValue())),\n }),\n columnHelper.accessor('verificationStatus', {\n header: 'Verification Status',\n cell: ctx => (\n <Stack\n sx={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: 1,\n }}\n >\n {ctx.row.original.verificationStatus === 'PENDING' && (\n // useEffect above will trigger a refetch until this resolves\n <SynapseSpinner size={20} />\n )}\n {ctx.row.original.verificationStatus !==\n WebhookVerificationStatus.PENDING &&\n upperFirst(\n (ctx.row.original.verificationStatus || '')\n .toLowerCase()\n .replaceAll('_', ' '),\n )}\n {ctx.row.original.verificationMsg && (\n <HelpPopover markdownText={ctx.row.original.verificationMsg} />\n )}\n </Stack>\n ),\n }),\n columnHelper.display({\n id: 'actions',\n header: 'Actions',\n size: 10,\n meta: {\n textAlign: 'right',\n },\n cell: ctx => (\n <Stack\n sx={{\n flexDirection: 'row',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: 2,\n }}\n >\n {ctx.row.original.verificationStatus ===\n WebhookVerificationStatus.CODE_SENT && (\n <Button\n variant={'outlined'}\n onClick={() => {\n onClickVerifyWebhook(ctx.row.original)\n }}\n >\n Verify code\n </Button>\n )}\n\n {WEBHOOK_CAN_RESEND_CODE_STATES.includes(\n ctx.row.original.verificationStatus as WebhookVerificationStatus,\n ) && (\n <Button\n variant={'outlined'}\n onClick={() => {\n onClickResendVerificationCode(ctx.row.original)\n }}\n >\n Resend code\n </Button>\n )}\n <Button\n size=\"small\"\n variant=\"contained\"\n onClick={() => {\n onClickEditWebhook(ctx.row.original)\n }}\n >\n Edit\n </Button>\n </Stack>\n ),\n }),\n ]\n}\n\nexport default function WebhookDashboard() {\n const [showCreateModal, setShowCreateModal] = useState(false)\n const [showVerificationDialog, setShowVerificationDialog] = useState(false)\n const [webhookToUpdate, setWebhookToUpdate] = useState<Webhook | undefined>(\n undefined,\n )\n\n const theme = useTheme()\n const hideOptionalColumns = useMediaQuery(theme.breakpoints.down('md'))\n\n const {\n data: infiniteData,\n refetch,\n hasNextPage,\n fetchNextPage,\n isFetchingNextPage,\n isLoading,\n } = useGetWebhooksInfinite()\n const webhooks = useMemo(\n () => infiniteData?.pages.flatMap(page => page.page!) ?? [],\n [infiniteData],\n )\n\n // If the Webhook verification status is PENDING, Synapse may not have sent the verification code, or may have not reported a response.\n // Refetch on an interval to check if the verification status has changed.\n useEffect(() => {\n let intervalId: NodeJS.Timeout\n if (webhooks.some(webhook => webhook.verificationStatus === 'PENDING')) {\n intervalId = setInterval(() => {\n void refetch()\n }, 2500)\n }\n return () => clearInterval(intervalId)\n }, [refetch, webhooks])\n\n const { mutate: resendVerificationCode } = useResendVerificationCode()\n\n const onClickVerifyWebhook = useCallback((webhook: Webhook) => {\n setWebhookToUpdate(webhook)\n setShowVerificationDialog(true)\n }, [])\n const onClickEditWebhook = useCallback((webhook: Webhook) => {\n setWebhookToUpdate(webhook)\n setShowCreateModal(true)\n }, [])\n const onClickResendVerificationCode = useCallback(\n (webhook: Webhook) => {\n resendVerificationCode(webhook.id!)\n },\n [resendVerificationCode],\n )\n\n const columns = useMemo(\n () =>\n getWebhookTableColumns(\n onClickVerifyWebhook,\n onClickResendVerificationCode,\n onClickEditWebhook,\n ),\n [onClickEditWebhook, onClickResendVerificationCode, onClickVerifyWebhook],\n )\n\n const webhookTable = useReactTable<Webhook>({\n data: webhooks,\n columns: columns,\n state: {\n columnVisibility: {\n createdOn: !hideOptionalColumns,\n modifiedOn: !hideOptionalColumns,\n },\n },\n getCoreRowModel: getCoreRowModel(),\n })\n\n const isEmpty = !isLoading && webhookTable.getRowModel().rows.length === 0\n\n return (\n <div>\n <WebhookVerificationDialog\n key={webhookToUpdate?.id}\n open={showVerificationDialog}\n onClose={() => setShowVerificationDialog(false)}\n webhookId={webhookToUpdate?.id!}\n />\n <Typography variant={'headline3'}>Webhook Dashboard</Typography>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n my: 2,\n gap: 3,\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n }}\n >\n <div>\n <Typography variant={'body1'} gutterBottom>\n Webhooks can be used to programmatically receive alerts that are\n triggered by events in Synapse. A webhook can specify a Synapse\n entity to receive events related to that entity. For entities that\n represent a container (folder and project), matching events are\n published to the webhook endpoint for any entity in its hierarchy.\n </Typography>\n <Typography variant={'body1'} gutterBottom>\n For more information, see the{' '}\n <Link\n href={\n 'http://dev.release.rest.doc.sagebase.org.s3-website-us-east-1.amazonaws.com/index.html#org.sagebionetworks.repo.web.controller.WebhookController'\n }\n target={'blank'}\n >\n Synapse API REST Docs section on Webhooks\n </Link>\n .\n </Typography>\n </div>\n <Button\n size=\"large\"\n variant=\"contained\"\n startIcon={<AddCircleTwoTone />}\n onClick={() => {\n setWebhookToUpdate(undefined)\n setShowCreateModal(true)\n }}\n sx={{ flexShrink: 0 }}\n >\n Create Webhook\n </Button>\n <CreateWebhookModal\n initialData={webhookToUpdate}\n open={showCreateModal}\n onClose={() => setShowCreateModal(false)}\n />\n </Box>\n <InfiniteTableLayout\n table={<StyledTanStackTable table={webhookTable} />}\n isLoading={isLoading}\n noResults={\n <Typography variant=\"body1\">\n You have not created any webhooks. Click &quot;Create Webhook&quot;\n above to begin.\n </Typography>\n }\n isEmpty={isEmpty}\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n </div>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WikiMarkdownEditor.js","names":[],"sources":["../../../src/components/WikiMarkdownEditor/WikiMarkdownEditor.tsx"],"sourcesContent":["import { UpdateWikiPageInput, useUpdateWikiPage } from '@/synapse-queries'\nimport { Alert, Box, Button, TextField } from '@mui/material'\nimport { ObjectType, WikiPage } from '@sage-bionetworks/synapse-types'\nimport { noop } from 'lodash-es'\nimport { useState } from 'react'\nimport ConfirmationDialog from '../ConfirmationDialog'\nimport { DialogBase } from '../DialogBase'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport { MarkdownEditor } from '../Markdown/MarkdownEditor'\n\nexport const UNSAVED_CHANGES = 'Unsaved Changes'\nexport const NAVIGATE_AWAY_CONFIRMATION_MESSAGE =\n 'Any unsaved changes may be lost. Are you sure that you would like to navigate away from this editor?'\nexport const ERROR_SAVING_WIKI =\n 'Could not save your changes. It is recommended that you copy your version of the wiki text so that it is not lost. '\n\nexport type WikiMarkdownEditorProps = {\n open: boolean\n ownerObjectType: ObjectType\n ownerObjectId: string\n wikiPage: WikiPage\n onCancel?: () => void\n onSave?: () => void\n // TODO: SWC-6774 - expose delete prop\n // showDeleteButton: boolean\n}\n\nexport function WikiMarkdownEditor(props: WikiMarkdownEditorProps) {\n // TODO: SWC-6774 - get showDeleteButton from props\n const showDeleteButton = false\n const {\n open,\n ownerObjectId,\n ownerObjectType,\n wikiPage,\n onCancel = noop,\n onSave = noop,\n } = props\n\n const [title, setTitle] = useState<string>(wikiPage.title)\n const [markdown, setMarkdown] = useState<string>(wikiPage.markdown)\n const [showConfirmCancelDialog, setShowConfirmDialog] =\n useState<boolean>(false)\n\n const handleCancel = () => {\n if (wikiPage && wikiPage.markdown !== markdown) {\n setShowConfirmDialog(true)\n } else {\n onCancel()\n }\n }\n\n const {\n mutate: updateWikiPage,\n isPending: isUpdatingWikiPage,\n error: errorUpdatingWikiPage,\n } = useUpdateWikiPage({\n onSuccess: () => onSave(),\n })\n\n return (\n <DialogBase\n open={open}\n onCancel={handleCancel}\n maxWidth={'xl'}\n fullWidth={true}\n title=\"Edit Wiki Markdown\"\n content={\n <>\n {isUpdatingWikiPage && <SynapseSpinner />}\n {wikiPage && (\n <>\n {wikiPage.parentWikiId && (\n <TextField\n label=\"Title\"\n placeholder=\"Title\"\n fullWidth\n sx={{ mb: 2 }}\n value={title}\n onChange={e => setTitle(e.target.value)}\n />\n )}\n <MarkdownEditor text={markdown} setText={setMarkdown} />\n <ConfirmationDialog\n open={showConfirmCancelDialog}\n title={UNSAVED_CHANGES}\n content={NAVIGATE_AWAY_CONFIRMATION_MESSAGE}\n onCancel={() => setShowConfirmDialog(false)}\n onConfirm={() => {\n setShowConfirmDialog(false)\n onCancel()\n }}\n />\n </>\n )}\n {errorUpdatingWikiPage && (\n <Alert severity=\"error\">\n {ERROR_SAVING_WIKI + errorUpdatingWikiPage.reason}\n </Alert>\n )}\n </>\n }\n actions={\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row-reverse',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <Box\n sx={{\n display: 'flex',\n gap: 1,\n }}\n >\n <Button\n variant=\"outlined\"\n disabled={isUpdatingWikiPage}\n onClick={handleCancel}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={isUpdatingWikiPage}\n onClick={() => {\n if (wikiPage) {\n const input: UpdateWikiPageInput = {\n ownerObjectId,\n ownerObjectType,\n wikiPage: { ...wikiPage, title: title, markdown: markdown },\n }\n updateWikiPage(input)\n }\n }}\n >\n {isUpdatingWikiPage ? 'Saving...' : 'Save'}\n </Button>\n </Box>\n {showDeleteButton && (\n <Button\n variant=\"contained\"\n color=\"error\"\n disabled={isUpdatingWikiPage}\n onClick={() => {\n // TODO: SWC-6774 - implement delete functionality\n }}\n >\n Delete Page\n </Button>\n )}\n </Box>\n }\n />\n )\n}\n\nexport default WikiMarkdownEditor\n"],"mappings":";;;;;;;;;;;AAUA,IAAa,IAAkB,mBAClB,IACX,wGACW,IACX;AAaF,SAAgB,EAAmB,GAAgC;CAEjE,IACM,EACJ,SACA,kBACA,oBACA,aACA,cAAW,GACX,YAAS,MACP,GAEE,CAAC,GAAO,KAAY,EAAiB,EAAS,MAAM,EACpD,CAAC,GAAU,KAAe,EAAiB,EAAS,SAAS,EAC7D,CAAC,GAAyB,KAC9B,EAAkB,GAAM,EAEpB,UAAqB;AACzB,EAAI,KAAY,EAAS,aAAa,IACpC,EAAqB,GAAK,GAE1B,GAAU;IAIR,EACJ,QAAQ,GACR,WAAW,GACX,OAAO,MACL,EAAkB,EACpB,iBAAiB,GAAQ,EAC1B,CAAC;AAEF,QACE,kBAAC,GAAD;EACQ;EACN,UAAU;EACV,UAAU;EACV,WAAW;EACX,OAAM;EACN,SACE,kBAAA,GAAA,EAAA,UAAA;GACG,KAAsB,kBAAC,GAAD,EAAkB,CAAA;GACxC,KACC,kBAAA,GAAA,EAAA,UAAA;IACG,EAAS,gBACR,kBAAC,GAAD;KACE,OAAM;KACN,aAAY;KACZ,WAAA;KACA,IAAI,EAAE,IAAI,GAAG;KACb,OAAO;KACP,WAAU,MAAK,EAAS,EAAE,OAAO,MAAM;KACvC,CAAA;IAEJ,kBAAC,GAAD;KAAgB,MAAM;KAAU,SAAS;KAAe,CAAA;IACxD,kBAAC,GAAD;KACE,MAAM;KACN,OAAA;KACA,SAAA;KACA,gBAAgB,EAAqB,GAAM;KAC3C,iBAAiB;AAEf,MADA,EAAqB,GAAM,EAC3B,GAAU;;KAEZ,CAAA;IACD,EAAA,CAAA;GAEJ,KACC,kBAAC,GAAD;IAAO,UAAS;sIACO,EAAsB;IACrC,CAAA;GAET,EAAA,CAAA;EAEL,SACE,kBAAC,GAAD;GACE,IAAI;IACF,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,OAAO;IACR;aANH,CAQE,kBAAC,GAAD;IACE,IAAI;KACF,SAAS;KACT,KAAK;KACN;cAJH,CAME,kBAAC,GAAD;KACE,SAAQ;KACR,UAAU;KACV,SAAS;eACV;KAEQ,CAAA,EACT,kBAAC,GAAD;KACE,SAAQ;KACR,OAAM;KACN,UAAU;KACV,eAAe;AACb,MAAI,KAMF,EALmC;OACjC;OACA;OACA,UAAU;QAAE,GAAG;QAAiB;QAAiB;QAAU;OAC5D,CACoB;;eAIxB,IAAqB,cAAc;KAC7B,CAAA,CACL;OACL,GAYG;;EAER,CAAA"}
1
+ {"version":3,"file":"WikiMarkdownEditor.js","names":[],"sources":["../../../src/components/WikiMarkdownEditor/WikiMarkdownEditor.tsx"],"sourcesContent":["import { UpdateWikiPageInput, useUpdateWikiPage } from '@/synapse-queries'\nimport { Alert, Box, Button, TextField } from '@mui/material'\nimport { ObjectType, WikiPage } from '@sage-bionetworks/synapse-types'\nimport { noop } from 'lodash-es'\nimport { useState } from 'react'\nimport ConfirmationDialog from '../ConfirmationDialog'\nimport { DialogBase } from '../DialogBase'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport { MarkdownEditor } from '../Markdown/MarkdownEditor'\n\nexport const UNSAVED_CHANGES = 'Unsaved Changes'\nexport const NAVIGATE_AWAY_CONFIRMATION_MESSAGE =\n 'Any unsaved changes may be lost. Are you sure that you would like to navigate away from this editor?'\nexport const ERROR_SAVING_WIKI =\n 'Could not save your changes. It is recommended that you copy your version of the wiki text so that it is not lost. '\n\nexport type WikiMarkdownEditorProps = {\n open: boolean\n ownerObjectType: ObjectType\n ownerObjectId: string\n wikiPage: WikiPage\n onCancel?: () => void\n onSave?: () => void\n // TODO: SWC-6774 - expose delete prop\n // showDeleteButton: boolean\n}\n\nexport function WikiMarkdownEditor(props: WikiMarkdownEditorProps) {\n // TODO: SWC-6774 - get showDeleteButton from props\n const showDeleteButton = false\n const {\n open,\n ownerObjectId,\n ownerObjectType,\n wikiPage,\n onCancel = noop,\n onSave = noop,\n } = props\n\n const [title, setTitle] = useState<string>(wikiPage.title)\n const [markdown, setMarkdown] = useState<string>(wikiPage.markdown)\n const [showConfirmCancelDialog, setShowConfirmDialog] =\n useState<boolean>(false)\n\n const handleCancel = () => {\n if (wikiPage && wikiPage.markdown !== markdown) {\n setShowConfirmDialog(true)\n } else {\n onCancel()\n }\n }\n\n const {\n mutate: updateWikiPage,\n isPending: isUpdatingWikiPage,\n error: errorUpdatingWikiPage,\n } = useUpdateWikiPage({\n onSuccess: () => onSave(),\n })\n\n return (\n <DialogBase\n open={open}\n onCancel={handleCancel}\n maxWidth={'xl'}\n fullWidth={true}\n title=\"Edit Wiki Markdown\"\n content={\n <>\n {isUpdatingWikiPage && <SynapseSpinner />}\n {wikiPage && (\n <>\n {wikiPage.parentWikiId && (\n <TextField\n label=\"Title\"\n placeholder=\"Title\"\n fullWidth\n sx={{ mb: 2 }}\n value={title}\n onChange={e => setTitle(e.target.value)}\n />\n )}\n <MarkdownEditor text={markdown} setText={setMarkdown} />\n <ConfirmationDialog\n open={showConfirmCancelDialog}\n title={UNSAVED_CHANGES}\n content={NAVIGATE_AWAY_CONFIRMATION_MESSAGE}\n onCancel={() => setShowConfirmDialog(false)}\n onConfirm={() => {\n setShowConfirmDialog(false)\n onCancel()\n }}\n />\n </>\n )}\n {errorUpdatingWikiPage && (\n <Alert severity=\"error\">\n {ERROR_SAVING_WIKI + errorUpdatingWikiPage.reason}\n </Alert>\n )}\n </>\n }\n actions={\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row-reverse',\n justifyContent: 'space-between',\n width: '100%',\n }}\n >\n <Box\n sx={{\n display: 'flex',\n gap: 1,\n }}\n >\n <Button\n variant=\"outlined\"\n disabled={isUpdatingWikiPage}\n onClick={handleCancel}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={isUpdatingWikiPage}\n onClick={() => {\n if (wikiPage) {\n const input: UpdateWikiPageInput = {\n ownerObjectId,\n ownerObjectType,\n wikiPage: { ...wikiPage, title: title, markdown: markdown },\n }\n updateWikiPage(input)\n }\n }}\n >\n {isUpdatingWikiPage ? 'Saving...' : 'Save'}\n </Button>\n </Box>\n {showDeleteButton && (\n <Button\n variant=\"contained\"\n color=\"error\"\n disabled={isUpdatingWikiPage}\n onClick={() => {\n // TODO: SWC-6774 - implement delete functionality\n }}\n >\n Delete Page\n </Button>\n )}\n </Box>\n }\n />\n )\n}\n\nexport default WikiMarkdownEditor\n"],"mappings":";;;;;;;;;;;AAUA,IAAa,IAAkB,mBAClB,IACX,wGACW,IACX;AAaF,SAAgB,EAAmB,GAAgC;CAEjE,IACM,EACJ,SACA,kBACA,oBACA,aACA,cAAW,GACX,YAAS,MACP,GAEE,CAAC,GAAO,KAAY,EAAiB,EAAS,MAAM,EACpD,CAAC,GAAU,KAAe,EAAiB,EAAS,SAAS,EAC7D,CAAC,GAAyB,KAC9B,EAAkB,GAAM,EAEpB,UAAqB;AACzB,EAAI,KAAY,EAAS,aAAa,IACpC,EAAqB,GAAK,GAE1B,GAAU;IAIR,EACJ,QAAQ,GACR,WAAW,GACX,OAAO,MACL,EAAkB,EACpB,iBAAiB,GAAQ,EAC1B,CAAC;AAEF,QACE,kBAAC,GAAD;EACQ;EACN,UAAU;EACV,UAAU;EACV,WAAW;EACX,OAAM;EACN,SACE,kBAAA,GAAA,EAAA,UAAA;GACG,KAAsB,kBAAC,GAAD,EAAkB,CAAA;GACxC,KACC,kBAAA,GAAA,EAAA,UAAA;IACG,EAAS,gBACR,kBAAC,GAAD;KACE,OAAM;KACN,aAAY;KACZ,WAAA;KACA,IAAI,EAAE,IAAI,GAAG;KACb,OAAO;KACP,WAAU,MAAK,EAAS,EAAE,OAAO,MAAM;KACvC,CAAA;IAEJ,kBAAC,GAAD;KAAgB,MAAM;KAAU,SAAS;KAAe,CAAA;IACxD,kBAAC,GAAD;KACE,MAAM;KACN,OAAA;KACA,SAAA;KACA,gBAAgB,EAAqB,GAAM;KAC3C,iBAAiB;AAEf,MADA,EAAqB,GAAM,EAC3B,GAAU;;KAEZ,CAAA;IACD,EAAA,CAAA;GAEJ,KACC,kBAAC,GAAD;IAAO,UAAS;sIACO,EAAsB;IACrC,CAAA;GAET,EAAA,CAAA;EAEL,SACE,kBAAC,GAAD;GACE,IAAI;IACF,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,OAAO;IACR;aANH,CAQE,kBAAC,GAAD;IACE,IAAI;KACF,SAAS;KACT,KAAK;KACN;cAJH,CAME,kBAAC,GAAD;KACE,SAAQ;KACR,UAAU;KACV,SAAS;eACV;KAEQ,CAAA,EACT,kBAAC,GAAD;KACE,SAAQ;KACR,OAAM;KACN,UAAU;KACV,eAAe;AACb,MAAI,KAMF,EAAe;OAJb;OACA;OACA,UAAU;QAAE,GAAG;QAAiB;QAAiB;QAAU;OAE9C,CAAM;;eAIxB,IAAqB,cAAc;KAC7B,CAAA,CACL;OACL,GAYG;;EAER,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"WikiMarkdownEditorButton.js","names":[],"sources":["../../../src/components/WikiMarkdownEditorButton/WikiMarkdownEditorButton.tsx"],"sourcesContent":["import {\n CreateWikiPageInput,\n useCreateWikiPage,\n useGetRootWikiPageKey,\n useGetWikiPage,\n} from '@/synapse-queries'\nimport { Alert, Box, Button, ButtonProps } from '@mui/material'\nimport { ObjectType, WikiPageKey } from '@sage-bionetworks/synapse-types'\nimport { defaults } from 'lodash-es'\nimport { useMemo, useState } from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport MarkdownSynapse, {\n MarkdownSynapseProps,\n} from '../Markdown/MarkdownSynapse'\nimport WikiMarkdownEditor from '../WikiMarkdownEditor/WikiMarkdownEditor'\n\nexport const ERROR_LOADING_WIKI_FAILED = 'Failed to load the wiki page: '\nexport const DEFAULT_BUTTON_TEXT = 'Edit Wiki Page'\nconst DEFAULT_BUTTON_PROPS: Omit<ButtonProps, 'onClick'> = {\n children: DEFAULT_BUTTON_TEXT,\n color: 'primary',\n variant: 'contained',\n}\n\nexport type WikiMarkdownEditorButtonProps = {\n ownerObjectType: ObjectType\n ownerObjectId: string\n // if wikiPageId is undefined, will get (or create) the root WikiPage for this ownerObject\n // otherwise, will get the WikiPage with the specified wikiPageId\n wikiPageId?: string\n buttonProps?: Omit<ButtonProps, 'onClick' | 'disabled'>\n displayWikiMarkdown?: boolean\n}\n\nexport function WikiMarkdownEditorButton(props: WikiMarkdownEditorButtonProps) {\n const {\n ownerObjectType,\n ownerObjectId,\n wikiPageId: initialWikiPageId,\n displayWikiMarkdown = false,\n } = props\n\n const buttonProps: Omit<ButtonProps, 'onClick' | 'disabled'> = defaults(\n {},\n props.buttonProps,\n DEFAULT_BUTTON_PROPS,\n )\n\n const [open, setOpen] = useState<boolean>(false)\n\n const {\n data: rootWikiPageKey,\n isLoading: isLoadingRootWikiPageKey,\n error: errorLoadingRootWikiPageKey,\n } = useGetRootWikiPageKey(ownerObjectType, ownerObjectId, {\n enabled: initialWikiPageId === undefined,\n })\n\n const {\n mutate: createWikiPage,\n isPending: isCreatingWikiPage,\n error: errorCreatingWikiPage,\n } = useCreateWikiPage({\n onSuccess: () => setOpen(true),\n })\n\n const wikiPageKey = useMemo(() => {\n const wikiPageId = initialWikiPageId || rootWikiPageKey?.wikiPageId || ''\n const wikiPageKey: WikiPageKey = {\n ownerObjectType,\n ownerObjectId,\n wikiPageId: wikiPageId,\n }\n return wikiPageKey\n }, [initialWikiPageId, rootWikiPageKey, ownerObjectId, ownerObjectType])\n\n const {\n data: wikiPage,\n isLoading: isLoadingWikiPage,\n error: errorLoadingWikiPage,\n } = useGetWikiPage(wikiPageKey, {\n enabled: wikiPageKey.wikiPageId !== '',\n // Set staleTime to infinity to prevent re-fetching while editing\n staleTime: Infinity,\n })\n\n const error = useMemo(() => {\n if (errorLoadingRootWikiPageKey) {\n return ERROR_LOADING_WIKI_FAILED + errorLoadingRootWikiPageKey.reason\n }\n if (errorLoadingWikiPage) {\n return ERROR_LOADING_WIKI_FAILED + errorLoadingWikiPage.reason\n }\n if (errorCreatingWikiPage) {\n return errorCreatingWikiPage.reason\n }\n return null\n }, [errorLoadingRootWikiPageKey, errorLoadingWikiPage, errorCreatingWikiPage])\n\n const handleClick = () => {\n if (wikiPage) {\n setOpen(true)\n } else if (rootWikiPageKey === null) {\n // root WikiPageKey was not found,\n // then create a root WikiPage for this ownerObject\n const rootWikiPage: CreateWikiPageInput['wikiPage'] = {\n parentWikiId: undefined,\n title: '',\n markdown: '',\n attachmentFileHandleIds: [],\n }\n const input: CreateWikiPageInput = {\n ownerObjectId,\n ownerObjectType,\n wikiPage: rootWikiPage,\n }\n createWikiPage(input)\n } else {\n // Should only reach this block if there was:\n // - a non-404 error fetching the root WikiPageKey\n // - an error fetching a specific wikiPage\n // Otherwise the button should be disabled.\n console.warn(\n 'There was an error fetching the root WikiPageKey or WikiPage - address that error first.',\n )\n }\n }\n\n /* TODO - pass ownerId, objectType, wikiId directly to MarkdownSynapse after \n MarkdownSynapse is updated to fetch root WikiPages for ACCESS_REQUIREMENT object types.\n See https://sagebionetworks.jira.com/browse/SWC-6791. */\n const markdownSynapseProps = useMemo(() => {\n const markdownSynapseProps: MarkdownSynapseProps = {\n showPlaceholderIfNoWikiContent: true,\n }\n if (wikiPage) {\n return {\n ...markdownSynapseProps,\n ownerId: ownerObjectId,\n objectType: ownerObjectType,\n wikiId: wikiPage.id,\n }\n } else {\n // use a placeholder value for markdown so that MarkdownSynapse\n // displays no content placeholder for owners without root wiki pages\n return { ...markdownSynapseProps, markdown: '' }\n }\n }, [ownerObjectId, ownerObjectType, wikiPage])\n\n return (\n <>\n {displayWikiMarkdown && (\n <Box\n sx={{\n mb: 1,\n }}\n >\n {isLoadingWikiPage || isLoadingRootWikiPageKey ? (\n <SynapseSpinner />\n ) : (\n // TODO - remove key once MarkdownSynapse uses tanstack-query\n <MarkdownSynapse\n key={wikiPage?.markdown}\n {...markdownSynapseProps}\n />\n )}\n </Box>\n )}\n <Button\n onClick={handleClick}\n disabled={\n isLoadingWikiPage || isLoadingRootWikiPageKey || isCreatingWikiPage\n }\n {...buttonProps}\n />\n {error && (\n <Alert severity=\"error\" sx={{ marginTop: 2 }}>\n {error}\n </Alert>\n )}\n {wikiPage && (\n <WikiMarkdownEditor\n // Specify a key so that uncommitted changes in WikiMarkdownEditor\n // are not displayed when editor is re-opened\n key={open.toString()}\n open={open}\n ownerObjectType={ownerObjectType}\n ownerObjectId={ownerObjectId}\n wikiPage={wikiPage}\n onSave={() => setOpen(false)}\n onCancel={() => setOpen(false)}\n />\n )}\n </>\n )\n}\n\nexport default WikiMarkdownEditorButton\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,IAA4B,kCAC5B,IAAsB,kBAC7B,IAAqD;CACzD,UAAU;CACV,OAAO;CACP,SAAS;CACV;AAYD,SAAgB,EAAyB,GAAsC;CAC7E,IAAM,EACJ,oBACA,kBACA,YAAY,GACZ,yBAAsB,OACpB,GAEE,IAAyD,EAC7D,EAAE,EACF,EAAM,aACN,EACD,EAEK,CAAC,GAAM,KAAW,EAAkB,GAAM,EAE1C,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EAAsB,GAAiB,GAAe,EACxD,SAAS,MAAsB,KAAA,GAChC,CAAC,EAEI,EACJ,QAAQ,GACR,WAAW,GACX,OAAO,MACL,EAAkB,EACpB,iBAAiB,EAAQ,GAAK,EAC/B,CAAC,EAEI,IAAc,SAEe;EAC/B;EACA;EACY,YAJK,KAAqB,GAAiB,cAAc;EAKtE,GAEA;EAAC;EAAmB;EAAiB;EAAe;EAAgB,CAAC,EAElE,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EAAe,GAAa;EAC9B,SAAS,EAAY,eAAe;EAEpC,WAAW;EACZ,CAAC,EAEI,IAAQ,QACR,IACK,IAA4B,EAA4B,SAE7D,IACK,IAA4B,EAAqB,SAEtD,IACK,EAAsB,SAExB,MACN;EAAC;EAA6B;EAAsB;EAAsB,CAAC,EAExE,UAAoB;AACxB,EAAI,IACF,EAAQ,GAAK,GACJ,MAAoB,OAc7B,EALmC;GACjC;GACA;GACA,UAToD;IACpD,cAAc,KAAA;IACd,OAAO;IACP,UAAU;IACV,yBAAyB,EAAE;IAC5B;GAKA,CACoB,GAMrB,QAAQ,KACN,2FACD;IAOC,IAAuB,QAAc;EACzC,IAAM,IAA6C,EACjD,gCAAgC,IACjC;AAWC,SAVE,IACK;GACL,GAAG;GACH,SAAS;GACT,YAAY;GACZ,QAAQ,EAAS;GAClB,GAIM;GAAE,GAAG;GAAsB,UAAU;GAAI;IAEjD;EAAC;EAAe;EAAiB;EAAS,CAAC;AAE9C,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,KACC,kBAAC,GAAD;GACE,IAAI,EACF,IAAI,GACL;aAEA,KAAqB,IACpB,kBAAC,GAAD,EAAkB,CAAA,GAGlB,kBAAC,GAAD,EAEE,GAAI,GACJ,EAFK,GAAU,SAEf;GAEA,CAAA;EAER,kBAAC,GAAD;GACE,SAAS;GACT,UACE,KAAqB,KAA4B;GAEnD,GAAI;GACJ,CAAA;EACD,KACC,kBAAC,GAAD;GAAO,UAAS;GAAQ,IAAI,EAAE,WAAW,GAAG;aACzC;GACK,CAAA;EAET,KACC,kBAAC,GAAD;GAIQ;GACW;GACF;GACL;GACV,cAAc,EAAQ,GAAM;GAC5B,gBAAgB,EAAQ,GAAM;GAC9B,EAPK,EAAK,UAAU,CAOpB;EAEH,EAAA,CAAA"}
1
+ {"version":3,"file":"WikiMarkdownEditorButton.js","names":[],"sources":["../../../src/components/WikiMarkdownEditorButton/WikiMarkdownEditorButton.tsx"],"sourcesContent":["import {\n CreateWikiPageInput,\n useCreateWikiPage,\n useGetRootWikiPageKey,\n useGetWikiPage,\n} from '@/synapse-queries'\nimport { Alert, Box, Button, ButtonProps } from '@mui/material'\nimport { ObjectType, WikiPageKey } from '@sage-bionetworks/synapse-types'\nimport { defaults } from 'lodash-es'\nimport { useMemo, useState } from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport MarkdownSynapse, {\n MarkdownSynapseProps,\n} from '../Markdown/MarkdownSynapse'\nimport WikiMarkdownEditor from '../WikiMarkdownEditor/WikiMarkdownEditor'\n\nexport const ERROR_LOADING_WIKI_FAILED = 'Failed to load the wiki page: '\nexport const DEFAULT_BUTTON_TEXT = 'Edit Wiki Page'\nconst DEFAULT_BUTTON_PROPS: Omit<ButtonProps, 'onClick'> = {\n children: DEFAULT_BUTTON_TEXT,\n color: 'primary',\n variant: 'contained',\n}\n\nexport type WikiMarkdownEditorButtonProps = {\n ownerObjectType: ObjectType\n ownerObjectId: string\n // if wikiPageId is undefined, will get (or create) the root WikiPage for this ownerObject\n // otherwise, will get the WikiPage with the specified wikiPageId\n wikiPageId?: string\n buttonProps?: Omit<ButtonProps, 'onClick' | 'disabled'>\n displayWikiMarkdown?: boolean\n}\n\nexport function WikiMarkdownEditorButton(props: WikiMarkdownEditorButtonProps) {\n const {\n ownerObjectType,\n ownerObjectId,\n wikiPageId: initialWikiPageId,\n displayWikiMarkdown = false,\n } = props\n\n const buttonProps: Omit<ButtonProps, 'onClick' | 'disabled'> = defaults(\n {},\n props.buttonProps,\n DEFAULT_BUTTON_PROPS,\n )\n\n const [open, setOpen] = useState<boolean>(false)\n\n const {\n data: rootWikiPageKey,\n isLoading: isLoadingRootWikiPageKey,\n error: errorLoadingRootWikiPageKey,\n } = useGetRootWikiPageKey(ownerObjectType, ownerObjectId, {\n enabled: initialWikiPageId === undefined,\n })\n\n const {\n mutate: createWikiPage,\n isPending: isCreatingWikiPage,\n error: errorCreatingWikiPage,\n } = useCreateWikiPage({\n onSuccess: () => setOpen(true),\n })\n\n const wikiPageKey = useMemo(() => {\n const wikiPageId = initialWikiPageId || rootWikiPageKey?.wikiPageId || ''\n const wikiPageKey: WikiPageKey = {\n ownerObjectType,\n ownerObjectId,\n wikiPageId: wikiPageId,\n }\n return wikiPageKey\n }, [initialWikiPageId, rootWikiPageKey, ownerObjectId, ownerObjectType])\n\n const {\n data: wikiPage,\n isLoading: isLoadingWikiPage,\n error: errorLoadingWikiPage,\n } = useGetWikiPage(wikiPageKey, {\n enabled: wikiPageKey.wikiPageId !== '',\n // Set staleTime to infinity to prevent re-fetching while editing\n staleTime: Infinity,\n })\n\n const error = useMemo(() => {\n if (errorLoadingRootWikiPageKey) {\n return ERROR_LOADING_WIKI_FAILED + errorLoadingRootWikiPageKey.reason\n }\n if (errorLoadingWikiPage) {\n return ERROR_LOADING_WIKI_FAILED + errorLoadingWikiPage.reason\n }\n if (errorCreatingWikiPage) {\n return errorCreatingWikiPage.reason\n }\n return null\n }, [errorLoadingRootWikiPageKey, errorLoadingWikiPage, errorCreatingWikiPage])\n\n const handleClick = () => {\n if (wikiPage) {\n setOpen(true)\n } else if (rootWikiPageKey === null) {\n // root WikiPageKey was not found,\n // then create a root WikiPage for this ownerObject\n const rootWikiPage: CreateWikiPageInput['wikiPage'] = {\n parentWikiId: undefined,\n title: '',\n markdown: '',\n attachmentFileHandleIds: [],\n }\n const input: CreateWikiPageInput = {\n ownerObjectId,\n ownerObjectType,\n wikiPage: rootWikiPage,\n }\n createWikiPage(input)\n } else {\n // Should only reach this block if there was:\n // - a non-404 error fetching the root WikiPageKey\n // - an error fetching a specific wikiPage\n // Otherwise the button should be disabled.\n console.warn(\n 'There was an error fetching the root WikiPageKey or WikiPage - address that error first.',\n )\n }\n }\n\n /* TODO - pass ownerId, objectType, wikiId directly to MarkdownSynapse after \n MarkdownSynapse is updated to fetch root WikiPages for ACCESS_REQUIREMENT object types.\n See https://sagebionetworks.jira.com/browse/SWC-6791. */\n const markdownSynapseProps = useMemo(() => {\n const markdownSynapseProps: MarkdownSynapseProps = {\n showPlaceholderIfNoWikiContent: true,\n }\n if (wikiPage) {\n return {\n ...markdownSynapseProps,\n ownerId: ownerObjectId,\n objectType: ownerObjectType,\n wikiId: wikiPage.id,\n }\n } else {\n // use a placeholder value for markdown so that MarkdownSynapse\n // displays no content placeholder for owners without root wiki pages\n return { ...markdownSynapseProps, markdown: '' }\n }\n }, [ownerObjectId, ownerObjectType, wikiPage])\n\n return (\n <>\n {displayWikiMarkdown && (\n <Box\n sx={{\n mb: 1,\n }}\n >\n {isLoadingWikiPage || isLoadingRootWikiPageKey ? (\n <SynapseSpinner />\n ) : (\n // TODO - remove key once MarkdownSynapse uses tanstack-query\n <MarkdownSynapse\n key={wikiPage?.markdown}\n {...markdownSynapseProps}\n />\n )}\n </Box>\n )}\n <Button\n onClick={handleClick}\n disabled={\n isLoadingWikiPage || isLoadingRootWikiPageKey || isCreatingWikiPage\n }\n {...buttonProps}\n />\n {error && (\n <Alert severity=\"error\" sx={{ marginTop: 2 }}>\n {error}\n </Alert>\n )}\n {wikiPage && (\n <WikiMarkdownEditor\n // Specify a key so that uncommitted changes in WikiMarkdownEditor\n // are not displayed when editor is re-opened\n key={open.toString()}\n open={open}\n ownerObjectType={ownerObjectType}\n ownerObjectId={ownerObjectId}\n wikiPage={wikiPage}\n onSave={() => setOpen(false)}\n onCancel={() => setOpen(false)}\n />\n )}\n </>\n )\n}\n\nexport default WikiMarkdownEditorButton\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,IAA4B,kCAC5B,IAAsB,kBAC7B,IAAqD;CACzD,UAAU;CACV,OAAO;CACP,SAAS;CACV;AAYD,SAAgB,EAAyB,GAAsC;CAC7E,IAAM,EACJ,oBACA,kBACA,YAAY,GACZ,yBAAsB,OACpB,GAEE,IAAyD,EAC7D,EAAE,EACF,EAAM,aACN,EACD,EAEK,CAAC,GAAM,KAAW,EAAkB,GAAM,EAE1C,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EAAsB,GAAiB,GAAe,EACxD,SAAS,MAAsB,KAAA,GAChC,CAAC,EAEI,EACJ,QAAQ,GACR,WAAW,GACX,OAAO,MACL,EAAkB,EACpB,iBAAiB,EAAQ,GAAK,EAC/B,CAAC,EAEI,IAAc,SAOX;EAJL;EACA;EACY,YAJK,KAAqB,GAAiB,cAAc;EAMhE,GACN;EAAC;EAAmB;EAAiB;EAAe;EAAgB,CAAC,EAElE,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EAAe,GAAa;EAC9B,SAAS,EAAY,eAAe;EAEpC,WAAW;EACZ,CAAC,EAEI,IAAQ,QACR,IACK,IAA4B,EAA4B,SAE7D,IACK,IAA4B,EAAqB,SAEtD,IACK,EAAsB,SAExB,MACN;EAAC;EAA6B;EAAsB;EAAsB,CAAC,EAExE,UAAoB;AACxB,EAAI,IACF,EAAQ,GAAK,GACJ,MAAoB,OAc7B,EAAe;GAJb;GACA;GACA,UAAU;IARV,cAAc,KAAA;IACd,OAAO;IACP,UAAU;IACV,yBAAyB,EAAE;IAKjB;GAEG,CAAM,GAMrB,QAAQ,KACN,2FACD;IAOC,IAAuB,QAAc;EACzC,IAAM,IAA6C,EACjD,gCAAgC,IACjC;AAWC,SAVE,IACK;GACL,GAAG;GACH,SAAS;GACT,YAAY;GACZ,QAAQ,EAAS;GAClB,GAIM;GAAE,GAAG;GAAsB,UAAU;GAAI;IAEjD;EAAC;EAAe;EAAiB;EAAS,CAAC;AAE9C,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,KACC,kBAAC,GAAD;GACE,IAAI,EACF,IAAI,GACL;aAEA,KAAqB,IACpB,kBAAC,GAAD,EAAkB,CAAA,GAGlB,kBAAC,GAAD,EAEE,GAAI,GACJ,EAFK,GAAU,SAEf;GAEA,CAAA;EAER,kBAAC,GAAD;GACE,SAAS;GACT,UACE,KAAqB,KAA4B;GAEnD,GAAI;GACJ,CAAA;EACD,KACC,kBAAC,GAAD;GAAO,UAAS;GAAQ,IAAI,EAAE,WAAW,GAAG;aACzC;GACK,CAAA;EAET,KACC,kBAAC,GAAD;GAIQ;GACW;GACF;GACL;GACV,cAAc,EAAQ,GAAM;GAC5B,gBAAgB,EAAQ,GAAM;GAC9B,EAPK,EAAK,UAAU,CAOpB;EAEH,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"AccessApprovalsTable.js","names":[],"sources":["../../../src/components/dataaccess/AccessApprovalsTable.tsx"],"sourcesContent":["import InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport { useSearchAccessApprovalsInfinite } from '@/synapse-queries/dataaccess/useAccessApprovals'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { PRODUCTION_ENDPOINT_CONFIG } from '@/utils/functions/getEndpoint'\nimport {\n AccessApprovalSearchRequest,\n AccessApprovalSearchResult,\n AccessApprovalSearchSort,\n AccessApprovalSortField,\n Direction,\n} from '@sage-bionetworks/synapse-types'\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 ColumnHeader from '../TanStackTable/ColumnHeader'\nimport StyledTanStackTable from '../TanStackTable/StyledTanStackTable'\nimport UserOrTeamBadge from '../UserOrTeamBadge/index'\n\nconst columnHelper = createColumnHelper<AccessApprovalSearchResult>()\nconst columns = [\n columnHelper.accessor('accessRequirementId', {\n header: props => <ColumnHeader {...props} title={'AR ID'} />,\n enableSorting: false,\n cell: ctx => (\n <a\n href={`${\n PRODUCTION_ENDPOINT_CONFIG.PORTAL\n }AccessRequirement:AR_ID=${ctx.getValue()}`}\n target={'_blank'}\n >\n {ctx.getValue()}\n </a>\n ),\n }),\n columnHelper.accessor('accessRequirementName', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n enableSorting: false,\n }),\n columnHelper.accessor('submitterId', {\n header: props => <ColumnHeader {...props} title={'Submitter'} />,\n enableSorting: false,\n cell: ctx => <UserOrTeamBadge principalId={ctx.getValue()} />,\n }),\n columnHelper.accessor('state', {\n header: props => <ColumnHeader {...props} title={'Status'} />,\n enableSorting: false,\n cell: ctx => upperFirst(ctx.getValue().toLocaleLowerCase()),\n }),\n columnHelper.accessor('modifiedOn', {\n header: props => <ColumnHeader {...props} title={'Modified Date'} />,\n enableSorting: true,\n cell: ctx => formatDate(dayjs(ctx.getValue())),\n }),\n columnHelper.accessor('expiredOn', {\n header: props => <ColumnHeader {...props} title={'Expires'} />,\n enableSorting: true,\n cell: ctx => (\n <span\n className={`${\n ctx.getValue()\n ? new Date() > new Date(ctx.getValue())\n ? 'expired'\n : ''\n : 'non-expire'\n } remove-border`}\n >\n {ctx.getValue() ? formatDate(dayjs(ctx.getValue())) : 'Never'}\n </span>\n ),\n }),\n]\n\nfunction getSortApiRequestFromTableSortState(\n sortingState: SortingState,\n): AccessApprovalSearchSort[] | undefined {\n if (sortingState.length === 0) {\n return undefined\n }\n const sort = sortingState[0]\n let field: AccessApprovalSortField = AccessApprovalSortField.MODIFIED_ON\n if (sort.id === 'modifiedOn') {\n field = AccessApprovalSortField.MODIFIED_ON\n } else if (sort.id === 'expiredOn') {\n field = AccessApprovalSortField.EXPIRED_ON\n }\n return [\n {\n field,\n direction: sort.desc ? Direction.DESC : Direction.ASC,\n },\n ]\n}\n\nexport type AccessApprovalsTableProps = {\n accessorId: string\n accessRequirementId?: string\n}\nexport function AccessApprovalsTable({\n accessorId,\n accessRequirementId,\n}: AccessApprovalsTableProps) {\n const [tableSortState, setTableSortState] = useState<SortingState>([\n {\n desc: true,\n id: 'modifiedOn',\n },\n ])\n\n const searchRequest: AccessApprovalSearchRequest = useMemo(\n () => ({\n accessorId,\n accessRequirementId,\n sort: getSortApiRequestFromTableSortState(tableSortState),\n }),\n [accessorId, accessRequirementId, tableSortState],\n )\n\n const { data, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } =\n useSearchAccessApprovalsInfinite(searchRequest)\n const accessApprovals = useMemo(\n () => data?.pages.flatMap(page => page.results) ?? [],\n [data?.pages],\n )\n\n const table = useReactTable<AccessApprovalSearchResult>({\n data: accessApprovals,\n columns: columns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: true,\n onSortingChange: setTableSortState,\n state: {\n sorting: tableSortState,\n },\n columnResizeMode: 'onChange',\n })\n\n const isEmpty = !isLoading && table.getRowModel().rows.length === 0\n\n return (\n <div className=\"AccessApprovalsTable\">\n <InfiniteTableLayout\n table={<StyledTanStackTable table={table} />}\n isLoading={isLoading}\n isEmpty={isEmpty}\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAwBA,IAAM,IAAe,GAAgD,EAC/D,IAAU;CACd,EAAa,SAAS,uBAAuB;EAC3C,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAW,CAAA;EAC5D,eAAe;EACf,OAAM,MACJ,kBAAC,KAAD;GACE,MAAM,GACJ,EAA2B,OAC5B,0BAA0B,EAAI,UAAU;GACzC,QAAQ;aAEP,EAAI,UAAU;GACb,CAAA;EAEP,CAAC;CACF,EAAa,SAAS,yBAAyB;EAC7C,SAAQ,MACN,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAA6B,CAAA;EAE/D,eAAe;EAChB,CAAC;CACF,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;EAC9D,CAAC;CACF,EAAa,SAAS,SAAS;EAC7B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAY,CAAA;EAC7D,eAAe;EACf,OAAM,MAAO,EAAW,EAAI,UAAU,CAAC,mBAAmB,CAAC;EAC5D,CAAC;CACF,EAAa,SAAS,cAAc;EAClC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAmB,CAAA;EACpE,eAAe;EACf,OAAM,MAAO,EAAW,EAAM,EAAI,UAAU,CAAC,CAAC;EAC/C,CAAC;CACF,EAAa,SAAS,aAAa;EACjC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAa,CAAA;EAC9D,eAAe;EACf,OAAM,MACJ,kBAAC,QAAD;GACE,WAAW,GACT,EAAI,UAAU,mBACV,IAAI,MAAM,GAAG,IAAI,KAAK,EAAI,UAAU,CAAC,GACnC,YACA,KACF,aACL;aAEA,EAAI,UAAU,GAAG,EAAW,EAAM,EAAI,UAAU,CAAC,CAAC,GAAG;GACjD,CAAA;EAEV,CAAC;CACH;AAED,SAAS,EACP,GACwC;AACxC,KAAI,EAAa,WAAW,EAC1B;CAEF,IAAM,IAAO,EAAa,IACtB,IAAiC,EAAwB;AAM7D,QALI,EAAK,OAAO,eACd,IAAQ,EAAwB,cACvB,EAAK,OAAO,gBACrB,IAAQ,EAAwB,aAE3B,CACL;EACE;EACA,WAAW,EAAK,OAAO,EAAU,OAAO,EAAU;EACnD,CACF;;AAOH,SAAgB,EAAqB,EACnC,eACA,0BAC4B;CAC5B,IAAM,CAAC,GAAgB,KAAqB,EAAuB,CACjE;EACE,MAAM;EACN,IAAI;EACL,CACF,CAAC,EAWI,EAAE,SAAM,gBAAa,kBAAe,cAAW,0BACnD,EAViD,SAC1C;EACL;EACA;EACA,MAAM,EAAoC,EAAe;EAC1D,GACD;EAAC;EAAY;EAAqB;EAAe,CAClD,CAGgD,EAM3C,IAAQ,EAA0C;EACtD,MANsB,QAChB,GAAM,MAAM,SAAQ,MAAQ,EAAK,QAAQ,IAAI,EAAE,EACrD,CAAC,GAAM,MAAM,CACd;EAIU;EACT,iBAAiB,GAAiB;EAClC,eAAe;EACf,iBAAiB;EACjB,OAAO,EACL,SAAS,GACV;EACD,kBAAkB;EACnB,CAAC,EAEI,IAAU,CAAC,KAAa,EAAM,aAAa,CAAC,KAAK,WAAW;AAElE,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,OAAO,kBAAC,GAAD,EAA4B,UAAS,CAAA;GACjC;GACF;GACI;GACb,8BAA8B;AACvB,OAAe;;GAEF;GACpB,CAAA;EACE,CAAA"}
1
+ {"version":3,"file":"AccessApprovalsTable.js","names":[],"sources":["../../../src/components/dataaccess/AccessApprovalsTable.tsx"],"sourcesContent":["import InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport { useSearchAccessApprovalsInfinite } from '@/synapse-queries/dataaccess/useAccessApprovals'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { PRODUCTION_ENDPOINT_CONFIG } from '@/utils/functions/getEndpoint'\nimport {\n AccessApprovalSearchRequest,\n AccessApprovalSearchResult,\n AccessApprovalSearchSort,\n AccessApprovalSortField,\n Direction,\n} from '@sage-bionetworks/synapse-types'\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 ColumnHeader from '../TanStackTable/ColumnHeader'\nimport StyledTanStackTable from '../TanStackTable/StyledTanStackTable'\nimport UserOrTeamBadge from '../UserOrTeamBadge/index'\n\nconst columnHelper = createColumnHelper<AccessApprovalSearchResult>()\nconst columns = [\n columnHelper.accessor('accessRequirementId', {\n header: props => <ColumnHeader {...props} title={'AR ID'} />,\n enableSorting: false,\n cell: ctx => (\n <a\n href={`${\n PRODUCTION_ENDPOINT_CONFIG.PORTAL\n }AccessRequirement:AR_ID=${ctx.getValue()}`}\n target={'_blank'}\n >\n {ctx.getValue()}\n </a>\n ),\n }),\n columnHelper.accessor('accessRequirementName', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n enableSorting: false,\n }),\n columnHelper.accessor('submitterId', {\n header: props => <ColumnHeader {...props} title={'Submitter'} />,\n enableSorting: false,\n cell: ctx => <UserOrTeamBadge principalId={ctx.getValue()} />,\n }),\n columnHelper.accessor('state', {\n header: props => <ColumnHeader {...props} title={'Status'} />,\n enableSorting: false,\n cell: ctx => upperFirst(ctx.getValue().toLocaleLowerCase()),\n }),\n columnHelper.accessor('modifiedOn', {\n header: props => <ColumnHeader {...props} title={'Modified Date'} />,\n enableSorting: true,\n cell: ctx => formatDate(dayjs(ctx.getValue())),\n }),\n columnHelper.accessor('expiredOn', {\n header: props => <ColumnHeader {...props} title={'Expires'} />,\n enableSorting: true,\n cell: ctx => (\n <span\n className={`${\n ctx.getValue()\n ? new Date() > new Date(ctx.getValue())\n ? 'expired'\n : ''\n : 'non-expire'\n } remove-border`}\n >\n {ctx.getValue() ? formatDate(dayjs(ctx.getValue())) : 'Never'}\n </span>\n ),\n }),\n]\n\nfunction getSortApiRequestFromTableSortState(\n sortingState: SortingState,\n): AccessApprovalSearchSort[] | undefined {\n if (sortingState.length === 0) {\n return undefined\n }\n const sort = sortingState[0]\n let field: AccessApprovalSortField = AccessApprovalSortField.MODIFIED_ON\n if (sort.id === 'modifiedOn') {\n field = AccessApprovalSortField.MODIFIED_ON\n } else if (sort.id === 'expiredOn') {\n field = AccessApprovalSortField.EXPIRED_ON\n }\n return [\n {\n field,\n direction: sort.desc ? Direction.DESC : Direction.ASC,\n },\n ]\n}\n\nexport type AccessApprovalsTableProps = {\n accessorId: string\n accessRequirementId?: string\n}\nexport function AccessApprovalsTable({\n accessorId,\n accessRequirementId,\n}: AccessApprovalsTableProps) {\n const [tableSortState, setTableSortState] = useState<SortingState>([\n {\n desc: true,\n id: 'modifiedOn',\n },\n ])\n\n const searchRequest: AccessApprovalSearchRequest = useMemo(\n () => ({\n accessorId,\n accessRequirementId,\n sort: getSortApiRequestFromTableSortState(tableSortState),\n }),\n [accessorId, accessRequirementId, tableSortState],\n )\n\n const { data, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } =\n useSearchAccessApprovalsInfinite(searchRequest)\n const accessApprovals = useMemo(\n () => data?.pages.flatMap(page => page.results) ?? [],\n [data?.pages],\n )\n\n const table = useReactTable<AccessApprovalSearchResult>({\n data: accessApprovals,\n columns: columns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: true,\n onSortingChange: setTableSortState,\n state: {\n sorting: tableSortState,\n },\n columnResizeMode: 'onChange',\n })\n\n const isEmpty = !isLoading && table.getRowModel().rows.length === 0\n\n return (\n <div className=\"AccessApprovalsTable\">\n <InfiniteTableLayout\n table={<StyledTanStackTable table={table} />}\n isLoading={isLoading}\n isEmpty={isEmpty}\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAwBA,IAAM,IAAe,GAAgD,EAC/D,IAAU;CACd,EAAa,SAAS,uBAAuB;EAC3C,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAW,CAAA;EAC5D,eAAe;EACf,OAAM,MACJ,kBAAC,KAAD;GACE,MAAM,GACJ,EAA2B,OAC5B,0BAA0B,EAAI,UAAU;GACzC,QAAQ;aAEP,EAAI,UAAU;GACb,CAAA;EAEP,CAAC;CACF,EAAa,SAAS,yBAAyB;EAC7C,SAAQ,MACN,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAA6B,CAAA;EAE/D,eAAe;EAChB,CAAC;CACF,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;EAC9D,CAAC;CACF,EAAa,SAAS,SAAS;EAC7B,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAY,CAAA;EAC7D,eAAe;EACf,OAAM,MAAO,EAAW,EAAI,UAAU,CAAC,mBAAmB,CAAC;EAC5D,CAAC;CACF,EAAa,SAAS,cAAc;EAClC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAmB,CAAA;EACpE,eAAe;EACf,OAAM,MAAO,EAAW,EAAM,EAAI,UAAU,CAAC,CAAC;EAC/C,CAAC;CACF,EAAa,SAAS,aAAa;EACjC,SAAQ,MAAS,kBAAC,GAAD;GAAc,GAAI;GAAO,OAAO;GAAa,CAAA;EAC9D,eAAe;EACf,OAAM,MACJ,kBAAC,QAAD;GACE,WAAW,GACT,EAAI,UAAU,mBACV,IAAI,MAAM,GAAG,IAAI,KAAK,EAAI,UAAU,CAAC,GACnC,YACA,KACF,aACL;aAEA,EAAI,UAAU,GAAG,EAAW,EAAM,EAAI,UAAU,CAAC,CAAC,GAAG;GACjD,CAAA;EAEV,CAAC;CACH;AAED,SAAS,EACP,GACwC;AACxC,KAAI,EAAa,WAAW,EAC1B;CAEF,IAAM,IAAO,EAAa,IACtB,IAAiC,EAAwB;AAM7D,QALI,EAAK,OAAO,eACd,IAAQ,EAAwB,cACvB,EAAK,OAAO,gBACrB,IAAQ,EAAwB,aAE3B,CACL;EACE;EACA,WAAW,EAAK,OAAO,EAAU,OAAO,EAAU;EACnD,CACF;;AAOH,SAAgB,EAAqB,EACnC,eACA,0BAC4B;CAC5B,IAAM,CAAC,GAAgB,KAAqB,EAAuB,CACjE;EACE,MAAM;EACN,IAAI;EACL,CACF,CAAC,EAWI,EAAE,SAAM,gBAAa,kBAAe,cAAW,0BACnD,EAViD,SAC1C;EACL;EACA;EACA,MAAM,EAAoC,EAAe;EAC1D,GACD;EAAC;EAAY;EAAqB;EAAe,CAIhB,CAAc,EAM3C,IAAQ,EAA0C;EACtD,MANsB,QAChB,GAAM,MAAM,SAAQ,MAAQ,EAAK,QAAQ,IAAI,EAAE,EACrD,CAAC,GAAM,MAAM,CAIP;EACG;EACT,iBAAiB,GAAiB;EAClC,eAAe;EACf,iBAAiB;EACjB,OAAO,EACL,SAAS,GACV;EACD,kBAAkB;EACnB,CAAC,EAEI,IAAU,CAAC,KAAa,EAAM,aAAa,CAAC,KAAK,WAAW;AAElE,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,OAAO,kBAAC,GAAD,EAA4B,UAAS,CAAA;GACjC;GACF;GACI;GACb,8BAA8B;AACvB,OAAe;;GAEF;GACpB,CAAA;EACE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"AccessRequestSubmissionTable.js","names":[],"sources":["../../../src/components/dataaccess/AccessRequestSubmissionTable.tsx"],"sourcesContent":["import InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport { useSearchAccessSubmissionsInfinite } from '@/synapse-queries/dataaccess/useDataAccessSubmission'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { ACT_TEAM_ID } from '@/utils/SynapseConstants'\nimport { Stack } from '@mui/material'\nimport {\n SubmissionReviewerFilterType,\n SubmissionSearchRequest,\n SubmissionSearchResult,\n SubmissionSearchSort,\n SubmissionState,\n} from '@sage-bionetworks/synapse-types'\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 { UserBadge } from '../UserCard/UserBadge'\nimport UserOrTeamBadge from '../UserOrTeamBadge/UserOrTeamBadge'\nimport { getSortApiRequestFromTableSortState } from './UserAccessRequestHistory/SubmissionSortStateTranslator'\n\nconst columnHelper = createColumnHelper<SubmissionSearchResult>()\nconst columns = [\n columnHelper.accessor('id', {\n header: props => <ColumnHeader {...props} title={'Request'} />,\n enableSorting: false,\n cell: ctx => (\n <Link to={`/Submissions/${ctx.getValue()}`}>{ctx.getValue()}</Link>\n ),\n }),\n columnHelper.accessor('accessRequirementName', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n enableSorting: false,\n }),\n columnHelper.accessor('submitterId', {\n header: props => <ColumnHeader {...props} title={'Submitter'} />,\n enableSorting: false,\n cell: ctx => <UserOrTeamBadge principalId={ctx.getValue()} />,\n }),\n columnHelper.accessor('state', {\n header: props => <ColumnHeader {...props} title={'Status'} />,\n enableSorting: false,\n cell: ctx => upperFirst(ctx.getValue().toLocaleLowerCase()),\n }),\n\n columnHelper.accessor('accessorChanges', {\n header: props => <ColumnHeader {...props} title={'Requesters'} />,\n enableSorting: false,\n cell: ctx => (\n <Stack\n sx={{\n gap: 1,\n }}\n >\n <UserOrTeamBadge principalId={ctx.row.original.submitterId} />\n {ctx\n .getValue()\n .filter(user => ctx.row.original.submitterId !== user.userId)\n .map(requester => (\n <UserBadge\n key={requester.userId}\n userId={requester.userId}\n className=\"requester\"\n />\n ))}\n </Stack>\n ),\n }),\n columnHelper.accessor('accessRequirementReviewerIds', {\n header: props => <ColumnHeader {...props} title={'Reviewer(s)'} />,\n enableSorting: false,\n cell: ctx => (\n <Stack\n sx={{\n gap: 1,\n }}\n >\n {ctx.getValue().length === 0 ? (\n <UserOrTeamBadge principalId={ACT_TEAM_ID} />\n ) : (\n ctx\n .getValue()\n .map(reviewerId => (\n <UserOrTeamBadge key={reviewerId} principalId={reviewerId} />\n ))\n )}\n </Stack>\n ),\n }),\n columnHelper.accessor('createdOn', {\n header: props => <ColumnHeader {...props} title={'Created Date'} />,\n enableSorting: true,\n cell: ctx => formatDate(dayjs(ctx.getValue())),\n sortDescFirst: true,\n }),\n]\n\nexport type AccessRequestSubmissionTableProps = {\n showSubmitter?: boolean\n showStatus?: boolean\n showRequesters?: boolean\n accessorId?: string\n accessRequirementId?: string\n reviewerId?: string\n submissionState?: SubmissionState\n reviewerFilterType?: SubmissionReviewerFilterType\n}\n\nexport function AccessRequestSubmissionTable({\n showSubmitter = false,\n showStatus = false,\n showRequesters = false,\n accessorId,\n accessRequirementId,\n reviewerId,\n submissionState,\n reviewerFilterType,\n}: AccessRequestSubmissionTableProps) {\n const [tableSortState, setTableSortState] = useState<SortingState>([\n {\n desc: true,\n id: 'createdOn',\n },\n ])\n\n const searchRequest: SubmissionSearchRequest = useMemo(\n () => ({\n accessorId,\n accessRequirementId,\n submissionState,\n reviewerId,\n reviewerFilterType,\n sort: getSortApiRequestFromTableSortState(tableSortState) as\n | SubmissionSearchSort[] // cast to synapse-types (not OpenAPI-defined) type\n | undefined,\n }),\n [\n accessorId,\n accessRequirementId,\n submissionState,\n reviewerId,\n reviewerFilterType,\n tableSortState,\n ],\n )\n\n const { data, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } =\n useSearchAccessSubmissionsInfinite(searchRequest)\n\n const accessSubmissions = useMemo(\n () => data?.pages.flatMap(page => page.results) ?? [],\n [data?.pages],\n )\n\n const table = useReactTable<SubmissionSearchResult>({\n data: accessSubmissions,\n columns: columns,\n getCoreRowModel: getCoreRowModel(),\n enableFilters: false, // filters are handled by separate controls\n manualSorting: true,\n onSortingChange: setTableSortState,\n state: {\n sorting: tableSortState,\n columnVisibility: {\n submitterId: showSubmitter,\n state: showStatus,\n accessorChanges: showRequesters,\n },\n },\n columnResizeMode: 'onChange',\n })\n\n const isEmpty = !isLoading && table.getRowModel().rows.length === 0\n\n return (\n <div className={'AccessSubmissionTable'}>\n <InfiniteTableLayout\n table={<StyledTanStackTable table={table} fullWidth={true} />}\n isLoading={isLoading}\n isEmpty={isEmpty}\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AccessRequestSubmissionTable.js","names":[],"sources":["../../../src/components/dataaccess/AccessRequestSubmissionTable.tsx"],"sourcesContent":["import InfiniteTableLayout from '@/components/layout/InfiniteTableLayout'\nimport { useSearchAccessSubmissionsInfinite } from '@/synapse-queries/dataaccess/useDataAccessSubmission'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { ACT_TEAM_ID } from '@/utils/SynapseConstants'\nimport { Stack } from '@mui/material'\nimport {\n SubmissionReviewerFilterType,\n SubmissionSearchRequest,\n SubmissionSearchResult,\n SubmissionSearchSort,\n SubmissionState,\n} from '@sage-bionetworks/synapse-types'\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 { UserBadge } from '../UserCard/UserBadge'\nimport UserOrTeamBadge from '../UserOrTeamBadge/UserOrTeamBadge'\nimport { getSortApiRequestFromTableSortState } from './UserAccessRequestHistory/SubmissionSortStateTranslator'\n\nconst columnHelper = createColumnHelper<SubmissionSearchResult>()\nconst columns = [\n columnHelper.accessor('id', {\n header: props => <ColumnHeader {...props} title={'Request'} />,\n enableSorting: false,\n cell: ctx => (\n <Link to={`/Submissions/${ctx.getValue()}`}>{ctx.getValue()}</Link>\n ),\n }),\n columnHelper.accessor('accessRequirementName', {\n header: props => (\n <ColumnHeader {...props} title={'Access Requirement Name'} />\n ),\n enableSorting: false,\n }),\n columnHelper.accessor('submitterId', {\n header: props => <ColumnHeader {...props} title={'Submitter'} />,\n enableSorting: false,\n cell: ctx => <UserOrTeamBadge principalId={ctx.getValue()} />,\n }),\n columnHelper.accessor('state', {\n header: props => <ColumnHeader {...props} title={'Status'} />,\n enableSorting: false,\n cell: ctx => upperFirst(ctx.getValue().toLocaleLowerCase()),\n }),\n\n columnHelper.accessor('accessorChanges', {\n header: props => <ColumnHeader {...props} title={'Requesters'} />,\n enableSorting: false,\n cell: ctx => (\n <Stack\n sx={{\n gap: 1,\n }}\n >\n <UserOrTeamBadge principalId={ctx.row.original.submitterId} />\n {ctx\n .getValue()\n .filter(user => ctx.row.original.submitterId !== user.userId)\n .map(requester => (\n <UserBadge\n key={requester.userId}\n userId={requester.userId}\n className=\"requester\"\n />\n ))}\n </Stack>\n ),\n }),\n columnHelper.accessor('accessRequirementReviewerIds', {\n header: props => <ColumnHeader {...props} title={'Reviewer(s)'} />,\n enableSorting: false,\n cell: ctx => (\n <Stack\n sx={{\n gap: 1,\n }}\n >\n {ctx.getValue().length === 0 ? (\n <UserOrTeamBadge principalId={ACT_TEAM_ID} />\n ) : (\n ctx\n .getValue()\n .map(reviewerId => (\n <UserOrTeamBadge key={reviewerId} principalId={reviewerId} />\n ))\n )}\n </Stack>\n ),\n }),\n columnHelper.accessor('createdOn', {\n header: props => <ColumnHeader {...props} title={'Created Date'} />,\n enableSorting: true,\n cell: ctx => formatDate(dayjs(ctx.getValue())),\n sortDescFirst: true,\n }),\n]\n\nexport type AccessRequestSubmissionTableProps = {\n showSubmitter?: boolean\n showStatus?: boolean\n showRequesters?: boolean\n accessorId?: string\n accessRequirementId?: string\n reviewerId?: string\n submissionState?: SubmissionState\n reviewerFilterType?: SubmissionReviewerFilterType\n}\n\nexport function AccessRequestSubmissionTable({\n showSubmitter = false,\n showStatus = false,\n showRequesters = false,\n accessorId,\n accessRequirementId,\n reviewerId,\n submissionState,\n reviewerFilterType,\n}: AccessRequestSubmissionTableProps) {\n const [tableSortState, setTableSortState] = useState<SortingState>([\n {\n desc: true,\n id: 'createdOn',\n },\n ])\n\n const searchRequest: SubmissionSearchRequest = useMemo(\n () => ({\n accessorId,\n accessRequirementId,\n submissionState,\n reviewerId,\n reviewerFilterType,\n sort: getSortApiRequestFromTableSortState(tableSortState) as\n | SubmissionSearchSort[] // cast to synapse-types (not OpenAPI-defined) type\n | undefined,\n }),\n [\n accessorId,\n accessRequirementId,\n submissionState,\n reviewerId,\n reviewerFilterType,\n tableSortState,\n ],\n )\n\n const { data, hasNextPage, fetchNextPage, isLoading, isFetchingNextPage } =\n useSearchAccessSubmissionsInfinite(searchRequest)\n\n const accessSubmissions = useMemo(\n () => data?.pages.flatMap(page => page.results) ?? [],\n [data?.pages],\n )\n\n const table = useReactTable<SubmissionSearchResult>({\n data: accessSubmissions,\n columns: columns,\n getCoreRowModel: getCoreRowModel(),\n enableFilters: false, // filters are handled by separate controls\n manualSorting: true,\n onSortingChange: setTableSortState,\n state: {\n sorting: tableSortState,\n columnVisibility: {\n submitterId: showSubmitter,\n state: showStatus,\n accessorChanges: showRequesters,\n },\n },\n columnResizeMode: 'onChange',\n })\n\n const isEmpty = !isLoading && table.getRowModel().rows.length === 0\n\n return (\n <div className={'AccessSubmissionTable'}>\n <InfiniteTableLayout\n table={<StyledTanStackTable table={table} fullWidth={true} />}\n isLoading={isLoading}\n isEmpty={isEmpty}\n hasNextPage={hasNextPage}\n onFetchNextPageClicked={() => {\n void fetchNextPage()\n }}\n isFetchingNextPage={isFetchingNextPage}\n />\n </div>\n )\n}\n"],"mappings":"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"}
@@ -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 { 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 +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"}