synapse-react-client 4.0.9 → 4.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (613) hide show
  1. package/dist/SWC.index.d.ts +1 -0
  2. package/dist/SWC.index.d.ts.map +1 -1
  3. package/dist/SWC.index.js +2 -1
  4. package/dist/SWC.index.js.map +1 -1
  5. package/dist/aridhia-queries/aridhiaTokenExchange.js.map +1 -1
  6. package/dist/aridhia-queries/useGetAridhiaRequests.js.map +1 -1
  7. package/dist/assets/icons/CloudWarning.d.ts +5 -0
  8. package/dist/assets/icons/CloudWarning.d.ts.map +1 -0
  9. package/dist/assets/icons/CloudWarning.js +47 -0
  10. package/dist/assets/icons/CloudWarning.js.map +1 -0
  11. package/dist/assets/icons/TasksIcon.d.ts.map +1 -1
  12. package/dist/assets/icons/TasksIcon.js +6 -10
  13. package/dist/assets/icons/TasksIcon.js.map +1 -1
  14. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.d.ts.map +1 -1
  15. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.js +69 -63
  16. package/dist/components/AccessRequirementAclEditor/AccessRequirementAclEditor.js.map +1 -1
  17. package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js.map +1 -1
  18. package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
  19. package/dist/components/AccessRequirementList/AccessRequirementListUtils.js.map +1 -1
  20. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsEditor.js.map +1 -1
  21. package/dist/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.js.map +1 -1
  22. package/dist/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.js.map +1 -1
  23. package/dist/components/AccessTokenPage/AccessTokenCard/AccessTokenCard.js.map +1 -1
  24. package/dist/components/AcknowledgementsPage/StudyAcknowledgements.js.map +1 -1
  25. package/dist/components/AclEditor/PermissionLevelMenu.js.map +1 -1
  26. package/dist/components/AclEditor/ResourceAccessAndUserGroupHeader.js.map +1 -1
  27. package/dist/components/AclEditor/useSortResourceAccessList.js.map +1 -1
  28. package/dist/components/AclEditor/useUpdateAcl.js.map +1 -1
  29. package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
  30. package/dist/components/Authentication/AuthenticationMethodSelection.d.ts.map +1 -1
  31. package/dist/components/Authentication/AuthenticationMethodSelection.js +38 -37
  32. package/dist/components/Authentication/AuthenticationMethodSelection.js.map +1 -1
  33. package/dist/components/Authentication/Constants.d.ts +1 -0
  34. package/dist/components/Authentication/Constants.d.ts.map +1 -1
  35. package/dist/components/Authentication/Constants.js +2 -2
  36. package/dist/components/Authentication/Constants.js.map +1 -1
  37. package/dist/components/Authentication/LastLoginInfo.js.map +1 -1
  38. package/dist/components/Authentication/RecoveryCodeForm.js.map +1 -1
  39. package/dist/components/Authentication/RecoveryCodeGrid.js.map +1 -1
  40. package/dist/components/Authentication/RegenerateBackupCodesWarning.js.map +1 -1
  41. package/dist/components/Authentication/Reset2FAWarning.js.map +1 -1
  42. package/dist/components/Authentication/StandaloneLoginForm.js +1 -1
  43. package/dist/components/Authentication/TwoFactorBackupCodes.js.map +1 -1
  44. package/dist/components/Authentication/TwoFactorEnrollmentForm.d.ts.map +1 -1
  45. package/dist/components/Authentication/TwoFactorEnrollmentForm.js +2 -1
  46. package/dist/components/Authentication/TwoFactorEnrollmentForm.js.map +1 -1
  47. package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.js.map +1 -1
  48. package/dist/components/CardContainer/CardContainer.js.map +1 -1
  49. package/dist/components/CardDeck/CardDeck.Mobile.js.map +1 -1
  50. package/dist/components/CardDeck/TableQueryCardDeck.js.map +1 -1
  51. package/dist/components/CertificationQuiz/CertificationQuiz.js.map +1 -1
  52. package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js.map +1 -1
  53. package/dist/components/ChallengeSubmission/ChallengeSubmission.js.map +1 -1
  54. package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js.map +1 -1
  55. package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js.map +1 -1
  56. package/dist/components/ChallengeSubmission/EvaluationQueueList.js.map +1 -1
  57. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.d.ts.map +1 -1
  58. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js +143 -140
  59. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
  60. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js.map +1 -1
  61. package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js.map +1 -1
  62. package/dist/components/ChangePassword/ChangePassword.js.map +1 -1
  63. package/dist/components/ChangePassword/ChangePasswordWithToken.js.map +1 -1
  64. package/dist/components/ChangePassword/useChangePasswordFormState.js +1 -1
  65. package/dist/components/ChangePassword/useChangePasswordFormState.js.map +1 -1
  66. package/dist/components/CitationPopover/CitationPopoverContent.js.map +1 -1
  67. package/dist/components/ColumnFilter/ColumnFilter.js.map +1 -1
  68. package/dist/components/ComponentCollapse.js.map +1 -1
  69. package/dist/components/CookiesNotification/CookiesNotification.js.map +1 -1
  70. package/dist/components/CreateProjectModal/CreateProjectModal.js.map +1 -1
  71. package/dist/components/CreateTableViewWizard/CreateTableViewWizardUtils.js.map +1 -1
  72. package/dist/components/DataGrid/DataGrid.d.ts +0 -1
  73. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
  74. package/dist/components/DataGrid/DataGrid.js +72 -72
  75. package/dist/components/DataGrid/DataGrid.js.map +1 -1
  76. package/dist/components/DataGrid/DataGridWebSocket.d.ts +4 -0
  77. package/dist/components/DataGrid/DataGridWebSocket.d.ts.map +1 -1
  78. package/dist/components/DataGrid/DataGridWebSocket.js +9 -8
  79. package/dist/components/DataGrid/DataGridWebSocket.js.map +1 -1
  80. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  81. package/dist/components/DataGrid/SynapseGrid.js +326 -268
  82. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  83. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts +2 -0
  84. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts.map +1 -1
  85. package/dist/components/DataGrid/columns/AutocompleteColumn.js +124 -67
  86. package/dist/components/DataGrid/columns/AutocompleteColumn.js.map +1 -1
  87. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts +2 -1
  88. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts.map +1 -1
  89. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js +126 -122
  90. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js.map +1 -1
  91. package/dist/components/DataGrid/columns/useGridAutocompleteState.d.ts +58 -0
  92. package/dist/components/DataGrid/columns/useGridAutocompleteState.d.ts.map +1 -0
  93. package/dist/components/DataGrid/columns/useGridAutocompleteState.js +52 -0
  94. package/dist/components/DataGrid/columns/useGridAutocompleteState.js.map +1 -0
  95. package/dist/components/DataGrid/components/ValidationAlert.d.ts +5 -2
  96. package/dist/components/DataGrid/components/ValidationAlert.d.ts.map +1 -1
  97. package/dist/components/DataGrid/components/ValidationAlert.js +429 -24
  98. package/dist/components/DataGrid/components/ValidationAlert.js.map +1 -1
  99. package/dist/components/DataGrid/hooks/useColumnResizeHandles.js.map +1 -1
  100. package/dist/components/DataGrid/hooks/useGetSchemaForGrid.js.map +1 -1
  101. package/dist/components/DataGrid/hooks/useGridUndoRedo.js.map +1 -1
  102. package/dist/components/DataGrid/hooks/useStack.js.map +1 -1
  103. package/dist/components/DataGrid/useCRDTModelView.js.map +1 -1
  104. package/dist/components/DataGrid/useDataGridWebsocket.d.ts +7 -0
  105. package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
  106. package/dist/components/DataGrid/useDataGridWebsocket.js +16 -2
  107. package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
  108. package/dist/components/DataGrid/useInitializeGridConnection.js.map +1 -1
  109. package/dist/components/DataGrid/useMergeGridWithRecordSet.js.map +1 -1
  110. package/dist/components/DataGrid/useMergeGridWithSource.js.map +1 -1
  111. package/dist/components/DataGrid/useMergeGridWithTable.js.map +1 -1
  112. package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
  113. package/dist/components/DataGrid/utils/applyModelChange.d.ts +1 -1
  114. package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
  115. package/dist/components/DataGrid/utils/applyModelChange.js +27 -24
  116. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  117. package/dist/components/DataGrid/utils/columnFactory.d.ts +8 -0
  118. package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
  119. package/dist/components/DataGrid/utils/columnFactory.js +47 -44
  120. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  121. package/dist/components/DataGrid/utils/computeReplicaSelectionModel.js.map +1 -1
  122. package/dist/components/DataGrid/utils/extractColumnValidationMessages.js.map +1 -1
  123. package/dist/components/DataGrid/utils/getCellClassName.d.ts.map +1 -1
  124. package/dist/components/DataGrid/utils/getCellClassName.js +8 -8
  125. package/dist/components/DataGrid/utils/getCellClassName.js.map +1 -1
  126. package/dist/components/DataGrid/utils/getEmptyValue.d.ts +2 -0
  127. package/dist/components/DataGrid/utils/getEmptyValue.d.ts.map +1 -0
  128. package/dist/components/DataGrid/utils/getEmptyValue.js +8 -0
  129. package/dist/components/DataGrid/utils/getEmptyValue.js.map +1 -0
  130. package/dist/components/DataGrid/utils/json-rx/JsonRx.js.map +1 -1
  131. package/dist/components/DataGrid/utils/modelColsToGrid.d.ts.map +1 -1
  132. package/dist/components/DataGrid/utils/modelColsToGrid.js +2 -1
  133. package/dist/components/DataGrid/utils/modelColsToGrid.js.map +1 -1
  134. package/dist/components/DataGrid/utils/modelRowsToGrid.js.map +1 -1
  135. package/dist/components/DataGrid/utils/parseFreeTextUsingJsonSchemaType.js.map +1 -1
  136. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts +32 -0
  137. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts.map +1 -0
  138. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js +22 -0
  139. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js.map +1 -0
  140. package/dist/components/DataGrid/utils/splitPatch.js.map +1 -1
  141. package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
  142. package/dist/components/DirectDownload/DirectDownload.js.map +1 -1
  143. package/dist/components/DirectDownloadButton.js.map +1 -1
  144. package/dist/components/DownloadCart/CreatePackageV2.js.map +1 -1
  145. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.css +1 -0
  146. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.d.ts.map +1 -1
  147. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +199 -132
  148. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
  149. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js +22 -0
  150. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js.map +1 -0
  151. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.scss +170 -0
  152. package/dist/components/DownloadCart/DownloadListActionsRequired.js.map +1 -1
  153. package/dist/components/DownloadCart/DownloadListTable.js.map +1 -1
  154. package/dist/components/DownloadCart/fileNameUtils.js.map +1 -1
  155. package/dist/components/DraggableDialog/DraggableDialog.js.map +1 -1
  156. package/dist/components/DynamicForm/DynamicFormModal.js.map +1 -1
  157. package/dist/components/Ecosystem/TableQueryEcosystem.js.map +1 -1
  158. package/dist/components/EntityAclEditor/EntityAclEditor.d.ts.map +1 -1
  159. package/dist/components/EntityAclEditor/EntityAclEditor.js +103 -103
  160. package/dist/components/EntityAclEditor/EntityAclEditor.js.map +1 -1
  161. package/dist/components/EntityAclEditor/useNotifyNewACLUsers.js.map +1 -1
  162. package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js.map +1 -1
  163. package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
  164. package/dist/components/EntityDownloadButton/EntityDownloadButton.d.ts.map +1 -1
  165. package/dist/components/EntityDownloadButton/EntityDownloadButton.js +1 -0
  166. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  167. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.d.ts.map +1 -1
  168. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js +36 -30
  169. package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js.map +1 -1
  170. package/dist/components/EntityFinder/EntityFinder.js.map +1 -1
  171. package/dist/components/EntityFinder/VersionSelectionType.js.map +1 -1
  172. package/dist/components/EntityFinder/details/configurations/EntityChildrenDetails.js.map +1 -1
  173. package/dist/components/EntityFinder/details/configurations/FavoritesDetails.js.map +1 -1
  174. package/dist/components/EntityFinder/details/configurations/ProjectListDetails.js.map +1 -1
  175. package/dist/components/EntityFinder/details/view/DetailsView.js.map +1 -1
  176. package/dist/components/EntityFinder/tree/EntityTree.js.map +1 -1
  177. package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
  178. package/dist/components/EntityFinder/useEntitySelection.js.map +1 -1
  179. package/dist/components/EntityForm/EntityForm.js.map +1 -1
  180. package/dist/components/EntityHeaderTable/EntityHeaderTable.js.map +1 -1
  181. package/dist/components/EntityHeaderTable/Filter.js.map +1 -1
  182. package/dist/components/EntityHeaderTable/useEntityHeaderTableState.js.map +1 -1
  183. package/dist/components/EntitySubjectsSelector/EntitySubjectsSelector.js.map +1 -1
  184. package/dist/components/EntityTreeTable/components/IdColumnHeader.js.map +1 -1
  185. package/dist/components/EntityTreeTable/hooks/useEntityTreeState.js.map +1 -1
  186. package/dist/components/EntityTreeTable/hooks/useTableColumns.js.map +1 -1
  187. package/dist/components/EntityTreeTable/hooks/useTableData.js.map +1 -1
  188. package/dist/components/EntityTreeTable/hooks/useTreeOperationsWithDirectFetch.js.map +1 -1
  189. package/dist/components/EntityUpload/EntityUpload.js.map +1 -1
  190. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.d.ts.map +1 -1
  191. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js +15 -14
  192. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js.map +1 -1
  193. package/dist/components/ExperimentalMode/ExperimentalMode.js.map +1 -1
  194. package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js.map +1 -1
  195. package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
  196. package/dist/components/FeaturedDataTabs/QueryPerFacetPlotsCard.js.map +1 -1
  197. package/dist/components/FeaturedDataTabs/SingleQueryFacetPlotsCards.js.map +1 -1
  198. package/dist/components/FeaturedResearch/FeaturedResearch.js.map +1 -1
  199. package/dist/components/FeaturedToolsList/FeaturedToolsList.js.map +1 -1
  200. package/dist/components/FilePreview/FileHandleContentRenderer.js.map +1 -1
  201. package/dist/components/FilePreview/HtmlPreview/HtmlPreview.js.map +1 -1
  202. package/dist/components/FilePreview/PreviewRendererType.js.map +1 -1
  203. package/dist/components/Forum/DiscussionReply.d.ts +1 -0
  204. package/dist/components/Forum/DiscussionReply.d.ts.map +1 -1
  205. package/dist/components/Forum/DiscussionReply.js +19 -19
  206. package/dist/components/Forum/DiscussionReply.js.map +1 -1
  207. package/dist/components/Forum/DiscussionSearchResult.js.map +1 -1
  208. package/dist/components/Forum/DiscussionThread.d.ts +1 -0
  209. package/dist/components/Forum/DiscussionThread.d.ts.map +1 -1
  210. package/dist/components/Forum/DiscussionThread.js +73 -72
  211. package/dist/components/Forum/DiscussionThread.js.map +1 -1
  212. package/dist/components/Forum/ForumTable.js.map +1 -1
  213. package/dist/components/Forum/ForumThreadEditor.js.map +1 -1
  214. package/dist/components/FullTextSearch/FullTextSearchUtils.js.map +1 -1
  215. package/dist/components/GenericCard/BioregistryRules.d.ts.map +1 -1
  216. package/dist/components/GenericCard/BioregistryRules.js +7 -3
  217. package/dist/components/GenericCard/BioregistryRules.js.map +1 -1
  218. package/dist/components/GenericCard/GenericCard.d.ts.map +1 -1
  219. package/dist/components/GenericCard/GenericCard.js +12 -7
  220. package/dist/components/GenericCard/GenericCard.js.map +1 -1
  221. package/dist/components/GenericCard/Linkify.js.map +1 -1
  222. package/dist/components/GenericCard/SynapseCardLabel.js.map +1 -1
  223. package/dist/components/GenericCard/TableRowGenericCard.js +105 -105
  224. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  225. package/dist/components/Goals/Goals.Mobile.js.map +1 -1
  226. package/dist/components/Goals/Goals.js.map +1 -1
  227. package/dist/components/GoalsV2/GoalsV2.Mobile.js.map +1 -1
  228. package/dist/components/GoalsV2/GoalsV2.js.map +1 -1
  229. package/dist/components/GoalsV3/GoalsV3.Mobile.js.map +1 -1
  230. package/dist/components/GoalsV3/GoalsV3.js.map +1 -1
  231. package/dist/components/GoogleMap/SynapseUserMarker.js.map +1 -1
  232. package/dist/components/HasAccess/AccessIcon.js.map +1 -1
  233. package/dist/components/HasAccess/useHasAccess.js.map +1 -1
  234. package/dist/components/HeaderCard/HeaderCardV2.js.map +1 -1
  235. package/dist/components/HeaderCard.d.ts +6 -1
  236. package/dist/components/HeaderCard.d.ts.map +1 -1
  237. package/dist/components/HeaderCard.js +107 -76
  238. package/dist/components/HeaderCard.js.map +1 -1
  239. package/dist/components/HexGrid/HexGrid.js.map +1 -1
  240. package/dist/components/IconList.js.map +1 -1
  241. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  242. package/dist/components/IconSvg/IconSvg.js +2 -1
  243. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  244. package/dist/components/ImageCardGridWithLinks/ImageCardGridWithLinks.js.map +1 -1
  245. package/dist/components/ImageFromSynapseTable.js.map +1 -1
  246. package/dist/components/JSONArrayEditor/useParseCsv.js.map +1 -1
  247. package/dist/components/JsonSchemaForm/templates/ArrayFieldDescriptionTemplate.js.map +1 -1
  248. package/dist/components/JsonSchemaForm/templates/ArrayFieldItemTemplate.js.map +1 -1
  249. package/dist/components/JsonSchemaForm/templates/BaseInputTemplate.js.map +1 -1
  250. package/dist/components/JsonSchemaForm/templates/FieldTemplate.js.map +1 -1
  251. package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js.map +1 -1
  252. package/dist/components/Markdown/MarkdownGithub.js.map +1 -1
  253. package/dist/components/Markdown/MarkdownSynapse.js.map +1 -1
  254. package/dist/components/Markdown/MarkdownUtils.js.map +1 -1
  255. package/dist/components/Markdown/SynapseWikiContext.js.map +1 -1
  256. package/dist/components/Markdown/UserMentionModal.js.map +1 -1
  257. package/dist/components/Markdown/widget/MarkdownProvenanceGraph.js.map +1 -1
  258. package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js.map +1 -1
  259. package/dist/components/ModalDownload/ModalDownload.js.map +1 -1
  260. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.d.ts.map +1 -1
  261. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.js +45 -39
  262. package/dist/components/OAuthClientAclEditor/OAuthClientAclEditor.js.map +1 -1
  263. package/dist/components/OAuthClientManagement/OAuthManagement.js.map +1 -1
  264. package/dist/components/PageProgress/PageProgress.js.map +1 -1
  265. package/dist/components/Plot/DotPlot.js.map +1 -1
  266. package/dist/components/Plot/Plot.js.map +1 -1
  267. package/dist/components/Plot/SynapsePlot.js.map +1 -1
  268. package/dist/components/Plot/ThemesPlot.js.map +1 -1
  269. package/dist/components/Plot/UpsetPlot.js.map +1 -1
  270. package/dist/components/PortalAclEditor/PortalAclEditor.d.ts.map +1 -1
  271. package/dist/components/PortalAclEditor/PortalAclEditor.js +43 -41
  272. package/dist/components/PortalAclEditor/PortalAclEditor.js.map +1 -1
  273. package/dist/components/PortalFeaturedPartners/PortalFeaturedPartners.js.map +1 -1
  274. package/dist/components/PortalList/CreatePortalModal.js.map +1 -1
  275. package/dist/components/ProgrammaticInstructionsModal/ProgrammaticInstructionsModal.js.map +1 -1
  276. package/dist/components/ProgrammaticTableDownload/ProgrammaticTableDownload.js.map +1 -1
  277. package/dist/components/Programs/Programs.Mobile.js.map +1 -1
  278. package/dist/components/Programs/Programs.js.map +1 -1
  279. package/dist/components/ProvenanceGraph/ProvenanceExternalIcon.js.map +1 -1
  280. package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
  281. package/dist/components/ProvenanceGraph/ProvenanceGraphUtils.js.map +1 -1
  282. package/dist/components/ProvenanceGraph/ProvenanceUtils.js.map +1 -1
  283. package/dist/components/QueryCount/QueryCount.js.map +1 -1
  284. package/dist/components/QueryCountButton/QueryCountButton.js.map +1 -1
  285. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
  286. package/dist/components/QueryWrapper/QueryWrapper.js.map +1 -1
  287. package/dist/components/QueryWrapper/TableQueryUseQueryOptions.js.map +1 -1
  288. package/dist/components/QueryWrapper/TableRowSelectionState.js.map +1 -1
  289. package/dist/components/QueryWrapper/generateEncodedPathAndQueryForSelectedFacetURL.js.map +1 -1
  290. package/dist/components/QueryWrapper/useGetQueryMetadata.js.map +1 -1
  291. package/dist/components/QueryWrapperErrorBoundary.js.map +1 -1
  292. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
  293. package/dist/components/QueryWrapperPlotNav/UseRowSet.js.map +1 -1
  294. package/dist/components/RecentPublicationsGrid/RecentPublicationsGrid.js.map +1 -1
  295. package/dist/components/ReleaseCard/ReleaseCardUtils.js.map +1 -1
  296. package/dist/components/ResizableContainer/hooks/useResizable.js.map +1 -1
  297. package/dist/components/Resources/Resources.Mobile.js.map +1 -1
  298. package/dist/components/Resources/Resources.js.map +1 -1
  299. package/dist/components/RowDataTable/RowDataTableWithQuery.js.map +1 -1
  300. package/dist/components/SageResourcesPopover/SageResourcesPopover.js.map +1 -1
  301. package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js.map +1 -1
  302. package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
  303. package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.js.map +1 -1
  304. package/dist/components/SmartLink/SmartButton.js.map +1 -1
  305. package/dist/components/SmartLink/SmartLink.js.map +1 -1
  306. package/dist/components/SourceAppImage.js.map +1 -1
  307. package/dist/components/StandaloneQueryWrapper/StandaloneQueryWrapper.js.map +1 -1
  308. package/dist/components/StatisticsPlot.js.map +1 -1
  309. package/dist/components/StorybookComponentWrapper.js.map +1 -1
  310. package/dist/components/SubsectionRowRenderer/SubsectionRowRenderer.js.map +1 -1
  311. package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js.map +1 -1
  312. package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
  313. package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
  314. package/dist/components/SynapseChat/SynapseChatMessage.js.map +1 -1
  315. package/dist/components/SynapseChat/extractMessageFromTraceEvent.js.map +1 -1
  316. package/dist/components/SynapseForm/StepsSideNav.js.map +1 -1
  317. package/dist/components/SynapseForm/SummaryTable.js.map +1 -1
  318. package/dist/components/SynapseForm/SynapseForm.js +4 -2
  319. package/dist/components/SynapseForm/SynapseForm.js.map +1 -1
  320. package/dist/components/SynapseForm/SynapseFormWrapper.js.map +1 -1
  321. package/dist/components/SynapseHomepageV2/SynapseByTheNumbersItem.js.map +1 -1
  322. package/dist/components/SynapseHomepageV2/SynapseFeatureItem.js.map +1 -1
  323. package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js.map +1 -1
  324. package/dist/components/SynapseHomepageV2/SynapseHomepageSearch.js.map +1 -1
  325. package/dist/components/SynapseHomepageV2/SynapseInActionItem.js.map +1 -1
  326. package/dist/components/SynapseHomepageV2/SynapsePlans.js.map +1 -1
  327. package/dist/components/SynapseHomepageV2/SynapseTrendingProjects.js.map +1 -1
  328. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts +8 -7
  329. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts.map +1 -1
  330. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js +173 -164
  331. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js.map +1 -1
  332. package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js.map +1 -1
  333. package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanel.js.map +1 -1
  334. package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanelUtils.js.map +1 -1
  335. package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js.map +1 -1
  336. package/dist/components/SynapseTable/EntityIDColumnCopyIcon.js.map +1 -1
  337. package/dist/components/SynapseTable/NoContentPlaceholderType.js.map +1 -1
  338. package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js.map +1 -1
  339. package/dist/components/SynapseTable/SynapseTableCell/SynapseTableCell.js.map +1 -1
  340. package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
  341. package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
  342. package/dist/components/SynapseTable/table-top/ColumnSelection.js.map +1 -1
  343. package/dist/components/SynapseTable/table-top/DownloadOptions.js.map +1 -1
  344. package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
  345. package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js.map +1 -1
  346. package/dist/components/TableColumnSchemaEditor/ColumnModelFormFields/DefaultValueField.js.map +1 -1
  347. package/dist/components/TableColumnSchemaEditor/ImportTableColumnsButton.js.map +1 -1
  348. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts +1 -1
  349. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts.map +1 -1
  350. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
  351. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
  352. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js.map +1 -1
  353. package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.js.map +1 -1
  354. package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.js.map +1 -1
  355. package/dist/components/TanStackTable/ColumnHeader.d.ts +1 -0
  356. package/dist/components/TanStackTable/ColumnHeader.d.ts.map +1 -1
  357. package/dist/components/TanStackTable/ColumnHeader.js +8 -8
  358. package/dist/components/TanStackTable/ColumnHeader.js.map +1 -1
  359. package/dist/components/TanStackTable/ColumnHeaderEnumFilter.js.map +1 -1
  360. package/dist/components/TanStackTable/TableBody.js.map +1 -1
  361. package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js.map +1 -1
  362. package/dist/components/TextField/TextField.js.map +1 -1
  363. package/dist/components/TimelinePlot/TimelinePhase.js.map +1 -1
  364. package/dist/components/TimelinePlot/TimelinePlot.js.map +1 -1
  365. package/dist/components/TimelinePlot/TimelinePlotSpeciesSelector.js.map +1 -1
  366. package/dist/components/UserCard/Avatar.js.map +1 -1
  367. package/dist/components/UserCardList/UserCardList.js.map +1 -1
  368. package/dist/components/UserCardList/UserCardListGroups/UserCardListGroups.Mobile.js.map +1 -1
  369. package/dist/components/UserCardList/UserCardListRotate.js.map +1 -1
  370. package/dist/components/UserOrTeamBadge/useUserOrTeam.js.map +1 -1
  371. package/dist/components/UserProfileLinks/UserProjects.js.map +1 -1
  372. package/dist/components/UserSearchBox/UserSearchBox.js.map +1 -1
  373. package/dist/components/Webhook/WebhookDashboard.js.map +1 -1
  374. package/dist/components/WikiMarkdownEditor/WikiMarkdownEditor.js.map +1 -1
  375. package/dist/components/WikiMarkdownEditorButton/WikiMarkdownEditorButton.js.map +1 -1
  376. package/dist/components/dataaccess/AccessApprovalsTable.js.map +1 -1
  377. package/dist/components/dataaccess/AccessRequestSubmissionTable.js.map +1 -1
  378. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.d.ts.map +1 -1
  379. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +157 -148
  380. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js.map +1 -1
  381. package/dist/components/dataaccess/UseAccessRequirementTable.js.map +1 -1
  382. package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js.map +1 -1
  383. package/dist/components/doi/CreateOrUpdateDoiModal.d.ts.map +1 -1
  384. package/dist/components/doi/CreateOrUpdateDoiModal.js +20 -19
  385. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  386. package/dist/components/entity/page/CreatedByModifiedBy.js.map +1 -1
  387. package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
  388. package/dist/components/entity/page/title_bar/useDataCiteUsage.js.map +1 -1
  389. package/dist/components/entity/page/title_bar/useGetMentions.js.map +1 -1
  390. package/dist/components/error/ErrorPage.js.map +1 -1
  391. package/dist/components/favorites/FavoritesPage.js.map +1 -1
  392. package/dist/components/file/upload/BasicFileHandleUpload.js.map +1 -1
  393. package/dist/components/layout/SWCHeader.d.ts +9 -0
  394. package/dist/components/layout/SWCHeader.d.ts.map +1 -0
  395. package/dist/components/layout/SWCHeader.js +19 -0
  396. package/dist/components/layout/SWCHeader.js.map +1 -0
  397. package/dist/components/layout/SWCPageLayout.d.ts +9 -0
  398. package/dist/components/layout/SWCPageLayout.d.ts.map +1 -0
  399. package/dist/components/layout/SWCPageLayout.js +14 -0
  400. package/dist/components/layout/SWCPageLayout.js.map +1 -0
  401. package/dist/components/menu/ComplexMenu.js.map +1 -1
  402. package/dist/components/row_renderers/utils/ChipContainer.js.map +1 -1
  403. package/dist/components/styled/StyledPopover.js.map +1 -1
  404. package/dist/components/table/CsvPreview/CsvPreview.js +2 -1
  405. package/dist/components/table/CsvPreview/CsvPreview.js.map +1 -1
  406. package/dist/components/table/CsvPreview/CsvPreviewDialog.js.map +1 -1
  407. package/dist/components/trash/TrashCanList.js.map +1 -1
  408. package/dist/components/widgets/FileHandleLink.js.map +1 -1
  409. package/dist/components/widgets/RangeSlider/RangeSlider.js.map +1 -1
  410. package/dist/components/widgets/SynapseVideo.js.map +1 -1
  411. package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
  412. package/dist/components/widgets/facet-nav/PlotsContainer.js.map +1 -1
  413. package/dist/components/widgets/facet-nav/SelectionCriteriaPills.js.map +1 -1
  414. package/dist/components/widgets/facet-nav/useFacetPlots.js.map +1 -1
  415. package/dist/components/widgets/query-filter/CombinedRangeFacetFilter.js.map +1 -1
  416. package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
  417. package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
  418. package/dist/components/widgets/query-filter/RangeFacetFilter.js.map +1 -1
  419. package/dist/components/widgets/query-filter/RangeFacetFilterUI.js.map +1 -1
  420. package/dist/features/curator/GridPage/components/GridPageTitle.d.ts.map +1 -1
  421. package/dist/features/curator/GridPage/components/GridPageTitle.js +23 -30
  422. package/dist/features/curator/GridPage/components/GridPageTitle.js.map +1 -1
  423. package/dist/features/curator/dashboard/CuratorDashboard.d.ts +2 -0
  424. package/dist/features/curator/dashboard/CuratorDashboard.d.ts.map +1 -0
  425. package/dist/features/curator/dashboard/CuratorDashboard.js +45 -0
  426. package/dist/features/curator/dashboard/CuratorDashboard.js.map +1 -0
  427. package/dist/features/curator/dashboard/components/CurationTaskCard.css +1 -0
  428. package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts +9 -0
  429. package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts.map +1 -0
  430. package/dist/features/curator/dashboard/components/CurationTaskCard.js +106 -0
  431. package/dist/features/curator/dashboard/components/CurationTaskCard.js.map +1 -0
  432. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js +12 -0
  433. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js.map +1 -0
  434. package/dist/features/curator/dashboard/components/CurationTaskCard.module.scss +52 -0
  435. package/dist/features/curator/dashboard/components/NextStepButton.css +1 -0
  436. package/dist/features/curator/dashboard/components/NextStepButton.d.ts +14 -0
  437. package/dist/features/curator/dashboard/components/NextStepButton.d.ts.map +1 -0
  438. package/dist/features/curator/dashboard/components/NextStepButton.js +35 -0
  439. package/dist/features/curator/dashboard/components/NextStepButton.js.map +1 -0
  440. package/dist/features/curator/dashboard/components/NextStepButton.module.js +11 -0
  441. package/dist/features/curator/dashboard/components/NextStepButton.module.js.map +1 -0
  442. package/dist/features/curator/dashboard/components/NextStepButton.module.scss +57 -0
  443. package/dist/features/curator/dashboard/components/UserOrTeamChip.css +1 -1
  444. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.js +1 -1
  445. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.js.map +1 -1
  446. package/dist/features/curator/dashboard/components/UserOrTeamChip.module.scss +5 -5
  447. package/dist/features/curator/dashboard/components/shared.css +1 -0
  448. package/dist/features/curator/dashboard/components/shared.module.js +5 -0
  449. package/dist/features/curator/dashboard/components/shared.module.js.map +1 -0
  450. package/dist/features/curator/dashboard/components/shared.module.scss +8 -0
  451. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts +0 -2
  452. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
  453. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +16 -34
  454. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  455. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts.map +1 -1
  456. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +1 -1
  457. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  458. package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js.map +1 -1
  459. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js.map +1 -1
  460. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js.map +1 -1
  461. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js +1 -1
  462. package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js.map +1 -1
  463. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts +10 -0
  464. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts.map +1 -0
  465. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js +37 -0
  466. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js.map +1 -0
  467. package/dist/features/entity/metadata-task/utils/constants.d.ts +5 -0
  468. package/dist/features/entity/metadata-task/utils/constants.d.ts.map +1 -0
  469. package/dist/features/entity/metadata-task/utils/constants.js +6 -0
  470. package/dist/features/entity/metadata-task/utils/constants.js.map +1 -0
  471. package/dist/mocks/challenge/mockChallenge.js.map +1 -1
  472. package/dist/mocks/entity/mockDataset.js.map +1 -1
  473. package/dist/mocks/entity/mockDatasetCollection.js.map +1 -1
  474. package/dist/mocks/entity/mockFileEntity.js.map +1 -1
  475. package/dist/mocks/entity/mockFileView.js.map +1 -1
  476. package/dist/mocks/entity/mockGeneratedEntityData.js.map +1 -1
  477. package/dist/mocks/entity/mockProject.js.map +1 -1
  478. package/dist/mocks/entity/mockProjectView.js.map +1 -1
  479. package/dist/mocks/entity/mockRootEntity.js.map +1 -1
  480. package/dist/mocks/entity/mockTableEntity.js.map +1 -1
  481. package/dist/mocks/mockWiki.js.map +1 -1
  482. package/dist/mocks/msw/handlers/asyncJobHandlers.js.map +1 -1
  483. package/dist/mocks/msw/handlers/challengeHandlers.js.map +1 -1
  484. package/dist/mocks/msw/handlers/changePasswordHandlers.js.map +1 -1
  485. package/dist/mocks/msw/handlers/discussionHandlers.js.map +1 -1
  486. package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
  487. package/dist/mocks/msw/handlers/fileHandlers.js.map +1 -1
  488. package/dist/mocks/msw/handlers/gridHandlers.js.map +1 -1
  489. package/dist/mocks/msw/handlers/personalAccessTokenHandlers.js.map +1 -1
  490. package/dist/mocks/msw/handlers/subscriptionHandlers.js.map +1 -1
  491. package/dist/mocks/msw/handlers/teamHandlers.js.map +1 -1
  492. package/dist/mocks/msw/handlers/userProfileHandlers.js.map +1 -1
  493. package/dist/mocks/msw/handlers/wikiHandlers.js.map +1 -1
  494. package/dist/mocks/provenance/mockActivity.js.map +1 -1
  495. package/dist/mocks/query/mockReleaseCardsTableQueryResultBundle.js.map +1 -1
  496. package/dist/ror-client/index.js.map +1 -1
  497. package/dist/style/components/_cards.scss +4 -0
  498. package/dist/style/components/_data-grid-extra.css +1 -1
  499. package/dist/style/components/_data-grid-extra.scss +2 -0
  500. package/dist/style/main.css +1 -1
  501. package/dist/synapse-client/HttpClient.js.map +1 -1
  502. package/dist/synapse-client/SynapseClient.js.map +1 -1
  503. package/dist/synapse-queries/KeyFactory.d.ts +1 -0
  504. package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
  505. package/dist/synapse-queries/KeyFactory.js +3 -0
  506. package/dist/synapse-queries/KeyFactory.js.map +1 -1
  507. package/dist/synapse-queries/QueryMatching.test-utils.js.map +1 -1
  508. package/dist/synapse-queries/auth/useTwoFactorEnrollment.js.map +1 -1
  509. package/dist/synapse-queries/curation/task/useCurationTask.d.ts +1 -1
  510. package/dist/synapse-queries/curation/task/useCurationTask.d.ts.map +1 -1
  511. package/dist/synapse-queries/curation/task/useCurationTask.js +1 -1
  512. package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
  513. package/dist/synapse-queries/dataaccess/useRestrictionInformation.js.map +1 -1
  514. package/dist/synapse-queries/doi/useDOI.js.map +1 -1
  515. package/dist/synapse-queries/download/useDownloadList.js.map +1 -1
  516. package/dist/synapse-queries/entity/useEntity.js.map +1 -1
  517. package/dist/synapse-queries/entity/useEntityBundle.js.map +1 -1
  518. package/dist/synapse-queries/entity/useExportTableQueryToAnalysisPlatform.js.map +1 -1
  519. package/dist/synapse-queries/entity/useExportToTerra.js.map +1 -1
  520. package/dist/synapse-queries/entity/useGetQueryResultBundle.js.map +1 -1
  521. package/dist/synapse-queries/entity/useSchema.js.map +1 -1
  522. package/dist/synapse-queries/file/UploadToS3.js.map +1 -1
  523. package/dist/synapse-queries/file/useDirectUploadToS3.js.map +1 -1
  524. package/dist/synapse-queries/file/useFiles.js.map +1 -1
  525. package/dist/synapse-queries/forum/useReply.js.map +1 -1
  526. package/dist/synapse-queries/forum/useThread.d.ts +1 -0
  527. package/dist/synapse-queries/forum/useThread.d.ts.map +1 -1
  528. package/dist/synapse-queries/forum/useThread.js +19 -12
  529. package/dist/synapse-queries/forum/useThread.js.map +1 -1
  530. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts +2 -0
  531. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts.map +1 -1
  532. package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js.map +1 -1
  533. package/dist/synapse-queries/grid/useExportGrid.js.map +1 -1
  534. package/dist/synapse-queries/grid/useGridSession.js.map +1 -1
  535. package/dist/synapse-queries/grid/useImportCsvIntoGrid.js.map +1 -1
  536. package/dist/synapse-queries/subscription/useSubscription.js.map +1 -1
  537. package/dist/synapse-queries/table/useGetCsvPreview.js.map +1 -1
  538. package/dist/synapse-queries/table/useTableUpdateTransaction.js.map +1 -1
  539. package/dist/synapse-queries/team/useTeamMembers.js.map +1 -1
  540. package/dist/synapse-queries/user/useGetUserChallenges.js.map +1 -1
  541. package/dist/synapse-queries/user/useUserBundle.js.map +1 -1
  542. package/dist/synapse-queries/user/useUserGroupHeader.js.map +1 -1
  543. package/dist/testutils/ReactQueryMockUtils.js.map +1 -1
  544. package/dist/theme/ThemeProvider.js.map +1 -1
  545. package/dist/tsconfig.build.tsbuildinfo +1 -1
  546. package/dist/utils/APIConstants.d.ts +1 -0
  547. package/dist/utils/APIConstants.d.ts.map +1 -1
  548. package/dist/utils/APIConstants.js +2 -2
  549. package/dist/utils/APIConstants.js.map +1 -1
  550. package/dist/utils/AppUtils/session/ApplicationSessionManager.d.ts.map +1 -1
  551. package/dist/utils/AppUtils/session/ApplicationSessionManager.js +7 -4
  552. package/dist/utils/AppUtils/session/ApplicationSessionManager.js.map +1 -1
  553. package/dist/utils/AppUtils/session/SynapseSessionManager.js.map +1 -1
  554. package/dist/utils/AppUtils/session/useSessionManager.js.map +1 -1
  555. package/dist/utils/PermissionLevelToAccessType.js.map +1 -1
  556. package/dist/utils/challenge/evaluation/EvaluationUtils.js.map +1 -1
  557. package/dist/utils/context/SynapseContext.js.map +1 -1
  558. package/dist/utils/functions/AccessControlListUtils.d.ts +4 -0
  559. package/dist/utils/functions/AccessControlListUtils.d.ts.map +1 -1
  560. package/dist/utils/functions/AccessControlListUtils.js +12 -1
  561. package/dist/utils/functions/AccessControlListUtils.js.map +1 -1
  562. package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
  563. package/dist/utils/functions/EntityTypeUtils.js +15 -4
  564. package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
  565. package/dist/utils/functions/GridApiUtils.js.map +1 -1
  566. package/dist/utils/functions/QueryFilterUtils.js.map +1 -1
  567. package/dist/utils/functions/RealmUtils.d.ts +4 -0
  568. package/dist/utils/functions/RealmUtils.d.ts.map +1 -1
  569. package/dist/utils/functions/RealmUtils.js +9 -3
  570. package/dist/utils/functions/RealmUtils.js.map +1 -1
  571. package/dist/utils/functions/SanitizeHtmlUtils.js.map +1 -1
  572. package/dist/utils/functions/SanitizeHtmlUtils.test-utils.js.map +1 -1
  573. package/dist/utils/functions/SqlFunctions.js.map +1 -1
  574. package/dist/utils/functions/StringUtils.js.map +1 -1
  575. package/dist/utils/functions/deepLinkingUtils.js.map +1 -1
  576. package/dist/utils/functions/getDataFromFromStorage.js.map +1 -1
  577. package/dist/utils/functions/getEndpoint.js.map +1 -1
  578. package/dist/utils/functions/getUserData.js.map +1 -1
  579. package/dist/utils/functions/queryUtils.js.map +1 -1
  580. package/dist/utils/functions/testDownloadSpeed.js.map +1 -1
  581. package/dist/utils/hooks/useConfirmItems.js.map +1 -1
  582. package/dist/utils/hooks/useCookiePreferences.js.map +1 -1
  583. package/dist/utils/hooks/useCreateShortUrl.js.map +1 -1
  584. package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
  585. package/dist/utils/hooks/useDirectDownloadHandler.js.map +1 -1
  586. package/dist/utils/hooks/useGetGoalData.js.map +1 -1
  587. package/dist/utils/hooks/useGetInfoFromIds.js.map +1 -1
  588. package/dist/utils/hooks/useImageUrlUtils.js.map +1 -1
  589. package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js.map +1 -1
  590. package/dist/utils/hooks/useImmutableTableQuery/useTableQueryReducer.js.map +1 -1
  591. package/dist/utils/hooks/useIsBot.js.map +1 -1
  592. package/dist/utils/hooks/useListState.js.map +1 -1
  593. package/dist/utils/hooks/useLogin.d.ts.map +1 -1
  594. package/dist/utils/hooks/useLogin.js +53 -52
  595. package/dist/utils/hooks/useLogin.js.map +1 -1
  596. package/dist/utils/hooks/useMutuallyExclusiveState.js.map +1 -1
  597. package/dist/utils/hooks/useOverlay.js.map +1 -1
  598. package/dist/utils/hooks/usePreFetchResource.js.map +1 -1
  599. package/dist/utils/hooks/useQuerySearchParam.js.map +1 -1
  600. package/dist/utils/hooks/useScrollFadeTransition.js.map +1 -1
  601. package/dist/utils/hooks/useSet.js.map +1 -1
  602. package/dist/utils/hooks/useSourceAppConfigs.js.map +1 -1
  603. package/dist/utils/hooks/useTableImageUrl.js.map +1 -1
  604. package/dist/utils/hooks/useUploadFileEntity/useCreatePathsAndGetParentId.js.map +1 -1
  605. package/dist/utils/hooks/useUploadFileEntity/useLinkFileEntityToURL.js.map +1 -1
  606. package/dist/utils/hooks/useUploadFileEntity/usePrepareFileEntityUpload.js.map +1 -1
  607. package/dist/utils/hooks/useUploadFileEntity/useTrackFileUploads.js.map +1 -1
  608. package/dist/utils/hooks/useUploadFileEntity/useUploadFileEntities.js.map +1 -1
  609. package/dist/utils/hooks/useUploadFileEntity/useUploadFiles.js.map +1 -1
  610. package/dist/utils/hooks/useUploadFileEntity/willUploadsExceedStorageLimit.js.map +1 -1
  611. package/dist/utils/html/TargetEnum.js.map +1 -1
  612. package/dist/utils/jsonschema/SchemaAnnotationUtils.js.map +1 -1
  613. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"FacetNavPanel.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/FacetNavPanel.tsx"],"sourcesContent":["import StyledFormControl from '@/components/styled/StyledFormControl'\nimport SynapseClient from '@/synapse-client'\nimport { SynapseConstants } from '@/utils'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { getCorrespondingColumnForFacet } from '@/utils/functions/queryUtils'\nimport { InfoOutlined } from '@mui/icons-material'\nimport {\n Box,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n Tooltip,\n} from '@mui/material'\nimport {\n ColumnTypeEnum,\n FacetColumnRequest,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n} from '@sage-bionetworks/synapse-types'\nimport { useQuery } from '@tanstack/react-query'\nimport type Plotly from 'plotly.js-basic-dist'\nimport { useMemo, useState } from 'react'\nimport { getContrastColorPalette } from '../../ColorGradient/ColorGradient'\nimport { ConfirmationDialog } from '../../ConfirmationDialog/ConfirmationDialog'\nimport loadingScreen from '../../LoadingScreen/LoadingScreen'\nimport Plot from '../../Plot/Plot'\nimport PlotPanelHeader from '../../Plot/PlotPanelHeader'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { EnumFacetFilter } from '../query-filter/EnumFacetFilter/EnumFacetFilter'\nimport { FacetPlotLegendList } from './FacetPlotLegendList'\nimport { FacetWithLabel, truncate } from './FacetPlotLegendUtils'\nimport { useMeasure } from '@react-hookz/web'\n\nexport type FacetNavPanelProps = {\n applyChangesToGraphSlice: (\n facet: FacetColumnResultValues,\n value: FacetColumnResultValueCount | undefined,\n isSelected: boolean,\n ) => void\n applyChangesToFacetFilter: (facets: FacetColumnRequest[]) => void\n index: number\n facetToPlot: FacetColumnResultValues\n plotType: PlotType\n onSetPlotType: (plotType: PlotType) => void\n onHide: () => void\n isModalView: boolean\n onCloseModal?: () => void\n}\n\nconst maxLabelLength: number = 19\n\n// STACKED_HORIZONTAL_BAR corresponds to a bar chart where we just want to show the proportion (like a pie chart)\nexport type PlotType = 'PIE' | 'BAR' | 'STACKED_HORIZONTAL_BAR'\n\nconst layout: Partial<Plotly.Layout> = {\n showlegend: false,\n annotations: [],\n margin: { l: 0, r: 0, b: 0, t: 0, pad: 0 },\n yaxis: {\n visible: false,\n showgrid: false,\n },\n xaxis: {\n visible: false,\n showgrid: false,\n },\n}\n\nexport type GraphData = {\n data: Plotly.Data[]\n labels: FacetWithLabel[]\n colors: string[]\n}\n\nexport async function extractPlotDataArray(\n facetToPlot: FacetColumnResultValues,\n columnType: ColumnTypeEnum | undefined,\n index: number,\n plotType: PlotType,\n accessToken?: string,\n) {\n const colorPalette = getContrastColorPalette(\n // Use only the odd palette, using the same offset for all plots until palettes are improved.\n // See PORTALS-2916\n 'odd', // index % 2 === 0 ? 'even' : 'odd',\n 0, // Math.floor(index / 2),\n facetToPlot.facetValues.length,\n )\n\n const getLabels = async (\n facetValues: FacetColumnResultValueCount[],\n columnType?: ColumnTypeEnum,\n accessToken?: string,\n ) => {\n const map = new Map<string, string>()\n map.set(\n SynapseConstants.VALUE_NOT_SET,\n SynapseConstants.FRIENDLY_VALUE_NOT_SET,\n )\n // Filter out empties\n const filteredValues = facetValues\n .map(value => value.value)\n .filter(val => val !== SynapseConstants.VALUE_NOT_SET)\n if (\n columnType === ColumnTypeEnum.ENTITYID ||\n columnType === ColumnTypeEnum.ENTITYID_LIST\n ) {\n // TODO: Pagination\n const response = await SynapseClient.getEntityHeadersByIds(\n filteredValues,\n accessToken,\n )\n for (const header of response.results) {\n map.set(header.id, header.name)\n }\n } else if (\n columnType === ColumnTypeEnum.USERID ||\n columnType === ColumnTypeEnum.USERID_LIST\n ) {\n const response = await SynapseClient.getGroupHeadersBatch(\n filteredValues,\n accessToken,\n )\n for (const header of response.children) {\n map.set(header.ownerId, header.userName)\n }\n }\n\n return facetValues.map(facetValue => ({\n facet: facetValue,\n label: getLabel(facetValue, false, map),\n truncatedLabel: getLabel(facetValue, true, map),\n count: facetValue.count,\n }))\n }\n\n const getLabel = (\n facetValue: FacetColumnResultValueCount,\n truncateFlag: boolean,\n labelMap: Map<string, string>,\n ): string => {\n let label = labelMap.get(facetValue.value) ?? facetValue.value\n if (truncateFlag) {\n label = truncate(label, maxLabelLength)!\n }\n return label\n }\n\n const labels = await getLabels(\n facetToPlot.facetValues,\n columnType,\n accessToken,\n )\n const text = labels.map(el => el.truncatedLabel)\n\n const anyFacetsSelected = facetToPlot.facetValues.some(\n value => value.isSelected,\n )\n const selectionAwareColorPalette = anyFacetsSelected\n ? facetToPlot.facetValues.map((facetValue, index) =>\n facetValue.isSelected\n ? colorPalette[index]\n : colorPalette[index]\n .replace('rgb(', 'rgba(')\n .replace(')', ', 0.25)'),\n )\n : colorPalette\n const counts: Plotly.Datum[] = facetToPlot.facetValues.map(\n facet => facet.count,\n )\n let x: Plotly.Datum[] | Plotly.Datum[][] | Plotly.TypedArray | undefined\n\n if (plotType === 'BAR') {\n x = facetToPlot.facetValues.map(\n facet =>\n labels.find(label => label.facet === facet)?.label ?? facet.value,\n )\n } else if (plotType === 'STACKED_HORIZONTAL_BAR') {\n x = counts\n }\n\n let y: Plotly.Datum[] | Plotly.Datum[][] | Plotly.TypedArray | undefined\n if (plotType === 'BAR') {\n y = facetToPlot.facetValues.map(facet => facet.count)\n } else if (plotType === 'STACKED_HORIZONTAL_BAR') {\n y = Array(x?.length).fill('Proportional') // single value for every x value\n }\n\n const singleChartData: Plotly.Data = {\n values: plotType === 'PIE' ? counts : undefined,\n labels: labels.map(el => el.label),\n text,\n x,\n y,\n orientation: plotType === 'STACKED_HORIZONTAL_BAR' ? 'h' : 'v',\n // @ts-expect-error\n facetEnumerationValues: facetToPlot.facetValues.map(\n facetValue => facetValue.value,\n ),\n name: facetToPlot.columnName,\n textposition:\n plotType === 'STACKED_HORIZONTAL_BAR' || plotType === 'BAR'\n ? 'none'\n : 'inside',\n hovertemplate:\n plotType === 'PIE'\n ? '<b>%{text}</b><br>%{value} (%{percent})<br><extra></extra>'\n : '<b>%{text}: </b><br>%{value} <br><extra></extra>',\n textinfo: 'none',\n type: plotType === 'PIE' ? 'pie' : 'bar',\n pull:\n plotType === 'PIE'\n ? facetToPlot.facetValues.map(facetValue =>\n facetValue.isSelected ? 0.1 : 0,\n )\n : undefined,\n selectedpoints: anyFacetsSelected\n ? facetToPlot.facetValues\n .map((facetValue, index) => (facetValue.isSelected ? index : -1))\n .filter(index => index !== -1)\n : undefined,\n selected: { marker: { opacity: 1 } },\n unselected: { marker: { opacity: 0.25 } },\n\n marker: {\n colors: plotType === 'PIE' ? selectionAwareColorPalette : undefined,\n color: plotType === 'PIE' ? undefined : selectionAwareColorPalette,\n },\n }\n const result = {\n data: [singleChartData],\n labels,\n colors:\n plotType === 'PIE'\n ? ((singleChartData as any).marker?.colors as string[])\n : ((singleChartData as any).marker?.color as string[]),\n }\n return result\n}\n\nconst applyFacetFilter = (\n event: Plotly.PlotMouseEvent,\n allFacetValues: FacetColumnResultValues,\n callbackApplyFn: FacetNavPanelProps['applyChangesToGraphSlice'],\n) => {\n if (event.points && event.points[0]) {\n const plotPointData: any = event.points[0]\n const facetValueClickedValue =\n plotPointData.data.facetEnumerationValues[plotPointData.pointNumber]\n const facetValueClicked = allFacetValues.facetValues.find(\n facet => facet.value === facetValueClickedValue,\n )\n callbackApplyFn(\n allFacetValues,\n facetValueClicked,\n !facetValueClicked!.isSelected,\n )\n }\n}\n\nexport function getPlotStyle(\n parentWidth: number | null | undefined,\n plotType: PlotType,\n maxHeight: number,\n): { width: string; height: string } {\n if (parentWidth != undefined) {\n let quotient = 1\n switch (plotType) {\n case 'BAR':\n quotient = 0.8\n break\n case 'PIE':\n quotient = 0.6\n break\n case 'STACKED_HORIZONTAL_BAR':\n quotient = 1\n break\n }\n const width = parentWidth ? parentWidth * quotient : 200\n let height = plotType === 'PIE' ? width : width / 3\n // max height of .PlotsContainer row col* is 200px, so the effective plot height max is around 150 unless it's expanded\n if (height > maxHeight) {\n height = maxHeight\n }\n return {\n width: `${width}px`,\n height: `${height}px`,\n }\n }\n //else parent width is undefined\n return {\n width: '100%',\n height: `${maxHeight}px`,\n }\n}\n\nfunction FacetNavPanel(props: FacetNavPanelProps) {\n const {\n onHide,\n isModalView,\n applyChangesToGraphSlice,\n index,\n facetToPlot,\n plotType,\n onSetPlotType,\n } = props\n const { accessToken } = useSynapseContext()\n const { data: queryMetadata, isLoading: isLoadingQueryMetadata } =\n useGetQueryMetadata()\n\n const [plotContainerMeasurements, plotContainerRef] =\n useMeasure<HTMLDivElement>()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const [showModal, setShowModal] = useState(false)\n\n const plotTitle = getColumnDisplayName(\n facetToPlot.columnName,\n facetToPlot.jsonPath,\n )\n\n const columnModel = useMemo(\n () =>\n getCorrespondingColumnForFacet(\n facetToPlot,\n queryMetadata?.columnModels ?? [],\n ),\n [queryMetadata?.columnModels, facetToPlot],\n )\n const columnType = columnModel?.columnType as ColumnTypeEnum\n\n const { data: plotData } = useQuery({\n queryKey: [\n 'extractPlotDataArray',\n facetToPlot,\n columnType,\n index,\n plotType,\n accessToken,\n ],\n\n queryFn: () =>\n extractPlotDataArray(\n facetToPlot,\n columnType,\n index,\n plotType,\n accessToken,\n ),\n\n enabled: !!facetToPlot,\n })\n\n /* rendering functions */\n const chartSelectionToggle = (\n <StyledFormControl fullWidth>\n <InputLabel>Chart Type</InputLabel>\n <Select\n value={plotType}\n onChange={e => {\n onSetPlotType(e.target.value as PlotType)\n }}\n >\n <MenuItem value={'BAR'}>Bar Chart</MenuItem>\n <MenuItem value={'PIE'}>Pie Chart</MenuItem>\n </Select>\n </StyledFormControl>\n )\n\n if (\n (!queryMetadata && isLoadingQueryMetadata) ||\n !facetToPlot ||\n !columnModel\n ) {\n return (\n <div className=\"SRC-loadingContainer SRC-centerContentColumn\">\n {loadingScreen}\n </div>\n )\n } else {\n return (\n <>\n <ConfirmationDialog\n open={showModal}\n onCancel={() => setShowModal(false)}\n title={plotTitle ?? ''}\n content={<FacetNavPanel {...props} isModalView={true} />}\n hasCancelButton={false}\n confirmButtonProps={{ children: 'Apply Filters' }}\n onConfirm={() => setShowModal(false)}\n maxWidth={'md'}\n />\n <div\n role=\"figure\"\n className={`FacetNavPanel${isModalView ? '--expanded' : ''}`}\n >\n {!isModalView && (\n <PlotPanelHeader\n data={queryMetadata}\n isLoading={isLoadingQueryMetadata}\n title={plotTitle}\n facetToPlot={facetToPlot}\n onHide={onHide}\n setShowModal={setShowModal}\n />\n )}\n {isModalView && (\n <Stack\n sx={{\n gap: 2,\n }}\n >\n <StyledFormControl>\n <InputLabel\n sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}\n >\n <span>Filter All Data By</span>\n <Tooltip title=\"Selecting items in this dropdown will affect all facets on the Explore page.\">\n <InfoOutlined className=\"SRC-hand-cursor SRC-secondary-text-color\" />\n </Tooltip>\n </InputLabel>\n <EnumFacetFilter\n facet={facetToPlot}\n containerAs=\"Dropdown\"\n dropdownType=\"SelectBox\"\n />\n </StyledFormControl>\n {chartSelectionToggle}\n </Stack>\n )}\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: '50% 50%',\n alignItems: 'center',\n }}\n role=\"graphics-object\"\n className=\"FacetNavPanel__body\"\n >\n <div ref={plotContainerRef}>\n <Plot\n key={`${facetToPlot.columnName}-${facetToPlot.jsonPath}-${plotType}-${plotContainerMeasurements?.width}`}\n layout={layout}\n data={plotData?.data ?? []}\n style={getPlotStyle(\n plotContainerMeasurements?.width,\n plotType,\n isModalView ? 300 : 150,\n )}\n config={{ displayModeBar: false }}\n onClick={evt =>\n applyFacetFilter(evt, facetToPlot, applyChangesToGraphSlice)\n }\n />\n </div>\n <FacetPlotLegendList\n labels={plotData?.labels}\n colors={plotData?.colors}\n isExpanded={isModalView}\n />\n </Box>\n </div>\n </>\n )\n }\n}\n\nexport default FacetNavPanel\n"],"mappings":"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"}
