synapse-react-client 4.0.10 → 4.0.12

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 (210) hide show
  1. package/dist/SWC.index.d.ts +1 -1
  2. package/dist/SWC.index.js +1 -1
  3. package/dist/assets/icons/CloudWarning.d.ts +5 -0
  4. package/dist/assets/icons/CloudWarning.d.ts.map +1 -0
  5. package/dist/assets/icons/CloudWarning.js +47 -0
  6. package/dist/assets/icons/CloudWarning.js.map +1 -0
  7. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.d.ts +44 -0
  8. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.d.ts.map +1 -0
  9. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.js +46 -0
  10. package/dist/components/AdaptiveTwoColumnLayout/AdaptiveTwoColumnLayout.js.map +1 -0
  11. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.d.ts.map +1 -1
  12. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js +143 -140
  13. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
  14. package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts.map +1 -1
  15. package/dist/components/DataGrid/columns/AutocompleteColumn.js +66 -55
  16. package/dist/components/DataGrid/columns/AutocompleteColumn.js.map +1 -1
  17. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.d.ts.map +1 -1
  18. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js +1 -1
  19. package/dist/components/DataGrid/columns/AutocompleteMultipleEnumColumn.js.map +1 -1
  20. package/dist/components/DataGrid/utils/applyModelChange.d.ts +1 -1
  21. package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
  22. package/dist/components/DataGrid/utils/applyModelChange.js +27 -24
  23. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  24. package/dist/components/DataGrid/utils/columnFactory.d.ts +8 -0
  25. package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
  26. package/dist/components/DataGrid/utils/columnFactory.js +47 -44
  27. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  28. package/dist/components/DataGrid/utils/getEmptyValue.d.ts +2 -0
  29. package/dist/components/DataGrid/utils/getEmptyValue.d.ts.map +1 -0
  30. package/dist/components/DataGrid/utils/getEmptyValue.js +8 -0
  31. package/dist/components/DataGrid/utils/getEmptyValue.js.map +1 -0
  32. package/dist/components/DataGrid/utils/modelColsToGrid.d.ts.map +1 -1
  33. package/dist/components/DataGrid/utils/modelColsToGrid.js +2 -1
  34. package/dist/components/DataGrid/utils/modelColsToGrid.js.map +1 -1
  35. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts +32 -0
  36. package/dist/components/DataGrid/utils/schemaAwarePasteValue.d.ts.map +1 -0
  37. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js +22 -0
  38. package/dist/components/DataGrid/utils/schemaAwarePasteValue.js.map +1 -0
  39. package/dist/components/DownloadCart/DownloadCartPage.d.ts.map +1 -1
  40. package/dist/components/DownloadCart/DownloadCartPage.js +183 -185
  41. package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
  42. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.css +1 -0
  43. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.d.ts.map +1 -1
  44. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +199 -132
  45. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
  46. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js +22 -0
  47. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js.map +1 -0
  48. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.scss +170 -0
  49. package/dist/components/EntityAclEditor/EntityAclEditor.js +8 -8
  50. package/dist/components/EntityAclEditor/EntityAclEditor.js.map +1 -1
  51. package/dist/components/EntityAclEditor/InheritanceMessage.d.ts.map +1 -1
  52. package/dist/components/EntityAclEditor/InheritanceMessage.js +1 -2
  53. package/dist/components/EntityAclEditor/InheritanceMessage.js.map +1 -1
  54. package/dist/components/EntityDownloadButton/EntityDownloadButton.d.ts.map +1 -1
  55. package/dist/components/EntityDownloadButton/EntityDownloadButton.js +1 -0
  56. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  57. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.d.ts.map +1 -1
  58. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js +15 -14
  59. package/dist/components/EntityViewScopeEditor/EntityViewMaskEditor.js.map +1 -1
  60. package/dist/components/Forum/DiscussionReply.d.ts +1 -0
  61. package/dist/components/Forum/DiscussionReply.d.ts.map +1 -1
  62. package/dist/components/Forum/DiscussionReply.js +19 -19
  63. package/dist/components/Forum/DiscussionReply.js.map +1 -1
  64. package/dist/components/Forum/DiscussionThread.d.ts +1 -0
  65. package/dist/components/Forum/DiscussionThread.d.ts.map +1 -1
  66. package/dist/components/Forum/DiscussionThread.js +73 -72
  67. package/dist/components/Forum/DiscussionThread.js.map +1 -1
  68. package/dist/components/FullTextSearch/FullTextSearch.d.ts.map +1 -1
  69. package/dist/components/FullTextSearch/FullTextSearch.js +86 -47
  70. package/dist/components/FullTextSearch/FullTextSearch.js.map +1 -1
  71. package/dist/components/GenericCard/BioregistryRules.d.ts.map +1 -1
  72. package/dist/components/GenericCard/BioregistryRules.js +7 -3
  73. package/dist/components/GenericCard/BioregistryRules.js.map +1 -1
  74. package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
  75. package/dist/components/GenericCard/TableRowGenericCard.js +157 -157
  76. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  77. package/dist/components/HeaderCard.d.ts.map +1 -1
  78. package/dist/components/HeaderCard.js +131 -130
  79. package/dist/components/HeaderCard.js.map +1 -1
  80. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  81. package/dist/components/IconSvg/IconSvg.js +2 -1
  82. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  83. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts +4 -1
  84. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts.map +1 -1
  85. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js +3 -2
  86. package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js.map +1 -1
  87. package/dist/components/QueryContext/QueryContext.d.ts +6 -0
  88. package/dist/components/QueryContext/QueryContext.d.ts.map +1 -1
  89. package/dist/components/QueryContext/QueryContext.js.map +1 -1
  90. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.d.ts.map +1 -1
  91. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js +12 -11
  92. package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
  93. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +5 -0
  94. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
  95. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +32 -29
  96. package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
  97. package/dist/components/QueryWrapperPlotNav/UseRowSet.d.ts.map +1 -1
  98. package/dist/components/QueryWrapperPlotNav/UseRowSet.js +4 -1
  99. package/dist/components/QueryWrapperPlotNav/UseRowSet.js.map +1 -1
  100. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +59 -0
  101. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -0
  102. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +174 -0
  103. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -0
  104. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts +40 -0
  105. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts.map +1 -0
  106. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js +100 -0
  107. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js.map +1 -0
  108. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts +56 -0
  109. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts.map +1 -0
  110. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js +73 -0
  111. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js.map +1 -0
  112. package/dist/components/ShareThisPage/ShareThisPage.js +1 -1
  113. package/dist/components/ShareThisPage/ShareThisPage.js.map +1 -1
  114. package/dist/components/SynapseChat/GridAgentChat.d.ts.map +1 -1
  115. package/dist/components/SynapseChat/GridAgentChat.js +20 -14
  116. package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
  117. package/dist/components/SynapseChat/SynapseChat.d.ts +3 -1
  118. package/dist/components/SynapseChat/SynapseChat.d.ts.map +1 -1
  119. package/dist/components/SynapseChat/SynapseChat.js +51 -36
  120. package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
  121. package/dist/components/SynapseHomepageV2/HotdropsAndNews.css +1 -1
  122. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js +8 -7
  123. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js.map +1 -1
  124. package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.scss +16 -0
  125. package/dist/components/SynapseHomepageV2/WordPressNews.d.ts +3 -1
  126. package/dist/components/SynapseHomepageV2/WordPressNews.d.ts.map +1 -1
  127. package/dist/components/SynapseHomepageV2/WordPressNews.js +9 -8
  128. package/dist/components/SynapseHomepageV2/WordPressNews.js.map +1 -1
  129. package/dist/components/SynapseHomepageV2/WordPressNewsItem.d.ts +2 -1
  130. package/dist/components/SynapseHomepageV2/WordPressNewsItem.d.ts.map +1 -1
  131. package/dist/components/SynapseHomepageV2/WordPressNewsItem.js +2 -2
  132. package/dist/components/SynapseHomepageV2/WordPressNewsItem.js.map +1 -1
  133. package/dist/components/SynapseTable/SearchV2.d.ts +7 -0
  134. package/dist/components/SynapseTable/SearchV2.d.ts.map +1 -1
  135. package/dist/components/SynapseTable/SearchV2.js.map +1 -1
  136. package/dist/components/SynapseTable/SynapseTableRenderers.d.ts.map +1 -1
  137. package/dist/components/SynapseTable/SynapseTableRenderers.js +1 -1
  138. package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
  139. package/dist/components/SynapseTable/usePrefetchTableData.d.ts.map +1 -1
  140. package/dist/components/SynapseTable/usePrefetchTableData.js +6 -5
  141. package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
  142. package/dist/components/ToastMessage/ToastMessage.d.ts +1 -1
  143. package/dist/components/ToastMessage/ToastMessage.d.ts.map +1 -1
  144. package/dist/components/ToastMessage/ToastMessage.js +2 -2
  145. package/dist/components/ToastMessage/ToastMessage.js.map +1 -1
  146. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.d.ts.map +1 -1
  147. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +157 -148
  148. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js.map +1 -1
  149. package/dist/components/doi/CreateOrUpdateDoiModal.d.ts.map +1 -1
  150. package/dist/components/doi/CreateOrUpdateDoiModal.js +20 -19
  151. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  152. package/dist/components/error/ErrorPage.d.ts +0 -4
  153. package/dist/components/error/ErrorPage.d.ts.map +1 -1
  154. package/dist/components/error/ErrorPage.js +25 -30
  155. package/dist/components/error/ErrorPage.js.map +1 -1
  156. package/dist/components/index.d.ts +4 -0
  157. package/dist/components/index.d.ts.map +1 -1
  158. package/dist/components/index.js +41 -39
  159. package/dist/components/widgets/query-filter/FacetFilterControls.d.ts.map +1 -1
  160. package/dist/components/widgets/query-filter/FacetFilterControls.js +2 -2
  161. package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
  162. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts.map +1 -1
  163. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +1 -1
  164. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  165. package/dist/index.js +52 -50
  166. package/dist/index.js.map +1 -1
  167. package/dist/mocks/entity/index.d.ts.map +1 -1
  168. package/dist/mocks/entity/index.js +18 -16
  169. package/dist/mocks/entity/index.js.map +1 -1
  170. package/dist/mocks/mockSearchQueryData.d.ts +14 -0
  171. package/dist/mocks/mockSearchQueryData.d.ts.map +1 -0
  172. package/dist/mocks/mockSearchQueryData.js +564 -0
  173. package/dist/mocks/mockSearchQueryData.js.map +1 -0
  174. package/dist/mocks/msw/handlers/searchQueryHandlers.d.ts +22 -0
  175. package/dist/mocks/msw/handlers/searchQueryHandlers.d.ts.map +1 -0
  176. package/dist/mocks/msw/handlers/searchQueryHandlers.js +63 -0
  177. package/dist/mocks/msw/handlers/searchQueryHandlers.js.map +1 -0
  178. package/dist/mocks/msw/handlers.d.ts.map +1 -1
  179. package/dist/mocks/msw/handlers.js +9 -7
  180. package/dist/mocks/msw/handlers.js.map +1 -1
  181. package/dist/style/components/_cards.scss +15 -0
  182. package/dist/style/main.css +1 -1
  183. package/dist/synapse-client/SynapseClient.d.ts +7 -1
  184. package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
  185. package/dist/synapse-client/SynapseClient.js +422 -417
  186. package/dist/synapse-client/SynapseClient.js.map +1 -1
  187. package/dist/synapse-client/index.js +3 -3
  188. package/dist/synapse-queries/KeyFactory.d.ts +3 -0
  189. package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
  190. package/dist/synapse-queries/KeyFactory.js +6 -0
  191. package/dist/synapse-queries/KeyFactory.js.map +1 -1
  192. package/dist/synapse-queries/forum/useThread.d.ts +1 -0
  193. package/dist/synapse-queries/forum/useThread.d.ts.map +1 -1
  194. package/dist/synapse-queries/forum/useThread.js +19 -12
  195. package/dist/synapse-queries/forum/useThread.js.map +1 -1
  196. package/dist/tsconfig.build.tsbuildinfo +1 -1
  197. package/dist/utils/APIConstants.d.ts +3 -0
  198. package/dist/utils/APIConstants.d.ts.map +1 -1
  199. package/dist/utils/APIConstants.js +2 -2
  200. package/dist/utils/APIConstants.js.map +1 -1
  201. package/dist/utils/AppUtils/session/ApplicationSessionManager.d.ts.map +1 -1
  202. package/dist/utils/AppUtils/session/ApplicationSessionManager.js +7 -4
  203. package/dist/utils/AppUtils/session/ApplicationSessionManager.js.map +1 -1
  204. package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
  205. package/dist/utils/functions/EntityTypeUtils.js +15 -4
  206. package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
  207. package/dist/utils/functions/calculateFriendlyFileSize.d.ts.map +1 -1
  208. package/dist/utils/functions/calculateFriendlyFileSize.js +3 -3
  209. package/dist/utils/functions/calculateFriendlyFileSize.js.map +1 -1
  210. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"QueryWrapperPlotNav.js","names":[],"sources":["../../../src/components/QueryWrapperPlotNav/QueryWrapperPlotNav.tsx"],"sourcesContent":["import { QueryOrDeprecatedSearchParams } from '@/components/CardContainerLogic/CardContainerLogic'\nimport AddToDownloadListConfirmationAlert from '@/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert'\nimport { useGetAddToDownloadListRequestForCurrentQuery } from '@/components/QueryWrapper/useGetAddToDownloadListRequestForCurrentQuery'\nimport { NoContentPlaceholderType } from '@/components/SynapseTable/NoContentPlaceholderType'\nimport { useGetEntity } from '@/synapse-queries'\nimport { SynapseConstants } from '@/utils'\nimport {\n getAdditionalFilters,\n parseEntityIdAndVersionFromSqlStatement,\n} from '@/utils/functions'\nimport { isTable } from '@/utils/functions/EntityTypeUtils'\nimport { DEFAULT_PAGE_SIZE } from '@/utils/SynapseConstants'\nimport { Box } from '@mui/material'\nimport { Query, QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport { useQuery } from '@tanstack/react-query'\nimport { useAtomValue } from 'jotai'\nimport { Suspense, useMemo, useState } from 'react'\nimport { CardConfiguration } from '../CardContainer/CardConfiguration'\nimport { SynapseErrorBoundary } from '../error'\nimport FullTextSearch from '../FullTextSearch/FullTextSearch'\nimport ModalDownload from '../ModalDownload/ModalDownload'\nimport { QueryWrapperPlotNavCustomPlotParams } from '../Plot/SynapsePlot'\nimport { QueryContextType, useQueryContext } from '../QueryContext'\nimport {\n QueryVisualizationContextConsumer,\n QueryVisualizationWrapper,\n QueryVisualizationWrapperProps,\n} from '../QueryVisualizationWrapper'\nimport { QueryWrapper, QueryWrapperProps } from '../QueryWrapper'\nimport { isRowSelectionVisibleAtom } from '../QueryWrapper/TableRowSelectionState'\nimport { QueryWrapperErrorBoundary } from '../QueryWrapperErrorBoundary'\nimport { SynapseTableConfiguration } from '../SynapseTable'\nimport SearchV2, { SearchV2Props } from '../SynapseTable/SearchV2'\nimport SqlEditor from '../SynapseTable/SqlEditor'\nimport TopLevelControls, {\n TopLevelControlsProps,\n CustomControl,\n} from '../SynapseTable/TopLevelControls/TopLevelControls'\nimport { CustomControls } from '../SynapseTable/CustomControls/CustomControls'\nimport TotalQueryResults from '../TotalQueryResults'\nimport PlotsContainer, {\n PlotsContainerProps,\n} from '../widgets/facet-nav/PlotsContainer'\nimport FacetFilterControls, {\n FacetFilterControlsProps,\n} from '../widgets/query-filter/FacetFilterControls'\nimport { QueryWrapperSynapsePlotProps } from './QueryWrapperSynapsePlot'\nimport { RowSetView } from './RowSetView'\nimport QueryWrapperLoadingScreen from '../QueryWrapper/QueryWrapperLoadingScreen'\n\nexport const QUERY_FILTERS_EXPANDED_CSS: string = 'isShowingFacetFilters'\nexport const QUERY_FILTERS_COLLAPSED_CSS: string = 'isHidingFacetFilters'\n\nexport const HAS_SELECTED_ROWS_CSS: string = 'hasSelectedRows'\n\ntype QueryWrapperPlotNavOwnProps = {\n /** Whether the displayed results should be paginated or infinite. Default for cards is true, default for table is false */\n isInfinite?: boolean\n /** Set to true when you want the query to be saved in the URL search parameters. If you are controlling the view (such as in PortalSearch), you'll want to set this to false */\n shouldDeepLink?: boolean\n /** If onQueryChange is set, the callback will be invoked when the Query changes */\n onQueryChange?: (newQueryJson: string) => void\n /** If onQueryResultBundleChange is set, the callback will be invoked when the QueryResultBundle changes */\n onQueryResultBundleChange?: (newQueryResultBundleJson: string) => void\n /** If initQueryJson is set, it will be the Query used in the initial QueryBundleRequest */\n initQueryJson?: string\n tableConfiguration?: SynapseTableConfiguration\n cardConfiguration?: CardConfiguration\n searchConfiguration?: Omit<\n SearchV2Props,\n 'queryContext' | 'queryVisualizationContext'\n >\n facetsToPlot?: string[]\n availableFacets?: FacetFilterControlsProps['availableFacets']\n initialExpandedFacetControls?: FacetFilterControlsProps['initialExpandedFacetControls']\n customPlots?: QueryWrapperSynapsePlotProps[]\n customControls?: CustomControl[]\n defaultColumn?: string\n defaultShowSearchBox?: boolean\n lockedColumn?: QueryWrapperProps['lockedColumn']\n onViewSharingSettingsClicked?: (benefactorId: string) => void\n initialLimit?: number\n hideTopLevelControls?: boolean\n} & Omit<TopLevelControlsProps, 'entityId'> &\n Pick<QueryWrapperPlotNavCustomPlotParams, 'onCustomPlotClick'> &\n Pick<\n QueryWrapperProps,\n | 'isRowSelectionVisible'\n | 'rowSelectionPrimaryKey'\n | 'isRowSelectionUIFloating'\n | 'fileIdColumnName'\n | 'fileNameColumnName'\n | 'fileVersionColumnName'\n > &\n Pick<\n QueryVisualizationWrapperProps,\n | 'defaultShowPlots'\n | 'visibleColumnCount'\n | 'columnAliases'\n | 'rgbIndex'\n | 'showLastUpdatedOn'\n | 'noContentPlaceholderType'\n | 'unitDescription'\n | 'additionalFiltersSessionStorageKey'\n | 'helpConfiguration'\n | 'hideCopyToClipboard'\n | 'hideSearchBarControl'\n | 'hideVisualizationsControl'\n | 'enabledExternalAnalysisPlatforms'\n > &\n Pick<QueryContextType, 'combineRangeFacetConfig'>\n\nexport type QueryWrapperPlotNavProps = QueryOrDeprecatedSearchParams &\n PlotsContainerProps &\n QueryWrapperPlotNavOwnProps\n\ntype QueryWrapperPlotNavContentsProps = Pick<\n QueryWrapperPlotNavProps,\n | 'tableConfiguration'\n | 'name'\n | 'cardConfiguration'\n | 'facetsToPlot'\n | 'availableFacets'\n | 'initialExpandedFacetControls'\n | 'hideDownload'\n | 'hideQueryCount'\n | 'hideSqlEditorControl'\n | 'hideVisualizationsControl'\n | 'searchConfiguration'\n | 'enabledExternalAnalysisPlatforms'\n | 'cavaticaConnectAccountURL'\n | 'customControls'\n | 'customPlots'\n | 'fileIdColumnName'\n | 'fileNameColumnName'\n | 'fileVersionColumnName'\n | 'initialLimit'\n | 'initialPlotTypeByFacetColumnName'\n | 'hideTopLevelControls'\n> & {\n isFullTextSearchEnabled: boolean\n remount: () => void\n}\n\nfunction QueryWrapperPlotNavContents(props: QueryWrapperPlotNavContentsProps) {\n const {\n tableConfiguration,\n name,\n cardConfiguration,\n facetsToPlot,\n availableFacets,\n initialExpandedFacetControls,\n hideDownload,\n hideQueryCount,\n hideSqlEditorControl,\n hideVisualizationsControl,\n searchConfiguration,\n cavaticaConnectAccountURL,\n customControls,\n remount,\n isFullTextSearchEnabled,\n customPlots,\n initialLimit,\n initialPlotTypeByFacetColumnName,\n hideTopLevelControls,\n } = props\n const queryContext = useQueryContext()\n const [showExportMetadata, setShowExportMetadata] = useState(false)\n const { hasFacetedSelectColumn: isFaceted, queryMetadataQueryOptions } =\n queryContext\n const { isLoading: isLoadingQueryMetadata } = useQuery(\n queryMetadataQueryOptions,\n )\n\n const isRowSelectionVisible = useAtomValue(isRowSelectionVisibleAtom)\n\n const currentQueryRequest = queryContext.currentQueryRequest\n\n const hasFacetsOrFilters =\n (currentQueryRequest?.query.selectedFacets !== undefined &&\n currentQueryRequest.query.selectedFacets.length > 0) ||\n (currentQueryRequest?.query.additionalFilters !== undefined &&\n currentQueryRequest?.query.additionalFilters.length > 0)\n\n const addToDownloadListRequest =\n useGetAddToDownloadListRequestForCurrentQuery()\n\n return (\n <QueryVisualizationContextConsumer>\n {queryVisualizationContext => {\n if (queryVisualizationContext === undefined) {\n throw new Error(\n 'No queryVisualizationContext found when using QueryVisualizationContextConsumer',\n )\n }\n\n return (\n <Box\n className={`QueryWrapperPlotNav ${\n queryVisualizationContext.showFacetFilter\n ? QUERY_FILTERS_EXPANDED_CSS\n : QUERY_FILTERS_COLLAPSED_CSS\n } ${isRowSelectionVisible ? HAS_SELECTED_ROWS_CSS : ''} ${\n hideTopLevelControls ? 'isHidingTopLevelControls' : ''\n }`}\n sx={{\n '*': {\n cursor: isLoadingQueryMetadata ? 'wait' : undefined,\n },\n }}\n >\n <QueryWrapperErrorBoundary>\n {isFullTextSearchEnabled ? (\n <FullTextSearch ftsConfig={searchConfiguration?.ftsConfig} />\n ) : (\n <SearchV2\n {...searchConfiguration}\n queryContext={queryContext}\n queryVisualizationContext={queryVisualizationContext}\n />\n )}\n <SqlEditor />\n {queryVisualizationContext.showDownloadConfirmation && (\n <AddToDownloadListConfirmationAlert\n addToDownloadListRequest={addToDownloadListRequest}\n onClose={() =>\n queryVisualizationContext.setShowDownloadConfirmation(false)\n }\n />\n )}\n {!hideTopLevelControls && (\n <SynapseErrorBoundary>\n <TopLevelControls\n showColumnSelection={tableConfiguration !== undefined}\n name={name}\n hideDownload={hideDownload}\n hideQueryCount={hideQueryCount}\n hideFacetFilterControl={!isFaceted}\n hideVisualizationsControl={\n !isFaceted || hideVisualizationsControl\n }\n hideSqlEditorControl={hideSqlEditorControl}\n cavaticaConnectAccountURL={cavaticaConnectAccountURL}\n remount={remount}\n customControls={customControls}\n />\n </SynapseErrorBoundary>\n )}\n {isFaceted && (\n <>\n <FacetFilterControls\n availableFacets={availableFacets}\n initialExpandedFacetControls={initialExpandedFacetControls}\n />\n </>\n )}\n <TotalQueryResults\n frontText={''}\n endText={hasFacetsOrFilters ? 'filtered by' : ''}\n hideIfUnfiltered={true}\n />\n <CustomControls\n customControls={customControls}\n remount={remount}\n />\n <PlotsContainer\n facetsToPlot={facetsToPlot}\n customPlots={customPlots}\n initialPlotTypeByFacetColumnName={\n initialPlotTypeByFacetColumnName\n }\n />\n <RowSetView\n tableConfiguration={tableConfiguration}\n hideDownload={hideDownload}\n cardConfiguration={cardConfiguration}\n initialLimit={initialLimit}\n />\n {showExportMetadata && (\n <ModalDownload\n getLastQueryRequest={queryContext?.getCurrentQueryRequest}\n onClose={() => setShowExportMetadata(false)}\n />\n )}\n </QueryWrapperErrorBoundary>\n </Box>\n )\n }}\n </QueryVisualizationContextConsumer>\n )\n}\n\nexport default function QueryWrapperPlotNav(props: QueryWrapperPlotNavProps) {\n const {\n sql: deprecatedSql,\n tableConfiguration,\n isInfinite = !tableConfiguration,\n limit = DEFAULT_PAGE_SIZE,\n showLastUpdatedOn,\n unitDescription,\n additionalFiltersSessionStorageKey,\n helpConfiguration,\n customPlots,\n enabledExternalAnalysisPlatforms,\n } = props\n\n const sql = props.query?.sql ?? deprecatedSql ?? ''\n const { entityId, versionNumber } =\n parseEntityIdAndVersionFromSqlStatement(sql)\n\n const query: Query = useMemo(() => {\n if (props.query) {\n // use query if set\n return props.query\n } else if (props.initQueryJson) {\n // Otherwise use initQueryJson\n return JSON.parse(props.initQueryJson) as Query\n } else {\n // use the deprecated sql, searchParams, and sqlOperator\n const additionalFilters = getAdditionalFilters(\n props.searchParams,\n props.sqlOperator,\n additionalFiltersSessionStorageKey,\n )\n return {\n sql: deprecatedSql!,\n additionalFilters,\n limit: limit,\n offset: 0,\n }\n }\n }, [\n props.query,\n props.initQueryJson,\n props.searchParams,\n props.sqlOperator,\n additionalFiltersSessionStorageKey,\n deprecatedSql,\n limit,\n ])\n\n const [componentKey, setComponentKey] = useState(1)\n const remount = () => {\n setComponentKey(componentKey + 1)\n }\n\n const { data: entity } = useGetEntity(entityId, versionNumber)\n const initQueryRequest: QueryBundleRequest = {\n entityId: entityId ?? '',\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n partMask:\n SynapseConstants.BUNDLE_MASK_QUERY_RESULTS |\n SynapseConstants.BUNDLE_MASK_QUERY_COUNT |\n SynapseConstants.BUNDLE_MASK_QUERY_SELECT_COLUMNS |\n SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE |\n SynapseConstants.BUNDLE_MASK_QUERY_COLUMN_MODELS |\n SynapseConstants.BUNDLE_MASK_QUERY_FACETS |\n SynapseConstants.BUNDLE_MASK_SUM_FILES_SIZE_BYTES |\n SynapseConstants.BUNDLE_MASK_LAST_UPDATED_ON,\n query,\n }\n const isFullTextSearchEnabled =\n (entity && isTable(entity) && entity.isSearchEnabled) ?? false\n\n /**\n * Fully re-render the uncontrolled QueryWrapper component when the initial query changes. This eliminates a class of\n * bugs where our 'derived' state (the current query), which should be reset, is out of sync with props.\n *\n * See https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key\n */\n const queryWrapperKey = `${JSON.stringify(initQueryRequest)}-${componentKey}`\n\n return (\n <QueryWrapper\n {...props}\n initQueryRequest={initQueryRequest}\n key={queryWrapperKey}\n isInfinite={isInfinite}\n >\n <Suspense fallback={<QueryWrapperLoadingScreen />}>\n <QueryVisualizationWrapper\n unitDescription={unitDescription}\n rgbIndex={props.rgbIndex}\n columnAliases={props.columnAliases}\n helpConfiguration={helpConfiguration}\n visibleColumnCount={props.visibleColumnCount}\n defaultShowPlots={props.defaultShowPlots}\n hideCopyToClipboard={props.hideCopyToClipboard}\n defaultShowSearchBar={\n (props.defaultShowSearchBox || isFullTextSearchEnabled) &&\n !props.hideSearchBarControl\n }\n hideSearchBarControl={props.hideSearchBarControl}\n showLastUpdatedOn={showLastUpdatedOn}\n noContentPlaceholderType={NoContentPlaceholderType.INTERACTIVE}\n hasCustomPlots={Array.isArray(customPlots) && customPlots.length > 0}\n enabledExternalAnalysisPlatforms={enabledExternalAnalysisPlatforms}\n >\n <QueryWrapperPlotNavContents\n {...props}\n isFullTextSearchEnabled={isFullTextSearchEnabled}\n remount={remount}\n />\n </QueryVisualizationWrapper>\n </Suspense>\n </QueryWrapper>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"QueryWrapperPlotNav.js","names":[],"sources":["../../../src/components/QueryWrapperPlotNav/QueryWrapperPlotNav.tsx"],"sourcesContent":["import { QueryOrDeprecatedSearchParams } from '@/components/CardContainerLogic/CardContainerLogic'\nimport AddToDownloadListConfirmationAlert from '@/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert'\nimport { useGetAddToDownloadListRequestForCurrentQuery } from '@/components/QueryWrapper/useGetAddToDownloadListRequestForCurrentQuery'\nimport { NoContentPlaceholderType } from '@/components/SynapseTable/NoContentPlaceholderType'\nimport { useGetEntity } from '@/synapse-queries'\nimport { SynapseConstants } from '@/utils'\nimport {\n getAdditionalFilters,\n parseEntityIdAndVersionFromSqlStatement,\n} from '@/utils/functions'\nimport { isTable } from '@/utils/functions/EntityTypeUtils'\nimport { DEFAULT_PAGE_SIZE } from '@/utils/SynapseConstants'\nimport { Box } from '@mui/material'\nimport { Query, QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport { useQuery } from '@tanstack/react-query'\nimport { useAtomValue } from 'jotai'\nimport { Suspense, useMemo, useState } from 'react'\nimport { CardConfiguration } from '../CardContainer/CardConfiguration'\nimport { SynapseErrorBoundary } from '../error'\nimport FullTextSearch from '../FullTextSearch/FullTextSearch'\nimport ModalDownload from '../ModalDownload/ModalDownload'\nimport { QueryWrapperPlotNavCustomPlotParams } from '../Plot/SynapsePlot'\nimport { QueryContextType, useQueryContext } from '../QueryContext'\nimport {\n QueryVisualizationContextConsumer,\n QueryVisualizationWrapper,\n QueryVisualizationWrapperProps,\n} from '../QueryVisualizationWrapper'\nimport { QueryWrapper, QueryWrapperProps } from '../QueryWrapper'\nimport { isRowSelectionVisibleAtom } from '../QueryWrapper/TableRowSelectionState'\nimport { QueryWrapperErrorBoundary } from '../QueryWrapperErrorBoundary'\nimport { SynapseTableConfiguration } from '../SynapseTable'\nimport SearchV2, { SearchV2Props } from '../SynapseTable/SearchV2'\nimport SqlEditor from '../SynapseTable/SqlEditor'\nimport TopLevelControls, {\n TopLevelControlsProps,\n CustomControl,\n} from '../SynapseTable/TopLevelControls/TopLevelControls'\nimport { CustomControls } from '../SynapseTable/CustomControls/CustomControls'\nimport TotalQueryResults from '../TotalQueryResults'\nimport PlotsContainer, {\n PlotsContainerProps,\n} from '../widgets/facet-nav/PlotsContainer'\nimport FacetFilterControls, {\n FacetFilterControlsProps,\n} from '../widgets/query-filter/FacetFilterControls'\nimport { QueryWrapperSynapsePlotProps } from './QueryWrapperSynapsePlot'\nimport { RowSetView } from './RowSetView'\nimport QueryWrapperLoadingScreen from '../QueryWrapper/QueryWrapperLoadingScreen'\n\nexport const QUERY_FILTERS_EXPANDED_CSS: string = 'isShowingFacetFilters'\nexport const QUERY_FILTERS_COLLAPSED_CSS: string = 'isHidingFacetFilters'\n\nexport const HAS_SELECTED_ROWS_CSS: string = 'hasSelectedRows'\n\ntype QueryWrapperPlotNavOwnProps = {\n /** Whether the displayed results should be paginated or infinite. Default for cards is true, default for table is false */\n isInfinite?: boolean\n /** Set to true when you want the query to be saved in the URL search parameters. If you are controlling the view (such as in PortalSearch), you'll want to set this to false */\n shouldDeepLink?: boolean\n /** If onQueryChange is set, the callback will be invoked when the Query changes */\n onQueryChange?: (newQueryJson: string) => void\n /** If onQueryResultBundleChange is set, the callback will be invoked when the QueryResultBundle changes */\n onQueryResultBundleChange?: (newQueryResultBundleJson: string) => void\n /** If initQueryJson is set, it will be the Query used in the initial QueryBundleRequest */\n initQueryJson?: string\n tableConfiguration?: SynapseTableConfiguration\n cardConfiguration?: CardConfiguration\n searchConfiguration?: Omit<\n SearchV2Props,\n 'queryContext' | 'queryVisualizationContext'\n >\n facetsToPlot?: string[]\n availableFacets?: FacetFilterControlsProps['availableFacets']\n initialExpandedFacetControls?: FacetFilterControlsProps['initialExpandedFacetControls']\n customPlots?: QueryWrapperSynapsePlotProps[]\n customControls?: CustomControl[]\n defaultColumn?: string\n defaultShowSearchBox?: boolean\n lockedColumn?: QueryWrapperProps['lockedColumn']\n onViewSharingSettingsClicked?: (benefactorId: string) => void\n initialLimit?: number\n hideTopLevelControls?: boolean\n} & Omit<TopLevelControlsProps, 'entityId'> &\n Pick<QueryWrapperPlotNavCustomPlotParams, 'onCustomPlotClick'> &\n Pick<\n QueryWrapperProps,\n | 'isRowSelectionVisible'\n | 'rowSelectionPrimaryKey'\n | 'isRowSelectionUIFloating'\n | 'fileIdColumnName'\n | 'fileNameColumnName'\n | 'fileVersionColumnName'\n > &\n Pick<\n QueryVisualizationWrapperProps,\n | 'defaultShowPlots'\n | 'visibleColumnCount'\n | 'columnAliases'\n | 'rgbIndex'\n | 'showLastUpdatedOn'\n | 'noContentPlaceholderType'\n | 'unitDescription'\n | 'additionalFiltersSessionStorageKey'\n | 'helpConfiguration'\n | 'hideCopyToClipboard'\n | 'hideSearchBarControl'\n | 'hideVisualizationsControl'\n | 'enabledExternalAnalysisPlatforms'\n > &\n Pick<QueryContextType, 'combineRangeFacetConfig'>\n\nexport type QueryWrapperPlotNavProps = QueryOrDeprecatedSearchParams &\n PlotsContainerProps &\n QueryWrapperPlotNavOwnProps\n\nexport type QueryWrapperPlotNavContentsProps = Pick<\n QueryWrapperPlotNavProps,\n | 'tableConfiguration'\n | 'name'\n | 'cardConfiguration'\n | 'facetsToPlot'\n | 'availableFacets'\n | 'initialExpandedFacetControls'\n | 'hideDownload'\n | 'hideQueryCount'\n | 'hideSqlEditorControl'\n | 'hideVisualizationsControl'\n | 'searchConfiguration'\n | 'enabledExternalAnalysisPlatforms'\n | 'cavaticaConnectAccountURL'\n | 'customControls'\n | 'customPlots'\n | 'fileIdColumnName'\n | 'fileNameColumnName'\n | 'fileVersionColumnName'\n | 'initialLimit'\n | 'initialPlotTypeByFacetColumnName'\n | 'hideTopLevelControls'\n> & {\n isFullTextSearchEnabled: boolean\n remount?: () => void\n}\n\nexport function QueryWrapperPlotNavContents(\n props: QueryWrapperPlotNavContentsProps,\n) {\n const {\n tableConfiguration,\n name,\n cardConfiguration,\n facetsToPlot,\n availableFacets,\n initialExpandedFacetControls,\n hideDownload,\n hideQueryCount,\n hideSqlEditorControl,\n hideVisualizationsControl,\n searchConfiguration,\n cavaticaConnectAccountURL,\n customControls,\n remount = () => {},\n isFullTextSearchEnabled,\n customPlots,\n initialLimit,\n initialPlotTypeByFacetColumnName,\n hideTopLevelControls,\n } = props\n const queryContext = useQueryContext()\n const [showExportMetadata, setShowExportMetadata] = useState(false)\n const { hasFacetedSelectColumn: isFaceted, queryMetadataQueryOptions } =\n queryContext\n const { isLoading: isLoadingQueryMetadata } = useQuery(\n queryMetadataQueryOptions,\n )\n\n const isRowSelectionVisible = useAtomValue(isRowSelectionVisibleAtom)\n\n const currentQueryRequest = queryContext.currentQueryRequest\n\n const hasFacetsOrFilters =\n (currentQueryRequest?.query.selectedFacets !== undefined &&\n currentQueryRequest.query.selectedFacets.length > 0) ||\n (currentQueryRequest?.query.additionalFilters !== undefined &&\n currentQueryRequest?.query.additionalFilters.length > 0)\n\n const addToDownloadListRequest =\n useGetAddToDownloadListRequestForCurrentQuery()\n\n return (\n <QueryVisualizationContextConsumer>\n {queryVisualizationContext => {\n if (queryVisualizationContext === undefined) {\n throw new Error(\n 'No queryVisualizationContext found when using QueryVisualizationContextConsumer',\n )\n }\n\n return (\n <Box\n className={`QueryWrapperPlotNav ${\n queryVisualizationContext.showFacetFilter\n ? QUERY_FILTERS_EXPANDED_CSS\n : QUERY_FILTERS_COLLAPSED_CSS\n } ${isRowSelectionVisible ? HAS_SELECTED_ROWS_CSS : ''} ${\n hideTopLevelControls ? 'isHidingTopLevelControls' : ''\n }`}\n sx={{\n '*': {\n cursor: isLoadingQueryMetadata ? 'wait' : undefined,\n },\n }}\n >\n <QueryWrapperErrorBoundary>\n {isFullTextSearchEnabled ? (\n <FullTextSearch ftsConfig={searchConfiguration?.ftsConfig} />\n ) : (\n <SearchV2\n {...searchConfiguration}\n queryContext={queryContext}\n queryVisualizationContext={queryVisualizationContext}\n />\n )}\n <SqlEditor />\n {queryVisualizationContext.showDownloadConfirmation && (\n <AddToDownloadListConfirmationAlert\n addToDownloadListRequest={addToDownloadListRequest}\n onClose={() =>\n queryVisualizationContext.setShowDownloadConfirmation(false)\n }\n />\n )}\n {!hideTopLevelControls && (\n <SynapseErrorBoundary>\n <TopLevelControls\n showColumnSelection={tableConfiguration !== undefined}\n name={name}\n hideDownload={hideDownload}\n hideQueryCount={hideQueryCount}\n hideFacetFilterControl={!isFaceted}\n hideVisualizationsControl={\n !isFaceted || hideVisualizationsControl\n }\n hideSqlEditorControl={hideSqlEditorControl}\n cavaticaConnectAccountURL={cavaticaConnectAccountURL}\n remount={remount}\n customControls={customControls}\n />\n </SynapseErrorBoundary>\n )}\n {isFaceted && (\n <>\n <FacetFilterControls\n availableFacets={availableFacets}\n initialExpandedFacetControls={initialExpandedFacetControls}\n />\n </>\n )}\n {/* Isolated Suspense so that metadata loading does not hide the table */}\n <Suspense fallback={null}>\n <TotalQueryResults\n frontText={''}\n endText={hasFacetsOrFilters ? 'filtered by' : ''}\n hideIfUnfiltered={true}\n />\n </Suspense>\n <CustomControls\n customControls={customControls}\n remount={remount}\n />\n <PlotsContainer\n facetsToPlot={facetsToPlot}\n customPlots={customPlots}\n initialPlotTypeByFacetColumnName={\n initialPlotTypeByFacetColumnName\n }\n />\n <RowSetView\n tableConfiguration={tableConfiguration}\n hideDownload={hideDownload}\n cardConfiguration={cardConfiguration}\n initialLimit={initialLimit}\n />\n {showExportMetadata && (\n <ModalDownload\n getLastQueryRequest={queryContext?.getCurrentQueryRequest}\n onClose={() => setShowExportMetadata(false)}\n />\n )}\n </QueryWrapperErrorBoundary>\n </Box>\n )\n }}\n </QueryVisualizationContextConsumer>\n )\n}\n\nexport default function QueryWrapperPlotNav(props: QueryWrapperPlotNavProps) {\n const {\n sql: deprecatedSql,\n tableConfiguration,\n isInfinite = !tableConfiguration,\n limit = DEFAULT_PAGE_SIZE,\n showLastUpdatedOn,\n unitDescription,\n additionalFiltersSessionStorageKey,\n helpConfiguration,\n customPlots,\n enabledExternalAnalysisPlatforms,\n } = props\n\n const sql = props.query?.sql ?? deprecatedSql ?? ''\n const { entityId, versionNumber } =\n parseEntityIdAndVersionFromSqlStatement(sql)\n\n const query: Query = useMemo(() => {\n if (props.query) {\n // use query if set\n return props.query\n } else if (props.initQueryJson) {\n // Otherwise use initQueryJson\n return JSON.parse(props.initQueryJson) as Query\n } else {\n // use the deprecated sql, searchParams, and sqlOperator\n const additionalFilters = getAdditionalFilters(\n props.searchParams,\n props.sqlOperator,\n additionalFiltersSessionStorageKey,\n )\n return {\n sql: deprecatedSql!,\n additionalFilters,\n limit: limit,\n offset: 0,\n }\n }\n }, [\n props.query,\n props.initQueryJson,\n props.searchParams,\n props.sqlOperator,\n additionalFiltersSessionStorageKey,\n deprecatedSql,\n limit,\n ])\n\n const [componentKey, setComponentKey] = useState(1)\n const remount = () => {\n setComponentKey(componentKey + 1)\n }\n\n const { data: entity } = useGetEntity(entityId, versionNumber)\n const initQueryRequest: QueryBundleRequest = {\n entityId: entityId ?? '',\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n partMask:\n SynapseConstants.BUNDLE_MASK_QUERY_RESULTS |\n SynapseConstants.BUNDLE_MASK_QUERY_COUNT |\n SynapseConstants.BUNDLE_MASK_QUERY_SELECT_COLUMNS |\n SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE |\n SynapseConstants.BUNDLE_MASK_QUERY_COLUMN_MODELS |\n SynapseConstants.BUNDLE_MASK_QUERY_FACETS |\n SynapseConstants.BUNDLE_MASK_SUM_FILES_SIZE_BYTES |\n SynapseConstants.BUNDLE_MASK_LAST_UPDATED_ON,\n query,\n }\n const isFullTextSearchEnabled =\n (entity && isTable(entity) && entity.isSearchEnabled) ?? false\n\n /**\n * Fully re-render the uncontrolled QueryWrapper component when the initial query changes. This eliminates a class of\n * bugs where our 'derived' state (the current query), which should be reset, is out of sync with props.\n *\n * See https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key\n */\n const queryWrapperKey = `${JSON.stringify(initQueryRequest)}-${componentKey}`\n\n return (\n <QueryWrapper\n {...props}\n initQueryRequest={initQueryRequest}\n key={queryWrapperKey}\n isInfinite={isInfinite}\n >\n <Suspense fallback={<QueryWrapperLoadingScreen />}>\n <QueryVisualizationWrapper\n unitDescription={unitDescription}\n rgbIndex={props.rgbIndex}\n columnAliases={props.columnAliases}\n helpConfiguration={helpConfiguration}\n visibleColumnCount={props.visibleColumnCount}\n defaultShowPlots={props.defaultShowPlots}\n hideCopyToClipboard={props.hideCopyToClipboard}\n defaultShowSearchBar={\n (props.defaultShowSearchBox || isFullTextSearchEnabled) &&\n !props.hideSearchBarControl\n }\n hideSearchBarControl={props.hideSearchBarControl}\n showLastUpdatedOn={showLastUpdatedOn}\n noContentPlaceholderType={NoContentPlaceholderType.INTERACTIVE}\n hasCustomPlots={Array.isArray(customPlots) && customPlots.length > 0}\n enabledExternalAnalysisPlatforms={enabledExternalAnalysisPlatforms}\n >\n <QueryWrapperPlotNavContents\n {...props}\n isFullTextSearchEnabled={isFullTextSearchEnabled}\n remount={remount}\n />\n </QueryVisualizationWrapper>\n </Suspense>\n </QueryWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,IAAa,IAAqC,yBACrC,IAAsC,wBAEtC,IAAgC;AA2F7C,SAAgB,EACd,GACA;CACA,IAAM,EACJ,uBACA,SACA,sBACA,iBACA,oBACA,iCACA,iBACA,mBACA,yBACA,8BACA,wBACA,8BACA,mBACA,mBAAgB,IAChB,4BACA,iBACA,iBACA,qCACA,4BACE,GACE,IAAe,GAAiB,EAChC,CAAC,GAAoB,KAAyB,EAAS,GAAM,EAC7D,EAAE,wBAAwB,GAAW,iCACzC,GACI,EAAE,WAAW,MAA2B,EAC5C,EACD,EAEK,KAAwB,EAAa,EAA0B,EAE/D,IAAsB,EAAa,qBAEnC,KACH,GAAqB,MAAM,mBAAmB,KAAA,KAC7C,EAAoB,MAAM,eAAe,SAAS,KACnD,GAAqB,MAAM,sBAAsB,KAAA,KAChD,GAAqB,MAAM,kBAAkB,SAAS,GAEpD,KACJ,GAA+C;AAEjD,QACE,kBAAC,GAAD,EAAA,WACG,MAA6B;AAC5B,MAAI,MAA8B,KAAA,EAChC,OAAU,MACR,kFACD;AAGH,SACE,kBAAC,GAAD;GACE,WAAW,uBACT,EAA0B,kBACtB,IACA,EACL,GAAG,KAAwB,IAAwB,GAAG,GACrD,IAAuB,6BAA6B;GAEtD,IAAI,EACF,KAAK,EACH,QAAQ,IAAyB,SAAS,KAAA,GAC3C,EACF;aAED,kBAAC,GAAD,EAAA,UAAA;IACG,IACC,kBAAC,GAAD,EAAgB,WAAW,GAAqB,WAAa,CAAA,GAE7D,kBAAC,GAAD;KACE,GAAI;KACU;KACa;KAC3B,CAAA;IAEJ,kBAAC,GAAD,EAAa,CAAA;IACZ,EAA0B,4BACzB,kBAAC,GAAD;KAC4B;KAC1B,eACE,EAA0B,4BAA4B,GAAM;KAE9D,CAAA;IAEH,CAAC,KACA,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;KACE,qBAAqB,MAAuB,KAAA;KACtC;KACQ;KACE;KAChB,wBAAwB,CAAC;KACzB,2BACE,CAAC,KAAa;KAEM;KACK;KAClB;KACO;KAChB,CAAA,EACmB,CAAA;IAExB,KACC,kBAAA,GAAA,EAAA,UACE,kBAAC,GAAD;KACmB;KACa;KAC9B,CAAA,EACD,CAAA;IAGL,kBAAC,GAAD;KAAU,UAAU;eAClB,kBAAC,GAAD;MACE,WAAW;MACX,SAAS,KAAqB,gBAAgB;MAC9C,kBAAkB;MAClB,CAAA;KACO,CAAA;IACX,kBAAC,GAAD;KACkB;KACP;KACT,CAAA;IACF,kBAAC,GAAD;KACgB;KACD;KAEX;KAEF,CAAA;IACF,kBAAC,GAAD;KACsB;KACN;KACK;KACL;KACd,CAAA;IACD,KACC,kBAAC,GAAD;KACE,qBAAqB,GAAc;KACnC,eAAe,EAAsB,GAAM;KAC3C,CAAA;IAEsB,EAAA,CAAA;GACxB,CAAA;IAGwB,CAAA;;AAIxC,SAAwB,EAAoB,GAAiC;CAC3E,IAAM,EACJ,KAAK,GACL,uBACA,gBAAa,CAAC,GACd,WAAA,IACA,sBACA,oBACA,uCACA,sBACA,gBACA,wCACE,GAGE,EAAE,aAAU,qBAChB,EAFU,EAAM,OAAO,OAAO,KAAiB,GAEH,EAExC,IAAe,QACf,EAAM,QAED,EAAM,QACJ,EAAM,gBAER,KAAK,MAAM,EAAM,cAAc,GAQ/B;EACL,KAAK;EACL,mBAPwB,EACxB,EAAM,cACN,EAAM,aACN,EAIA;EACO;EACP,QAAQ;EACT,EAEF;EACD,EAAM;EACN,EAAM;EACN,EAAM;EACN,EAAM;EACN;EACA;EACA;EACD,CAAC,EAEI,CAAC,GAAc,KAAmB,EAAS,EAAE,EAC7C,UAAgB;AACpB,IAAgB,IAAe,EAAE;IAG7B,EAAE,MAAM,MAAW,EAAa,GAAU,EAAc,EACxD,IAAuC;EAC3C,UAAU,KAAY;EACtB,cAAc;EACd,UACE;EAQF;EACD,EACK,KACH,KAAU,EAAQ,EAAO,IAAI,EAAO,oBAAoB,IAQrD,IAAkB,GAAG,KAAK,UAAU,EAAiB,CAAC,GAAG;AAE/D,QACE,kBAAC,GAAD;EACE,GAAI;EACc;EAClB,KAAK;EACO;EA4BC,EA1Bb,kBAAC,GAAD;EAAU,UAAU,kBAAC,GAAD,EAA6B,CAAA;YAC/C,kBAAC,GAAD;GACmB;GACjB,UAAU,EAAM;GAChB,eAAe,EAAM;GACF;GACnB,oBAAoB,EAAM;GAC1B,kBAAkB,EAAM;GACxB,qBAAqB,EAAM;GAC3B,uBACG,EAAM,wBAAwB,MAC/B,CAAC,EAAM;GAET,sBAAsB,EAAM;GACT;GACnB,0BAA0B,EAAyB;GACnD,gBAAgB,MAAM,QAAQ,EAAY,IAAI,EAAY,SAAS;GACjC;aAElC,kBAAC,GAAD;IACE,GAAI;IACqB;IAChB;IACT,CAAA;GACwB,CAAA;EACnB,CAAA,CACE"}
@@ -1 +1 @@
1
- {"version":3,"file":"UseRowSet.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapperPlotNav/UseRowSet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AAwExD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM;;;;;;;EAyC9C"}
1
+ {"version":3,"file":"UseRowSet.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapperPlotNav/UseRowSet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AA2ExD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM;;;;;;;EAyC9C"}
@@ -30,7 +30,10 @@ function s() {
30
30
  ...r,
31
31
  enabled: !n,
32
32
  placeholderData: (t) => {
33
- if (t && e(t.requestBody.query, i().query)) return t;
33
+ if (t) {
34
+ let n = t.requestBody?.query;
35
+ if (n && e(n, i().query)) return t;
36
+ }
34
37
  }
35
38
  }),
36
39
  paginatedQueryProgressMessage: a({
@@ -1 +1 @@
1
- {"version":3,"file":"UseRowSet.js","names":[],"sources":["../../../src/components/QueryWrapperPlotNav/UseRowSet.ts"],"sourcesContent":["import { queryRequestsHaveSameTotalResults } from '@/utils/functions/queryUtils'\nimport { RowSet } from '@sage-bionetworks/synapse-types'\nimport { useInfiniteQuery, useQuery } from '@tanstack/react-query'\nimport { cloneDeep } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../QueryContext'\n\nfunction useGetInfiniteRowSet() {\n const { isInfinite, rowDataInfiniteQueryOptions } = useQueryContext()\n const infiniteQuery = useInfiniteQuery({\n ...rowDataInfiniteQueryOptions,\n enabled: isInfinite,\n })\n\n const infiniteQueryProgressMessage = useInfiniteQuery({\n ...rowDataInfiniteQueryOptions,\n select: asyncJob => asyncJob.pages[0].progressMessage,\n enabled: isInfinite,\n })\n\n const infiniteQueryRowSet: RowSet | undefined = useMemo(() => {\n const rowSet = cloneDeep(\n infiniteQuery.data?.pages[0]?.responseBody?.queryResult?.queryResults,\n )\n if (rowSet) {\n rowSet.rows =\n infiniteQuery.data?.pages.flatMap(\n page => page.responseBody?.queryResult?.queryResults.rows || [],\n ) || []\n }\n return rowSet\n }, [infiniteQuery.data?.pages])\n\n return {\n infiniteQuery,\n infiniteQueryRowSet,\n infiniteQueryProgressMessage,\n }\n}\n\nfunction useGetPaginatedRowSet() {\n const { isInfinite, rowDataQueryOptions, getCurrentQueryRequest } =\n useQueryContext()\n const paginatedQuery = useQuery({\n ...rowDataQueryOptions,\n enabled: !isInfinite,\n // Keep the previous data when fetching a new page. We will use `UseQueryResult.isPlaceholderData` to trigger a showing placeholder UI\n placeholderData: prevData => {\n if (prevData) {\n // Check that only the page/sort changed; if the filters/sql changed, then don't hold on to the old data\n if (\n queryRequestsHaveSameTotalResults(\n prevData.requestBody.query,\n getCurrentQueryRequest().query,\n )\n ) {\n return prevData\n }\n }\n return undefined\n },\n })\n const paginatedQueryProgressMessage = useQuery({\n ...rowDataQueryOptions,\n select: asyncJob => asyncJob.progressMessage,\n enabled: !isInfinite,\n // Keep the previous data when fetching a new page. We will use `isPlaceholderData` to trigger a showing placeholder UI\n placeholderData: prevData => prevData,\n })\n\n return { paginatedQuery, paginatedQueryProgressMessage }\n}\n\n/**\n * Fetches the row data for a query and returns a RowSet that can be rendered as cards or a table. Respects the value of\n * QueryContext.isInfinite.\n * @param initialLimit\n */\nexport function useRowSet(initialLimit?: number) {\n const { isInfinite } = useQueryContext()\n\n const { paginatedQuery, paginatedQueryProgressMessage } =\n useGetPaginatedRowSet()\n const { infiniteQuery, infiniteQueryRowSet, infiniteQueryProgressMessage } =\n useGetInfiniteRowSet()\n\n const rowSet = useMemo(() => {\n let rowSet: RowSet | undefined\n if (isInfinite) {\n rowSet = infiniteQueryRowSet\n } else {\n rowSet = paginatedQuery.data\n }\n if (rowSet && initialLimit != null) {\n rowSet = { ...rowSet, rows: rowSet.rows.slice(0, initialLimit) }\n }\n return rowSet\n }, [infiniteQueryRowSet, initialLimit, isInfinite, paginatedQuery.data])\n\n const progressMessage: string | undefined = isInfinite\n ? infiniteQueryProgressMessage.data\n : paginatedQueryProgressMessage.data\n\n const isLoading = isInfinite\n ? infiniteQuery.isLoading\n : paginatedQuery.isLoading\n\n const isLoadingNewPage = isInfinite\n ? infiniteQuery.isFetchingNextPage\n : paginatedQuery.isPlaceholderData\n\n return {\n rowSet,\n progressMessage,\n isLoading,\n isLoadingNewPage,\n fetchNextPageOfInfiniteData: infiniteQuery.fetchNextPage,\n hasNextPageOfInfiniteData: infiniteQuery.hasNextPage,\n }\n}\n"],"mappings":";;;;;;;AAOA,SAAS,IAAuB;CAC9B,IAAM,EAAE,eAAY,mCAAgC,GAAiB,EAC/D,IAAgB,EAAiB;EACrC,GAAG;EACH,SAAS;EACV,CAAC,EAEI,IAA+B,EAAiB;EACpD,GAAG;EACH,SAAQ,MAAY,EAAS,MAAM,GAAG;EACtC,SAAS;EACV,CAAC;AAeF,QAAO;EACL;EACA,qBAf8C,QAAc;GAC5D,IAAM,IAAS,EACb,EAAc,MAAM,MAAM,IAAI,cAAc,aAAa,aAC1D;AAOD,UANI,MACF,EAAO,OACL,EAAc,MAAM,MAAM,SACxB,MAAQ,EAAK,cAAc,aAAa,aAAa,QAAQ,EAAE,CAChE,IAAI,EAAE,GAEJ;KACN,CAAC,EAAc,MAAM,MAAM,CAI5B;EACA;EACD;;AAGH,SAAS,IAAwB;CAC/B,IAAM,EAAE,eAAY,wBAAqB,8BACvC,GAAiB;AA4BnB,QAAO;EAAE,gBA3Bc,EAAS;GAC9B,GAAG;GACH,SAAS,CAAC;GAEV,kBAAiB,MAAY;AAC3B,QAAI,KAGA,EACE,EAAS,YAAY,OACrB,GAAwB,CAAC,MAC1B,CAED,QAAO;;GAKd,CASQ;EAAgB,+BARa,EAAS;GAC7C,GAAG;GACH,SAAQ,MAAY,EAAS;GAC7B,SAAS,CAAC;GAEV,kBAAiB,MAAY;GAC9B,CAEwB;EAA+B;;AAQ1D,SAAgB,EAAU,GAAuB;CAC/C,IAAM,EAAE,kBAAe,GAAiB,EAElC,EAAE,mBAAgB,qCACtB,GAAuB,EACnB,EAAE,kBAAe,wBAAqB,oCAC1C,GAAsB;AA2BxB,QAAO;EACL,QA1Ba,QAAc;GAC3B,IAAI;AASJ,UARA,AAGE,IAHE,IACO,IAEA,EAAe,MAEtB,KAAU,KAAgB,SAC5B,IAAS;IAAE,GAAG;IAAQ,MAAM,EAAO,KAAK,MAAM,GAAG,EAAa;IAAE,GAE3D;KACN;GAAC;GAAqB;GAAc;GAAY,EAAe;GAAK,CAerE;EACA,iBAd0C,IACxC,EAA6B,OAC7B,EAA8B;EAahC,WAXgB,IACd,EAAc,YACd,EAAe;EAUjB,kBARuB,IACrB,EAAc,qBACd,EAAe;EAOjB,6BAA6B,EAAc;EAC3C,2BAA2B,EAAc;EAC1C"}
1
+ {"version":3,"file":"UseRowSet.js","names":[],"sources":["../../../src/components/QueryWrapperPlotNav/UseRowSet.ts"],"sourcesContent":["import { queryRequestsHaveSameTotalResults } from '@/utils/functions/queryUtils'\nimport { RowSet } from '@sage-bionetworks/synapse-types'\nimport { useInfiniteQuery, useQuery } from '@tanstack/react-query'\nimport { cloneDeep } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { useQueryContext } from '../QueryContext'\n\nfunction useGetInfiniteRowSet() {\n const { isInfinite, rowDataInfiniteQueryOptions } = useQueryContext()\n const infiniteQuery = useInfiniteQuery({\n ...rowDataInfiniteQueryOptions,\n enabled: isInfinite,\n })\n\n const infiniteQueryProgressMessage = useInfiniteQuery({\n ...rowDataInfiniteQueryOptions,\n select: asyncJob => asyncJob.pages[0].progressMessage,\n enabled: isInfinite,\n })\n\n const infiniteQueryRowSet: RowSet | undefined = useMemo(() => {\n const rowSet = cloneDeep(\n infiniteQuery.data?.pages[0]?.responseBody?.queryResult?.queryResults,\n )\n if (rowSet) {\n rowSet.rows =\n infiniteQuery.data?.pages.flatMap(\n page => page.responseBody?.queryResult?.queryResults.rows || [],\n ) || []\n }\n return rowSet\n }, [infiniteQuery.data?.pages])\n\n return {\n infiniteQuery,\n infiniteQueryRowSet,\n infiniteQueryProgressMessage,\n }\n}\n\nfunction useGetPaginatedRowSet() {\n const { isInfinite, rowDataQueryOptions, getCurrentQueryRequest } =\n useQueryContext()\n const paginatedQuery = useQuery({\n ...rowDataQueryOptions,\n enabled: !isInfinite,\n // Keep the previous data when fetching a new page. We will use `UseQueryResult.isPlaceholderData` to trigger a showing placeholder UI\n placeholderData: prevData => {\n if (prevData) {\n const prevQuery = prevData.requestBody?.query\n // Check that only the page/sort changed; if the filters/sql changed, then don't hold on to the old data\n // prevQuery may be undefined when the requestBody is not a QueryBundleRequest (e.g. SearchQueryWrapper)\n if (\n prevQuery &&\n queryRequestsHaveSameTotalResults(\n prevQuery,\n getCurrentQueryRequest().query,\n )\n ) {\n return prevData\n }\n }\n return undefined\n },\n })\n const paginatedQueryProgressMessage = useQuery({\n ...rowDataQueryOptions,\n select: asyncJob => asyncJob.progressMessage,\n enabled: !isInfinite,\n // Keep the previous data when fetching a new page. We will use `isPlaceholderData` to trigger a showing placeholder UI\n placeholderData: prevData => prevData,\n })\n\n return { paginatedQuery, paginatedQueryProgressMessage }\n}\n\n/**\n * Fetches the row data for a query and returns a RowSet that can be rendered as cards or a table. Respects the value of\n * QueryContext.isInfinite.\n * @param initialLimit\n */\nexport function useRowSet(initialLimit?: number) {\n const { isInfinite } = useQueryContext()\n\n const { paginatedQuery, paginatedQueryProgressMessage } =\n useGetPaginatedRowSet()\n const { infiniteQuery, infiniteQueryRowSet, infiniteQueryProgressMessage } =\n useGetInfiniteRowSet()\n\n const rowSet = useMemo(() => {\n let rowSet: RowSet | undefined\n if (isInfinite) {\n rowSet = infiniteQueryRowSet\n } else {\n rowSet = paginatedQuery.data\n }\n if (rowSet && initialLimit != null) {\n rowSet = { ...rowSet, rows: rowSet.rows.slice(0, initialLimit) }\n }\n return rowSet\n }, [infiniteQueryRowSet, initialLimit, isInfinite, paginatedQuery.data])\n\n const progressMessage: string | undefined = isInfinite\n ? infiniteQueryProgressMessage.data\n : paginatedQueryProgressMessage.data\n\n const isLoading = isInfinite\n ? infiniteQuery.isLoading\n : paginatedQuery.isLoading\n\n const isLoadingNewPage = isInfinite\n ? infiniteQuery.isFetchingNextPage\n : paginatedQuery.isPlaceholderData\n\n return {\n rowSet,\n progressMessage,\n isLoading,\n isLoadingNewPage,\n fetchNextPageOfInfiniteData: infiniteQuery.fetchNextPage,\n hasNextPageOfInfiniteData: infiniteQuery.hasNextPage,\n }\n}\n"],"mappings":";;;;;;;AAOA,SAAS,IAAuB;CAC9B,IAAM,EAAE,eAAY,mCAAgC,GAAiB,EAC/D,IAAgB,EAAiB;EACrC,GAAG;EACH,SAAS;EACV,CAAC,EAEI,IAA+B,EAAiB;EACpD,GAAG;EACH,SAAQ,MAAY,EAAS,MAAM,GAAG;EACtC,SAAS;EACV,CAAC;AAeF,QAAO;EACL;EACA,qBAf8C,QAAc;GAC5D,IAAM,IAAS,EACb,EAAc,MAAM,MAAM,IAAI,cAAc,aAAa,aAC1D;AAOD,UANI,MACF,EAAO,OACL,EAAc,MAAM,MAAM,SACxB,MAAQ,EAAK,cAAc,aAAa,aAAa,QAAQ,EAAE,CAChE,IAAI,EAAE,GAEJ;KACN,CAAC,EAAc,MAAM,MAAM,CAI5B;EACA;EACD;;AAGH,SAAS,IAAwB;CAC/B,IAAM,EAAE,eAAY,wBAAqB,8BACvC,GAAiB;AA+BnB,QAAO;EAAE,gBA9Bc,EAAS;GAC9B,GAAG;GACH,SAAS,CAAC;GAEV,kBAAiB,MAAY;AAC3B,QAAI,GAAU;KACZ,IAAM,IAAY,EAAS,aAAa;AAGxC,SACE,KACA,EACE,GACA,GAAwB,CAAC,MAC1B,CAED,QAAO;;;GAKd,CASQ;EAAgB,+BARa,EAAS;GAC7C,GAAG;GACH,SAAQ,MAAY,EAAS;GAC7B,SAAS,CAAC;GAEV,kBAAiB,MAAY;GAC9B,CAEwB;EAA+B;;AAQ1D,SAAgB,EAAU,GAAuB;CAC/C,IAAM,EAAE,kBAAe,GAAiB,EAElC,EAAE,mBAAgB,qCACtB,GAAuB,EACnB,EAAE,kBAAe,wBAAqB,oCAC1C,GAAsB;AA2BxB,QAAO;EACL,QA1Ba,QAAc;GAC3B,IAAI;AASJ,UARA,AAGE,IAHE,IACO,IAEA,EAAe,MAEtB,KAAU,KAAgB,SAC5B,IAAS;IAAE,GAAG;IAAQ,MAAM,EAAO,KAAK,MAAM,GAAG,EAAa;IAAE,GAE3D;KACN;GAAC;GAAqB;GAAc;GAAY,EAAe;GAAK,CAerE;EACA,iBAd0C,IACxC,EAA6B,OAC7B,EAA8B;EAahC,WAXgB,IACd,EAAc,YACd,EAAe;EAUjB,kBARuB,IACrB,EAAc,qBACd,EAAe;EAOjB,6BAA6B,EAAc;EAC3C,2BAA2B,EAAc;EAC1C"}
@@ -0,0 +1,59 @@
1
+ import { AsynchronousJobStatus, ColumnModel, QueryBundleRequest, QueryResultBundle, RowSet } from '@sage-bionetworks/synapse-types';
2
+ import type { SearchIndexQuery, SearchQueryResults, SynapseClientError } from '@sage-bionetworks/synapse-client';
3
+ import { InfiniteData, QueryKey, UseInfiniteQueryOptions, UseSuspenseQueryOptions } from '@tanstack/react-query';
4
+ import { KeyFactory } from '@/synapse-queries/KeyFactory';
5
+ /**
6
+ * TanStack Query options for the SearchQueryServicesApi, mirroring TableQueryUseQueryOptions
7
+ * but parameterised over SearchIndexQuery rather than QueryBundleRequest. This eliminates
8
+ * `as unknown as` casts inside the implementation. A single cast to TableQueryUseQueryOptions
9
+ * is still required at the boundary where SearchQueryWrapper assigns these into QueryContextType.
10
+ */
11
+ export type SearchTableQueryUseQueryOptions = {
12
+ rowDataQueryOptions: UseSuspenseQueryOptions<AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>, SynapseClientError, RowSet | undefined>;
13
+ rowDataInfiniteQueryOptions: UseInfiniteQueryOptions<AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>, SynapseClientError, InfiniteData<AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>>, QueryKey, string | number | undefined>;
14
+ queryMetadataQueryOptions: UseSuspenseQueryOptions<AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>, SynapseClientError, Omit<QueryResultBundle, 'queryResult'>>;
15
+ };
16
+ /**
17
+ * Converts a QueryBundleRequest (used internally for state management) into a SearchIndexQuery
18
+ * that can be sent to the SearchQueryServicesApi.
19
+ *
20
+ * Mapping:
21
+ * - columnModels (facetType defined) → facetRequests (columns to aggregate as facets, with optional sort config)
22
+ * - query.selectedFacets (enumeration) → termsFilters (IN-clause filters)
23
+ * - query.selectedFacets (range) → rangeFilters (range filters)
24
+ * - query.sort → sort (SortItem { column, direction } → SearchSortField { columnName, direction })
25
+ * - query.limit → limit
26
+ * - query.offset → offset
27
+ * - partMask → dropped (SearchIndexQuery has no bitmask concept)
28
+ */
29
+ export declare function toSearchIndexQuery(queryBundleRequest: QueryBundleRequest, searchIndexId: string, columnModels?: ColumnModel[]): SearchIndexQuery;
30
+ /**
31
+ * Converts a SearchQueryResults (the actual API response) into a QueryResultBundle
32
+ * so that existing subcomponents (FacetFilterControls, RowSetView, etc.) work unchanged.
33
+ *
34
+ * Mapping:
35
+ * - totalHits → queryCount
36
+ * - hits → queryResult.queryResults (rows derived from hit.rowId/rowVersion/fields)
37
+ * - facets → facets (same FacetColumnResult type)
38
+ */
39
+ export declare function searchQueryResultsToQueryResultBundle(results: SearchQueryResults | undefined, query: SearchIndexQuery, columnModels?: ColumnModel[]): QueryResultBundle;
40
+ export declare function getSearchQueryUseQueryOptions(queryBundleRequest: QueryBundleRequest, keyFactory: KeyFactory, accessToken: string | undefined, searchIndexId: string, columnModels?: ColumnModel[]): SearchTableQueryUseQueryOptions;
41
+ /**
42
+ * Returns a stable callback that fetches autocomplete suggestions for a search input
43
+ * using the synchronous `POST /search/autocomplete` endpoint.
44
+ *
45
+ * The query is built from the current `searchIndexId` and `autocompleteFieldName`:
46
+ * - `searchQuery.queryText` is set to the user-entered search text
47
+ * - `searchQuery.queryFields` is set to `[autocompleteFieldName]` so the server
48
+ * only returns values for that single field
49
+ *
50
+ * When `autocompleteFieldName` is undefined, the returned callback immediately returns `[]`.
51
+ */
52
+ export declare function useGetSuggestionsForSearchIndex(searchIndexId: string, autocompleteFieldName: string | undefined): (searchText: string) => Promise<string[]>;
53
+ /**
54
+ * Returns TanStack Query options that call the SearchQueryServicesApi (instead of the
55
+ * standard Table Query API) but return data in the same QueryResultBundle format, allowing
56
+ * all existing subcomponents (FacetFilterControls, RowSetView, etc.) to work unchanged.
57
+ */
58
+ export declare function useSearchQueryUseQueryOptions(queryBundleRequest: QueryBundleRequest, searchIndexId: string, synapseId?: string): SearchTableQueryUseQueryOptions;
59
+ //# sourceMappingURL=SearchQueryUseQueryOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchQueryUseQueryOptions.d.ts","sourceRoot":"","sources":["../../../src/components/SearchQueryWrapper/SearchQueryUseQueryOptions.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,qBAAqB,EACrB,WAAW,EAKX,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,EAIP,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAGV,gBAAgB,EAEhB,kBAAkB,EAGlB,kBAAkB,EACnB,MAAM,kCAAkC,CAAA;AAKzC,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,mBAAmB,EAAE,uBAAuB,CAC1C,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,EAC1D,kBAAkB,EAClB,MAAM,GAAG,SAAS,CACnB,CAAA;IACD,2BAA2B,EAAE,uBAAuB,CAClD,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,EAC1D,kBAAkB,EAClB,YAAY,CAAC,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,MAAM,GAAG,SAAS,CAC5B,CAAA;IACD,yBAAyB,EAAE,uBAAuB,CAChD,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,EAC1D,kBAAkB,EAClB,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,CACvC,CAAA;CACF,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,WAAW,EAAE,GAC3B,gBAAgB,CAsFlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,kBAAkB,GAAG,SAAS,EACvC,KAAK,EAAE,gBAAgB,EACvB,YAAY,CAAC,EAAE,WAAW,EAAE,GAC3B,iBAAiB,CAqDnB;AAED,wBAAgB,6BAA6B,CAC3C,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,aAAa,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,WAAW,EAAE,GAC3B,+BAA+B,CA+IjC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,MAAM,GAAG,SAAS,GACxC,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAmC3C;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,MAAM,GACjB,+BAA+B,CAmBjC"}
@@ -0,0 +1,174 @@
1
+ import { getSearchQueryAsyncJobResults as e } from "../../synapse-client/SynapseClient.js";
2
+ import { useSynapseContext as t } from "../../utils/context/SynapseContext.js";
3
+ import n from "../../synapse-queries/entity/useEntityBundle.js";
4
+ import { tableQueryUseQueryDefaults as r } from "../../synapse-queries/entity/useGetQueryResultBundle.js";
5
+ import "../../synapse-queries/index.js";
6
+ import { useCallback as i, useMemo as a } from "react";
7
+ import { omit as o } from "lodash-es";
8
+ import { FACET_COLUMN_RANGE_REQUEST_CONCRETE_TYPE_VALUE as s, FACET_COLUMN_VALUES_REQUEST_CONCRETE_TYPE_VALUE as c, TEXT_MATCHES_QUERY_FILTER_CONCRETE_TYPE_VALUE as l } from "@sage-bionetworks/synapse-types";
9
+ import { FacetRequestSortDirectionEnum as u, FacetRequestSortFieldEnum as d } from "@sage-bionetworks/synapse-client";
10
+ //#region src/components/SearchQueryWrapper/SearchQueryUseQueryOptions.ts
11
+ function f(e, t, n) {
12
+ let r = n?.filter((e) => e.facetType != null).map((e) => {
13
+ let t = {
14
+ columnName: e.name,
15
+ maxValueCount: 100
16
+ };
17
+ return e.facetSortConfig && (e.facetSortConfig.property != null && (t.sortField = e.facetSortConfig.property === "VALUE" ? d.KEY : d.COUNT), e.facetSortConfig.direction != null && (t.sortDirection = e.facetSortConfig.direction === "ASC" ? u.ASC : u.DESC)), t;
18
+ }), i = e.query.selectedFacets?.filter((e) => e.concreteType === c).map((e) => ({
19
+ key: e.columnName,
20
+ values: e.facetValues
21
+ })), a = e.query.selectedFacets?.filter((e) => e.concreteType === s).map((e) => ({
22
+ key: e.columnName,
23
+ min: e.min,
24
+ max: e.max
25
+ })), o = e.query.additionalFilters?.filter((e) => e.concreteType === l).map((e) => e.searchExpression).filter((e) => e != null && e.length > 0), f = o && o.length > 0 ? o.join(" ") : void 0, p = e.query.sort?.filter((e) => e.direction === "ASC" || e.direction === "DESC").map((e) => ({
26
+ columnName: e.column,
27
+ direction: e.direction
28
+ }));
29
+ return {
30
+ concreteType: "org.sagebionetworks.repo.model.search.table.SearchIndexQuery",
31
+ searchIndexId: t,
32
+ searchQuery: {
33
+ facetRequests: r?.length ? r : void 0,
34
+ termsFilters: i?.length ? i : void 0,
35
+ rangeFilters: a?.length ? a : void 0,
36
+ queryText: f,
37
+ queryType: "MULTI_MATCH",
38
+ fuzziness: "AUTO",
39
+ sort: p?.length ? p : void 0,
40
+ limit: e.query.limit,
41
+ offset: e.query.offset
42
+ }
43
+ };
44
+ }
45
+ function p(e, t, n) {
46
+ if (!e) return { concreteType: "org.sagebionetworks.repo.model.table.QueryResultBundle" };
47
+ let r = e.selectColumns?.map((e) => e.name).filter((e) => !!e) ?? [], i = r.map((e) => ({
48
+ name: e,
49
+ columnType: n?.find((t) => t.name === e)?.columnType ?? "STRING"
50
+ })), a = (e.hits ?? []).map((e) => ({
51
+ rowId: e.rowId,
52
+ versionNumber: e.rowVersion,
53
+ values: r.map((t) => e.fields?.find((e) => e.name === t)?.value ?? null)
54
+ })), o = i.length > 0 || a.length > 0 ? {
55
+ concreteType: "org.sagebionetworks.repo.model.table.QueryResult",
56
+ queryResults: {
57
+ concreteType: "org.sagebionetworks.repo.model.table.RowSet",
58
+ tableId: t.searchIndexId ?? "",
59
+ etag: "",
60
+ headers: i,
61
+ rows: a
62
+ }
63
+ } : void 0;
64
+ return {
65
+ concreteType: "org.sagebionetworks.repo.model.table.QueryResultBundle",
66
+ queryCount: e.totalHits,
67
+ selectColumns: i,
68
+ queryResult: o,
69
+ facets: e.facets
70
+ };
71
+ }
72
+ function m(t, n, i, a, s) {
73
+ let c = f(t, a, s), l = {
74
+ ...c,
75
+ searchQuery: {
76
+ ...c.searchQuery,
77
+ facetRequests: void 0
78
+ },
79
+ responseParts: new Set(["HITS", "SELECT_COLUMNS"])
80
+ }, u = {
81
+ ...c,
82
+ responseParts: new Set([
83
+ "TOTAL_HITS",
84
+ "SELECT_COLUMNS",
85
+ "FACETS"
86
+ ])
87
+ }, d = (e) => ({
88
+ ...e,
89
+ responseParts: e.responseParts ? [...e.responseParts].sort() : void 0
90
+ }), m = async (t) => {
91
+ let n = await e(t, i);
92
+ return {
93
+ ...n,
94
+ responseBody: p(n.responseBody, t, s)
95
+ };
96
+ };
97
+ return {
98
+ rowDataQueryOptions: {
99
+ ...r,
100
+ queryKey: n.getSearchQueryResultWithAsyncStatusQueryKey(d(l), !1),
101
+ queryFn: () => m(l),
102
+ select: (e) => e.responseBody?.queryResult?.queryResults
103
+ },
104
+ rowDataInfiniteQueryOptions: {
105
+ ...r,
106
+ queryKey: n.getSearchQueryResultWithAsyncStatusQueryKey(d(l), !0),
107
+ initialPageParam: 0,
108
+ getNextPageParam: (e, t) => {
109
+ let n = e.responseBody?.queryCount, r = t.reduce((e, t) => e + (t.responseBody?.queryResult?.queryResults.rows?.length ?? 0), 0);
110
+ if (!(n != null && r >= n)) return r;
111
+ },
112
+ queryFn: (e) => {
113
+ let t = typeof e.pageParam == "string" ? parseInt(e.pageParam) : e.pageParam ?? 0;
114
+ return m({
115
+ ...l,
116
+ searchQuery: {
117
+ ...l.searchQuery,
118
+ offset: t
119
+ }
120
+ });
121
+ },
122
+ select: (e) => e
123
+ },
124
+ queryMetadataQueryOptions: {
125
+ ...r,
126
+ queryKey: n.getSearchQueryResultWithAsyncStatusQueryKey(d(u), !1),
127
+ queryFn: () => m(u),
128
+ select: (e) => {
129
+ let t = o(e.responseBody ?? {}, "queryResult");
130
+ return s ? {
131
+ ...t,
132
+ columnModels: s
133
+ } : t;
134
+ }
135
+ }
136
+ };
137
+ }
138
+ function h(e, n) {
139
+ let { synapseClient: r } = t();
140
+ return i(async (t) => {
141
+ if (!n) return [];
142
+ let i = t.trim();
143
+ if (!i) return [];
144
+ let a = await r.searchManagementServicesClient.postRepoV1SearchAutocomplete({ searchIndexQuery: {
145
+ concreteType: "org.sagebionetworks.repo.model.search.table.SearchIndexQuery",
146
+ searchIndexId: e,
147
+ searchQuery: {
148
+ queryText: i,
149
+ queryFields: [n],
150
+ returnFields: [n]
151
+ }
152
+ } }), o = [];
153
+ for (let e of a.hits ?? []) for (let t of e.fields ?? []) t.value && o.push(t.value);
154
+ return o;
155
+ }, [
156
+ r,
157
+ e,
158
+ n
159
+ ]);
160
+ }
161
+ function g(e, r, i) {
162
+ let { keyFactory: o, accessToken: s } = t(), { data: c } = n(i, void 0, { includeTableBundle: !0 }), l = c?.tableBundle?.columnModels;
163
+ return a(() => m(e, o, s, r, l), [
164
+ o,
165
+ s,
166
+ e,
167
+ r,
168
+ l
169
+ ]);
170
+ }
171
+ //#endregion
172
+ export { m as getSearchQueryUseQueryOptions, p as searchQueryResultsToQueryResultBundle, f as toSearchIndexQuery, h as useGetSuggestionsForSearchIndex, g as useSearchQueryUseQueryOptions };
173
+
174
+ //# sourceMappingURL=SearchQueryUseQueryOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchQueryUseQueryOptions.js","names":[],"sources":["../../../src/components/SearchQueryWrapper/SearchQueryUseQueryOptions.ts"],"sourcesContent":["import * as SynapseClient from '@/synapse-client/SynapseClient'\nimport { tableQueryUseQueryDefaults } from '@/synapse-queries'\nimport { useGetEntityBundle } from '@/synapse-queries/entity/useEntityBundle'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport {\n AsynchronousJobStatus,\n ColumnModel,\n FACET_COLUMN_RANGE_REQUEST_CONCRETE_TYPE_VALUE,\n FacetColumnRangeRequest,\n FACET_COLUMN_VALUES_REQUEST_CONCRETE_TYPE_VALUE,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n QueryResultBundle,\n RowSet,\n SortItem,\n TEXT_MATCHES_QUERY_FILTER_CONCRETE_TYPE_VALUE,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport type {\n FacetRequest,\n KeyValues,\n SearchIndexQuery,\n SearchKeyRange,\n SearchQueryResults,\n SearchSearchQuery,\n SearchSortField,\n SynapseClientError,\n} from '@sage-bionetworks/synapse-client'\nimport {\n FacetRequestSortDirectionEnum as FacetRequestSortDirectionEnumValues,\n FacetRequestSortFieldEnum as FacetRequestSortFieldEnumValues,\n} from '@sage-bionetworks/synapse-client'\nimport {\n InfiniteData,\n QueryKey,\n UseInfiniteQueryOptions,\n UseSuspenseQueryOptions,\n} from '@tanstack/react-query'\nimport { omit } from 'lodash-es'\nimport { useCallback, useMemo } from 'react'\nimport { KeyFactory } from '@/synapse-queries/KeyFactory'\n\n/**\n * TanStack Query options for the SearchQueryServicesApi, mirroring TableQueryUseQueryOptions\n * but parameterised over SearchIndexQuery rather than QueryBundleRequest. This eliminates\n * `as unknown as` casts inside the implementation. A single cast to TableQueryUseQueryOptions\n * is still required at the boundary where SearchQueryWrapper assigns these into QueryContextType.\n */\nexport type SearchTableQueryUseQueryOptions = {\n rowDataQueryOptions: UseSuspenseQueryOptions<\n AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n SynapseClientError,\n RowSet | undefined\n >\n rowDataInfiniteQueryOptions: UseInfiniteQueryOptions<\n AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n SynapseClientError,\n InfiniteData<AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>>,\n QueryKey,\n string | number | undefined\n >\n queryMetadataQueryOptions: UseSuspenseQueryOptions<\n AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n SynapseClientError,\n Omit<QueryResultBundle, 'queryResult'>\n >\n}\n\n/**\n * Converts a QueryBundleRequest (used internally for state management) into a SearchIndexQuery\n * that can be sent to the SearchQueryServicesApi.\n *\n * Mapping:\n * - columnModels (facetType defined) → facetRequests (columns to aggregate as facets, with optional sort config)\n * - query.selectedFacets (enumeration) → termsFilters (IN-clause filters)\n * - query.selectedFacets (range) → rangeFilters (range filters)\n * - query.sort → sort (SortItem { column, direction } → SearchSortField { columnName, direction })\n * - query.limit → limit\n * - query.offset → offset\n * - partMask → dropped (SearchIndexQuery has no bitmask concept)\n */\nexport function toSearchIndexQuery(\n queryBundleRequest: QueryBundleRequest,\n searchIndexId: string,\n columnModels?: ColumnModel[],\n): SearchIndexQuery {\n // Build facetRequests from ColumnModels that have a facetType defined\n const facetRequests: FacetRequest[] | undefined = columnModels\n ?.filter(cm => cm.facetType != null)\n .map(cm => {\n const facetReq: FacetRequest = { columnName: cm.name, maxValueCount: 100 }\n if (cm.facetSortConfig) {\n // Map FacetColumnSortProperty ('FREQUENCY'|'VALUE') → FacetRequestSortFieldEnum ('COUNT'|'KEY')\n if (cm.facetSortConfig.property != null) {\n facetReq.sortField =\n cm.facetSortConfig.property === 'VALUE'\n ? FacetRequestSortFieldEnumValues.KEY\n : FacetRequestSortFieldEnumValues.COUNT\n }\n if (cm.facetSortConfig.direction != null) {\n facetReq.sortDirection =\n cm.facetSortConfig.direction === 'ASC'\n ? FacetRequestSortDirectionEnumValues.ASC\n : FacetRequestSortDirectionEnumValues.DESC\n }\n }\n return facetReq\n })\n\n // Build termsFilters from enumeration selectedFacets\n const termsFilters: KeyValues[] | undefined =\n queryBundleRequest.query.selectedFacets\n ?.filter(\n (f): f is FacetColumnValuesRequest =>\n f.concreteType === FACET_COLUMN_VALUES_REQUEST_CONCRETE_TYPE_VALUE,\n )\n .map(f => ({ key: f.columnName, values: f.facetValues }))\n\n // Build rangeFilters from range selectedFacets\n const rangeFilters: SearchKeyRange[] | undefined =\n queryBundleRequest.query.selectedFacets\n ?.filter(\n (f): f is FacetColumnRangeRequest =>\n f.concreteType === FACET_COLUMN_RANGE_REQUEST_CONCRETE_TYPE_VALUE,\n )\n .map(f => ({\n key: f.columnName,\n min: f.min,\n max: f.max,\n }))\n\n // Extract queryText by concatenating all TextMatchesQueryFilter searchExpression values\n const textMatchesExpressions = queryBundleRequest.query.additionalFilters\n ?.filter(\n (f): f is TextMatchesQueryFilter =>\n f.concreteType === TEXT_MATCHES_QUERY_FILTER_CONCRETE_TYPE_VALUE,\n )\n .map(f => f.searchExpression)\n .filter((expr): expr is string => expr != null && expr.length > 0)\n const queryText =\n textMatchesExpressions && textMatchesExpressions.length > 0\n ? textMatchesExpressions.join(' ')\n : undefined\n\n // Map SortItem[] (column + direction) → SearchSortField[] (columnName + direction),\n // filtering out entries with no direction (which mean \"remove sort\").\n const sort: SearchSortField[] | undefined = queryBundleRequest.query.sort\n ?.filter(\n (s): s is SortItem & { direction: 'ASC' | 'DESC' } =>\n s.direction === 'ASC' || s.direction === 'DESC',\n )\n .map(s => ({ columnName: s.column, direction: s.direction }))\n\n const searchQuery: SearchSearchQuery = {\n facetRequests: facetRequests?.length ? facetRequests : undefined,\n termsFilters: termsFilters?.length ? termsFilters : undefined,\n rangeFilters: rangeFilters?.length ? rangeFilters : undefined,\n queryText,\n queryType: 'MULTI_MATCH',\n fuzziness: 'AUTO',\n sort: sort?.length ? sort : undefined,\n limit: queryBundleRequest.query.limit,\n offset: queryBundleRequest.query.offset,\n }\n\n return {\n concreteType:\n 'org.sagebionetworks.repo.model.search.table.SearchIndexQuery' as const,\n searchIndexId,\n searchQuery,\n }\n}\n\n/**\n * Converts a SearchQueryResults (the actual API response) into a QueryResultBundle\n * so that existing subcomponents (FacetFilterControls, RowSetView, etc.) work unchanged.\n *\n * Mapping:\n * - totalHits → queryCount\n * - hits → queryResult.queryResults (rows derived from hit.rowId/rowVersion/fields)\n * - facets → facets (same FacetColumnResult type)\n */\nexport function searchQueryResultsToQueryResultBundle(\n results: SearchQueryResults | undefined,\n query: SearchIndexQuery,\n columnModels?: ColumnModel[],\n): QueryResultBundle {\n if (!results) {\n return {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryResultBundle',\n }\n }\n\n // Derive column names from the server-returned selectColumns. Both the row data\n // query and the metadata query request SELECT_COLUMNS, so this is always present.\n const fieldNames: string[] =\n results.selectColumns\n ?.map(col => col.name)\n .filter((n): n is string => !!n) ?? []\n\n const headers = fieldNames.map(name => ({\n name,\n columnType:\n columnModels?.find(cm => cm.name === name)?.columnType ??\n ('STRING' as const),\n }))\n\n const rows = (results.hits ?? []).map(hit => ({\n rowId: hit.rowId,\n versionNumber: hit.rowVersion,\n values: fieldNames.map(name => {\n return hit.fields?.find(f => f.name === name)?.value ?? null\n }),\n }))\n\n const queryResult =\n headers.length > 0 || rows.length > 0\n ? {\n concreteType:\n 'org.sagebionetworks.repo.model.table.QueryResult' as const,\n queryResults: {\n concreteType:\n 'org.sagebionetworks.repo.model.table.RowSet' as const,\n tableId: query.searchIndexId ?? '',\n etag: '',\n headers,\n rows,\n },\n }\n : undefined\n\n return {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryResultBundle',\n queryCount: results.totalHits,\n selectColumns: headers,\n queryResult,\n // FacetColumnResult is the same discriminated union type in both response shapes\n facets: results.facets as QueryResultBundle['facets'],\n }\n}\n\nexport function getSearchQueryUseQueryOptions(\n queryBundleRequest: QueryBundleRequest,\n keyFactory: KeyFactory,\n accessToken: string | undefined,\n searchIndexId: string,\n columnModels?: ColumnModel[],\n): SearchTableQueryUseQueryOptions {\n const baseQuery: SearchIndexQuery = toSearchIndexQuery(\n queryBundleRequest,\n searchIndexId,\n columnModels,\n )\n const rowDataQuery: SearchIndexQuery = {\n ...baseQuery,\n searchQuery: {\n ...baseQuery.searchQuery,\n // Omit facetRequests from the row data query: facet aggregations are only needed\n // in the metadata query (which requests FACETS). Removing facetRequests here keeps\n // the row data query key stable while column models are loading, preventing an\n // unnecessary re-fetch (and a brief loading flash) when column models first arrive.\n facetRequests: undefined,\n },\n // Request SELECT_COLUMNS so headers are available for row rendering.\n // HITS is returned by default even when responseParts is specified.\n responseParts: new Set(['HITS', 'SELECT_COLUMNS'] as const),\n }\n const metadataQuery: SearchIndexQuery = {\n ...baseQuery,\n // Request all opt-in parts needed for the metadata response:\n // TOTAL_HITS → queryCount (drives tab count / spinner resolution)\n // SELECT_COLUMNS → column headers for the table\n // FACETS → facet aggregations for FacetFilterControls / plots\n responseParts: new Set(['TOTAL_HITS', 'SELECT_COLUMNS', 'FACETS'] as const),\n }\n\n // Convert responseParts Set → sorted array for query key building.\n // JSON.stringify(new Set([...])) === '{}', so two queries whose only difference is\n // their responseParts would hash to the same key and share a cache entry.\n // Using a sorted array gives each query a distinct, stable key.\n const toKeyShape = (query: SearchIndexQuery) => ({\n ...query,\n responseParts: query.responseParts\n ? [...query.responseParts].sort()\n : undefined,\n })\n\n // Fetches from the SearchQueryServicesApi and converts the SearchQueryResults responseBody\n // into QueryResultBundle shape. This allows all downstream shared components\n // (UseRowSet, QueryVisualizationWrapper, etc.) to access data.responseBody.*\n // using the same patterns as regular table queries (queryResult.queryResults, selectColumns, etc.).\n const fetchAndConvert = async (query: SearchIndexQuery) => {\n const asyncStatus = await SynapseClient.getSearchQueryAsyncJobResults(\n query,\n accessToken,\n )\n return {\n ...asyncStatus,\n responseBody: searchQueryResultsToQueryResultBundle(\n asyncStatus.responseBody,\n query,\n columnModels,\n ),\n }\n }\n\n // `as unknown as` is necessary because SearchIndexQuery.responseParts is a Set but\n // toKeyShape converts it to a sorted string[] for stable cache key serialisation.\n const rowDataQueryOptions: SearchTableQueryUseQueryOptions['rowDataQueryOptions'] =\n {\n ...tableQueryUseQueryDefaults,\n queryKey: keyFactory.getSearchQueryResultWithAsyncStatusQueryKey(\n toKeyShape(rowDataQuery) as unknown as SearchIndexQuery,\n false,\n ),\n queryFn: () => fetchAndConvert(rowDataQuery),\n select: (\n data: AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n ): RowSet | undefined => data.responseBody?.queryResult?.queryResults,\n }\n\n const rowDataInfiniteQueryOptions: SearchTableQueryUseQueryOptions['rowDataInfiniteQueryOptions'] =\n {\n ...tableQueryUseQueryDefaults,\n queryKey: keyFactory.getSearchQueryResultWithAsyncStatusQueryKey(\n toKeyShape(rowDataQuery) as unknown as SearchIndexQuery,\n true,\n ),\n initialPageParam: 0 as number | string | undefined,\n getNextPageParam: (\n lastPage: AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n allPages: AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>[],\n ): number | string | undefined => {\n const totalRows = lastPage.responseBody?.queryCount\n const fetchedRows = allPages.reduce(\n (acc, page) =>\n acc +\n (page.responseBody?.queryResult?.queryResults.rows?.length ?? 0),\n 0,\n )\n if (totalRows != null && fetchedRows >= totalRows) {\n return undefined\n }\n return fetchedRows\n },\n queryFn: (context: { pageParam?: number | string }) => {\n const offset =\n typeof context.pageParam === 'string'\n ? parseInt(context.pageParam)\n : context.pageParam ?? 0\n const requestForPage: SearchIndexQuery = {\n ...rowDataQuery,\n searchQuery: {\n ...rowDataQuery.searchQuery,\n offset,\n },\n }\n return fetchAndConvert(requestForPage)\n },\n select: (\n data: InfiniteData<\n AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>\n >,\n ) => data,\n }\n\n const queryMetadataQueryOptions: SearchTableQueryUseQueryOptions['queryMetadataQueryOptions'] =\n {\n ...tableQueryUseQueryDefaults,\n queryKey: keyFactory.getSearchQueryResultWithAsyncStatusQueryKey(\n toKeyShape(metadataQuery) as unknown as SearchIndexQuery,\n false,\n ),\n queryFn: () => fetchAndConvert(metadataQuery),\n select: (\n data: AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n ): Omit<QueryResultBundle, 'queryResult'> => {\n const result = omit(data.responseBody ?? {}, 'queryResult') as Omit<\n QueryResultBundle,\n 'queryResult'\n >\n return columnModels ? { ...result, columnModels } : result\n },\n }\n\n return {\n rowDataQueryOptions,\n rowDataInfiniteQueryOptions,\n queryMetadataQueryOptions,\n }\n}\n\n/**\n * Returns a stable callback that fetches autocomplete suggestions for a search input\n * using the synchronous `POST /search/autocomplete` endpoint.\n *\n * The query is built from the current `searchIndexId` and `autocompleteFieldName`:\n * - `searchQuery.queryText` is set to the user-entered search text\n * - `searchQuery.queryFields` is set to `[autocompleteFieldName]` so the server\n * only returns values for that single field\n *\n * When `autocompleteFieldName` is undefined, the returned callback immediately returns `[]`.\n */\nexport function useGetSuggestionsForSearchIndex(\n searchIndexId: string,\n autocompleteFieldName: string | undefined,\n): (searchText: string) => Promise<string[]> {\n const { synapseClient } = useSynapseContext()\n\n return useCallback(\n async (searchText: string): Promise<string[]> => {\n if (!autocompleteFieldName) return []\n const trimmed = searchText.trim()\n if (!trimmed) return []\n const results =\n await synapseClient.searchManagementServicesClient.postRepoV1SearchAutocomplete(\n {\n searchIndexQuery: {\n concreteType:\n 'org.sagebionetworks.repo.model.search.table.SearchIndexQuery' as const,\n searchIndexId,\n searchQuery: {\n queryText: trimmed,\n queryFields: [autocompleteFieldName],\n returnFields: [autocompleteFieldName],\n },\n },\n },\n )\n const suggestions: string[] = []\n for (const hit of results.hits ?? []) {\n for (const field of hit.fields ?? []) {\n if (field.value) {\n suggestions.push(field.value)\n }\n }\n }\n return suggestions\n },\n [synapseClient, searchIndexId, autocompleteFieldName],\n )\n}\n\n/**\n * Returns TanStack Query options that call the SearchQueryServicesApi (instead of the\n * standard Table Query API) but return data in the same QueryResultBundle format, allowing\n * all existing subcomponents (FacetFilterControls, RowSetView, etc.) to work unchanged.\n */\nexport function useSearchQueryUseQueryOptions(\n queryBundleRequest: QueryBundleRequest,\n searchIndexId: string,\n synapseId?: string,\n): SearchTableQueryUseQueryOptions {\n const { keyFactory, accessToken } = useSynapseContext()\n\n const { data: entityBundle } = useGetEntityBundle(synapseId, undefined, {\n includeTableBundle: true,\n })\n const columnModels = entityBundle?.tableBundle?.columnModels\n\n return useMemo(\n () =>\n getSearchQueryUseQueryOptions(\n queryBundleRequest,\n keyFactory,\n accessToken,\n searchIndexId,\n columnModels,\n ),\n [keyFactory, accessToken, queryBundleRequest, searchIndexId, columnModels],\n )\n}\n"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { QueryBundleRequest } from '@sage-bionetworks/synapse-types';
2
+ import { PropsWithChildren } from 'react';
3
+ /**
4
+ * The initQueryRequest used internally within SearchQueryWrapper. It uses a synthetic entity ID
5
+ * and SQL so we can reuse useImmutableTableQuery for facet/pagination state management, even though
6
+ * the actual data is fetched from the SearchQueryServicesApi (not a table entity).
7
+ */
8
+ export declare const SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID = "search";
9
+ export declare const SEARCH_QUERY_WRAPPER_SYNTHETIC_SQL = "SELECT * FROM search";
10
+ export type SearchQueryWrapperProps = PropsWithChildren<{
11
+ /**
12
+ * The ID of the SearchIndex entity to query.
13
+ */
14
+ searchIndexId: string;
15
+ /**
16
+ * The initial query request. Only `query.selectedFacets`, `query.additionalFilters`,
17
+ * `query.limit`, and `query.offset` are used; the `entityId` and `sql` fields are
18
+ * overridden with synthetic values. The `partMask` controls which parts of the response
19
+ * bundle to request.
20
+ */
21
+ initQueryRequest: {
22
+ concreteType?: QueryBundleRequest['concreteType'];
23
+ partMask?: QueryBundleRequest['partMask'];
24
+ query?: Partial<QueryBundleRequest['query']>;
25
+ };
26
+ /** If onQueryChange is set, the callback will be invoked when the Query changes */
27
+ onQueryChange?: (newQueryJson: string) => void;
28
+ /** If onQueryResultBundleChange is set, it will be called whenever the query result bundle changes */
29
+ onQueryResultBundleChange?: (newQueryResultBundleJson: string) => void;
30
+ isInfinite?: boolean;
31
+ /** Whether the URL should update when the query is modified (deep linking). */
32
+ shouldDeepLink?: boolean;
33
+ }>;
34
+ /**
35
+ * Provides a QueryContext populated by results from the SearchQueryServicesApi rather than
36
+ * the standard Table Query Services. All subcomponents that consume QueryContext can be
37
+ * used unchanged within a SearchQueryWrapper tree.
38
+ */
39
+ export declare function SearchQueryWrapper(props: SearchQueryWrapperProps): import("react/jsx-runtime").JSX.Element;
40
+ //# sourceMappingURL=SearchQueryWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchQueryWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/SearchQueryWrapper/SearchQueryWrapper.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,kBAAkB,EAEnB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,iBAAiB,EAAmC,MAAM,OAAO,CAAA;AAwB1E;;;;GAIG;AACH,eAAO,MAAM,wCAAwC,WAAW,CAAA;AAChE,eAAO,MAAM,kCAAkC,yBAA8D,CAAA;AAE7G,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;IACtD;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;;;;OAKG;IACH,gBAAgB,EAAE;QAChB,YAAY,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAA;QACjD,QAAQ,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAA;QACzC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAA;KAC7C,CAAA;IACD,mFAAmF;IACnF,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,sGAAsG;IACtG,yBAAyB,CAAC,EAAE,CAAC,wBAAwB,EAAE,MAAM,KAAK,IAAI,CAAA;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAC,CAAA;AAwNF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,2CAMhE"}
@@ -0,0 +1,100 @@
1
+ import { parseEntityIdFromSqlStatement as e } from "../../utils/functions/SqlFunctions.js";
2
+ import { useSynapseContext as t } from "../../utils/context/SynapseContext.js";
3
+ import { SessionInitializedGuard as n } from "../../utils/AppUtils/session/SessionInitializedGuard.js";
4
+ import r from "../../synapse-queries/entity/useEntityBundle.js";
5
+ import { useGetEntity as i } from "../../synapse-queries/entity/useEntity.js";
6
+ import { hasResettableFilters as a } from "../../utils/functions/queryUtils.js";
7
+ import "../../synapse-queries/index.js";
8
+ import { QueryContextProvider as o, useQueryContext as s } from "../QueryContext/QueryContext.js";
9
+ import { goToPage as c } from "../../utils/hooks/useImmutableTableQuery/TableQueryReducerActions.js";
10
+ import l from "../../utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js";
11
+ import u from "../QueryWrapper/useHasFacetedSelectColumn.js";
12
+ import { getSearchQueryUseQueryOptions as d, useSearchQueryUseQueryOptions as f } from "./SearchQueryUseQueryOptions.js";
13
+ import { useCallback as p, useEffect as m, useMemo as h } from "react";
14
+ import { cloneDeep as g } from "lodash-es";
15
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
16
+ import { useQuery as y } from "@tanstack/react-query";
17
+ import { useDeepCompareMemoize as b } from "use-deep-compare-effect";
18
+ import { Provider as x } from "jotai";
19
+ //#region src/components/SearchQueryWrapper/SearchQueryWrapper.tsx
20
+ var S = "search", C = `SELECT * FROM ${S}`;
21
+ function w({ onQueryResultBundleChange: e }) {
22
+ let { queryMetadataQueryOptions: t } = s(), { data: n } = y(t);
23
+ return m(() => {
24
+ n && e(JSON.stringify(n));
25
+ }, [n, e]), null;
26
+ }
27
+ function T(e) {
28
+ return /* @__PURE__ */ _(n, { children: /* @__PURE__ */ _(E, { ...e }) });
29
+ }
30
+ function E(n) {
31
+ let { initQueryRequest: s, onQueryChange: m, onQueryResultBundleChange: y, isInfinite: x = !1, searchIndexId: T, shouldDeepLink: E = !1 } = n, { keyFactory: D, accessToken: O } = t(), { data: k } = i(T, void 0, { throwOnError: !0 }), A = k, j = A?.definingSQL ? e(A.definingSQL) : void 0, { data: M } = r(j, void 0, { includeTableBundle: !0 }, { throwOnError: !0 }), N = M?.tableBundle?.columnModels, { getInitQueryRequest: P, getCurrentQueryRequest: F, setQuery: I, resetQuery: L, removeSelectedFacet: R, removeValueFromSelectedFacet: z, removeQueryFilter: B, removeValueFromQueryFilter: V, nextQueryRequest: H, currentQueryRequest: U, addValueToSelectedFacet: W, setRangeFacetValue: G, resetDebounceTimer: K, currentPage: q, goToPage: J, pageSize: Y, setPageSize: X } = l({
32
+ initQueryRequest: b({
33
+ concreteType: "org.sagebionetworks.repo.model.table.QueryBundleRequest",
34
+ entityId: S,
35
+ partMask: s.partMask ?? 0,
36
+ query: {
37
+ sql: C,
38
+ selectedFacets: s.query?.selectedFacets,
39
+ additionalFilters: s.query?.additionalFilters,
40
+ limit: s.query?.limit,
41
+ offset: s.query?.offset
42
+ }
43
+ }),
44
+ onQueryChange: m,
45
+ shouldDeepLink: E
46
+ }), { rowDataQueryOptions: Z, rowDataInfiniteQueryOptions: Q, queryMetadataQueryOptions: $ } = f(U, T, j);
47
+ return /* @__PURE__ */ v(o, {
48
+ queryContext: b({
49
+ isInfinite: x,
50
+ entityId: void 0,
51
+ versionNumber: void 0,
52
+ nextQueryRequest: H,
53
+ currentQueryRequest: U,
54
+ getCurrentQueryRequest: F,
55
+ getInitQueryRequest: P,
56
+ executeQueryRequest: I,
57
+ hasFacetedSelectColumn: u($),
58
+ hasResettableFilters: h(() => a(F().query, void 0), [F]),
59
+ removeSelectedFacet: R,
60
+ removeValueFromSelectedFacet: z,
61
+ resetQuery: L,
62
+ removeQueryFilter: B,
63
+ removeValueFromQueryFilter: V,
64
+ onViewSharingSettingsClicked: void 0,
65
+ addValueToSelectedFacet: W,
66
+ combineRangeFacetConfig: void 0,
67
+ setRangeFacetValue: G,
68
+ resetDebounceTimer: K,
69
+ rowDataQueryOptions: Z,
70
+ rowDataInfiniteQueryOptions: Q,
71
+ queryMetadataQueryOptions: $,
72
+ currentPage: q,
73
+ goToPage: J,
74
+ pageSize: Y,
75
+ setPageSize: X,
76
+ lockedColumn: void 0,
77
+ fileIdColumnName: void 0,
78
+ fileVersionColumnName: void 0,
79
+ fileNameColumnName: void 0,
80
+ getRowDataQueryOptionsForPage: p((e) => d(c({
81
+ type: "goToPage",
82
+ pageNumber: e
83
+ }, g(F())), D, O, T, N).rowDataQueryOptions, [
84
+ F,
85
+ D,
86
+ O,
87
+ T,
88
+ N
89
+ ])
90
+ }),
91
+ children: [y && /* @__PURE__ */ _(w, { onQueryResultBundleChange: y }), n.children]
92
+ });
93
+ }
94
+ function D(e) {
95
+ return /* @__PURE__ */ _(x, { children: /* @__PURE__ */ _(T, { ...e }) });
96
+ }
97
+ //#endregion
98
+ export { S as SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID, C as SEARCH_QUERY_WRAPPER_SYNTHETIC_SQL, D as SearchQueryWrapper };
99
+
100
+ //# sourceMappingURL=SearchQueryWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchQueryWrapper.js","names":[],"sources":["../../../src/components/SearchQueryWrapper/SearchQueryWrapper.tsx"],"sourcesContent":["import { hasResettableFilters as hasResettableFiltersUtil } from '@/utils/functions/queryUtils'\nimport { parseEntityIdFromSqlStatement } from '@/utils/functions/SqlFunctions'\nimport useImmutableTableQuery from '@/utils/hooks/useImmutableTableQuery/useImmutableTableQuery'\nimport { goToPage as transformQueryToGoToPage } from '@/utils/hooks/useImmutableTableQuery/TableQueryReducerActions'\nimport {\n AsynchronousJobStatus,\n QueryBundleRequest,\n QueryResultBundle,\n} from '@sage-bionetworks/synapse-types'\nimport { Provider } from 'jotai'\nimport { PropsWithChildren, useCallback, useEffect, useMemo } from 'react'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport {\n QueryContextProvider,\n QueryContextType,\n useQueryContext,\n} from '../QueryContext/QueryContext'\nimport {\n getSearchQueryUseQueryOptions,\n useSearchQueryUseQueryOptions,\n} from './SearchQueryUseQueryOptions'\nimport { TableQueryUseQueryOptions } from '../QueryWrapper/TableQueryUseQueryOptions'\nimport useHasFacetedSelectColumn from '../QueryWrapper/useHasFacetedSelectColumn'\nimport { SessionInitializedGuard } from '@/utils/AppUtils/session/SessionInitializedGuard'\nimport { useGetEntity, useGetEntityBundle } from '@/synapse-queries'\nimport type {\n SearchIndexQuery,\n SynapseClientError,\n} from '@sage-bionetworks/synapse-client'\nimport { SearchIndex } from '@sage-bionetworks/synapse-client'\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { cloneDeep } from 'lodash-es'\n\n/**\n * The initQueryRequest used internally within SearchQueryWrapper. It uses a synthetic entity ID\n * and SQL so we can reuse useImmutableTableQuery for facet/pagination state management, even though\n * the actual data is fetched from the SearchQueryServicesApi (not a table entity).\n */\nexport const SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID = 'search'\nexport const SEARCH_QUERY_WRAPPER_SYNTHETIC_SQL = `SELECT * FROM ${SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID}`\n\nexport type SearchQueryWrapperProps = PropsWithChildren<{\n /**\n * The ID of the SearchIndex entity to query.\n */\n searchIndexId: string\n /**\n * The initial query request. Only `query.selectedFacets`, `query.additionalFilters`,\n * `query.limit`, and `query.offset` are used; the `entityId` and `sql` fields are\n * overridden with synthetic values. The `partMask` controls which parts of the response\n * bundle to request.\n */\n initQueryRequest: {\n concreteType?: QueryBundleRequest['concreteType']\n partMask?: QueryBundleRequest['partMask']\n query?: Partial<QueryBundleRequest['query']>\n }\n /** If onQueryChange is set, the callback will be invoked when the Query changes */\n onQueryChange?: (newQueryJson: string) => void\n /** If onQueryResultBundleChange is set, it will be called whenever the query result bundle changes */\n onQueryResultBundleChange?: (newQueryResultBundleJson: string) => void\n isInfinite?: boolean\n /** Whether the URL should update when the query is modified (deep linking). */\n shouldDeepLink?: boolean\n}>\n\n/**\n * Internal component that reads the current query metadata from QueryContext and fires\n * onQueryResultBundleChange whenever the data changes. Must be rendered as a child of\n * QueryContextProvider (i.e. inside SearchQueryWrapper).\n */\nfunction SearchQueryResultBundleChangeNotifier({\n onQueryResultBundleChange,\n}: {\n onQueryResultBundleChange: (json: string) => void\n}) {\n const { queryMetadataQueryOptions } = useQueryContext()\n // queryMetadataQueryOptions is UseSuspenseQueryOptions; cast to UseQueryOptions so we can use\n // regular (non-suspense) `useQuery` here — the same cache key is shared, so no extra request is made.\n const queryOpts = queryMetadataQueryOptions as UseQueryOptions<\n AsynchronousJobStatus<SearchIndexQuery, QueryResultBundle>,\n SynapseClientError,\n Omit<QueryResultBundle, 'queryResult'>\n >\n const { data } = useQuery(queryOpts)\n useEffect(() => {\n if (data) {\n onQueryResultBundleChange(JSON.stringify(data))\n }\n }, [data, onQueryResultBundleChange])\n return null\n}\n\nfunction SearchQueryWrapperInternal(props: SearchQueryWrapperProps) {\n return (\n <SessionInitializedGuard>\n <SearchQueryWrapperInternalWithSession {...props} />\n </SessionInitializedGuard>\n )\n}\n\nfunction SearchQueryWrapperInternalWithSession(props: SearchQueryWrapperProps) {\n const {\n initQueryRequest: initQueryRequestFromProps,\n onQueryChange,\n onQueryResultBundleChange,\n isInfinite = false,\n searchIndexId,\n shouldDeepLink = false,\n } = props\n\n const { keyFactory, accessToken } = useSynapseContext()\n\n const { data: searchIndexEntityData } = useGetEntity(\n searchIndexId,\n undefined,\n {\n throwOnError: true,\n },\n )\n const searchIndexEntity = searchIndexEntityData as SearchIndex | undefined\n\n const synapseId = searchIndexEntity?.definingSQL\n ? parseEntityIdFromSqlStatement(searchIndexEntity.definingSQL)\n : undefined\n\n const { data: entityBundle } = useGetEntityBundle(\n synapseId,\n undefined,\n { includeTableBundle: true },\n { throwOnError: true },\n )\n const columnModels = entityBundle?.tableBundle?.columnModels\n\n // Build a full synthetic QueryBundleRequest so we can reuse useImmutableTableQuery.\n // The entityId and sql are placeholders; only selectedFacets, limit, offset, and partMask\n // are passed through to the actual SearchQueryServicesApi call.\n const initQueryRequest = useDeepCompareMemoize({\n concreteType:\n 'org.sagebionetworks.repo.model.table.QueryBundleRequest' as const,\n entityId: SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID,\n partMask: initQueryRequestFromProps.partMask ?? 0,\n query: {\n sql: SEARCH_QUERY_WRAPPER_SYNTHETIC_SQL,\n selectedFacets: initQueryRequestFromProps.query?.selectedFacets,\n additionalFilters: initQueryRequestFromProps.query?.additionalFilters,\n limit: initQueryRequestFromProps.query?.limit,\n offset: initQueryRequestFromProps.query?.offset,\n },\n }) as QueryBundleRequest\n\n const immutableTableQueryResult = useImmutableTableQuery({\n initQueryRequest,\n onQueryChange,\n shouldDeepLink,\n })\n\n const {\n getInitQueryRequest,\n getCurrentQueryRequest,\n setQuery,\n resetQuery,\n removeSelectedFacet,\n removeValueFromSelectedFacet,\n removeQueryFilter,\n removeValueFromQueryFilter,\n nextQueryRequest,\n currentQueryRequest,\n addValueToSelectedFacet,\n setRangeFacetValue,\n resetDebounceTimer,\n currentPage,\n goToPage,\n pageSize,\n setPageSize,\n } = immutableTableQueryResult\n\n // SearchTableQueryUseQueryOptions uses SearchIndexQuery generics rather than QueryBundleRequest.\n // QueryContextType (and all downstream consumers) expect TableQueryUseQueryOptions. The runtime\n // shapes are identical — only the TypeScript generics differ — so a single cast is made here at\n // the architectural boundary rather than scattering `as unknown as` across the implementation.\n const {\n rowDataQueryOptions,\n rowDataInfiniteQueryOptions,\n queryMetadataQueryOptions,\n } = useSearchQueryUseQueryOptions(\n currentQueryRequest as QueryBundleRequest,\n searchIndexId,\n synapseId,\n ) as unknown as TableQueryUseQueryOptions\n\n const hasFacetedSelectColumn = useHasFacetedSelectColumn(\n queryMetadataQueryOptions,\n )\n\n const hasResettableFilters = useMemo(() => {\n const request = getCurrentQueryRequest()\n return hasResettableFiltersUtil(request.query, undefined)\n }, [getCurrentQueryRequest])\n\n // Provides page-specific row query options using the search API, so components like\n // usePrefetchTableRows don't accidentally call the standard table query API with the\n // synthetic entity ID.\n const getRowDataQueryOptionsForPage = useCallback(\n (pageNumber: number) => {\n const queryWithUpdatedPage = transformQueryToGoToPage(\n { type: 'goToPage', pageNumber },\n cloneDeep(getCurrentQueryRequest()),\n )\n return (\n getSearchQueryUseQueryOptions(\n queryWithUpdatedPage,\n keyFactory,\n accessToken,\n searchIndexId,\n columnModels,\n ) as unknown as TableQueryUseQueryOptions\n ).rowDataQueryOptions\n },\n [\n getCurrentQueryRequest,\n keyFactory,\n accessToken,\n searchIndexId,\n columnModels,\n ],\n )\n\n // TODO: useDeepCompareMemoize cannot meaningfully compare functions — it falls back to\n // reference equality for them. The callbacks below (getCurrentQueryRequest, removeSelectedFacet,\n // getRowDataQueryOptionsForPage, etc.) behave identically to a shallow useMemo dep.\n // The correct fix is to deep-compare only serializable data fields and use a plain useMemo for\n // the full context object. QueryWrapper.tsx has the same issue; fix both together in a follow-up.\n const context: QueryContextType = useDeepCompareMemoize({\n isInfinite,\n entityId: undefined,\n versionNumber: undefined,\n nextQueryRequest,\n currentQueryRequest,\n getCurrentQueryRequest,\n getInitQueryRequest,\n executeQueryRequest: setQuery,\n hasFacetedSelectColumn,\n hasResettableFilters,\n removeSelectedFacet,\n removeValueFromSelectedFacet,\n resetQuery,\n removeQueryFilter,\n removeValueFromQueryFilter,\n onViewSharingSettingsClicked: undefined,\n addValueToSelectedFacet,\n combineRangeFacetConfig: undefined,\n setRangeFacetValue,\n resetDebounceTimer,\n rowDataQueryOptions,\n rowDataInfiniteQueryOptions,\n queryMetadataQueryOptions,\n currentPage,\n goToPage,\n pageSize,\n setPageSize,\n lockedColumn: undefined,\n fileIdColumnName: undefined,\n fileVersionColumnName: undefined,\n fileNameColumnName: undefined,\n getRowDataQueryOptionsForPage,\n })\n\n return (\n <QueryContextProvider queryContext={context}>\n {onQueryResultBundleChange && (\n <SearchQueryResultBundleChangeNotifier\n onQueryResultBundleChange={onQueryResultBundleChange}\n />\n )}\n {props.children}\n </QueryContextProvider>\n )\n}\n\n/**\n * Provides a QueryContext populated by results from the SearchQueryServicesApi rather than\n * the standard Table Query Services. All subcomponents that consume QueryContext can be\n * used unchanged within a SearchQueryWrapper tree.\n */\nexport function SearchQueryWrapper(props: SearchQueryWrapperProps) {\n return (\n <Provider>\n <SearchQueryWrapperInternal {...props} />\n </Provider>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuCA,IAAa,IAA2C,UAC3C,IAAqC,iBAAiB;AAgCnE,SAAS,EAAsC,EAC7C,gCAGC;CACD,IAAM,EAAE,iCAA8B,GAAiB,EAQjD,EAAE,YAAS,EAAS,EAAU;AAMpC,QALA,QAAgB;AACd,EAAI,KACF,EAA0B,KAAK,UAAU,EAAK,CAAC;IAEhD,CAAC,GAAM,EAA0B,CAAC,EAC9B;;AAGT,SAAS,EAA2B,GAAgC;AAClE,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAuC,GAAI,GAAS,CAAA,EAC5B,CAAA;;AAI9B,SAAS,EAAsC,GAAgC;CAC7E,IAAM,EACJ,kBAAkB,GAClB,kBACA,8BACA,gBAAa,IACb,kBACA,oBAAiB,OACf,GAEE,EAAE,eAAY,mBAAgB,GAAmB,EAEjD,EAAE,MAAM,MAA0B,EACtC,GACA,KAAA,GACA,EACE,cAAc,IACf,CACF,EACK,IAAoB,GAEpB,IAAY,GAAmB,cACjC,EAA8B,EAAkB,YAAY,GAC5D,KAAA,GAEE,EAAE,MAAM,MAAiB,EAC7B,GACA,KAAA,GACA,EAAE,oBAAoB,IAAM,EAC5B,EAAE,cAAc,IAAM,CACvB,EACK,IAAe,GAAc,aAAa,cAyB1C,EACJ,wBACA,2BACA,aACA,eACA,wBACA,iCACA,sBACA,+BACA,qBACA,wBACA,4BACA,uBACA,uBACA,gBACA,UAAA,GACA,aACA,mBAvBgC,EAAuB;EACvD,kBAfuB,EAAsB;GAC7C,cACE;GACF,UAAU;GACV,UAAU,EAA0B,YAAY;GAChD,OAAO;IACL,KAAK;IACL,gBAAgB,EAA0B,OAAO;IACjD,mBAAmB,EAA0B,OAAO;IACpD,OAAO,EAA0B,OAAO;IACxC,QAAQ,EAA0B,OAAO;IAC1C;GACF,CAGC;EACA;EACA;EACD,CAoBG,EAME,EACJ,wBACA,gCACA,iCACE,EACF,GACA,GACA,EACD;AA+ED,QACE,kBAAC,GAAD;EAAsB,cApCU,EAAsB;GACtD;GACA,UAAU,KAAA;GACV,eAAe,KAAA;GACf;GACA;GACA;GACA;GACA,qBAAqB;GACrB,wBAnD6B,EAC7B,EAkDA;GACA,sBAhD2B,QAEpB,EADS,GACgB,CAAQ,OAAO,KAAA,EAAU,EACxD,CAAC,EAAuB,CA6CzB;GACA;GACA;GACA;GACA;GACA;GACA,8BAA8B,KAAA;GAC9B;GACA,yBAAyB,KAAA;GACzB;GACA;GACA;GACA;GACA;GACA;GACA,UAAA;GACA;GACA;GACA,cAAc,KAAA;GACd,kBAAkB,KAAA;GAClB,uBAAuB,KAAA;GACvB,oBAAoB,KAAA;GACpB,+BA9DoC,GACnC,MAMG,EAL2B,EAC3B;IAAE,MAAM;IAAY;IAAY,EAChC,EAAU,GAAwB,CAAC,CAIjC,EACA,GACA,GACA,GACA,EACD,CACD,qBAEJ;IACE;IACA;IACA;IACA;IACA;IACD,CAwCD;GACD,CAGqC;YAApC,CACG,KACC,kBAAC,GAAD,EAC6B,8BAC3B,CAAA,EAEH,EAAM,SACc;;;AAS3B,SAAgB,EAAmB,GAAgC;AACjE,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAA4B,GAAI,GAAS,CAAA,EAChC,CAAA"}