1
+ {"version":3,"file":"FacetNavPanel.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/FacetNavPanel.tsx"],"sourcesContent":["import StyledFormControl from '@/components/styled/StyledFormControl'\nimport SynapseClient from '@/synapse-client'\nimport { SynapseConstants } from '@/utils'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { getCorrespondingColumnForFacet } from '@/utils/functions/queryUtils'\nimport { InfoOutlined } from '@mui/icons-material'\nimport {\n Box,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n Tooltip,\n} from '@mui/material'\nimport {\n ColumnTypeEnum,\n FacetColumnRequest,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n} from '@sage-bionetworks/synapse-types'\nimport { useQuery } from '@tanstack/react-query'\nimport type Plotly from 'plotly.js-basic-dist'\nimport { useMemo, useState } from 'react'\nimport { getContrastColorPalette } from '../../ColorGradient/ColorGradient'\nimport { ConfirmationDialog } from '../../ConfirmationDialog/ConfirmationDialog'\nimport loadingScreen from '../../LoadingScreen/LoadingScreen'\nimport Plot from '../../Plot/Plot'\nimport PlotPanelHeader from '../../Plot/PlotPanelHeader'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { EnumFacetFilter } from '../query-filter/EnumFacetFilter/EnumFacetFilter'\nimport { FacetPlotLegendList } from './FacetPlotLegendList'\nimport { FacetWithLabel, truncate } from './FacetPlotLegendUtils'\nimport { useMeasure } from '@react-hookz/web'\n\nexport type FacetNavPanelProps = {\n applyChangesToGraphSlice: (\n facet: FacetColumnResultValues,\n value: FacetColumnResultValueCount | undefined,\n isSelected: boolean,\n ) => void\n applyChangesToFacetFilter: (facets: FacetColumnRequest[]) => void\n index: number\n facetToPlot: FacetColumnResultValues\n plotType: PlotType\n onSetPlotType: (plotType: PlotType) => void\n onHide: () => void\n isModalView: boolean\n onCloseModal?: () => void\n}\n\nconst maxLabelLength: number = 19\n\n// STACKED_HORIZONTAL_BAR corresponds to a bar chart where we just want to show the proportion (like a pie chart)\nexport type PlotType = 'PIE' | 'BAR' | 'STACKED_HORIZONTAL_BAR'\n\nconst layout: Partial<Plotly.Layout> = {\n showlegend: false,\n annotations: [],\n margin: { l: 0, r: 0, b: 0, t: 0, pad: 0 },\n yaxis: {\n visible: false,\n showgrid: false,\n },\n xaxis: {\n visible: false,\n showgrid: false,\n },\n}\n\nexport type GraphData = {\n data: Plotly.Data[]\n labels: FacetWithLabel[]\n colors: string[]\n}\n\nexport async function extractPlotDataArray(\n facetToPlot: FacetColumnResultValues,\n columnType: ColumnTypeEnum | undefined,\n index: number,\n plotType: PlotType,\n accessToken?: string,\n) {\n const colorPalette = getContrastColorPalette(\n // Use only the odd palette, using the same offset for all plots until palettes are improved.\n // See PORTALS-2916\n 'odd', // index % 2 === 0 ? 'even' : 'odd',\n 0, // Math.floor(index / 2),\n facetToPlot.facetValues.length,\n )\n\n const getLabels = async (\n facetValues: FacetColumnResultValueCount[],\n columnType?: ColumnTypeEnum,\n accessToken?: string,\n ) => {\n const map = new Map<string, string>()\n map.set(\n SynapseConstants.VALUE_NOT_SET,\n SynapseConstants.FRIENDLY_VALUE_NOT_SET,\n )\n // Filter out empties\n const filteredValues = facetValues\n .map(value => value.value)\n .filter(val => val !== SynapseConstants.VALUE_NOT_SET)\n if (\n columnType === ColumnTypeEnum.ENTITYID ||\n columnType === ColumnTypeEnum.ENTITYID_LIST\n ) {\n // TODO: Pagination\n const response = await SynapseClient.getEntityHeadersByIds(\n filteredValues,\n accessToken,\n )\n for (const header of response.results) {\n map.set(header.id, header.name)\n }\n } else if (\n columnType === ColumnTypeEnum.USERID ||\n columnType === ColumnTypeEnum.USERID_LIST\n ) {\n const response = await SynapseClient.getGroupHeadersBatch(\n filteredValues,\n accessToken,\n )\n for (const header of response.children) {\n map.set(header.ownerId, header.userName)\n }\n }\n\n return facetValues.map(facetValue => ({\n facet: facetValue,\n label: getLabel(facetValue, false, map),\n truncatedLabel: getLabel(facetValue, true, map),\n count: facetValue.count,\n }))\n }\n\n const getLabel = (\n facetValue: FacetColumnResultValueCount,\n truncateFlag: boolean,\n labelMap: Map<string, string>,\n ): string => {\n let label = labelMap.get(facetValue.value) ?? facetValue.value\n if (truncateFlag) {\n label = truncate(label, maxLabelLength)!\n }\n return label\n }\n\n const labels = await getLabels(\n facetToPlot.facetValues,\n columnType,\n accessToken,\n )\n const text = labels.map(el => el.truncatedLabel)\n\n const anyFacetsSelected = facetToPlot.facetValues.some(\n value => value.isSelected,\n )\n const selectionAwareColorPalette = anyFacetsSelected\n ? facetToPlot.facetValues.map((facetValue, index) =>\n facetValue.isSelected\n ? colorPalette[index]\n : colorPalette[index]\n .replace('rgb(', 'rgba(')\n .replace(')', ', 0.25)'),\n )\n : colorPalette\n const counts: Plotly.Datum[] = facetToPlot.facetValues.map(\n facet => facet.count,\n )\n let x: Plotly.Datum[] | Plotly.Datum[][] | Plotly.TypedArray | undefined\n\n if (plotType === 'BAR') {\n x = facetToPlot.facetValues.map(\n facet =>\n labels.find(label => label.facet === facet)?.label ?? facet.value,\n )\n } else if (plotType === 'STACKED_HORIZONTAL_BAR') {\n x = counts\n }\n\n let y: Plotly.Datum[] | Plotly.Datum[][] | Plotly.TypedArray | undefined\n if (plotType === 'BAR') {\n y = facetToPlot.facetValues.map(facet => facet.count)\n } else if (plotType === 'STACKED_HORIZONTAL_BAR') {\n y = Array(x?.length).fill('Proportional') // single value for every x value\n }\n\n const singleChartData: Plotly.Data = {\n values: plotType === 'PIE' ? counts : undefined,\n labels: labels.map(el => el.label),\n text,\n x,\n y,\n orientation: plotType === 'STACKED_HORIZONTAL_BAR' ? 'h' : 'v',\n // @ts-expect-error\n facetEnumerationValues: facetToPlot.facetValues.map(\n facetValue => facetValue.value,\n ),\n name: facetToPlot.columnName,\n textposition:\n plotType === 'STACKED_HORIZONTAL_BAR' || plotType === 'BAR'\n ? 'none'\n : 'inside',\n hovertemplate:\n plotType === 'PIE'\n ? '<b>%{text}</b><br>%{value} (%{percent})<br><extra></extra>'\n : '<b>%{text}: </b><br>%{value} <br><extra></extra>',\n textinfo: 'none',\n type: plotType === 'PIE' ? 'pie' : 'bar',\n pull:\n plotType === 'PIE'\n ? facetToPlot.facetValues.map(facetValue =>\n facetValue.isSelected ? 0.1 : 0,\n )\n : undefined,\n selectedpoints: anyFacetsSelected\n ? facetToPlot.facetValues\n .map((facetValue, index) => (facetValue.isSelected ? index : -1))\n .filter(index => index !== -1)\n : undefined,\n selected: { marker: { opacity: 1 } },\n unselected: { marker: { opacity: 0.25 } },\n\n marker: {\n colors: plotType === 'PIE' ? selectionAwareColorPalette : undefined,\n color: plotType === 'PIE' ? undefined : selectionAwareColorPalette,\n },\n }\n const result = {\n data: [singleChartData],\n labels,\n colors:\n plotType === 'PIE'\n ? ((singleChartData as any).marker?.colors as string[])\n : ((singleChartData as any).marker?.color as string[]),\n }\n return result\n}\n\nconst applyFacetFilter = (\n event: Plotly.PlotMouseEvent,\n allFacetValues: FacetColumnResultValues,\n callbackApplyFn: FacetNavPanelProps['applyChangesToGraphSlice'],\n) => {\n if (event.points && event.points[0]) {\n const plotPointData: any = event.points[0]\n const facetValueClickedValue =\n plotPointData.data.facetEnumerationValues[plotPointData.pointNumber]\n const facetValueClicked = allFacetValues.facetValues.find(\n facet => facet.value === facetValueClickedValue,\n )\n callbackApplyFn(\n allFacetValues,\n facetValueClicked,\n !facetValueClicked!.isSelected,\n )\n }\n}\n\nexport function getPlotStyle(\n parentWidth: number | null | undefined,\n plotType: PlotType,\n maxHeight: number,\n): { width: string; height: string } {\n if (parentWidth != undefined) {\n let quotient = 1\n switch (plotType) {\n case 'BAR':\n quotient = 0.8\n break\n case 'PIE':\n quotient = 0.6\n break\n case 'STACKED_HORIZONTAL_BAR':\n quotient = 1\n break\n }\n const width = parentWidth ? parentWidth * quotient : 200\n let height = plotType === 'PIE' ? width : width / 3\n // max height of .PlotsContainer row col* is 200px, so the effective plot height max is around 150 unless it's expanded\n if (height > maxHeight) {\n height = maxHeight\n }\n return {\n width: `${width}px`,\n height: `${height}px`,\n }\n }\n //else parent width is undefined\n return {\n width: '100%',\n height: `${maxHeight}px`,\n }\n}\n\nfunction FacetNavPanel(props: FacetNavPanelProps) {\n const {\n onHide,\n isModalView,\n applyChangesToGraphSlice,\n index,\n facetToPlot,\n plotType,\n onSetPlotType,\n } = props\n const { accessToken } = useSynapseContext()\n const { data: queryMetadata, isLoading: isLoadingQueryMetadata } =\n useGetQueryMetadata()\n\n const [plotContainerMeasurements, plotContainerRef] =\n useMeasure<HTMLDivElement>()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const [showModal, setShowModal] = useState(false)\n\n const plotTitle = getColumnDisplayName(\n facetToPlot.columnName,\n facetToPlot.jsonPath,\n )\n\n const columnModel = useMemo(\n () =>\n getCorrespondingColumnForFacet(\n facetToPlot,\n queryMetadata?.columnModels ?? [],\n ),\n [queryMetadata?.columnModels, facetToPlot],\n )\n const columnType = columnModel?.columnType as ColumnTypeEnum\n\n const { data: plotData } = useQuery({\n queryKey: [\n 'extractPlotDataArray',\n facetToPlot,\n columnType,\n index,\n plotType,\n accessToken,\n ],\n\n queryFn: () =>\n extractPlotDataArray(\n facetToPlot,\n columnType,\n index,\n plotType,\n accessToken,\n ),\n\n enabled: !!facetToPlot,\n })\n\n /* rendering functions */\n const chartSelectionToggle = (\n <StyledFormControl fullWidth>\n <InputLabel>Chart Type</InputLabel>\n <Select\n value={plotType}\n onChange={e => {\n onSetPlotType(e.target.value as PlotType)\n }}\n >\n <MenuItem value={'BAR'}>Bar Chart</MenuItem>\n <MenuItem value={'PIE'}>Pie Chart</MenuItem>\n </Select>\n </StyledFormControl>\n )\n\n if (\n (!queryMetadata && isLoadingQueryMetadata) ||\n !facetToPlot ||\n !columnModel\n ) {\n return (\n <div className=\"SRC-loadingContainer SRC-centerContentColumn\">\n {loadingScreen}\n </div>\n )\n } else {\n return (\n <>\n <ConfirmationDialog\n open={showModal}\n onCancel={() => setShowModal(false)}\n title={plotTitle ?? ''}\n content={<FacetNavPanel {...props} isModalView={true} />}\n hasCancelButton={false}\n confirmButtonProps={{ children: 'Apply Filters' }}\n onConfirm={() => setShowModal(false)}\n maxWidth={'md'}\n />\n <div\n role=\"figure\"\n className={`FacetNavPanel${isModalView ? '--expanded' : ''}`}\n >\n {!isModalView && (\n <PlotPanelHeader\n data={queryMetadata}\n isLoading={isLoadingQueryMetadata}\n title={plotTitle}\n facetToPlot={facetToPlot}\n onHide={onHide}\n setShowModal={setShowModal}\n />\n )}\n {isModalView && (\n <Stack\n sx={{\n gap: 2,\n }}\n >\n <StyledFormControl>\n <InputLabel\n sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}\n >\n <span>Filter All Data By</span>\n <Tooltip title=\"Selecting items in this dropdown will affect all facets on the Explore page.\">\n <InfoOutlined className=\"SRC-hand-cursor SRC-secondary-text-color\" />\n </Tooltip>\n </InputLabel>\n <EnumFacetFilter\n facet={facetToPlot}\n containerAs=\"Dropdown\"\n dropdownType=\"SelectBox\"\n />\n </StyledFormControl>\n {chartSelectionToggle}\n </Stack>\n )}\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: '50% 50%',\n alignItems: 'center',\n }}\n role=\"graphics-object\"\n className=\"FacetNavPanel__body\"\n >\n <div ref={plotContainerRef}>\n <Plot\n key={`${facetToPlot.columnName}-${facetToPlot.jsonPath}-${plotType}-${plotContainerMeasurements?.width}`}\n layout={layout}\n data={plotData?.data ?? []}\n style={getPlotStyle(\n plotContainerMeasurements?.width,\n plotType,\n isModalView ? 300 : 150,\n )}\n config={{ displayModeBar: false }}\n onClick={evt =>\n applyFacetFilter(evt, facetToPlot, applyChangesToGraphSlice)\n }\n />\n </div>\n <FacetPlotLegendList\n labels={plotData?.labels}\n colors={plotData?.colors}\n isExpanded={isModalView}\n />\n </Box>\n </div>\n </>\n )\n }\n}\n\nexport default FacetNavPanel\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlotsContainer.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/PlotsContainer.tsx"],"sourcesContent":["import { UniqueFacetIdentifier } from '@/utils'\nimport { facetObjectMatchesDefinition } from '@/utils/functions/queryUtils'\nimport { Box, Button } from '@mui/material'\nimport type { PlotType as PlotlyPlotType } from 'plotly.js-basic-dist'\nimport { Suspense, useEffect, useMemo, useState } from 'react'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport QueryWrapperSynapsePlot, {\n QueryWrapperSynapsePlotProps,\n} from '../../QueryWrapperPlotNav/QueryWrapperSynapsePlot'\nimport FacetNavPanel, {\n FacetNavPanelProps,\n PlotType,\n} from '../facet-nav/FacetNavPanel'\nimport { PlotsContainerSkeleton } from './PlotsContainerSkeleton'\nimport useFacetPlots, { getFacets } from './useFacetPlots'\n\nconst DEFAULT_VISIBLE_PLOTS = 2\ntype ShowMoreState = 'MORE' | 'LESS' | 'NONE'\nexport type PlotsContainerProps = {\n facetsToPlot?: string[]\n customPlots?: QueryWrapperSynapsePlotProps[]\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>\n}\ntype CustomPlotIdentifier = {\n title: string\n __custom: true\n}\nexport type PlotIdentifier = UniqueFacetIdentifier | CustomPlotIdentifier\n\nexport type UiPlotState = {\n plotId: PlotIdentifier\n isHidden: boolean\n plotType: PlotType\n index?: number\n}\nconst plotMatchesDefinition = (\n definition: PlotIdentifier,\n plotId: PlotIdentifier,\n) => {\n if ('__custom' in plotId && '__custom' in definition) {\n return definition.title == plotId.title\n } else if (!('__custom' in plotId) && !('__custom' in definition)) {\n return facetObjectMatchesDefinition(definition, plotId)\n } else {\n return false\n }\n}\n\nfunction convertPlotlyPlotTypeToFacetNavPlotType(\n plotlyPlotType: PlotlyPlotType,\n): PlotType {\n if (plotlyPlotType === 'bar') {\n return 'BAR'\n } else if (plotlyPlotType === 'pie') {\n return 'PIE'\n }\n return 'PIE'\n}\n\nconst generatePlotKey = (plotUiState: UiPlotState) => {\n if ('__custom' in plotUiState.plotId) {\n // For custom plots\n return `custom-${plotUiState.plotId.title}`\n } else {\n // For facet plots\n return `facet-${plotUiState.plotId.columnName}-${plotUiState.plotId.jsonPath}`\n }\n}\n\nconst isPlotInState = (\n plotId: PlotIdentifier,\n plotUiStateArray: UiPlotState[],\n): boolean => {\n return !!plotUiStateArray.find(plot => {\n return plotMatchesDefinition(plot.plotId, plotId)\n })\n}\n\nconst getCustomPlotIdentifier = (\n customPlot: QueryWrapperSynapsePlotProps,\n): PlotIdentifier => {\n return { __custom: true, title: customPlot.title ?? '' }\n}\n\nconst getCombinedNewPlots = (\n customPlots: QueryWrapperSynapsePlotProps[] = [],\n facetNavPanelPropsArray: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[] = [],\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>,\n): UiPlotState[] => [\n ...customPlots.map((plotProps, index) => ({\n plotId: getCustomPlotIdentifier(plotProps),\n isHidden: index >= DEFAULT_VISIBLE_PLOTS,\n plotType: convertPlotlyPlotTypeToFacetNavPlotType(plotProps.type),\n })),\n ...facetNavPanelPropsArray.map((facetPlotProps, index) => ({\n plotId: facetPlotProps.facetToPlot,\n isHidden: index + customPlots.length >= DEFAULT_VISIBLE_PLOTS,\n plotType:\n initialPlotTypeByFacetColumnName?.[\n facetPlotProps.facetToPlot.columnName\n ] ?? DEFAULT_PLOT_TYPE,\n })),\n]\n\n// Remove plots that are no longer in props from prevPlots\nconst isPlotStillPresent = (\n prevPlot: UiPlotState,\n customPlots: QueryWrapperSynapsePlotProps[],\n facetNavPanelProps: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[],\n): boolean => {\n return (\n customPlots.some(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n prevPlot.plotId,\n ),\n ) ||\n facetNavPanelProps.some(facetPlot =>\n plotMatchesDefinition(facetPlot.facetToPlot, prevPlot.plotId),\n )\n )\n} // fn returns true iff the plot id is in customPlots or facetNavPanelPropsArray\n\nconst DEFAULT_PLOT_TYPE: PlotType = 'PIE'\n\nconst DEFAULT_FACETS_TO_PLOT: string[] = []\nconst DEFAULT_CUSTOM_PLOTS: QueryWrapperSynapsePlotProps[] = []\n\nfunction PlotsContainer(props: PlotsContainerProps) {\n const {\n facetsToPlot = DEFAULT_FACETS_TO_PLOT,\n customPlots = DEFAULT_CUSTOM_PLOTS,\n initialPlotTypeByFacetColumnName,\n } = props\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { showPlots: showPlotVisualization } = useQueryVisualizationContext()\n const [plotUiStateArray, setPlotUiStateArray] = useState<UiPlotState[]>([])\n const facetNavPanelPropsArray = useFacetPlots(facetsToPlot)\n\n const getPlotType = (plotId: PlotIdentifier): PlotType => {\n const plotType = plotUiStateArray.find(item =>\n plotMatchesDefinition(plotId, item.plotId),\n )?.plotType\n return plotType ?? DEFAULT_PLOT_TYPE\n }\n\n useEffect(() => {\n const combinedNewPlots = getCombinedNewPlots(\n customPlots,\n facetNavPanelPropsArray,\n initialPlotTypeByFacetColumnName,\n )\n\n // Update the state with new plots\n setPlotUiStateArray(prevPlots => {\n // Filter to only include new plots\n const newPlots = combinedNewPlots.filter(plot => {\n const inState = isPlotInState(plot.plotId, prevPlots)\n return !inState\n })\n\n const updatedPlots = prevPlots.filter(prevPlot =>\n isPlotStillPresent(prevPlot, customPlots, facetNavPanelPropsArray),\n )\n\n // Append new plots\n const combinedPlots = [...updatedPlots, ...newPlots]\n return combinedPlots\n })\n }, [customPlots, facetNavPanelPropsArray, initialPlotTypeByFacetColumnName])\n\n // when 'show more/less' is clicked\n const onShowMoreClick = (shouldShowMore: boolean) => {\n setPlotUiStateArray(plotUiStateArray => {\n return plotUiStateArray.map((item, index) => {\n if (shouldShowMore) {\n // show everything\n return { ...item, isHidden: false }\n }\n // otherwise hide everything except the first few items\n return { ...item, isHidden: index >= DEFAULT_VISIBLE_PLOTS }\n })\n })\n }\n\n const isPlotHiddenInGrid = (plotId: PlotIdentifier) => {\n const itemHidden = plotUiStateArray.find(\n item =>\n plotMatchesDefinition(plotId, item.plotId) && item.isHidden === true,\n )\n const result = itemHidden !== undefined\n return result\n }\n\n const showMoreButtonState = useMemo<ShowMoreState>(() => {\n if (\n // if at least one item is hidden\n plotUiStateArray.find(item => item.isHidden === true)\n ) {\n return 'MORE'\n } else if (plotUiStateArray.length <= DEFAULT_VISIBLE_PLOTS) {\n return 'NONE'\n } else {\n return 'LESS'\n }\n }, [plotUiStateArray])\n\n // hides plot graph\n const hidePlotInGrid = (plotId: PlotIdentifier) => {\n setUiPropertyForPlot(plotId, 'isHidden', true)\n }\n\n const setPlotType = (plotId: PlotIdentifier, plotType: PlotType) => {\n setUiPropertyForPlot(plotId, 'plotType', plotType)\n }\n\n const setUiPropertyForPlot = (\n plotId: PlotIdentifier,\n propName: keyof UiPlotState,\n value: boolean | PlotType, // 'the possible values of the above type' (currently can't be specified in TS using symbols)\n ) => {\n setPlotUiStateArray(plotUiStateArray =>\n plotUiStateArray.map(item =>\n plotMatchesDefinition(plotId, item.plotId)\n ? { ...item, [propName]: value }\n : item,\n ),\n )\n }\n\n const colorTracker: { facet: PlotIdentifier; colorIndex: number }[] =\n // TODO: customPlots should use the color index\n // additionally, it is unclear why this object is created\n // We can probably just pass the index from `plotUiStateArray.map)\n getFacets(queryMetadata, facetsToPlot).map((el, index) => {\n return {\n facet: { columnName: el.columnName, jsonPath: el.jsonPath },\n colorIndex: index,\n }\n })\n\n return (\n <>\n {plotUiStateArray.length > 0 && (\n <div\n className={`PlotsContainer ${showPlotVisualization ? '' : 'hidden'} ${\n showMoreButtonState === 'LESS' ? 'less' : ''\n }`}\n >\n <div className=\"PlotsContainer__row\" role=\"list\">\n {plotUiStateArray.map(plotUiState => {\n const isCustomPlot = '__custom' in plotUiState.plotId\n const customPlotProps = customPlots.find(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n plotUiState.plotId,\n ),\n )\n const facetNavPanelProps = facetNavPanelPropsArray.find(props =>\n plotMatchesDefinition(props.facetToPlot, plotUiState.plotId),\n )\n\n return (\n <div\n className={\n plotUiState.plotType === 'BAR'\n ? 'PlotsContainer__row__item--full-width'\n : undefined\n }\n style={{\n minWidth: '435px',\n display: isPlotHiddenInGrid(plotUiState.plotId)\n ? 'none'\n : 'block',\n }}\n key={generatePlotKey(plotUiState)}\n >\n {isCustomPlot && customPlotProps && (\n <QueryWrapperSynapsePlot\n {...customPlotProps}\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n />\n )}\n {!isCustomPlot && facetNavPanelProps && (\n <FacetNavPanel\n index={\n colorTracker.find(el =>\n plotMatchesDefinition(el.facet, plotUiState.plotId),\n )?.colorIndex!\n }\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n plotType={getPlotType(plotUiState.plotId)}\n onSetPlotType={(plotType: PlotType) =>\n setPlotType(plotUiState.plotId, plotType)\n }\n isModalView={false}\n {...facetNavPanelProps}\n />\n )}\n </div>\n )\n })}\n </div>\n {showMoreButtonState !== 'NONE' && (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n backgroundColor: 'grey.100',\n p: 2,\n mt: 2,\n }}\n >\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => onShowMoreClick(showMoreButtonState === 'MORE')}\n sx={{ width: '150px' }}\n >\n {showMoreButtonState === 'LESS'\n ? 'Hide Charts'\n : 'View All Charts'}\n </Button>\n </Box>\n )}\n </div>\n )}\n </>\n )\n}\n\nexport default function PlotsContainerWithSuspense(props: PlotsContainerProps) {\n const { showPlots } = useQueryVisualizationContext()\n return (\n <Suspense fallback={showPlots ? <PlotsContainerSkeleton /> : null}>\n <PlotsContainer {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PlotsContainer.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/PlotsContainer.tsx"],"sourcesContent":["import { UniqueFacetIdentifier } from '@/utils'\nimport { facetObjectMatchesDefinition } from '@/utils/functions/queryUtils'\nimport { Box, Button } from '@mui/material'\nimport type { PlotType as PlotlyPlotType } from 'plotly.js-basic-dist'\nimport { Suspense, useEffect, useMemo, useState } from 'react'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport QueryWrapperSynapsePlot, {\n QueryWrapperSynapsePlotProps,\n} from '../../QueryWrapperPlotNav/QueryWrapperSynapsePlot'\nimport FacetNavPanel, {\n FacetNavPanelProps,\n PlotType,\n} from '../facet-nav/FacetNavPanel'\nimport { PlotsContainerSkeleton } from './PlotsContainerSkeleton'\nimport useFacetPlots, { getFacets } from './useFacetPlots'\n\nconst DEFAULT_VISIBLE_PLOTS = 2\ntype ShowMoreState = 'MORE' | 'LESS' | 'NONE'\nexport type PlotsContainerProps = {\n facetsToPlot?: string[]\n customPlots?: QueryWrapperSynapsePlotProps[]\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>\n}\ntype CustomPlotIdentifier = {\n title: string\n __custom: true\n}\nexport type PlotIdentifier = UniqueFacetIdentifier | CustomPlotIdentifier\n\nexport type UiPlotState = {\n plotId: PlotIdentifier\n isHidden: boolean\n plotType: PlotType\n index?: number\n}\nconst plotMatchesDefinition = (\n definition: PlotIdentifier,\n plotId: PlotIdentifier,\n) => {\n if ('__custom' in plotId && '__custom' in definition) {\n return definition.title == plotId.title\n } else if (!('__custom' in plotId) && !('__custom' in definition)) {\n return facetObjectMatchesDefinition(definition, plotId)\n } else {\n return false\n }\n}\n\nfunction convertPlotlyPlotTypeToFacetNavPlotType(\n plotlyPlotType: PlotlyPlotType,\n): PlotType {\n if (plotlyPlotType === 'bar') {\n return 'BAR'\n } else if (plotlyPlotType === 'pie') {\n return 'PIE'\n }\n return 'PIE'\n}\n\nconst generatePlotKey = (plotUiState: UiPlotState) => {\n if ('__custom' in plotUiState.plotId) {\n // For custom plots\n return `custom-${plotUiState.plotId.title}`\n } else {\n // For facet plots\n return `facet-${plotUiState.plotId.columnName}-${plotUiState.plotId.jsonPath}`\n }\n}\n\nconst isPlotInState = (\n plotId: PlotIdentifier,\n plotUiStateArray: UiPlotState[],\n): boolean => {\n return !!plotUiStateArray.find(plot => {\n return plotMatchesDefinition(plot.plotId, plotId)\n })\n}\n\nconst getCustomPlotIdentifier = (\n customPlot: QueryWrapperSynapsePlotProps,\n): PlotIdentifier => {\n return { __custom: true, title: customPlot.title ?? '' }\n}\n\nconst getCombinedNewPlots = (\n customPlots: QueryWrapperSynapsePlotProps[] = [],\n facetNavPanelPropsArray: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[] = [],\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>,\n): UiPlotState[] => [\n ...customPlots.map((plotProps, index) => ({\n plotId: getCustomPlotIdentifier(plotProps),\n isHidden: index >= DEFAULT_VISIBLE_PLOTS,\n plotType: convertPlotlyPlotTypeToFacetNavPlotType(plotProps.type),\n })),\n ...facetNavPanelPropsArray.map((facetPlotProps, index) => ({\n plotId: facetPlotProps.facetToPlot,\n isHidden: index + customPlots.length >= DEFAULT_VISIBLE_PLOTS,\n plotType:\n initialPlotTypeByFacetColumnName?.[\n facetPlotProps.facetToPlot.columnName\n ] ?? DEFAULT_PLOT_TYPE,\n })),\n]\n\n// Remove plots that are no longer in props from prevPlots\nconst isPlotStillPresent = (\n prevPlot: UiPlotState,\n customPlots: QueryWrapperSynapsePlotProps[],\n facetNavPanelProps: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[],\n): boolean => {\n return (\n customPlots.some(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n prevPlot.plotId,\n ),\n ) ||\n facetNavPanelProps.some(facetPlot =>\n plotMatchesDefinition(facetPlot.facetToPlot, prevPlot.plotId),\n )\n )\n} // fn returns true iff the plot id is in customPlots or facetNavPanelPropsArray\n\nconst DEFAULT_PLOT_TYPE: PlotType = 'PIE'\n\nconst DEFAULT_FACETS_TO_PLOT: string[] = []\nconst DEFAULT_CUSTOM_PLOTS: QueryWrapperSynapsePlotProps[] = []\n\nfunction PlotsContainer(props: PlotsContainerProps) {\n const {\n facetsToPlot = DEFAULT_FACETS_TO_PLOT,\n customPlots = DEFAULT_CUSTOM_PLOTS,\n initialPlotTypeByFacetColumnName,\n } = props\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { showPlots: showPlotVisualization } = useQueryVisualizationContext()\n const [plotUiStateArray, setPlotUiStateArray] = useState<UiPlotState[]>([])\n const facetNavPanelPropsArray = useFacetPlots(facetsToPlot)\n\n const getPlotType = (plotId: PlotIdentifier): PlotType => {\n const plotType = plotUiStateArray.find(item =>\n plotMatchesDefinition(plotId, item.plotId),\n )?.plotType\n return plotType ?? DEFAULT_PLOT_TYPE\n }\n\n useEffect(() => {\n const combinedNewPlots = getCombinedNewPlots(\n customPlots,\n facetNavPanelPropsArray,\n initialPlotTypeByFacetColumnName,\n )\n\n // Update the state with new plots\n setPlotUiStateArray(prevPlots => {\n // Filter to only include new plots\n const newPlots = combinedNewPlots.filter(plot => {\n const inState = isPlotInState(plot.plotId, prevPlots)\n return !inState\n })\n\n const updatedPlots = prevPlots.filter(prevPlot =>\n isPlotStillPresent(prevPlot, customPlots, facetNavPanelPropsArray),\n )\n\n // Append new plots\n const combinedPlots = [...updatedPlots, ...newPlots]\n return combinedPlots\n })\n }, [customPlots, facetNavPanelPropsArray, initialPlotTypeByFacetColumnName])\n\n // when 'show more/less' is clicked\n const onShowMoreClick = (shouldShowMore: boolean) => {\n setPlotUiStateArray(plotUiStateArray => {\n return plotUiStateArray.map((item, index) => {\n if (shouldShowMore) {\n // show everything\n return { ...item, isHidden: false }\n }\n // otherwise hide everything except the first few items\n return { ...item, isHidden: index >= DEFAULT_VISIBLE_PLOTS }\n })\n })\n }\n\n const isPlotHiddenInGrid = (plotId: PlotIdentifier) => {\n const itemHidden = plotUiStateArray.find(\n item =>\n plotMatchesDefinition(plotId, item.plotId) && item.isHidden === true,\n )\n const result = itemHidden !== undefined\n return result\n }\n\n const showMoreButtonState = useMemo<ShowMoreState>(() => {\n if (\n // if at least one item is hidden\n plotUiStateArray.find(item => item.isHidden === true)\n ) {\n return 'MORE'\n } else if (plotUiStateArray.length <= DEFAULT_VISIBLE_PLOTS) {\n return 'NONE'\n } else {\n return 'LESS'\n }\n }, [plotUiStateArray])\n\n // hides plot graph\n const hidePlotInGrid = (plotId: PlotIdentifier) => {\n setUiPropertyForPlot(plotId, 'isHidden', true)\n }\n\n const setPlotType = (plotId: PlotIdentifier, plotType: PlotType) => {\n setUiPropertyForPlot(plotId, 'plotType', plotType)\n }\n\n const setUiPropertyForPlot = (\n plotId: PlotIdentifier,\n propName: keyof UiPlotState,\n value: boolean | PlotType, // 'the possible values of the above type' (currently can't be specified in TS using symbols)\n ) => {\n setPlotUiStateArray(plotUiStateArray =>\n plotUiStateArray.map(item =>\n plotMatchesDefinition(plotId, item.plotId)\n ? { ...item, [propName]: value }\n : item,\n ),\n )\n }\n\n const colorTracker: { facet: PlotIdentifier; colorIndex: number }[] =\n // TODO: customPlots should use the color index\n // additionally, it is unclear why this object is created\n // We can probably just pass the index from `plotUiStateArray.map)\n getFacets(queryMetadata, facetsToPlot).map((el, index) => {\n return {\n facet: { columnName: el.columnName, jsonPath: el.jsonPath },\n colorIndex: index,\n }\n })\n\n return (\n <>\n {plotUiStateArray.length > 0 && (\n <div\n className={`PlotsContainer ${showPlotVisualization ? '' : 'hidden'} ${\n showMoreButtonState === 'LESS' ? 'less' : ''\n }`}\n >\n <div className=\"PlotsContainer__row\" role=\"list\">\n {plotUiStateArray.map(plotUiState => {\n const isCustomPlot = '__custom' in plotUiState.plotId\n const customPlotProps = customPlots.find(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n plotUiState.plotId,\n ),\n )\n const facetNavPanelProps = facetNavPanelPropsArray.find(props =>\n plotMatchesDefinition(props.facetToPlot, plotUiState.plotId),\n )\n\n return (\n <div\n className={\n plotUiState.plotType === 'BAR'\n ? 'PlotsContainer__row__item--full-width'\n : undefined\n }\n style={{\n minWidth: '435px',\n display: isPlotHiddenInGrid(plotUiState.plotId)\n ? 'none'\n : 'block',\n }}\n key={generatePlotKey(plotUiState)}\n >\n {isCustomPlot && customPlotProps && (\n <QueryWrapperSynapsePlot\n {...customPlotProps}\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n />\n )}\n {!isCustomPlot && facetNavPanelProps && (\n <FacetNavPanel\n index={\n colorTracker.find(el =>\n plotMatchesDefinition(el.facet, plotUiState.plotId),\n )?.colorIndex!\n }\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n plotType={getPlotType(plotUiState.plotId)}\n onSetPlotType={(plotType: PlotType) =>\n setPlotType(plotUiState.plotId, plotType)\n }\n isModalView={false}\n {...facetNavPanelProps}\n />\n )}\n </div>\n )\n })}\n </div>\n {showMoreButtonState !== 'NONE' && (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n backgroundColor: 'grey.100',\n p: 2,\n mt: 2,\n }}\n >\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => onShowMoreClick(showMoreButtonState === 'MORE')}\n sx={{ width: '150px' }}\n >\n {showMoreButtonState === 'LESS'\n ? 'Hide Charts'\n : 'View All Charts'}\n </Button>\n </Box>\n )}\n </div>\n )}\n </>\n )\n}\n\nexport default function PlotsContainerWithSuspense(props: PlotsContainerProps) {\n const { showPlots } = useQueryVisualizationContext()\n return (\n <Suspense fallback={showPlots ? <PlotsContainerSkeleton /> : null}>\n <PlotsContainer {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionCriteriaPills.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/SelectionCriteriaPills.tsx"],"sourcesContent":["import {\n isColumnMultiValueFunctionQueryFilter,\n isColumnSingleValueQueryFilter,\n isFacetColumnRangeRequest,\n isFacetColumnValuesRequest,\n isTextMatchesQueryFilter,\n LockedColumn,\n} from '@/utils'\nimport { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport {\n ColumnModel,\n ColumnMultiValueFunctionQueryFilter,\n ColumnSingleValueQueryFilter,\n FacetColumnRangeRequest,\n FacetColumnRequest,\n QueryFilter,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport pluralize from 'pluralize'\nimport { ReadonlyDeep } from 'type-fest'\nimport { QueryContextType, useQueryContext } from '../../QueryContext'\nimport {\n QueryVisualizationContextType,\n useQueryVisualizationContext,\n} from '../../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport SelectionCriteriaPill, {\n SelectionCriteriaPillProps,\n} from './SelectionCriteriaPill'\nimport { getSearchTextFromBooleanModeSearchExpression } from '@/components/FullTextSearch/FullTextSearchUtils'\n\nconst MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS = 4\n\nfunction getPillPropsFromColumnQueryFilter(\n queryFilter:\n | ColumnSingleValueQueryFilter\n | ColumnMultiValueFunctionQueryFilter,\n queryContext: QueryContextType,\n columnModel: ColumnModel | undefined,\n queryVisualizationContext: QueryVisualizationContextType,\n): SelectionCriteriaPillProps[] {\n const { getColumnDisplayName } = queryVisualizationContext\n // ColumnSingleValueQueryFilter and ColumnMultiValueQueryFilter both allow for a list of values\n // If there are more than _n_ values, consolidate to one pill\n if (\n queryFilter.values.length > MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(queryFilter.columnName),\n )} (${queryFilter.values.length.toLocaleString()})`\n\n return [\n {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n return queryFilter.values.map(value => {\n let filterValue = value\n\n if (value?.startsWith('%') && value?.endsWith('%')) {\n // strip '%' wildcard character when using a LIKE condition\n filterValue = filterValue.substring(1, filterValue.length - 1)\n }\n filterValue = queryVisualizationContext.getDisplayValue(\n filterValue,\n columnModel.columnType,\n )\n const text = `${getColumnDisplayName(\n queryFilter.columnName,\n )}: ${filterValue}`\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}-${value}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeValueFromQueryFilter(queryFilter, value)\n },\n }\n })\n}\n\nexport function getPillPropsFromTextMatchesQueryFilter(\n queryFilter: TextMatchesQueryFilter,\n queryContext: QueryContextType,\n): SelectionCriteriaPillProps {\n let innerText = queryFilter.searchExpression\n if (queryFilter.searchMode == 'BOOLEAN') {\n innerText = getSearchTextFromBooleanModeSearchExpression(\n queryFilter.searchExpression,\n )\n }\n\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.searchExpression}`,\n innerText,\n tooltipText: `Text matches: \"${innerText}\"`,\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n }\n}\n\nfunction getPillPropsFromQueryFilters(\n queryFilters: ReadonlyDeep<QueryFilter[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n): SelectionCriteriaPillProps[] {\n return queryFilters.flatMap(queryFilter => {\n if (\n isColumnSingleValueQueryFilter(queryFilter) ||\n isColumnMultiValueFunctionQueryFilter(queryFilter)\n ) {\n const columnModel = columnModels.find(\n cm => cm.name === queryFilter.columnName,\n )\n if (\n queryFilter.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n return getPillPropsFromColumnQueryFilter(\n queryFilter,\n queryContext,\n columnModel,\n queryVisualizationContext,\n )\n } else if (isTextMatchesQueryFilter(queryFilter)) {\n return [getPillPropsFromTextMatchesQueryFilter(queryFilter, queryContext)]\n } else {\n console.log('Unknown query filter type', queryFilter)\n return []\n }\n })\n}\n\nfunction getRangeFacetInnerText(min?: string, max?: string) {\n if (min == undefined && max == undefined) {\n return 'Any value'\n } else if (min == undefined) {\n return `Up to ${max}`\n } else if (max == undefined) {\n return `${min} or greater`\n } else if (min === VALUE_NOT_SET && max === VALUE_NOT_SET) {\n return FRIENDLY_VALUE_NOT_SET\n } else {\n return `${min} - ${max}`\n }\n}\n\nfunction getPillPropsFromFacetFilters(\n selectedFacets: ReadonlyDeep<FacetColumnRequest[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n): SelectionCriteriaPillProps[] {\n return selectedFacets.flatMap(selectedFacet => {\n if (\n selectedFacet.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n const columnModel = columnModels.find(\n cm => cm.name === selectedFacet.columnName,\n )\n const { getColumnDisplayName, getDisplayValue } = queryVisualizationContext\n if (isFacetColumnValuesRequest(selectedFacet)) {\n // If there are more than _n_ values, consolidate to one pill\n if (\n selectedFacet.facetValues.length >\n MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n ),\n )} (${selectedFacet.facetValues.length.toLocaleString()})`\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n\n return selectedFacet.facetValues.map(facetValue => {\n const innerText = getDisplayValue(facetValue, columnModel.columnType)\n return {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${facetValue}`,\n innerText: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeValueFromSelectedFacet(selectedFacet, facetValue)\n },\n }\n })\n } else if (isFacetColumnRangeRequest(selectedFacet)) {\n // Include a single pill for both facet filters if a combined range facet filter config is defined\n const { combineRangeFacetConfig } = queryContext\n if (\n combineRangeFacetConfig &&\n (selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn ||\n selectedFacet.columnName == combineRangeFacetConfig.maxFacetColumn)\n ) {\n if (\n selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn\n ) {\n return []\n } else {\n // find the min facet also\n const maxFacet = selectedFacet\n const minFacet = selectedFacets.find(\n v => v.columnName == combineRangeFacetConfig.minFacetColumn,\n ) as FacetColumnRangeRequest\n const innerText = getRangeFacetInnerText(maxFacet.min, minFacet.max)\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${innerText}`,\n innerText: innerText,\n tooltipText: `${combineRangeFacetConfig.label}: ${innerText}`,\n onRemoveFilter: () => {\n // Remove both facets on pill click\n queryContext.removeSelectedFacet([minFacet, maxFacet])\n },\n },\n ]\n }\n }\n\n const innerText = getRangeFacetInnerText(\n selectedFacet.min,\n selectedFacet.max,\n )\n\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${selectedFacet.min}-${selectedFacet.max}`,\n innerText: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n } else {\n console.log(\n 'Unknown facet type',\n (selectedFacet as unknown as FacetColumnRequest).concreteType,\n )\n return []\n }\n })\n}\n\nfunction SelectionCriteriaPills() {\n const queryContext = useQueryContext()\n const lockedColumn = queryContext.lockedColumn\n const queryVisualizationContext = useQueryVisualizationContext()\n const { currentQueryRequest } = queryContext\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const queryFilterPillProps = getPillPropsFromQueryFilters(\n currentQueryRequest.query?.additionalFilters ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n )\n\n const facetPillProps = getPillPropsFromFacetFilters(\n currentQueryRequest.query.selectedFacets ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n )\n\n const allPills = [...queryFilterPillProps, ...facetPillProps]\n\n return (\n <>\n {allPills.map(pillProps => {\n // Encode the key because the facet may include an illegal character\n const key = encodeURIComponent(pillProps.key)\n return <SelectionCriteriaPill {...pillProps} key={key} />\n })}\n </>\n )\n}\n\nexport default SelectionCriteriaPills\n"],"mappings":";;;;;;;;;;;;;;AA+BA,IAAM,IAA4C;AAElD,SAAS,EACP,GAGA,GACA,GACA,GAC8B;CAC9B,IAAM,EAAE,4BAAyB;AAGjC,KACE,EAAY,OAAO,SAAS,KAC5B,CAAC,GACD;EACA,IAAM,IAAO,GAAG,EACd,EAAqB,EAAY,WAAW,CAC7C,CAAC,IAAI,EAAY,OAAO,OAAO,gBAAgB,CAAC;AAEjD,SAAO,CACL;GACE,KAAK,eAAe,EAAY,aAAa,GAAG,EAAY;GAC5D,WAAW;GACX,aAAa;GACb,sBAAsB;AACpB,MAAa,kBAAkB,EAAY;;GAE9C,CACF;;AAIH,QAAO,EAAY,OAAO,KAAI,MAAS;EACrC,IAAI,IAAc;AAMlB,EAJI,GAAO,WAAW,IAAI,IAAI,GAAO,SAAS,IAAI,KAEhD,IAAc,EAAY,UAAU,GAAG,EAAY,SAAS,EAAE,GAEhE,IAAc,EAA0B,gBACtC,GACA,EAAY,WACb;EACD,IAAM,IAAO,GAAG,EACd,EAAY,WACb,CAAC,IAAI;AACN,SAAO;GACL,KAAK,eAAe,EAAY,aAAa,GAAG,EAAY,WAAW,GAAG;GAC1E,WAAW;GACX,aAAa;GACb,sBAAsB;AACpB,MAAa,2BAA2B,GAAa,EAAM;;GAE9D;GACD;;AAGJ,SAAgB,EACd,GACA,GAC4B;CAC5B,IAAI,IAAY,EAAY;AAO5B,QANI,EAAY,cAAc,cAC5B,IAAY,EACV,EAAY,iBACb,GAGI;EACL,KAAK,eAAe,EAAY,aAAa,GAAG,EAAY;EAC5D;EACA,aAAa,kBAAkB,EAAU;EACzC,sBAAsB;AACpB,KAAa,kBAAkB,EAAY;;EAE9C;;AAGH,SAAS,EACP,GACA,GACA,GACA,GACA,GAC8B;AAC9B,QAAO,EAAa,SAAQ,MAAe;AACzC,MACE,EAA+B,EAAY,IAC3C,EAAsC,EAAY,EAClD;GACA,IAAM,IAAc,EAAa,MAC/B,MAAM,EAAG,SAAS,EAAY,WAC/B;AAOD,UALE,EAAY,WAAW,aAAa,KACpC,GAAc,YAAY,aAAa,GAEhC,EAAE,GAEJ,EACL,GACA,GACA,GACA,EACD;aACQ,EAAyB,EAAY,CAC9C,QAAO,CAAC,EAAuC,GAAa,EAAa,CAAC;MAG1E,QADA,QAAQ,IAAI,6BAA6B,EAAY,EAC9C,EAAE;GAEX;;AAGJ,SAAS,EAAuB,GAAc,GAAc;AAUxD,QATE,KAAO,QAAa,KAAO,OACtB,cACE,KAAO,OACT,SAAS,MACP,KAAO,OACT,GAAG,EAAI,eACL,MAAA,+CAAyB,MAAA,8CAC3B,IAEA,GAAG,EAAI,KAAK;;AAIvB,SAAS,EACP,GACA,GACA,GACA,GACA,GAC8B;AAC9B,QAAO,EAAe,SAAQ,MAAiB;AAC7C,MACE,EAAc,WAAW,aAAa,KACtC,GAAc,YAAY,aAAa,CAEvC,QAAO,EAAE;EAEX,IAAM,IAAc,EAAa,MAC/B,MAAM,EAAG,SAAS,EAAc,WACjC,EACK,EAAE,yBAAsB,uBAAoB;AAClD,MAAI,EAA2B,EAAc,EAAE;AAE7C,OACE,EAAc,YAAY,SACxB,KACF,CAAC,GACD;IACA,IAAM,IAAO,GAAG,EACd,EACE,EAAc,YACd,EAAc,SACf,CACF,CAAC,IAAI,EAAc,YAAY,OAAO,gBAAgB,CAAC;AACxD,WAAO,CACL;KACE,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc;KAC1D,WAAW;KACX,aAAa;KACb,sBAAsB;AACpB,QAAa,oBAAoB,EAAc;;KAElD,CACF;;AAKH,UAAO,EAAc,YAAY,KAAI,MAAc;IACjD,IAAM,IAAY,EAAgB,GAAY,EAAY,WAAW;AACrE,WAAO;KACL,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc,WAAW,GAAG;KAC7D;KACX,aAAa,GAAG,EACd,EAAc,YACd,EAAc,SACf,CAAC,IAAI;KACN,sBAAsB;AACpB,QAAa,6BAA6B,GAAe,EAAW;;KAEvE;KACD;aACO,EAA0B,EAAc,EAAE;GAEnD,IAAM,EAAE,+BAA4B;AACpC,OACE,MACC,EAAc,cAAc,EAAwB,kBACnD,EAAc,cAAc,EAAwB,iBAEtD;QACE,EAAc,cAAc,EAAwB,eAEpD,QAAO,EAAE;IACJ;KAEL,IAAM,IAAW,GACX,IAAW,EAAe,MAC9B,MAAK,EAAE,cAAc,EAAwB,eAC9C,EACK,IAAY,EAAuB,EAAS,KAAK,EAAS,IAAI;AACpE,YAAO,CACL;MACE,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc,WAAW,GAAG;MAC7D;MACX,aAAa,GAAG,EAAwB,MAAM,IAAI;MAClD,sBAAsB;AAEpB,SAAa,oBAAoB,CAAC,GAAU,EAAS,CAAC;;MAEzD,CACF;;;GAIL,IAAM,IAAY,EAChB,EAAc,KACd,EAAc,IACf;AAED,UAAO,CACL;IACE,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc,WAAW,GAAG,EAAc,IAAI,GAAG,EAAc;IAChG;IACX,aAAa,GAAG,EACd,EAAc,YACd,EAAc,SACf,CAAC,IAAI;IACN,sBAAsB;AACpB,OAAa,oBAAoB,EAAc;;IAElD,CACF;QAMD,QAJA,QAAQ,IACN,sBACC,EAAgD,aAClD,EACM,EAAE;GAEX;;AAGJ,SAAS,IAAyB;CAChC,IAAM,IAAe,GAAiB,EAChC,IAAe,EAAa,cAC5B,IAA4B,GAA8B,EAC1D,EAAE,2BAAwB,GAC1B,EAAE,MAAM,MAAkB,GAAqB,EAE/C,IAAuB,EAC3B,EAAoB,OAAO,qBAAqB,EAAE,EAClD,GACA,GAAe,gBAAgB,EAAE,EACjC,GACA,EACD,EAEK,IAAiB,EACrB,EAAoB,MAAM,kBAAkB,EAAE,EAC9C,GACA,GAAe,gBAAgB,EAAE,EACjC,GACA,EACD;AAID,QACE,kBAAA,GAAA,EAAA,UAHe,CAAC,GAAG,GAAsB,GAAG,EAAe,CAI/C,KAAI,MAAa;EAEzB,IAAM,IAAM,mBAAmB,EAAU,IAAI;AAC7C,SAAO,kBAAC,GAAD;GAAuB,GAAI;GAAgB;GAAO,CAAA;GACzD,EACD,CAAA"}
1
+ {"version":3,"file":"SelectionCriteriaPills.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/SelectionCriteriaPills.tsx"],"sourcesContent":["import {\n isColumnMultiValueFunctionQueryFilter,\n isColumnSingleValueQueryFilter,\n isFacetColumnRangeRequest,\n isFacetColumnValuesRequest,\n isTextMatchesQueryFilter,\n LockedColumn,\n} from '@/utils'\nimport { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport {\n ColumnModel,\n ColumnMultiValueFunctionQueryFilter,\n ColumnSingleValueQueryFilter,\n FacetColumnRangeRequest,\n FacetColumnRequest,\n QueryFilter,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport pluralize from 'pluralize'\nimport { ReadonlyDeep } from 'type-fest'\nimport { QueryContextType, useQueryContext } from '../../QueryContext'\nimport {\n QueryVisualizationContextType,\n useQueryVisualizationContext,\n} from '../../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport SelectionCriteriaPill, {\n SelectionCriteriaPillProps,\n} from './SelectionCriteriaPill'\nimport { getSearchTextFromBooleanModeSearchExpression } from '@/components/FullTextSearch/FullTextSearchUtils'\n\nconst MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS = 4\n\nfunction getPillPropsFromColumnQueryFilter(\n queryFilter:\n | ColumnSingleValueQueryFilter\n | ColumnMultiValueFunctionQueryFilter,\n queryContext: QueryContextType,\n columnModel: ColumnModel | undefined,\n queryVisualizationContext: QueryVisualizationContextType,\n): SelectionCriteriaPillProps[] {\n const { getColumnDisplayName } = queryVisualizationContext\n // ColumnSingleValueQueryFilter and ColumnMultiValueQueryFilter both allow for a list of values\n // If there are more than _n_ values, consolidate to one pill\n if (\n queryFilter.values.length > MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(queryFilter.columnName),\n )} (${queryFilter.values.length.toLocaleString()})`\n\n return [\n {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n return queryFilter.values.map(value => {\n let filterValue = value\n\n if (value?.startsWith('%') && value?.endsWith('%')) {\n // strip '%' wildcard character when using a LIKE condition\n filterValue = filterValue.substring(1, filterValue.length - 1)\n }\n filterValue = queryVisualizationContext.getDisplayValue(\n filterValue,\n columnModel.columnType,\n )\n const text = `${getColumnDisplayName(\n queryFilter.columnName,\n )}: ${filterValue}`\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}-${value}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeValueFromQueryFilter(queryFilter, value)\n },\n }\n })\n}\n\nexport function getPillPropsFromTextMatchesQueryFilter(\n queryFilter: TextMatchesQueryFilter,\n queryContext: QueryContextType,\n): SelectionCriteriaPillProps {\n let innerText = queryFilter.searchExpression\n if (queryFilter.searchMode == 'BOOLEAN') {\n innerText = getSearchTextFromBooleanModeSearchExpression(\n queryFilter.searchExpression,\n )\n }\n\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.searchExpression}`,\n innerText,\n tooltipText: `Text matches: \"${innerText}\"`,\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n }\n}\n\nfunction getPillPropsFromQueryFilters(\n queryFilters: ReadonlyDeep<QueryFilter[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n): SelectionCriteriaPillProps[] {\n return queryFilters.flatMap(queryFilter => {\n if (\n isColumnSingleValueQueryFilter(queryFilter) ||\n isColumnMultiValueFunctionQueryFilter(queryFilter)\n ) {\n const columnModel = columnModels.find(\n cm => cm.name === queryFilter.columnName,\n )\n if (\n queryFilter.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n return getPillPropsFromColumnQueryFilter(\n queryFilter,\n queryContext,\n columnModel,\n queryVisualizationContext,\n )\n } else if (isTextMatchesQueryFilter(queryFilter)) {\n return [getPillPropsFromTextMatchesQueryFilter(queryFilter, queryContext)]\n } else {\n console.log('Unknown query filter type', queryFilter)\n return []\n }\n })\n}\n\nfunction getRangeFacetInnerText(min?: string, max?: string) {\n if (min == undefined && max == undefined) {\n return 'Any value'\n } else if (min == undefined) {\n return `Up to ${max}`\n } else if (max == undefined) {\n return `${min} or greater`\n } else if (min === VALUE_NOT_SET && max === VALUE_NOT_SET) {\n return FRIENDLY_VALUE_NOT_SET\n } else {\n return `${min} - ${max}`\n }\n}\n\nfunction getPillPropsFromFacetFilters(\n selectedFacets: ReadonlyDeep<FacetColumnRequest[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n): SelectionCriteriaPillProps[] {\n return selectedFacets.flatMap(selectedFacet => {\n if (\n selectedFacet.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n const columnModel = columnModels.find(\n cm => cm.name === selectedFacet.columnName,\n )\n const { getColumnDisplayName, getDisplayValue } = queryVisualizationContext\n if (isFacetColumnValuesRequest(selectedFacet)) {\n // If there are more than _n_ values, consolidate to one pill\n if (\n selectedFacet.facetValues.length >\n MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n ),\n )} (${selectedFacet.facetValues.length.toLocaleString()})`\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n\n return selectedFacet.facetValues.map(facetValue => {\n const innerText = getDisplayValue(facetValue, columnModel.columnType)\n return {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${facetValue}`,\n innerText: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeValueFromSelectedFacet(selectedFacet, facetValue)\n },\n }\n })\n } else if (isFacetColumnRangeRequest(selectedFacet)) {\n // Include a single pill for both facet filters if a combined range facet filter config is defined\n const { combineRangeFacetConfig } = queryContext\n if (\n combineRangeFacetConfig &&\n (selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn ||\n selectedFacet.columnName == combineRangeFacetConfig.maxFacetColumn)\n ) {\n if (\n selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn\n ) {\n return []\n } else {\n // find the min facet also\n const maxFacet = selectedFacet\n const minFacet = selectedFacets.find(\n v => v.columnName == combineRangeFacetConfig.minFacetColumn,\n ) as FacetColumnRangeRequest\n const innerText = getRangeFacetInnerText(maxFacet.min, minFacet.max)\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${innerText}`,\n innerText: innerText,\n tooltipText: `${combineRangeFacetConfig.label}: ${innerText}`,\n onRemoveFilter: () => {\n // Remove both facets on pill click\n queryContext.removeSelectedFacet([minFacet, maxFacet])\n },\n },\n ]\n }\n }\n\n const innerText = getRangeFacetInnerText(\n selectedFacet.min,\n selectedFacet.max,\n )\n\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${selectedFacet.min}-${selectedFacet.max}`,\n innerText: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n } else {\n console.log(\n 'Unknown facet type',\n (selectedFacet as unknown as FacetColumnRequest).concreteType,\n )\n return []\n }\n })\n}\n\nfunction SelectionCriteriaPills() {\n const queryContext = useQueryContext()\n const lockedColumn = queryContext.lockedColumn\n const queryVisualizationContext = useQueryVisualizationContext()\n const { currentQueryRequest } = queryContext\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const queryFilterPillProps = getPillPropsFromQueryFilters(\n currentQueryRequest.query?.additionalFilters ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n )\n\n const facetPillProps = getPillPropsFromFacetFilters(\n currentQueryRequest.query.selectedFacets ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n )\n\n const allPills = [...queryFilterPillProps, ...facetPillProps]\n\n return (\n <>\n {allPills.map(pillProps => {\n // Encode the key because the facet may include an illegal character\n const key = encodeURIComponent(pillProps.key)\n return <SelectionCriteriaPill {...pillProps} key={key} />\n })}\n </>\n )\n}\n\nexport default SelectionCriteriaPills\n"],"mappings":";;;;;;;;;;;;;;AA+BA,IAAM,IAA4C;AAElD,SAAS,EACP,GAGA,GACA,GACA,GAC8B;CAC9B,IAAM,EAAE,4BAAyB;AAGjC,KACE,EAAY,OAAO,SAAS,KAC5B,CAAC,GACD;EACA,IAAM,IAAO,GAAG,EACd,EAAqB,EAAY,WAAW,CAC7C,CAAC,IAAI,EAAY,OAAO,OAAO,gBAAgB,CAAC;AAEjD,SAAO,CACL;GACE,KAAK,eAAe,EAAY,aAAa,GAAG,EAAY;GAC5D,WAAW;GACX,aAAa;GACb,sBAAsB;AACpB,MAAa,kBAAkB,EAAY;;GAE9C,CACF;;AAIH,QAAO,EAAY,OAAO,KAAI,MAAS;EACrC,IAAI,IAAc;AAMlB,EAJI,GAAO,WAAW,IAAI,IAAI,GAAO,SAAS,IAAI,KAEhD,IAAc,EAAY,UAAU,GAAG,EAAY,SAAS,EAAE,GAEhE,IAAc,EAA0B,gBACtC,GACA,EAAY,WACb;EACD,IAAM,IAAO,GAAG,EACd,EAAY,WACb,CAAC,IAAI;AACN,SAAO;GACL,KAAK,eAAe,EAAY,aAAa,GAAG,EAAY,WAAW,GAAG;GAC1E,WAAW;GACX,aAAa;GACb,sBAAsB;AACpB,MAAa,2BAA2B,GAAa,EAAM;;GAE9D;GACD;;AAGJ,SAAgB,EACd,GACA,GAC4B;CAC5B,IAAI,IAAY,EAAY;AAO5B,QANI,EAAY,cAAc,cAC5B,IAAY,EACV,EAAY,iBACb,GAGI;EACL,KAAK,eAAe,EAAY,aAAa,GAAG,EAAY;EAC5D;EACA,aAAa,kBAAkB,EAAU;EACzC,sBAAsB;AACpB,KAAa,kBAAkB,EAAY;;EAE9C;;AAGH,SAAS,EACP,GACA,GACA,GACA,GACA,GAC8B;AAC9B,QAAO,EAAa,SAAQ,MAAe;AACzC,MACE,EAA+B,EAAY,IAC3C,EAAsC,EAAY,EAClD;GACA,IAAM,IAAc,EAAa,MAC/B,MAAM,EAAG,SAAS,EAAY,WAC/B;AAOD,UALE,EAAY,WAAW,aAAa,KACpC,GAAc,YAAY,aAAa,GAEhC,EAAE,GAEJ,EACL,GACA,GACA,GACA,EACD;aACQ,EAAyB,EAAY,CAC9C,QAAO,CAAC,EAAuC,GAAa,EAAa,CAAC;MAG1E,QADA,QAAQ,IAAI,6BAA6B,EAAY,EAC9C,EAAE;GAEX;;AAGJ,SAAS,EAAuB,GAAc,GAAc;AAUxD,QATE,KAAO,QAAa,KAAO,OACtB,cACE,KAAO,OACT,SAAS,MACP,KAAO,OACT,GAAG,EAAI,eACL,MAAA,+CAAyB,MAAA,8CAC3B,IAEA,GAAG,EAAI,KAAK;;AAIvB,SAAS,EACP,GACA,GACA,GACA,GACA,GAC8B;AAC9B,QAAO,EAAe,SAAQ,MAAiB;AAC7C,MACE,EAAc,WAAW,aAAa,KACtC,GAAc,YAAY,aAAa,CAEvC,QAAO,EAAE;EAEX,IAAM,IAAc,EAAa,MAC/B,MAAM,EAAG,SAAS,EAAc,WACjC,EACK,EAAE,yBAAsB,uBAAoB;AAClD,MAAI,EAA2B,EAAc,EAAE;AAE7C,OACE,EAAc,YAAY,SACxB,KACF,CAAC,GACD;IACA,IAAM,IAAO,GAAG,EACd,EACE,EAAc,YACd,EAAc,SACf,CACF,CAAC,IAAI,EAAc,YAAY,OAAO,gBAAgB,CAAC;AACxD,WAAO,CACL;KACE,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc;KAC1D,WAAW;KACX,aAAa;KACb,sBAAsB;AACpB,QAAa,oBAAoB,EAAc;;KAElD,CACF;;AAKH,UAAO,EAAc,YAAY,KAAI,MAAc;IACjD,IAAM,IAAY,EAAgB,GAAY,EAAY,WAAW;AACrE,WAAO;KACL,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc,WAAW,GAAG;KAC7D;KACX,aAAa,GAAG,EACd,EAAc,YACd,EAAc,SACf,CAAC,IAAI;KACN,sBAAsB;AACpB,QAAa,6BAA6B,GAAe,EAAW;;KAEvE;KACD;aACO,EAA0B,EAAc,EAAE;GAEnD,IAAM,EAAE,+BAA4B;AACpC,OACE,MACC,EAAc,cAAc,EAAwB,kBACnD,EAAc,cAAc,EAAwB,iBAEtD;QACE,EAAc,cAAc,EAAwB,eAEpD,QAAO,EAAE;IACJ;KAEL,IAAM,IAAW,GACX,IAAW,EAAe,MAC9B,MAAK,EAAE,cAAc,EAAwB,eAC9C,EACK,IAAY,EAAuB,EAAS,KAAK,EAAS,IAAI;AACpE,YAAO,CACL;MACE,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc,WAAW,GAAG;MAC7D;MACX,aAAa,GAAG,EAAwB,MAAM,IAAI;MAClD,sBAAsB;AAEpB,SAAa,oBAAoB,CAAC,GAAU,EAAS,CAAC;;MAEzD,CACF;;;GAIL,IAAM,IAAY,EAChB,EAAc,KACd,EAAc,IACf;AAED,UAAO,CACL;IACE,KAAK,SAAS,EAAc,aAAa,GAAG,EAAc,WAAW,GAAG,EAAc,IAAI,GAAG,EAAc;IAChG;IACX,aAAa,GAAG,EACd,EAAc,YACd,EAAc,SACf,CAAC,IAAI;IACN,sBAAsB;AACpB,OAAa,oBAAoB,EAAc;;IAElD,CACF;QAMD,QAJA,QAAQ,IACN,sBACC,EAAgD,aAClD,EACM,EAAE;GAEX;;AAGJ,SAAS,IAAyB;CAChC,IAAM,IAAe,GAAiB,EAChC,IAAe,EAAa,cAC5B,IAA4B,GAA8B,EAC1D,EAAE,2BAAwB,GAC1B,EAAE,MAAM,MAAkB,GAAqB,EAE/C,IAAuB,EAC3B,EAAoB,OAAO,qBAAqB,EAAE,EAClD,GACA,GAAe,gBAAgB,EAAE,EACjC,GACA,EACD,EAEK,IAAiB,EACrB,EAAoB,MAAM,kBAAkB,EAAE,EAC9C,GACA,GAAe,gBAAgB,EAAE,EACjC,GACA,EACD;AAID,QACE,kBAAA,GAAA,EAAA,UACG,CAJa,GAAG,GAAsB,GAAG,EAIzC,CAAS,KAAI,MAAa;EAEzB,IAAM,IAAM,mBAAmB,EAAU,IAAI;AAC7C,SAAO,kBAAC,GAAD;GAAuB,GAAI;GAAgB;GAAO,CAAA;GACzD,EACD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFacetPlots.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/useFacetPlots.ts"],"sourcesContent":["import { isSingleNotSetValue } from '@/utils/functions/queryUtils'\nimport {\n FacetColumnRequest,\n FacetColumnResult,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n QueryResultBundle,\n} from '@sage-bionetworks/synapse-types'\nimport { useCallback, useMemo } from 'react'\nimport { useQueryContext } from '../../QueryContext'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { applyChangesToValuesColumn } from '../query-filter/FacetFilterControls'\nimport { FacetNavPanelProps } from './FacetNavPanel'\n\n// Custom hook for generating properties for FacetNavPanel components with filter controls based on the given facets\nexport default function useFacetPlots(\n facetsToPlot: string[],\n): Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n>[] {\n const { getCurrentQueryRequest, executeQueryRequest } = useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n\n const lastQueryRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n const facets = useMemo(\n () => getFacets(queryMetadata, facetsToPlot),\n [queryMetadata, facetsToPlot],\n )\n\n const applyChangesFromQueryFilter = useCallback(\n (facets: FacetColumnRequest[]) => {\n executeQueryRequest(\n lastQueryRequest => {\n lastQueryRequest.query.selectedFacets = facets\n lastQueryRequest.query.offset = 0\n return lastQueryRequest\n },\n { debounce: true },\n )\n },\n [executeQueryRequest],\n )\n\n const facetNavPanelProps = useMemo(\n () =>\n facets.map(facet => {\n return {\n facetToPlot: facet as FacetColumnResultValues,\n\n applyChangesToFacetFilter: applyChangesFromQueryFilter,\n\n applyChangesToGraphSlice: (\n facet: FacetColumnResultValues,\n value: FacetColumnResultValueCount | undefined,\n isSelected: boolean,\n ) =>\n applyChangesToValuesColumn(\n lastQueryRequest,\n facet,\n applyChangesFromQueryFilter,\n value?.value,\n isSelected,\n ),\n }\n }),\n [facets, applyChangesFromQueryFilter, lastQueryRequest],\n )\n return facetNavPanelProps\n}\n\nexport function getFacets(\n data: QueryResultBundle | undefined,\n facetsToPlot?: string[],\n): FacetColumnResult[] {\n const result =\n data?.facets?.filter(item => {\n const isFacetToPlot =\n item.facetType === 'enumeration' &&\n (!facetsToPlot?.length || facetsToPlot.indexOf(item.columnName) > -1)\n // PORTALS-1993: only plot if the facet has count data\n return (\n isFacetToPlot &&\n item.facetValues.length > 0 &&\n !isSingleNotSetValue(item)\n )\n }) ?? []\n if (facetsToPlot?.length) {\n result.sort(\n (a, b) =>\n facetsToPlot.indexOf(a.columnName) - facetsToPlot.indexOf(b.columnName),\n )\n }\n return result\n}\n"],"mappings":";;;;;;;AAeA,SAAwB,EACtB,GAIE;CACF,IAAM,EAAE,2BAAwB,2BAAwB,GAAiB,EAEnE,EAAE,MAAM,MAAkB,GAA6B,EAEvD,IAAmB,QACjB,GAAwB,EAC9B,CAAC,EAAuB,CACzB,EACK,IAAS,QACP,EAAU,GAAe,EAAa,EAC5C,CAAC,GAAe,EAAa,CAC9B,EAEK,IAA8B,GACjC,MAAiC;AAChC,KACE,OACE,EAAiB,MAAM,iBAAiB,GACxC,EAAiB,MAAM,SAAS,GACzB,IAET,EAAE,UAAU,IAAM,CACnB;IAEH,CAAC,EAAoB,CACtB;AA0BD,QAxB2B,QAEvB,EAAO,KAAI,OACF;EACL,aAAa;EAEb,2BAA2B;EAE3B,2BACE,GACA,GACA,MAEA,EACE,GACA,GACA,GACA,GAAO,OACP,EACD;EACJ,EACD,EACJ;EAAC;EAAQ;EAA6B;EAAiB,CACxD;;AAIH,SAAgB,EACd,GACA,GACqB;CACrB,IAAM,IACJ,GAAM,QAAQ,QAAO,MAEjB,EAAK,cAAc,kBAClB,CAAC,GAAc,UAAU,EAAa,QAAQ,EAAK,WAAW,GAAG,OAIlE,EAAK,YAAY,SAAS,KAC1B,CAAC,EAAoB,EAAK,CAE5B,IAAI,EAAE;AAOV,QANI,GAAc,UAChB,EAAO,MACJ,GAAG,MACF,EAAa,QAAQ,EAAE,WAAW,GAAG,EAAa,QAAQ,EAAE,WAAW,CAC1E,EAEI"}
1
+ {"version":3,"file":"useFacetPlots.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/useFacetPlots.ts"],"sourcesContent":["import { isSingleNotSetValue } from '@/utils/functions/queryUtils'\nimport {\n FacetColumnRequest,\n FacetColumnResult,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n QueryResultBundle,\n} from '@sage-bionetworks/synapse-types'\nimport { useCallback, useMemo } from 'react'\nimport { useQueryContext } from '../../QueryContext'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { applyChangesToValuesColumn } from '../query-filter/FacetFilterControls'\nimport { FacetNavPanelProps } from './FacetNavPanel'\n\n// Custom hook for generating properties for FacetNavPanel components with filter controls based on the given facets\nexport default function useFacetPlots(\n facetsToPlot: string[],\n): Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n>[] {\n const { getCurrentQueryRequest, executeQueryRequest } = useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n\n const lastQueryRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n const facets = useMemo(\n () => getFacets(queryMetadata, facetsToPlot),\n [queryMetadata, facetsToPlot],\n )\n\n const applyChangesFromQueryFilter = useCallback(\n (facets: FacetColumnRequest[]) => {\n executeQueryRequest(\n lastQueryRequest => {\n lastQueryRequest.query.selectedFacets = facets\n lastQueryRequest.query.offset = 0\n return lastQueryRequest\n },\n { debounce: true },\n )\n },\n [executeQueryRequest],\n )\n\n const facetNavPanelProps = useMemo(\n () =>\n facets.map(facet => {\n return {\n facetToPlot: facet as FacetColumnResultValues,\n\n applyChangesToFacetFilter: applyChangesFromQueryFilter,\n\n applyChangesToGraphSlice: (\n facet: FacetColumnResultValues,\n value: FacetColumnResultValueCount | undefined,\n isSelected: boolean,\n ) =>\n applyChangesToValuesColumn(\n lastQueryRequest,\n facet,\n applyChangesFromQueryFilter,\n value?.value,\n isSelected,\n ),\n }\n }),\n [facets, applyChangesFromQueryFilter, lastQueryRequest],\n )\n return facetNavPanelProps\n}\n\nexport function getFacets(\n data: QueryResultBundle | undefined,\n facetsToPlot?: string[],\n): FacetColumnResult[] {\n const result =\n data?.facets?.filter(item => {\n const isFacetToPlot =\n item.facetType === 'enumeration' &&\n (!facetsToPlot?.length || facetsToPlot.indexOf(item.columnName) > -1)\n // PORTALS-1993: only plot if the facet has count data\n return (\n isFacetToPlot &&\n item.facetValues.length > 0 &&\n !isSingleNotSetValue(item)\n )\n }) ?? []\n if (facetsToPlot?.length) {\n result.sort(\n (a, b) =>\n facetsToPlot.indexOf(a.columnName) - facetsToPlot.indexOf(b.columnName),\n )\n }\n return result\n}\n"],"mappings":";;;;;;;AAeA,SAAwB,EACtB,GAIE;CACF,IAAM,EAAE,2BAAwB,2BAAwB,GAAiB,EAEnE,EAAE,MAAM,MAAkB,GAA6B,EAEvD,IAAmB,QACjB,GAAwB,EAC9B,CAAC,EAAuB,CACzB,EACK,IAAS,QACP,EAAU,GAAe,EAAa,EAC5C,CAAC,GAAe,EAAa,CAC9B,EAEK,IAA8B,GACjC,MAAiC;AAChC,KACE,OACE,EAAiB,MAAM,iBAAiB,GACxC,EAAiB,MAAM,SAAS,GACzB,IAET,EAAE,UAAU,IAAM,CACnB;IAEH,CAAC,EAAoB,CACtB;AA0BD,QAxB2B,QAEvB,EAAO,KAAI,OACF;EACL,aAAa;EAEb,2BAA2B;EAE3B,2BACE,GACA,GACA,MAEA,EACE,GACA,GACA,GACA,GAAO,OACP,EACD;EACJ,EACD,EACJ;EAAC;EAAQ;EAA6B;EAAiB,CAElD;;AAGT,SAAgB,EACd,GACA,GACqB;CACrB,IAAM,IACJ,GAAM,QAAQ,QAAO,MAEjB,EAAK,cAAc,kBAClB,CAAC,GAAc,UAAU,EAAa,QAAQ,EAAK,WAAW,GAAG,OAIlE,EAAK,YAAY,SAAS,KAC1B,CAAC,EAAoB,EAAK,CAE5B,IAAI,EAAE;AAOV,QANI,GAAc,UAChB,EAAO,MACJ,GAAG,MACF,EAAa,QAAQ,EAAE,WAAW,GAAG,EAAa,QAAQ,EAAE,WAAW,CAC1E,EAEI"}
@@ -1 +1 @@
1
- {"version":3,"file":"CombinedRangeFacetFilter.js","names":[],"sources":["../../../../src/components/widgets/query-filter/CombinedRangeFacetFilter.tsx"],"sourcesContent":["import { useGetQueryResultBundleWithAsyncStatus } from '@/synapse-queries'\nimport { SynapseConstants } from '@/utils'\nimport { VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport { Skeleton } from '@mui/material'\nimport {\n ColumnType,\n FacetColumnResultRange,\n} from '@sage-bionetworks/synapse-types'\nimport { isNumber } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../../QueryContext'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { RangeValues } from '../Range'\nimport { RangeFacetFilterUI } from './RangeFacetFilterUI'\n\nexport type CombinedRangeFacetFilterProps = {\n facetResults: FacetColumnResultRange[]\n label: string\n columnType: ColumnType\n}\n\n/**\n * Inclusive range selector across two columns\n * Written for the ELITE portal cohort builder, may have other uses.\n * The following diagram shows how the Range Selector min and max values are used\n * to define the facet range values:\n * \n\n Range Selector \n min ├────────────────────────┤ max\n \n Min Column facet \n Column Min value ◄────────────────────────────┤ Range Selector max\n \n Max Column facet\n Range Selector min ├────────────────────────────► Column Max value\n \n\n*/\nexport function CombinedRangeFacetFilter({\n facetResults,\n label,\n columnType,\n}: CombinedRangeFacetFilterProps) {\n const { getCurrentQueryRequest, setRangeFacetValue, removeSelectedFacet } =\n useQueryContext()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const {\n columnName: col1Name,\n // columnMax: col1Max // not used\n // selectedMin: col1SelectedMin // not used\n selectedMax: col1SelectedMax,\n } = facetResults[0]\n const {\n columnName: col2Name,\n //columnMin: col2Min, // not used\n selectedMin: col2SelectedMin,\n // selectedMax: col2SelectedMax, // not used\n } = facetResults[1]\n\n // Also query for the facet columns full range (without any selected facets), to set the range selector range\n const queryBundleRequest = useMemo(() => {\n const requestCopy = getCurrentQueryRequest()\n requestCopy.partMask = SynapseConstants.BUNDLE_MASK_QUERY_FACETS\n const { selectedFacets } = requestCopy.query\n requestCopy.query.selectedFacets = selectedFacets\n ? selectedFacets.filter(\n facetRequest =>\n facetRequest.columnName !== col1Name &&\n facetRequest.columnName !== col2Name,\n )\n : []\n return requestCopy\n }, [col1Name, col2Name, getCurrentQueryRequest])\n\n const { data: queryResultFacetResponse, isLoading: isLoadingFacetStats } =\n useGetQueryResultBundleWithAsyncStatus(queryBundleRequest)\n\n const fullFacetStats = queryResultFacetResponse?.responseBody?.facets\n\n const col1Facet = fullFacetStats?.find(facet => facet.columnName === col1Name)\n const col2Facet = fullFacetStats?.find(facet => facet.columnName === col2Name)\n const col1GlobalMin = (col1Facet as FacetColumnResultRange)?.columnMin\n const col2GlobalMax = (col2Facet as FacetColumnResultRange)?.columnMax\n const selectedMin = col2SelectedMin\n const selectedMax = col1SelectedMax\n\n if (isLoadingFacetStats || !col1Facet || !col2Facet) {\n return <Skeleton variant=\"rectangular\" width=\"100\" />\n }\n return (\n <RangeFacetFilterUI\n label={getColumnDisplayName(label)}\n facetResult={{\n columnMin: col1GlobalMin,\n columnMax: col2GlobalMax,\n selectedMin: selectedMin,\n selectedMax: selectedMax,\n }}\n columnType={columnType}\n onRangeValueSelected={(values: RangeValues) => {\n setRangeFacetValue(\n col1Facet,\n col1GlobalMin,\n isNumber(values.max) ? String(values.max) : values.max,\n { noCommit: true },\n )\n\n setRangeFacetValue(\n col2Facet,\n isNumber(values.min) ? String(values.min) : values.min,\n col2GlobalMax,\n )\n }}\n onNotSetSelected={() => {\n setRangeFacetValue(col1Facet, VALUE_NOT_SET, VALUE_NOT_SET)\n setRangeFacetValue(col2Facet, VALUE_NOT_SET, VALUE_NOT_SET)\n }}\n onAnySelected={() => {\n removeSelectedFacet(col1Facet)\n removeSelectedFacet(col2Facet)\n }}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAuCA,SAAgB,EAAyB,EACvC,iBACA,UACA,iBACgC;CAChC,IAAM,EAAE,2BAAwB,uBAAoB,2BAClD,GAAiB,EACb,EAAE,4BAAyB,GAA8B,EAEzD,EACJ,YAAY,GAGZ,aAAa,MACX,EAAa,IACX,EACJ,YAAY,GAEZ,aAAa,MAEX,EAAa,IAiBX,EAAE,MAAM,GAA0B,WAAW,MACjD,EAfyB,QAAc;EACvC,IAAM,IAAc,GAAwB;AAC5C,IAAY,WAAW;EACvB,IAAM,EAAE,sBAAmB,EAAY;AAQvC,SAPA,EAAY,MAAM,iBAAiB,IAC/B,EAAe,QACb,MACE,EAAa,eAAe,KAC5B,EAAa,eAAe,EAC/B,GACD,EAAE,EACC;IACN;EAAC;EAAU;EAAU;EAAuB,CAAC,CAGY,EAEtD,IAAiB,GAA0B,cAAc,QAEzD,IAAY,GAAgB,MAAK,MAAS,EAAM,eAAe,EAAS,EACxE,IAAY,GAAgB,MAAK,MAAS,EAAM,eAAe,EAAS,EACxE,IAAiB,GAAsC,WACvD,IAAiB,GAAsC,WACvD,IAAc,GACd,IAAc;AAKpB,QAHI,KAAuB,CAAC,KAAa,CAAC,IACjC,kBAAC,GAAD;EAAU,SAAQ;EAAc,OAAM;EAAQ,CAAA,GAGrD,kBAAC,GAAD;EACE,OAAO,EAAqB,EAAM;EAClC,aAAa;GACX,WAAW;GACX,WAAW;GACE;GACA;GACd;EACW;EACZ,uBAAuB,MAAwB;AAQ7C,GAPA,EACE,GACA,GACA,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,KACnD,EAAE,UAAU,IAAM,CACnB,EAED,EACE,GACA,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,KACnD,EACD;;EAEH,wBAAwB;AAEtB,GADA,EAAmB,GAAW,GAAe,EAAc,EAC3D,EAAmB,GAAW,GAAe,EAAc;;EAE7D,qBAAqB;AAEnB,GADA,EAAoB,EAAU,EAC9B,EAAoB,EAAU;;EAEhC,CAAA"}
1
+ {"version":3,"file":"CombinedRangeFacetFilter.js","names":[],"sources":["../../../../src/components/widgets/query-filter/CombinedRangeFacetFilter.tsx"],"sourcesContent":["import { useGetQueryResultBundleWithAsyncStatus } from '@/synapse-queries'\nimport { SynapseConstants } from '@/utils'\nimport { VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport { Skeleton } from '@mui/material'\nimport {\n ColumnType,\n FacetColumnResultRange,\n} from '@sage-bionetworks/synapse-types'\nimport { isNumber } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../../QueryContext'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { RangeValues } from '../Range'\nimport { RangeFacetFilterUI } from './RangeFacetFilterUI'\n\nexport type CombinedRangeFacetFilterProps = {\n facetResults: FacetColumnResultRange[]\n label: string\n columnType: ColumnType\n}\n\n/**\n * Inclusive range selector across two columns\n * Written for the ELITE portal cohort builder, may have other uses.\n * The following diagram shows how the Range Selector min and max values are used\n * to define the facet range values:\n * \n\n Range Selector \n min ├────────────────────────┤ max\n \n Min Column facet \n Column Min value ◄────────────────────────────┤ Range Selector max\n \n Max Column facet\n Range Selector min ├────────────────────────────► Column Max value\n \n\n*/\nexport function CombinedRangeFacetFilter({\n facetResults,\n label,\n columnType,\n}: CombinedRangeFacetFilterProps) {\n const { getCurrentQueryRequest, setRangeFacetValue, removeSelectedFacet } =\n useQueryContext()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const {\n columnName: col1Name,\n // columnMax: col1Max // not used\n // selectedMin: col1SelectedMin // not used\n selectedMax: col1SelectedMax,\n } = facetResults[0]\n const {\n columnName: col2Name,\n //columnMin: col2Min, // not used\n selectedMin: col2SelectedMin,\n // selectedMax: col2SelectedMax, // not used\n } = facetResults[1]\n\n // Also query for the facet columns full range (without any selected facets), to set the range selector range\n const queryBundleRequest = useMemo(() => {\n const requestCopy = getCurrentQueryRequest()\n requestCopy.partMask = SynapseConstants.BUNDLE_MASK_QUERY_FACETS\n const { selectedFacets } = requestCopy.query\n requestCopy.query.selectedFacets = selectedFacets\n ? selectedFacets.filter(\n facetRequest =>\n facetRequest.columnName !== col1Name &&\n facetRequest.columnName !== col2Name,\n )\n : []\n return requestCopy\n }, [col1Name, col2Name, getCurrentQueryRequest])\n\n const { data: queryResultFacetResponse, isLoading: isLoadingFacetStats } =\n useGetQueryResultBundleWithAsyncStatus(queryBundleRequest)\n\n const fullFacetStats = queryResultFacetResponse?.responseBody?.facets\n\n const col1Facet = fullFacetStats?.find(facet => facet.columnName === col1Name)\n const col2Facet = fullFacetStats?.find(facet => facet.columnName === col2Name)\n const col1GlobalMin = (col1Facet as FacetColumnResultRange)?.columnMin\n const col2GlobalMax = (col2Facet as FacetColumnResultRange)?.columnMax\n const selectedMin = col2SelectedMin\n const selectedMax = col1SelectedMax\n\n if (isLoadingFacetStats || !col1Facet || !col2Facet) {\n return <Skeleton variant=\"rectangular\" width=\"100\" />\n }\n return (\n <RangeFacetFilterUI\n label={getColumnDisplayName(label)}\n facetResult={{\n columnMin: col1GlobalMin,\n columnMax: col2GlobalMax,\n selectedMin: selectedMin,\n selectedMax: selectedMax,\n }}\n columnType={columnType}\n onRangeValueSelected={(values: RangeValues) => {\n setRangeFacetValue(\n col1Facet,\n col1GlobalMin,\n isNumber(values.max) ? String(values.max) : values.max,\n { noCommit: true },\n )\n\n setRangeFacetValue(\n col2Facet,\n isNumber(values.min) ? String(values.min) : values.min,\n col2GlobalMax,\n )\n }}\n onNotSetSelected={() => {\n setRangeFacetValue(col1Facet, VALUE_NOT_SET, VALUE_NOT_SET)\n setRangeFacetValue(col2Facet, VALUE_NOT_SET, VALUE_NOT_SET)\n }}\n onAnySelected={() => {\n removeSelectedFacet(col1Facet)\n removeSelectedFacet(col2Facet)\n }}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAuCA,SAAgB,EAAyB,EACvC,iBACA,UACA,iBACgC;CAChC,IAAM,EAAE,2BAAwB,uBAAoB,2BAClD,GAAiB,EACb,EAAE,4BAAyB,GAA8B,EAEzD,EACJ,YAAY,GAGZ,aAAa,MACX,EAAa,IACX,EACJ,YAAY,GAEZ,aAAa,MAEX,EAAa,IAiBX,EAAE,MAAM,GAA0B,WAAW,MACjD,EAfyB,QAAc;EACvC,IAAM,IAAc,GAAwB;AAC5C,IAAY,WAAW;EACvB,IAAM,EAAE,sBAAmB,EAAY;AAQvC,SAPA,EAAY,MAAM,iBAAiB,IAC/B,EAAe,QACb,MACE,EAAa,eAAe,KAC5B,EAAa,eAAe,EAC/B,GACD,EAAE,EACC;IACN;EAAC;EAAU;EAAU;EAAuB,CAGN,CAAmB,EAEtD,IAAiB,GAA0B,cAAc,QAEzD,IAAY,GAAgB,MAAK,MAAS,EAAM,eAAe,EAAS,EACxE,IAAY,GAAgB,MAAK,MAAS,EAAM,eAAe,EAAS,EACxE,IAAiB,GAAsC,WACvD,IAAiB,GAAsC,WACvD,IAAc,GACd,IAAc;AAKpB,QAHI,KAAuB,CAAC,KAAa,CAAC,IACjC,kBAAC,GAAD;EAAU,SAAQ;EAAc,OAAM;EAAQ,CAAA,GAGrD,kBAAC,GAAD;EACE,OAAO,EAAqB,EAAM;EAClC,aAAa;GACX,WAAW;GACX,WAAW;GACE;GACA;GACd;EACW;EACZ,uBAAuB,MAAwB;AAQ7C,GAPA,EACE,GACA,GACA,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,KACnD,EAAE,UAAU,IAAM,CACnB,EAED,EACE,GACA,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,KACnD,EACD;;EAEH,wBAAwB;AAEtB,GADA,EAAmB,GAAW,GAAe,EAAc,EAC3D,EAAmB,GAAW,GAAe,EAAc;;EAE7D,qBAAqB;AAEnB,GADA,EAAoB,EAAU,EAC9B,EAAoB,EAAU;;EAEhC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnumFacetFilter.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx"],"sourcesContent":["import { isFacetColumnValuesRequest, SynapseConstants } from '@/utils'\nimport {\n getCorrespondingColumnForFacet,\n getCorrespondingSelectedFacet,\n} from '@/utils/functions/queryUtils'\nimport useGetInfoFromIds from '@/utils/hooks/useGetInfoFromIds'\nimport {\n ColumnTypeEnum,\n EntityHeader,\n Evaluation,\n FacetColumnRequest,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n UserGroupHeader,\n} from '@sage-bionetworks/synapse-types'\nimport { cloneDeep, partition, pick, sortBy } from 'lodash-es'\nimport { Suspense, useMemo } from 'react'\nimport { useQueryContext } from '../../../QueryContext'\nimport { useQueryVisualizationContext } from '../../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../../QueryWrapper/useGetQueryMetadata'\nimport { EnumFacetFilterSkeleton } from './EnumFacetFilterSkeleton'\nimport EnumFacetFilterUI, { RenderedFacetValue } from './EnumFacetFilterUI'\nimport { getAllIsSelected, valueToLabel } from './EnumFacetFilterUtils'\n\nexport type EnumFacetFilterProps = {\n facet: FacetColumnResultValues\n containerAs?: 'Collapsible' | 'Dropdown'\n dropdownType?: 'Icon' | 'SelectBox'\n hideCollapsible?: boolean\n defaultShowAllValues?: boolean\n}\n\nfunction EnumFacetFilterInternal(props: EnumFacetFilterProps) {\n const {\n facet,\n containerAs = 'Collapsible',\n dropdownType = 'Icon',\n hideCollapsible = false,\n defaultShowAllValues = false,\n } = props\n const {\n nextQueryRequest,\n addValueToSelectedFacet,\n removeSelectedFacet,\n removeValueFromSelectedFacet,\n resetDebounceTimer,\n } = useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const currentSelectedFacet: FacetColumnValuesRequest | undefined =\n useMemo(() => {\n const facetColumnRequest = getCorrespondingSelectedFacet(\n facet,\n cloneDeep(nextQueryRequest.query.selectedFacets) as\n | FacetColumnRequest[]\n | undefined,\n )\n\n if (\n facetColumnRequest &&\n !isFacetColumnValuesRequest(facetColumnRequest)\n ) {\n console.error(\n `The facet rendered in EnumFacetFilter is not a FacetColumnValuesRequest`,\n facet,\n )\n return undefined\n }\n return facetColumnRequest\n }, [facet, nextQueryRequest.query.selectedFacets])\n\n // Must compare the known facet values to the \"uncommitted\" current query\n const allIsSelected = getAllIsSelected(\n cloneDeep(nextQueryRequest) as QueryBundleRequest,\n facet,\n )\n\n const columnModel = queryMetadata.columnModels\n ? getCorrespondingColumnForFacet(facet, queryMetadata.columnModels)\n : undefined\n\n const isNumberColumnType = useMemo(() => {\n switch (columnModel?.columnType) {\n case ColumnTypeEnum.DOUBLE:\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.INTEGER:\n return true\n default:\n return false\n }\n }, [columnModel])\n\n const userIds =\n columnModel?.columnType === ColumnTypeEnum.USERID ||\n columnModel?.columnType === ColumnTypeEnum.USERID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const userGroupHeaders = useGetInfoFromIds<UserGroupHeader>({\n ids: userIds,\n type: 'USER_PROFILE',\n })\n\n const entityIds =\n columnModel?.columnType === ColumnTypeEnum.ENTITYID ||\n columnModel?.columnType === ColumnTypeEnum.ENTITYID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const entityHeaders = useGetInfoFromIds<EntityHeader>({\n ids: entityIds,\n type: 'ENTITY_HEADER',\n })\n\n const evaluationIds =\n columnModel?.columnType === ColumnTypeEnum.EVALUATIONID\n ? facet.facetValues.map(facet => facet.value)\n : []\n const evaluations = useGetInfoFromIds<Evaluation>({\n ids: evaluationIds,\n type: 'EVALUATION_QUEUE',\n })\n\n const displayedFacetValues: RenderedFacetValue[] = useMemo(() => {\n const renderedFacetValues = facet.facetValues.map(\n (facetValue: FacetColumnResultValueCount): RenderedFacetValue => {\n return {\n ...facetValue,\n // Selected status should be based on the 'nextQuery', not the result data\n // This ensures the checkboxes respond instantly to user interaction, like while waiting for multiple changes to debounce\n isSelected:\n currentSelectedFacet?.facetValues.includes(facetValue.value) ??\n false,\n displayText: valueToLabel(\n facetValue,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n ),\n }\n },\n )\n //Abby V's suggestion, always show the VALUE_NOT_SET facet value on the bottom of this sorted list\n const partitions = partition(\n renderedFacetValues,\n facet => facet.value === SynapseConstants.VALUE_NOT_SET,\n )\n const valueNotSetFacetArray = partitions[0]\n const restOfFacetValuesArray = partitions[1]\n\n // Apply client-side sorting if no server-side sort is specified\n let sortedValues: RenderedFacetValue[] = restOfFacetValuesArray\n const isClientSideSort =\n columnModel == undefined || columnModel.facetSortConfig == undefined\n if (isClientSideSort) {\n if (isNumberColumnType) {\n sortedValues = sortBy(restOfFacetValuesArray, fv => Number(fv.value))\n } else {\n sortedValues = sortBy(restOfFacetValuesArray, fv =>\n fv.displayText.toLowerCase(),\n )\n }\n }\n\n return [...sortedValues, ...valueNotSetFacetArray]\n }, [\n facet.facetValues,\n columnModel,\n currentSelectedFacet?.facetValues,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n isNumberColumnType,\n ])\n\n if (!columnModel) {\n return <></>\n }\n\n return (\n <EnumFacetFilterUI\n facetTitle={getColumnDisplayName(facet.columnName, facet.jsonPath)}\n filterIsActive={!allIsSelected}\n facetValues={displayedFacetValues}\n containerAs={containerAs}\n dropdownType={dropdownType}\n hideCollapsible={hideCollapsible}\n defaultShowAllValues={defaultShowAllValues}\n onHoverOverValue={() => {\n // SWC-6698: delay the query execution (via the debounce) when an item is hovered over\n resetDebounceTimer()\n }}\n onAddValueToSelection={value => {\n addValueToSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveValueFromSelection={value => {\n removeValueFromSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveAllFacetSelections={() =>\n removeSelectedFacet(pick(facet, ['columnName', 'jsonPath']))\n }\n canMultiSelect={true}\n />\n )\n}\n\nexport function EnumFacetFilter(props: EnumFacetFilterProps) {\n const { containerAs = 'Collapsible', dropdownType = 'Icon' } = props\n return (\n <Suspense\n fallback={\n <EnumFacetFilterSkeleton\n containerAs={containerAs}\n dropdownType={dropdownType}\n />\n }\n >\n <EnumFacetFilterInternal {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EnumFacetFilter.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx"],"sourcesContent":["import { isFacetColumnValuesRequest, SynapseConstants } from '@/utils'\nimport {\n getCorrespondingColumnForFacet,\n getCorrespondingSelectedFacet,\n} from '@/utils/functions/queryUtils'\nimport useGetInfoFromIds from '@/utils/hooks/useGetInfoFromIds'\nimport {\n ColumnTypeEnum,\n EntityHeader,\n Evaluation,\n FacetColumnRequest,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n UserGroupHeader,\n} from '@sage-bionetworks/synapse-types'\nimport { cloneDeep, partition, pick, sortBy } from 'lodash-es'\nimport { Suspense, useMemo } from 'react'\nimport { useQueryContext } from '../../../QueryContext'\nimport { useQueryVisualizationContext } from '../../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../../QueryWrapper/useGetQueryMetadata'\nimport { EnumFacetFilterSkeleton } from './EnumFacetFilterSkeleton'\nimport EnumFacetFilterUI, { RenderedFacetValue } from './EnumFacetFilterUI'\nimport { getAllIsSelected, valueToLabel } from './EnumFacetFilterUtils'\n\nexport type EnumFacetFilterProps = {\n facet: FacetColumnResultValues\n containerAs?: 'Collapsible' | 'Dropdown'\n dropdownType?: 'Icon' | 'SelectBox'\n hideCollapsible?: boolean\n defaultShowAllValues?: boolean\n}\n\nfunction EnumFacetFilterInternal(props: EnumFacetFilterProps) {\n const {\n facet,\n containerAs = 'Collapsible',\n dropdownType = 'Icon',\n hideCollapsible = false,\n defaultShowAllValues = false,\n } = props\n const {\n nextQueryRequest,\n addValueToSelectedFacet,\n removeSelectedFacet,\n removeValueFromSelectedFacet,\n resetDebounceTimer,\n } = useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const currentSelectedFacet: FacetColumnValuesRequest | undefined =\n useMemo(() => {\n const facetColumnRequest = getCorrespondingSelectedFacet(\n facet,\n cloneDeep(nextQueryRequest.query.selectedFacets) as\n | FacetColumnRequest[]\n | undefined,\n )\n\n if (\n facetColumnRequest &&\n !isFacetColumnValuesRequest(facetColumnRequest)\n ) {\n console.error(\n `The facet rendered in EnumFacetFilter is not a FacetColumnValuesRequest`,\n facet,\n )\n return undefined\n }\n return facetColumnRequest\n }, [facet, nextQueryRequest.query.selectedFacets])\n\n // Must compare the known facet values to the \"uncommitted\" current query\n const allIsSelected = getAllIsSelected(\n cloneDeep(nextQueryRequest) as QueryBundleRequest,\n facet,\n )\n\n const columnModel = queryMetadata.columnModels\n ? getCorrespondingColumnForFacet(facet, queryMetadata.columnModels)\n : undefined\n\n const isNumberColumnType = useMemo(() => {\n switch (columnModel?.columnType) {\n case ColumnTypeEnum.DOUBLE:\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.INTEGER:\n return true\n default:\n return false\n }\n }, [columnModel])\n\n const userIds =\n columnModel?.columnType === ColumnTypeEnum.USERID ||\n columnModel?.columnType === ColumnTypeEnum.USERID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const userGroupHeaders = useGetInfoFromIds<UserGroupHeader>({\n ids: userIds,\n type: 'USER_PROFILE',\n })\n\n const entityIds =\n columnModel?.columnType === ColumnTypeEnum.ENTITYID ||\n columnModel?.columnType === ColumnTypeEnum.ENTITYID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const entityHeaders = useGetInfoFromIds<EntityHeader>({\n ids: entityIds,\n type: 'ENTITY_HEADER',\n })\n\n const evaluationIds =\n columnModel?.columnType === ColumnTypeEnum.EVALUATIONID\n ? facet.facetValues.map(facet => facet.value)\n : []\n const evaluations = useGetInfoFromIds<Evaluation>({\n ids: evaluationIds,\n type: 'EVALUATION_QUEUE',\n })\n\n const displayedFacetValues: RenderedFacetValue[] = useMemo(() => {\n const renderedFacetValues = facet.facetValues.map(\n (facetValue: FacetColumnResultValueCount): RenderedFacetValue => {\n return {\n ...facetValue,\n // Selected status should be based on the 'nextQuery', not the result data\n // This ensures the checkboxes respond instantly to user interaction, like while waiting for multiple changes to debounce\n isSelected:\n currentSelectedFacet?.facetValues.includes(facetValue.value) ??\n false,\n displayText: valueToLabel(\n facetValue,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n ),\n }\n },\n )\n //Abby V's suggestion, always show the VALUE_NOT_SET facet value on the bottom of this sorted list\n const partitions = partition(\n renderedFacetValues,\n facet => facet.value === SynapseConstants.VALUE_NOT_SET,\n )\n const valueNotSetFacetArray = partitions[0]\n const restOfFacetValuesArray = partitions[1]\n\n // Apply client-side sorting if no server-side sort is specified\n let sortedValues: RenderedFacetValue[] = restOfFacetValuesArray\n const isClientSideSort =\n columnModel == undefined || columnModel.facetSortConfig == undefined\n if (isClientSideSort) {\n if (isNumberColumnType) {\n sortedValues = sortBy(restOfFacetValuesArray, fv => Number(fv.value))\n } else {\n sortedValues = sortBy(restOfFacetValuesArray, fv =>\n fv.displayText.toLowerCase(),\n )\n }\n }\n\n return [...sortedValues, ...valueNotSetFacetArray]\n }, [\n facet.facetValues,\n columnModel,\n currentSelectedFacet?.facetValues,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n isNumberColumnType,\n ])\n\n if (!columnModel) {\n return <></>\n }\n\n return (\n <EnumFacetFilterUI\n facetTitle={getColumnDisplayName(facet.columnName, facet.jsonPath)}\n filterIsActive={!allIsSelected}\n facetValues={displayedFacetValues}\n containerAs={containerAs}\n dropdownType={dropdownType}\n hideCollapsible={hideCollapsible}\n defaultShowAllValues={defaultShowAllValues}\n onHoverOverValue={() => {\n // SWC-6698: delay the query execution (via the debounce) when an item is hovered over\n resetDebounceTimer()\n }}\n onAddValueToSelection={value => {\n addValueToSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveValueFromSelection={value => {\n removeValueFromSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveAllFacetSelections={() =>\n removeSelectedFacet(pick(facet, ['columnName', 'jsonPath']))\n }\n canMultiSelect={true}\n />\n )\n}\n\nexport function EnumFacetFilter(props: EnumFacetFilterProps) {\n const { containerAs = 'Collapsible', dropdownType = 'Icon' } = props\n return (\n <Suspense\n fallback={\n <EnumFacetFilterSkeleton\n containerAs={containerAs}\n dropdownType={dropdownType}\n />\n }\n >\n <EnumFacetFilterInternal {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FacetFilterControls.js","names":[],"sources":["../../../../src/components/widgets/query-filter/FacetFilterControls.tsx"],"sourcesContent":["import {\n facetObjectMatchesDefinition,\n getCorrespondingColumnForFacet,\n isSingleNotSetValue,\n} from '@/utils/functions/queryUtils'\nimport {\n FacetColumnRequest,\n FacetColumnResultRange,\n FacetColumnResultValues,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n} from '@sage-bionetworks/synapse-types'\nimport { groupBy, noop, sortBy, union } from 'lodash-es'\nimport { Suspense, useCallback, useMemo, useState } from 'react'\nimport { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect'\nimport { useQueryContext } from '../../QueryContext'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { CombinedRangeFacetFilter } from './CombinedRangeFacetFilter'\nimport { EnumFacetFilter } from './EnumFacetFilter/EnumFacetFilter'\nimport { FacetChip } from './FacetChip'\nimport { FacetFilterHeader } from './FacetFilterHeader'\nimport { FacetFilterControlsSkeleton } from './FacetFilterSkeleton'\nimport { getDefaultShownFacetFilters } from './FacetFilterUtils'\nimport JsonColumnFacetFilters from './JsonColumnFacetFilters'\nimport { RangeFacetFilter } from './RangeFacetFilter'\n\nexport type FacetFilterControlsProps = {\n /* The set of faceted column names that should be shown in the Facet controls. If undefined, all faceted columns with\n at least one non-null value will be shown. */\n availableFacets?: string[]\n initialExpandedFacetControls?: string[]\n}\n\nconst convertFacetToFacetColumnValuesRequest = (\n facet: FacetColumnResultValues,\n): FacetColumnValuesRequest => ({\n concreteType: 'org.sagebionetworks.repo.model.table.FacetColumnValuesRequest',\n columnName: facet.columnName,\n facetValues: facet.facetValues\n .filter(facet => facet.isSelected)\n .map(facet => facet.value),\n})\n\nconst patchRequestFacets = (\n changedFacet: FacetColumnRequest,\n selections: FacetColumnRequest[] = [],\n): FacetColumnRequest[] => {\n const changedFacetIndex = selections.findIndex(facet =>\n facetObjectMatchesDefinition(facet, changedFacet),\n )\n const isEmptyValuesFacet =\n changedFacet.concreteType ===\n 'org.sagebionetworks.repo.model.table.FacetColumnValuesRequest' &&\n (!changedFacet.facetValues || !changedFacet.facetValues.length)\n const isEmptyRangesFacet =\n changedFacet.concreteType ===\n 'org.sagebionetworks.repo.model.table.FacetColumnRangeRequest' &&\n (!changedFacet.min || !changedFacet.max)\n\n if (changedFacetIndex > -1) {\n if (isEmptyValuesFacet || isEmptyRangesFacet) {\n selections.splice(changedFacetIndex, 1)\n } else {\n selections[changedFacetIndex] = changedFacet\n }\n } else {\n selections.push(changedFacet)\n }\n return selections\n}\n\nexport function applyChangesToValuesColumn(\n lastRequest: QueryBundleRequest | undefined,\n facet: FacetColumnResultValues,\n onChangeFn: (result: FacetColumnRequest[]) => void,\n facetName?: string,\n checked: boolean = false,\n) {\n if (facetName) {\n facet.facetValues.forEach(facetValue => {\n if (facetValue.value === facetName) {\n facetValue.isSelected = checked\n }\n })\n } else {\n // else clear all\n facet.facetValues.forEach(facet => {\n facet.isSelected = false\n })\n }\n\n const changedFacet = convertFacetToFacetColumnValuesRequest(facet)\n const result = patchRequestFacets(\n changedFacet,\n lastRequest?.query?.selectedFacets,\n )\n onChangeFn(result)\n}\n\nfunction FacetFilterControls(props: FacetFilterControlsProps) {\n const { availableFacets, initialExpandedFacetControls } = props\n const { getCurrentQueryRequest, combineRangeFacetConfig } = useQueryContext()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n const lastRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n\n const facets = queryMetadata\n .facets!.filter(\n facet =>\n // If availableFacets is configured, remove those that don't match.\n availableFacets == null || availableFacets.includes(facet.columnName),\n )\n // Don't include json subcolumn facets, those will be handled separately\n .filter(facet => facet.jsonPath == null)\n .filter(\n facet =>\n // Don't show facets if included in the combine range facet config, handled separately\n combineRangeFacetConfig == null ||\n (combineRangeFacetConfig.maxFacetColumn !== facet.columnName &&\n combineRangeFacetConfig.minFacetColumn !== facet.columnName),\n )\n .filter(\n facet =>\n // Don't show facets where there are no values\n !isSingleNotSetValue(facet),\n )\n\n const combinedRangeFacets = combineRangeFacetConfig\n ? queryMetadata.facets!.filter(\n facet =>\n combineRangeFacetConfig.maxFacetColumn === facet.columnName ||\n combineRangeFacetConfig.minFacetColumn === facet.columnName,\n )\n : []\n\n // Group JSON facets by column name, so they can be grouped in the UI under their parent column name\n const jsonFacetsGroupedByColumn = groupBy(\n queryMetadata.facets!.filter(f => !!f.jsonPath),\n 'columnName',\n )\n\n const allFacetColumns: string[] = useMemo(() => {\n const allFacetColumns: string[] = []\n facets.forEach(facet => allFacetColumns.push(facet.columnName))\n if (combineRangeFacetConfig) {\n allFacetColumns.push(combineRangeFacetConfig.label)\n }\n if (jsonFacetsGroupedByColumn) {\n Object.keys(jsonFacetsGroupedByColumn).forEach(jsonColumn =>\n allFacetColumns.push(jsonColumn),\n )\n }\n return allFacetColumns\n }, [combineRangeFacetConfig, facets, jsonFacetsGroupedByColumn])\n\n // Controls which facet columns are shown/hidden by clicking on chips. NOTE: One column may have multiple facets (e.g. JSON subcolumn facets)\n const [facetColumnsShown, setFacetColumnsShown] = useState<Set<string>>(\n getDefaultShownFacetFilters(\n allFacetColumns,\n lastRequest.query.selectedFacets,\n ),\n )\n\n /**\n * When the data facets change, reset the initially-selected chips\n */\n useDeepCompareEffectNoCheck(() => {\n // Select the first three facet columns, plus any columns where a facet is already filtered,\n // (PORTALS-3513) plus the initially expanded filters and any filters that the user explicitly expanded\n const expandedFacets = union(\n initialExpandedFacetControls ?? [],\n Array.from(facetColumnsShown),\n )\n setFacetColumnsShown(\n getDefaultShownFacetFilters(\n allFacetColumns,\n lastRequest.query.selectedFacets,\n expandedFacets,\n ),\n )\n }, [facets])\n\n const columnModels = queryMetadata.columnModels\n\n const toggleShowFacetFilter = useCallback(\n (facetColumnName: string) => {\n const newFacetColumnsShown = new Set(facetColumnsShown)\n if (newFacetColumnsShown.has(facetColumnName)) {\n newFacetColumnsShown.delete(facetColumnName)\n } else {\n newFacetColumnsShown.add(facetColumnName)\n }\n setFacetColumnsShown(newFacetColumnsShown)\n },\n [facetColumnsShown],\n )\n const combinedRangeFacetsColumnModelType = combineRangeFacetConfig\n ? columnModels!.find(\n model => model.name === combineRangeFacetConfig.minFacetColumn,\n )?.columnType\n : undefined\n\n const shownTopLevelFacets = useMemo(\n () =>\n (facets ?? []).filter(facet => facetColumnsShown.has(facet.columnName)),\n [facetColumnsShown, facets],\n )\n\n const shownJsonFacetGroups = useMemo(\n () =>\n Object.entries(jsonFacetsGroupedByColumn).filter(([columnName]) =>\n facetColumnsShown.has(columnName),\n ),\n [facetColumnsShown, jsonFacetsGroupedByColumn],\n )\n\n return (\n <div className={`FacetFilterControls`}>\n <div>\n <FacetFilterHeader\n label={'Available Filters'}\n hideCollapsible\n isCollapsed={false}\n onClick={noop}\n />\n {sortBy(allFacetColumns).map(columnName => {\n return (\n <FacetChip\n key={columnName}\n onClick={() => toggleShowFacetFilter(columnName)}\n isChecked={facetColumnsShown.has(columnName)}\n >\n {getColumnDisplayName(columnName)}\n </FacetChip>\n )\n })}\n </div>\n {combineRangeFacetConfig && combinedRangeFacets.length >= 2 && (\n <CombinedRangeFacetFilter\n facetResults={combinedRangeFacets as FacetColumnResultRange[]}\n label={combineRangeFacetConfig.label}\n columnType={combinedRangeFacetsColumnModelType!}\n />\n )}\n {shownTopLevelFacets.map(facet => {\n const columnModel = getCorrespondingColumnForFacet(facet, columnModels!)\n return (\n <div className=\"FacetFilterControls__facet\" key={facet.columnName}>\n {facet.facetType === 'enumeration' && columnModel && (\n <EnumFacetFilter containerAs=\"Collapsible\" facet={facet} />\n )}\n {facet.facetType === 'range' && columnModel && (\n <RangeFacetFilter facetResult={facet} />\n )}\n </div>\n )\n })}\n {shownJsonFacetGroups.map(([columnName, facets]) => {\n const columnModel = queryMetadata?.columnModels?.find(\n cm => cm.name === columnName,\n )\n return (\n columnModel && (\n <JsonColumnFacetFilters\n key={columnName}\n columnModel={columnModel}\n facets={facets}\n />\n )\n )\n })}\n </div>\n )\n}\n\nexport default function FacetFilterControlsWithSuspense(\n props: FacetFilterControlsProps,\n) {\n return (\n <Suspense fallback={<FacetFilterControlsSkeleton />}>\n <FacetFilterControls {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FacetFilterControls.js","names":[],"sources":["../../../../src/components/widgets/query-filter/FacetFilterControls.tsx"],"sourcesContent":["import {\n facetObjectMatchesDefinition,\n getCorrespondingColumnForFacet,\n isSingleNotSetValue,\n} from '@/utils/functions/queryUtils'\nimport {\n FacetColumnRequest,\n FacetColumnResultRange,\n FacetColumnResultValues,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n} from '@sage-bionetworks/synapse-types'\nimport { groupBy, noop, sortBy, union } from 'lodash-es'\nimport { Suspense, useCallback, useMemo, useState } from 'react'\nimport { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect'\nimport { useQueryContext } from '../../QueryContext'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { CombinedRangeFacetFilter } from './CombinedRangeFacetFilter'\nimport { EnumFacetFilter } from './EnumFacetFilter/EnumFacetFilter'\nimport { FacetChip } from './FacetChip'\nimport { FacetFilterHeader } from './FacetFilterHeader'\nimport { FacetFilterControlsSkeleton } from './FacetFilterSkeleton'\nimport { getDefaultShownFacetFilters } from './FacetFilterUtils'\nimport JsonColumnFacetFilters from './JsonColumnFacetFilters'\nimport { RangeFacetFilter } from './RangeFacetFilter'\n\nexport type FacetFilterControlsProps = {\n /* The set of faceted column names that should be shown in the Facet controls. If undefined, all faceted columns with\n at least one non-null value will be shown. */\n availableFacets?: string[]\n initialExpandedFacetControls?: string[]\n}\n\nconst convertFacetToFacetColumnValuesRequest = (\n facet: FacetColumnResultValues,\n): FacetColumnValuesRequest => ({\n concreteType: 'org.sagebionetworks.repo.model.table.FacetColumnValuesRequest',\n columnName: facet.columnName,\n facetValues: facet.facetValues\n .filter(facet => facet.isSelected)\n .map(facet => facet.value),\n})\n\nconst patchRequestFacets = (\n changedFacet: FacetColumnRequest,\n selections: FacetColumnRequest[] = [],\n): FacetColumnRequest[] => {\n const changedFacetIndex = selections.findIndex(facet =>\n facetObjectMatchesDefinition(facet, changedFacet),\n )\n const isEmptyValuesFacet =\n changedFacet.concreteType ===\n 'org.sagebionetworks.repo.model.table.FacetColumnValuesRequest' &&\n (!changedFacet.facetValues || !changedFacet.facetValues.length)\n const isEmptyRangesFacet =\n changedFacet.concreteType ===\n 'org.sagebionetworks.repo.model.table.FacetColumnRangeRequest' &&\n (!changedFacet.min || !changedFacet.max)\n\n if (changedFacetIndex > -1) {\n if (isEmptyValuesFacet || isEmptyRangesFacet) {\n selections.splice(changedFacetIndex, 1)\n } else {\n selections[changedFacetIndex] = changedFacet\n }\n } else {\n selections.push(changedFacet)\n }\n return selections\n}\n\nexport function applyChangesToValuesColumn(\n lastRequest: QueryBundleRequest | undefined,\n facet: FacetColumnResultValues,\n onChangeFn: (result: FacetColumnRequest[]) => void,\n facetName?: string,\n checked: boolean = false,\n) {\n if (facetName) {\n facet.facetValues.forEach(facetValue => {\n if (facetValue.value === facetName) {\n facetValue.isSelected = checked\n }\n })\n } else {\n // else clear all\n facet.facetValues.forEach(facet => {\n facet.isSelected = false\n })\n }\n\n const changedFacet = convertFacetToFacetColumnValuesRequest(facet)\n const result = patchRequestFacets(\n changedFacet,\n lastRequest?.query?.selectedFacets,\n )\n onChangeFn(result)\n}\n\nfunction FacetFilterControls(props: FacetFilterControlsProps) {\n const { availableFacets, initialExpandedFacetControls } = props\n const { getCurrentQueryRequest, combineRangeFacetConfig } = useQueryContext()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n const lastRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n\n const facets = queryMetadata\n .facets!.filter(\n facet =>\n // If availableFacets is configured, remove those that don't match.\n availableFacets == null || availableFacets.includes(facet.columnName),\n )\n // Don't include json subcolumn facets, those will be handled separately\n .filter(facet => facet.jsonPath == null)\n .filter(\n facet =>\n // Don't show facets if included in the combine range facet config, handled separately\n combineRangeFacetConfig == null ||\n (combineRangeFacetConfig.maxFacetColumn !== facet.columnName &&\n combineRangeFacetConfig.minFacetColumn !== facet.columnName),\n )\n .filter(\n facet =>\n // Don't show facets where there are no values\n !isSingleNotSetValue(facet),\n )\n\n const combinedRangeFacets = combineRangeFacetConfig\n ? queryMetadata.facets!.filter(\n facet =>\n combineRangeFacetConfig.maxFacetColumn === facet.columnName ||\n combineRangeFacetConfig.minFacetColumn === facet.columnName,\n )\n : []\n\n // Group JSON facets by column name, so they can be grouped in the UI under their parent column name\n const jsonFacetsGroupedByColumn = groupBy(\n queryMetadata.facets!.filter(f => !!f.jsonPath),\n 'columnName',\n )\n\n const allFacetColumns: string[] = useMemo(() => {\n const allFacetColumns: string[] = []\n facets.forEach(facet => allFacetColumns.push(facet.columnName))\n if (combineRangeFacetConfig) {\n allFacetColumns.push(combineRangeFacetConfig.label)\n }\n if (jsonFacetsGroupedByColumn) {\n Object.keys(jsonFacetsGroupedByColumn).forEach(jsonColumn =>\n allFacetColumns.push(jsonColumn),\n )\n }\n return allFacetColumns\n }, [combineRangeFacetConfig, facets, jsonFacetsGroupedByColumn])\n\n // Controls which facet columns are shown/hidden by clicking on chips. NOTE: One column may have multiple facets (e.g. JSON subcolumn facets)\n const [facetColumnsShown, setFacetColumnsShown] = useState<Set<string>>(\n getDefaultShownFacetFilters(\n allFacetColumns,\n lastRequest.query.selectedFacets,\n ),\n )\n\n /**\n * When the data facets change, reset the initially-selected chips\n */\n useDeepCompareEffectNoCheck(() => {\n // Select the first three facet columns, plus any columns where a facet is already filtered,\n // (PORTALS-3513) plus the initially expanded filters and any filters that the user explicitly expanded\n const expandedFacets = union(\n initialExpandedFacetControls ?? [],\n Array.from(facetColumnsShown),\n )\n setFacetColumnsShown(\n getDefaultShownFacetFilters(\n allFacetColumns,\n lastRequest.query.selectedFacets,\n expandedFacets,\n ),\n )\n }, [facets])\n\n const columnModels = queryMetadata.columnModels\n\n const toggleShowFacetFilter = useCallback(\n (facetColumnName: string) => {\n const newFacetColumnsShown = new Set(facetColumnsShown)\n if (newFacetColumnsShown.has(facetColumnName)) {\n newFacetColumnsShown.delete(facetColumnName)\n } else {\n newFacetColumnsShown.add(facetColumnName)\n }\n setFacetColumnsShown(newFacetColumnsShown)\n },\n [facetColumnsShown],\n )\n const combinedRangeFacetsColumnModelType = combineRangeFacetConfig\n ? columnModels!.find(\n model => model.name === combineRangeFacetConfig.minFacetColumn,\n )?.columnType\n : undefined\n\n const shownTopLevelFacets = useMemo(\n () =>\n (facets ?? []).filter(facet => facetColumnsShown.has(facet.columnName)),\n [facetColumnsShown, facets],\n )\n\n const shownJsonFacetGroups = useMemo(\n () =>\n Object.entries(jsonFacetsGroupedByColumn).filter(([columnName]) =>\n facetColumnsShown.has(columnName),\n ),\n [facetColumnsShown, jsonFacetsGroupedByColumn],\n )\n\n return (\n <div className={`FacetFilterControls`}>\n <div>\n <FacetFilterHeader\n label={'Available Filters'}\n hideCollapsible\n isCollapsed={false}\n onClick={noop}\n />\n {sortBy(allFacetColumns).map(columnName => {\n return (\n <FacetChip\n key={columnName}\n onClick={() => toggleShowFacetFilter(columnName)}\n isChecked={facetColumnsShown.has(columnName)}\n >\n {getColumnDisplayName(columnName)}\n </FacetChip>\n )\n })}\n </div>\n {combineRangeFacetConfig && combinedRangeFacets.length >= 2 && (\n <CombinedRangeFacetFilter\n facetResults={combinedRangeFacets as FacetColumnResultRange[]}\n label={combineRangeFacetConfig.label}\n columnType={combinedRangeFacetsColumnModelType!}\n />\n )}\n {shownTopLevelFacets.map(facet => {\n const columnModel = getCorrespondingColumnForFacet(facet, columnModels!)\n return (\n <div className=\"FacetFilterControls__facet\" key={facet.columnName}>\n {facet.facetType === 'enumeration' && columnModel && (\n <EnumFacetFilter containerAs=\"Collapsible\" facet={facet} />\n )}\n {facet.facetType === 'range' && columnModel && (\n <RangeFacetFilter facetResult={facet} />\n )}\n </div>\n )\n })}\n {shownJsonFacetGroups.map(([columnName, facets]) => {\n const columnModel = queryMetadata?.columnModels?.find(\n cm => cm.name === columnName,\n )\n return (\n columnModel && (\n <JsonColumnFacetFilters\n key={columnName}\n columnModel={columnModel}\n facets={facets}\n />\n )\n )\n })}\n </div>\n )\n}\n\nexport default function FacetFilterControlsWithSuspense(\n props: FacetFilterControlsProps,\n) {\n return (\n <Suspense fallback={<FacetFilterControlsSkeleton />}>\n <FacetFilterControls {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RangeFacetFilter.js","names":[],"sources":["../../../../src/components/widgets/query-filter/RangeFacetFilter.tsx"],"sourcesContent":["import { getCorrespondingColumnForFacet } from '@/utils/functions/queryUtils'\nimport { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport { FacetColumnResultRange } from '@sage-bionetworks/synapse-types'\nimport { isNumber } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../../QueryContext'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { RangeValues } from '../Range'\nimport { RangeFacetFilterUI } from './RangeFacetFilterUI'\n\nexport enum RadioValuesEnum {\n NOT_SET = 'org.sagebionetworks.UNDEFINED_NULL_NOTSET',\n RANGE = 'RANGE',\n ANY = '',\n}\nexport const options = [\n { label: FRIENDLY_VALUE_NOT_SET, value: RadioValuesEnum.NOT_SET },\n { label: 'Any', value: RadioValuesEnum.ANY },\n { label: 'Range', value: RadioValuesEnum.RANGE },\n]\nexport type RangeFacetFilterProps = {\n facetResult: FacetColumnResultRange\n hideCollapsible?: boolean\n}\n\nexport function RangeFacetFilter(props: RangeFacetFilterProps) {\n const { facetResult, hideCollapsible = false } = props\n const { setRangeFacetValue, removeSelectedFacet, getCurrentQueryRequest } =\n useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n\n const columnModel = queryMetadata.columnModels\n ? getCorrespondingColumnForFacet(facetResult, queryMetadata.columnModels)\n : undefined\n\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const lastQueryRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n\n if (!columnModel) {\n return <></>\n }\n\n return (\n <RangeFacetFilterUI\n label={getColumnDisplayName(facetResult.columnName, facetResult.jsonPath)}\n facetResult={facetResult}\n columnType={columnModel.columnType}\n hideCollapsible={hideCollapsible}\n onRangeValueSelected={(values: RangeValues) => {\n setRangeFacetValue(\n facetResult,\n isNumber(values.min) ? String(values.min) : values.min,\n isNumber(values.max) ? String(values.max) : values.max,\n )\n }}\n onNotSetSelected={() => {\n setRangeFacetValue(facetResult, VALUE_NOT_SET, VALUE_NOT_SET)\n }}\n onAnySelected={() => {\n const selectedFacet = lastQueryRequest.query.selectedFacets?.find(\n selectedFacet =>\n selectedFacet.columnName === facetResult.columnName &&\n selectedFacet.jsonPath === facetResult.jsonPath,\n )\n if (selectedFacet) {\n removeSelectedFacet(selectedFacet)\n }\n }}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;AAWA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,6CACA,EAAA,QAAA,SACA,EAAA,MAAA;KACD,EACY,IAAU;CACrB;EAAE,OAAO;EAAwB,OAAO,EAAgB;EAAS;CACjE;EAAE,OAAO;EAAO,OAAO,EAAgB;EAAK;CAC5C;EAAE,OAAO;EAAS,OAAO,EAAgB;EAAO;CACjD;AAMD,SAAgB,EAAiB,GAA8B;CAC7D,IAAM,EAAE,gBAAa,qBAAkB,OAAU,GAC3C,EAAE,uBAAoB,wBAAqB,8BAC/C,GAAiB,EAEb,EAAE,MAAM,MAAkB,GAA6B,EAEvD,IAAc,EAAc,eAC9B,EAA+B,GAAa,EAAc,aAAa,GACvE,KAAA,GAEE,EAAE,4BAAyB,GAA8B,EAEzD,IAAmB,QACjB,GAAwB,EAC9B,CAAC,EAAuB,CACzB;AAMD,QAJK,IAKH,kBAAC,GAAD;EACE,OAAO,EAAqB,EAAY,YAAY,EAAY,SAAS;EAC5D;EACb,YAAY,EAAY;EACP;EACjB,uBAAuB,MAAwB;AAC7C,KACE,GACA,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,KACnD,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,IACpD;;EAEH,wBAAwB;AACtB,KAAmB,GAAa,GAAe,EAAc;;EAE/D,qBAAqB;GACnB,IAAM,IAAgB,EAAiB,MAAM,gBAAgB,MAC3D,MACE,EAAc,eAAe,EAAY,cACzC,EAAc,aAAa,EAAY,SAC1C;AACD,GAAI,KACF,EAAoB,EAAc;;EAGtC,CAAA,GA7BK,kBAAA,GAAA,EAAK,CAAA"}
1
+ {"version":3,"file":"RangeFacetFilter.js","names":[],"sources":["../../../../src/components/widgets/query-filter/RangeFacetFilter.tsx"],"sourcesContent":["import { getCorrespondingColumnForFacet } from '@/utils/functions/queryUtils'\nimport { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport { FacetColumnResultRange } from '@sage-bionetworks/synapse-types'\nimport { isNumber } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../../QueryContext'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport { RangeValues } from '../Range'\nimport { RangeFacetFilterUI } from './RangeFacetFilterUI'\n\nexport enum RadioValuesEnum {\n NOT_SET = 'org.sagebionetworks.UNDEFINED_NULL_NOTSET',\n RANGE = 'RANGE',\n ANY = '',\n}\nexport const options = [\n { label: FRIENDLY_VALUE_NOT_SET, value: RadioValuesEnum.NOT_SET },\n { label: 'Any', value: RadioValuesEnum.ANY },\n { label: 'Range', value: RadioValuesEnum.RANGE },\n]\nexport type RangeFacetFilterProps = {\n facetResult: FacetColumnResultRange\n hideCollapsible?: boolean\n}\n\nexport function RangeFacetFilter(props: RangeFacetFilterProps) {\n const { facetResult, hideCollapsible = false } = props\n const { setRangeFacetValue, removeSelectedFacet, getCurrentQueryRequest } =\n useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n\n const columnModel = queryMetadata.columnModels\n ? getCorrespondingColumnForFacet(facetResult, queryMetadata.columnModels)\n : undefined\n\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const lastQueryRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n\n if (!columnModel) {\n return <></>\n }\n\n return (\n <RangeFacetFilterUI\n label={getColumnDisplayName(facetResult.columnName, facetResult.jsonPath)}\n facetResult={facetResult}\n columnType={columnModel.columnType}\n hideCollapsible={hideCollapsible}\n onRangeValueSelected={(values: RangeValues) => {\n setRangeFacetValue(\n facetResult,\n isNumber(values.min) ? String(values.min) : values.min,\n isNumber(values.max) ? String(values.max) : values.max,\n )\n }}\n onNotSetSelected={() => {\n setRangeFacetValue(facetResult, VALUE_NOT_SET, VALUE_NOT_SET)\n }}\n onAnySelected={() => {\n const selectedFacet = lastQueryRequest.query.selectedFacets?.find(\n selectedFacet =>\n selectedFacet.columnName === facetResult.columnName &&\n selectedFacet.jsonPath === facetResult.jsonPath,\n )\n if (selectedFacet) {\n removeSelectedFacet(selectedFacet)\n }\n }}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;AAWA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAU,6CACV,EAAA,QAAQ,SACR,EAAA,MAAM;KACP,EACY,IAAU;CACrB;EAAE,OAAO;EAAwB,OAAO,EAAgB;EAAS;CACjE;EAAE,OAAO;EAAO,OAAO,EAAgB;EAAK;CAC5C;EAAE,OAAO;EAAS,OAAO,EAAgB;EAAO;CACjD;AAMD,SAAgB,EAAiB,GAA8B;CAC7D,IAAM,EAAE,gBAAa,qBAAkB,OAAU,GAC3C,EAAE,uBAAoB,wBAAqB,8BAC/C,GAAiB,EAEb,EAAE,MAAM,MAAkB,GAA6B,EAEvD,IAAc,EAAc,eAC9B,EAA+B,GAAa,EAAc,aAAa,GACvE,KAAA,GAEE,EAAE,4BAAyB,GAA8B,EAEzD,IAAmB,QACjB,GAAwB,EAC9B,CAAC,EAAuB,CACzB;AAMD,QAJK,IAKH,kBAAC,GAAD;EACE,OAAO,EAAqB,EAAY,YAAY,EAAY,SAAS;EAC5D;EACb,YAAY,EAAY;EACP;EACjB,uBAAuB,MAAwB;AAC7C,KACE,GACA,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,KACnD,EAAS,EAAO,IAAI,GAAG,OAAO,EAAO,IAAI,GAAG,EAAO,IACpD;;EAEH,wBAAwB;AACtB,KAAmB,GAAa,GAAe,EAAc;;EAE/D,qBAAqB;GACnB,IAAM,IAAgB,EAAiB,MAAM,gBAAgB,MAC3D,MACE,EAAc,eAAe,EAAY,cACzC,EAAc,aAAa,EAAY,SAC1C;AACD,GAAI,KACF,EAAoB,EAAc;;EAGtC,CAAA,GA7BK,kBAAA,GAAA,EAAK,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RangeFacetFilterUI.js","names":[],"sources":["../../../../src/components/widgets/query-filter/RangeFacetFilterUI.tsx"],"sourcesContent":["import { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport { Collapse, FormControlLabel, Radio, RadioGroup } from '@mui/material'\nimport {\n ColumnType,\n FacetColumnResultRange,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { useState } from 'react'\nimport { Range, RangeValues } from '../Range'\nimport RangeSlider from '../RangeSlider/RangeSlider'\nimport { FacetFilterHeader } from './FacetFilterHeader'\n\nexport enum RadioValuesEnum {\n NOT_SET = 'org.sagebionetworks.UNDEFINED_NULL_NOTSET',\n RANGE = 'RANGE',\n ANY = '',\n}\nexport const options = [\n { label: FRIENDLY_VALUE_NOT_SET, value: RadioValuesEnum.NOT_SET },\n { label: 'Any', value: RadioValuesEnum.ANY },\n { label: 'Range', value: RadioValuesEnum.RANGE },\n]\nexport type RangeFacetFilterProps = {\n label: string\n facetResult: Pick<\n FacetColumnResultRange,\n 'columnMin' | 'columnMax' | 'selectedMin' | 'selectedMax'\n >\n columnType: ColumnType\n hideCollapsible?: boolean\n onRangeValueSelected: (values: RangeValues) => void\n onNotSetSelected: () => void\n onAnySelected: () => void\n}\n\nexport const getRadioValue = (min: string, isAnyValue: boolean) => {\n if (isAnyValue) {\n return RadioValuesEnum.ANY\n } else if (min === VALUE_NOT_SET) {\n return RadioValuesEnum.NOT_SET\n }\n return RadioValuesEnum.RANGE\n}\n\nexport function RangeFacetFilterUI(props: RangeFacetFilterProps) {\n const {\n label,\n facetResult,\n hideCollapsible = false,\n columnType,\n onAnySelected,\n onNotSetSelected,\n onRangeValueSelected,\n } = props\n\n const [isCollapsed, setIsCollapsed] = useState<boolean>(false)\n\n const { columnMin, columnMax, selectedMin, selectedMax } = facetResult // the upper bound of the selected range\n\n const hasAnyValue = !selectedMin && !selectedMax\n\n const currentMin = selectedMin || columnMin\n const currentMax = selectedMax || columnMax\n\n const rangeType = columnType === 'DOUBLE' ? 'number' : 'date'\n\n const handleRadioGroupChange = (radioValue: RadioValuesEnum) => {\n setRadioValue(radioValue)\n\n switch (radioValue) {\n case RadioValuesEnum.RANGE:\n // The range facet value will update when the user clicks the apply button\n break\n case RadioValuesEnum.NOT_SET:\n onNotSetSelected()\n break\n case RadioValuesEnum.ANY: {\n onAnySelected()\n break\n }\n }\n }\n\n const [radioValue, setRadioValue] = useState(\n getRadioValue(currentMin, hasAnyValue),\n )\n\n return (\n <div>\n <FacetFilterHeader\n isCollapsed={isCollapsed}\n label={label}\n onClick={(isCollapsed: boolean) => setIsCollapsed(isCollapsed)}\n hideCollapsible={hideCollapsible}\n />\n <Collapse in={!isCollapsed}>\n <RadioGroup\n value={radioValue}\n onChange={(_event, value) =>\n handleRadioGroupChange(value as RadioValuesEnum)\n }\n >\n {options.map(({ value, label }) => (\n <FormControlLabel\n key={value}\n control={<Radio />}\n label={label}\n value={value}\n />\n ))}\n </RadioGroup>\n {radioValue === RadioValuesEnum.RANGE &&\n (columnMin === columnMax ? (\n <label>{columnMax}</label>\n ) : (\n <>\n {columnType === 'INTEGER' && (\n <RangeSlider\n key=\"RangeSlider\"\n domain={[columnMin, columnMax]}\n initialValues={{\n min: parseInt(currentMin),\n max: parseInt(currentMax),\n }}\n step={1}\n onApplyClicked={onRangeValueSelected}\n >\n {'>'}\n </RangeSlider>\n )}\n\n {columnType === 'DATE' && (\n <Range\n key=\"Range\"\n initialValues={{\n // From the backend, selectedMin is a formatted date (like \"2021-06-15\"), but columnMin is a unix timestamp in millis (like \"1624651794856\")\n min: selectedMin ?? dayjs(parseInt(columnMin)).toString(),\n max: selectedMax ?? dayjs(parseInt(columnMax)).toString(),\n }}\n type={rangeType}\n onApplyClicked={onRangeValueSelected}\n />\n )}\n {columnType === 'DOUBLE' && (\n <Range\n key=\"Range\"\n initialValues={{\n min: parseFloat(currentMin),\n max: parseFloat(currentMax),\n }}\n type={rangeType}\n onApplyClicked={onRangeValueSelected}\n />\n )}\n </>\n ))}\n </Collapse>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAYA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,6CACA,EAAA,QAAA,SACA,EAAA,MAAA;KACD,EACY,IAAU;CACrB;EAAE,OAAO;EAAwB,OAAO,EAAgB;EAAS;CACjE;EAAE,OAAO;EAAO,OAAO,EAAgB;EAAK;CAC5C;EAAE,OAAO;EAAS,OAAO,EAAgB;EAAO;CACjD,EAcY,KAAiB,GAAa,MACrC,IACK,EAAgB,MACd,MAAA,8CACF,EAAgB,UAElB,EAAgB;AAGzB,SAAgB,EAAmB,GAA8B;CAC/D,IAAM,EACJ,UACA,gBACA,qBAAkB,IAClB,eACA,kBACA,qBACA,4BACE,GAEE,CAAC,GAAa,KAAkB,EAAkB,GAAM,EAExD,EAAE,cAAW,cAAW,gBAAa,mBAAgB,GAErD,IAAc,CAAC,KAAe,CAAC,GAE/B,IAAa,KAAe,GAC5B,IAAa,KAAe,GAE5B,IAAY,MAAe,WAAW,WAAW,QAEjD,KAA0B,MAAgC;AAG9D,UAFA,EAAc,EAAW,EAEjB,GAAR;GACE,KAAK,EAAgB,MAEnB;GACF,KAAK,EAAgB;AACnB,OAAkB;AAClB;GACF,KAAK,EAAgB;AACnB,OAAe;AACf;;IAKA,CAAC,GAAY,KAAiB,EAClC,EAAc,GAAY,EAAY,CACvC;AAED,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EACe;EACN;EACP,UAAU,MAAyB,EAAe,EAAY;EAC7C;EACjB,CAAA,EACF,kBAAC,GAAD;EAAU,IAAI,CAAC;YAAf,CACE,kBAAC,GAAD;GACE,OAAO;GACP,WAAW,GAAQ,MACjB,EAAuB,EAAyB;aAGjD,EAAQ,KAAK,EAAE,UAAO,eACrB,kBAAC,GAAD;IAEE,SAAS,kBAAC,GAAD,EAAS,CAAA;IACX;IACA;IACP,EAJK,EAIL,CACF;GACS,CAAA,EACZ,MAAe,EAAgB,UAC7B,MAAc,IACb,kBAAC,SAAD,EAAA,UAAQ,GAAkB,CAAA,GAE1B,kBAAA,GAAA,EAAA,UAAA;GACG,MAAe,aACd,kBAAC,GAAD;IAEE,QAAQ,CAAC,GAAW,EAAU;IAC9B,eAAe;KACb,KAAK,SAAS,EAAW;KACzB,KAAK,SAAS,EAAW;KAC1B;IACD,MAAM;IACN,gBAAgB;cAEf;IACW,EAVR,cAUQ;GAGf,MAAe,UACd,kBAAC,GAAD;IAEE,eAAe;KAEb,KAAK,KAAe,EAAM,SAAS,EAAU,CAAC,CAAC,UAAU;KACzD,KAAK,KAAe,EAAM,SAAS,EAAU,CAAC,CAAC,UAAU;KAC1D;IACD,MAAM;IACN,gBAAgB;IAChB,EARI,QAQJ;GAEH,MAAe,YACd,kBAAC,GAAD;IAEE,eAAe;KACb,KAAK,WAAW,EAAW;KAC3B,KAAK,WAAW,EAAW;KAC5B;IACD,MAAM;IACN,gBAAgB;IAChB,EAPI,QAOJ;GAEH,EAAA,CAAA,EAEE;IACP,EAAA,CAAA"}
1
+ {"version":3,"file":"RangeFacetFilterUI.js","names":[],"sources":["../../../../src/components/widgets/query-filter/RangeFacetFilterUI.tsx"],"sourcesContent":["import { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport { Collapse, FormControlLabel, Radio, RadioGroup } from '@mui/material'\nimport {\n ColumnType,\n FacetColumnResultRange,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { useState } from 'react'\nimport { Range, RangeValues } from '../Range'\nimport RangeSlider from '../RangeSlider/RangeSlider'\nimport { FacetFilterHeader } from './FacetFilterHeader'\n\nexport enum RadioValuesEnum {\n NOT_SET = 'org.sagebionetworks.UNDEFINED_NULL_NOTSET',\n RANGE = 'RANGE',\n ANY = '',\n}\nexport const options = [\n { label: FRIENDLY_VALUE_NOT_SET, value: RadioValuesEnum.NOT_SET },\n { label: 'Any', value: RadioValuesEnum.ANY },\n { label: 'Range', value: RadioValuesEnum.RANGE },\n]\nexport type RangeFacetFilterProps = {\n label: string\n facetResult: Pick<\n FacetColumnResultRange,\n 'columnMin' | 'columnMax' | 'selectedMin' | 'selectedMax'\n >\n columnType: ColumnType\n hideCollapsible?: boolean\n onRangeValueSelected: (values: RangeValues) => void\n onNotSetSelected: () => void\n onAnySelected: () => void\n}\n\nexport const getRadioValue = (min: string, isAnyValue: boolean) => {\n if (isAnyValue) {\n return RadioValuesEnum.ANY\n } else if (min === VALUE_NOT_SET) {\n return RadioValuesEnum.NOT_SET\n }\n return RadioValuesEnum.RANGE\n}\n\nexport function RangeFacetFilterUI(props: RangeFacetFilterProps) {\n const {\n label,\n facetResult,\n hideCollapsible = false,\n columnType,\n onAnySelected,\n onNotSetSelected,\n onRangeValueSelected,\n } = props\n\n const [isCollapsed, setIsCollapsed] = useState<boolean>(false)\n\n const { columnMin, columnMax, selectedMin, selectedMax } = facetResult // the upper bound of the selected range\n\n const hasAnyValue = !selectedMin && !selectedMax\n\n const currentMin = selectedMin || columnMin\n const currentMax = selectedMax || columnMax\n\n const rangeType = columnType === 'DOUBLE' ? 'number' : 'date'\n\n const handleRadioGroupChange = (radioValue: RadioValuesEnum) => {\n setRadioValue(radioValue)\n\n switch (radioValue) {\n case RadioValuesEnum.RANGE:\n // The range facet value will update when the user clicks the apply button\n break\n case RadioValuesEnum.NOT_SET:\n onNotSetSelected()\n break\n case RadioValuesEnum.ANY: {\n onAnySelected()\n break\n }\n }\n }\n\n const [radioValue, setRadioValue] = useState(\n getRadioValue(currentMin, hasAnyValue),\n )\n\n return (\n <div>\n <FacetFilterHeader\n isCollapsed={isCollapsed}\n label={label}\n onClick={(isCollapsed: boolean) => setIsCollapsed(isCollapsed)}\n hideCollapsible={hideCollapsible}\n />\n <Collapse in={!isCollapsed}>\n <RadioGroup\n value={radioValue}\n onChange={(_event, value) =>\n handleRadioGroupChange(value as RadioValuesEnum)\n }\n >\n {options.map(({ value, label }) => (\n <FormControlLabel\n key={value}\n control={<Radio />}\n label={label}\n value={value}\n />\n ))}\n </RadioGroup>\n {radioValue === RadioValuesEnum.RANGE &&\n (columnMin === columnMax ? (\n <label>{columnMax}</label>\n ) : (\n <>\n {columnType === 'INTEGER' && (\n <RangeSlider\n key=\"RangeSlider\"\n domain={[columnMin, columnMax]}\n initialValues={{\n min: parseInt(currentMin),\n max: parseInt(currentMax),\n }}\n step={1}\n onApplyClicked={onRangeValueSelected}\n >\n {'>'}\n </RangeSlider>\n )}\n\n {columnType === 'DATE' && (\n <Range\n key=\"Range\"\n initialValues={{\n // From the backend, selectedMin is a formatted date (like \"2021-06-15\"), but columnMin is a unix timestamp in millis (like \"1624651794856\")\n min: selectedMin ?? dayjs(parseInt(columnMin)).toString(),\n max: selectedMax ?? dayjs(parseInt(columnMax)).toString(),\n }}\n type={rangeType}\n onApplyClicked={onRangeValueSelected}\n />\n )}\n {columnType === 'DOUBLE' && (\n <Range\n key=\"Range\"\n initialValues={{\n min: parseFloat(currentMin),\n max: parseFloat(currentMax),\n }}\n type={rangeType}\n onApplyClicked={onRangeValueSelected}\n />\n )}\n </>\n ))}\n </Collapse>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAYA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAU,6CACV,EAAA,QAAQ,SACR,EAAA,MAAM;KACP,EACY,IAAU;CACrB;EAAE,OAAO;EAAwB,OAAO,EAAgB;EAAS;CACjE;EAAE,OAAO;EAAO,OAAO,EAAgB;EAAK;CAC5C;EAAE,OAAO;EAAS,OAAO,EAAgB;EAAO;CACjD,EAcY,KAAiB,GAAa,MACrC,IACK,EAAgB,MACd,MAAA,8CACF,EAAgB,UAElB,EAAgB;AAGzB,SAAgB,EAAmB,GAA8B;CAC/D,IAAM,EACJ,UACA,gBACA,qBAAkB,IAClB,eACA,kBACA,qBACA,4BACE,GAEE,CAAC,GAAa,KAAkB,EAAkB,GAAM,EAExD,EAAE,cAAW,cAAW,gBAAa,mBAAgB,GAErD,IAAc,CAAC,KAAe,CAAC,GAE/B,IAAa,KAAe,GAC5B,IAAa,KAAe,GAE5B,IAAY,MAAe,WAAW,WAAW,QAEjD,KAA0B,MAAgC;AAG9D,UAFA,EAAc,EAAW,EAEjB,GAAR;GACE,KAAK,EAAgB,MAEnB;GACF,KAAK,EAAgB;AACnB,OAAkB;AAClB;GACF,KAAK,EAAgB;AACnB,OAAe;AACf;;IAKA,CAAC,GAAY,KAAiB,EAClC,EAAc,GAAY,EAAY,CACvC;AAED,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EACe;EACN;EACP,UAAU,MAAyB,EAAe,EAAY;EAC7C;EACjB,CAAA,EACF,kBAAC,GAAD;EAAU,IAAI,CAAC;YAAf,CACE,kBAAC,GAAD;GACE,OAAO;GACP,WAAW,GAAQ,MACjB,EAAuB,EAAyB;aAGjD,EAAQ,KAAK,EAAE,UAAO,eACrB,kBAAC,GAAD;IAEE,SAAS,kBAAC,GAAD,EAAS,CAAA;IACX;IACA;IACP,EAJK,EAIL,CACF;GACS,CAAA,EACZ,MAAe,EAAgB,UAC7B,MAAc,IACb,kBAAC,SAAD,EAAA,UAAQ,GAAkB,CAAA,GAE1B,kBAAA,GAAA,EAAA,UAAA;GACG,MAAe,aACd,kBAAC,GAAD;IAEE,QAAQ,CAAC,GAAW,EAAU;IAC9B,eAAe;KACb,KAAK,SAAS,EAAW;KACzB,KAAK,SAAS,EAAW;KAC1B;IACD,MAAM;IACN,gBAAgB;cAEf;IACW,EAVR,cAUQ;GAGf,MAAe,UACd,kBAAC,GAAD;IAEE,eAAe;KAEb,KAAK,KAAe,EAAM,SAAS,EAAU,CAAC,CAAC,UAAU;KACzD,KAAK,KAAe,EAAM,SAAS,EAAU,CAAC,CAAC,UAAU;KAC1D;IACD,MAAM;IACN,gBAAgB;IAChB,EARI,QAQJ;GAEH,MAAe,YACd,kBAAC,GAAD;IAEE,eAAe;KACb,KAAK,WAAW,EAAW;KAC3B,KAAK,WAAW,EAAW;KAC5B;IACD,MAAM;IACN,gBAAgB;IAChB,EAPI,QAOJ;GAEH,EAAA,CAAA,EAEE;IACP,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"GridPageTitle.d.ts","sourceRoot":"","sources":["../../../../../src/features/curator/GridPage/components/GridPageTitle.tsx"],"names":[],"mappings":"AAQA,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAoD9D"}
1
+ {"version":3,"file":"GridPageTitle.d.ts","sourceRoot":"","sources":["../../../../../src/features/curator/GridPage/components/GridPageTitle.tsx"],"names":[],"mappings":"AASA,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAmD9D"}
@@ -7,62 +7,55 @@ import { StyledPopover as i } from "../../../../components/styled/StyledPopover.
7
7
  import "../../../../components/index.js";
8
8
  import { useGetGridSession as a } from "../../../../synapse-queries/grid/useGridSession.js";
9
9
  import { useGetCurationTask as o } from "../../../../synapse-queries/curation/task/useCurationTask.js";
10
- import { Link as s, Stack as c, Tooltip as l, Typography as u } from "@mui/material";
11
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
10
+ import s from "../../../../components/layout/SWCHeader.js";
11
+ import { Link as c, Stack as l, Tooltip as u, Typography as d } from "@mui/material";
12
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
12
13
  //#region src/features/curator/GridPage/components/GridPageTitle.tsx
13
- function p(p) {
14
- let { sessionId: m, taskId: h } = p, { data: g, error: _ } = a(m), { data: v } = r(g?.sourceEntityId), { data: y } = o(h || 0, { enabled: h != null });
15
- return _ ? /* @__PURE__ */ d(n, { error: _ }) : /* @__PURE__ */ f("div", {
16
- className: "pageHeader",
17
- children: [/* @__PURE__ */ f("h3", {
18
- className: "pageHeaderTitle",
19
- children: [
20
- "Working Copy",
21
- " ",
22
- v?.name ? `of ${v.name}` : ""
23
- ]
24
- }), /* @__PURE__ */ f(c, {
25
- className: "description",
14
+ function m(m) {
15
+ let { sessionId: h, taskId: g } = m, { data: _, error: v } = a(h), { data: y } = r(_?.sourceEntityId), { data: b } = o(g || 0, { enabled: g != null });
16
+ return v ? /* @__PURE__ */ f(n, { error: v }) : /* @__PURE__ */ f(s, {
17
+ title: `Working Copy ${y?.name ? `of ${y.name}` : ""}`,
18
+ description: /* @__PURE__ */ p(l, {
26
19
  spacing: 1,
27
20
  children: [
28
- /* @__PURE__ */ f(u, {
21
+ /* @__PURE__ */ p(d, {
29
22
  variant: "headline2",
30
- children: ["ID: ", m]
23
+ children: ["ID: ", h]
31
24
  }),
32
- y && /* @__PURE__ */ f(c, {
25
+ b && /* @__PURE__ */ p(l, {
33
26
  direction: "row",
34
27
  spacing: 1,
35
28
  alignItems: "center",
36
- children: [/* @__PURE__ */ f(u, {
29
+ children: [/* @__PURE__ */ p(d, {
37
30
  variant: "body1",
38
31
  children: [
39
- /* @__PURE__ */ d("strong", { children: "Task Name:" }),
32
+ /* @__PURE__ */ f("strong", { children: "Task Name:" }),
40
33
  " ",
41
- y.dataType,
34
+ b.dataType,
42
35
  " "
43
36
  ]
44
- }), /* @__PURE__ */ d(i, {
45
- popoverContent: y.instructions,
46
- children: /* @__PURE__ */ d(s, {
37
+ }), /* @__PURE__ */ f(i, {
38
+ popoverContent: b.instructions,
39
+ children: /* @__PURE__ */ f(c, {
47
40
  underline: "hover",
48
41
  children: "View Instructions"
49
42
  })
50
43
  })]
51
44
  }),
52
- g?.gridJsonSchema$Id && /* @__PURE__ */ d("div", { children: /* @__PURE__ */ d(l, {
53
- title: g?.gridJsonSchema$Id,
45
+ _?.gridJsonSchema$Id && /* @__PURE__ */ f("div", { children: /* @__PURE__ */ f(u, {
46
+ title: _?.gridJsonSchema$Id,
54
47
  placement: "right",
55
- children: /* @__PURE__ */ d(s, {
48
+ children: /* @__PURE__ */ f(c, {
56
49
  target: "_blank",
57
- href: `${t(e.REPO_ENDPOINT)}/repo/v1/schema/type/registered/${g?.gridJsonSchema$Id}`,
50
+ href: `${t(e.REPO_ENDPOINT)}/repo/v1/schema/type/registered/${_?.gridJsonSchema$Id}`,
58
51
  children: "View Validation Schema (JSON)"
59
52
  })
60
53
  }) })
61
54
  ]
62
- })]
55
+ })
63
56
  });
64
57
  }
65
58
  //#endregion
66
- export { p as default };
59
+ export { m as default };
67
60
 
68
61
  //# sourceMappingURL=GridPageTitle.js.map