synapse-react-client 4.0.12 → 4.0.15

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 (100) hide show
  1. package/dist/SWC.index.js +1 -1
  2. package/dist/components/ChallengeRegisterButton/ChallengeRegisterButton.d.ts.map +1 -1
  3. package/dist/components/ChallengeRegisterButton/ChallengeRegisterButton.js +76 -45
  4. package/dist/components/ChallengeRegisterButton/ChallengeRegisterButton.js.map +1 -1
  5. package/dist/components/ChallengeRequirementsModal/ChallengeRequirementsModal.d.ts.map +1 -1
  6. package/dist/components/ChallengeRequirementsModal/ChallengeRequirementsModal.js +2 -2
  7. package/dist/components/ChallengeRequirementsModal/ChallengeRequirementsModal.js.map +1 -1
  8. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.d.ts.map +1 -1
  9. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js +2 -2
  10. package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js.map +1 -1
  11. package/dist/components/DataGrid/utils/DataGridUtils.js +1 -1
  12. package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
  13. package/dist/components/DraggableDialog/DraggableDialog.js +21 -21
  14. package/dist/components/DraggableDialog/DraggableDialog.js.map +1 -1
  15. package/dist/components/EntityDownloadButton/EntityDownloadButton.d.ts +6 -0
  16. package/dist/components/EntityDownloadButton/EntityDownloadButton.d.ts.map +1 -1
  17. package/dist/components/EntityDownloadButton/EntityDownloadButton.js +6 -1
  18. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  19. package/dist/components/FullTextSearch/FullTextSearch.d.ts.map +1 -1
  20. package/dist/components/FullTextSearch/FullTextSearch.js +28 -20
  21. package/dist/components/FullTextSearch/FullTextSearch.js.map +1 -1
  22. package/dist/components/FullTextSearch/FullTextSearchUtils.d.ts.map +1 -1
  23. package/dist/components/FullTextSearch/FullTextSearchUtils.js +7 -2
  24. package/dist/components/FullTextSearch/FullTextSearchUtils.js.map +1 -1
  25. package/dist/components/GenericCard/BioregistryRules.d.ts.map +1 -1
  26. package/dist/components/GenericCard/BioregistryRules.js +9 -1
  27. package/dist/components/GenericCard/BioregistryRules.js.map +1 -1
  28. package/dist/components/Goals/Goals.Desktop.d.ts +3 -1
  29. package/dist/components/Goals/Goals.Desktop.d.ts.map +1 -1
  30. package/dist/components/Goals/Goals.Desktop.js +2 -3
  31. package/dist/components/Goals/Goals.Desktop.js.map +1 -1
  32. package/dist/components/Goals/Goals.d.ts +1 -0
  33. package/dist/components/Goals/Goals.d.ts.map +1 -1
  34. package/dist/components/Goals/Goals.js +33 -27
  35. package/dist/components/Goals/Goals.js.map +1 -1
  36. package/dist/components/Markdown/widget/MarkdownTableOfContents.d.ts.map +1 -1
  37. package/dist/components/Markdown/widget/MarkdownTableOfContents.js +15 -11
  38. package/dist/components/Markdown/widget/MarkdownTableOfContents.js.map +1 -1
  39. package/dist/components/QueryWrapper/useOnQueryDataChange.d.ts.map +1 -1
  40. package/dist/components/QueryWrapper/useOnQueryDataChange.js +19 -17
  41. package/dist/components/QueryWrapper/useOnQueryDataChange.js.map +1 -1
  42. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
  43. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +2 -2
  44. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
  45. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts.map +1 -1
  46. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js +30 -30
  47. package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js.map +1 -1
  48. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts +1 -1
  49. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts.map +1 -1
  50. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js +4 -2
  51. package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js.map +1 -1
  52. package/dist/components/SynapseHomepageV2/WordPressNews.d.ts.map +1 -1
  53. package/dist/components/SynapseHomepageV2/WordPressNews.js +13 -36
  54. package/dist/components/SynapseHomepageV2/WordPressNews.js.map +1 -1
  55. package/dist/components/SynapseSearchPageResults/SearchPagePortalBanners.d.ts.map +1 -1
  56. package/dist/components/SynapseSearchPageResults/SearchPagePortalBanners.js +1 -1
  57. package/dist/components/SynapseSearchPageResults/SearchPagePortalBanners.js.map +1 -1
  58. package/dist/components/SynapseSearchPageResults/SynapseSearchPageRouter.d.ts.map +1 -1
  59. package/dist/components/SynapseSearchPageResults/SynapseSearchPageRouter.js +14 -12
  60. package/dist/components/SynapseSearchPageResults/SynapseSearchPageRouter.js.map +1 -1
  61. package/dist/components/SynapseTable/SearchV2.d.ts +11 -0
  62. package/dist/components/SynapseTable/SearchV2.d.ts.map +1 -1
  63. package/dist/components/SynapseTable/SearchV2.js.map +1 -1
  64. package/dist/components/WordPress/WordPressLatestPostChip.css +1 -0
  65. package/dist/components/WordPress/WordPressLatestPostChip.d.ts +5 -0
  66. package/dist/components/WordPress/WordPressLatestPostChip.d.ts.map +1 -0
  67. package/dist/components/WordPress/WordPressLatestPostChip.js +29 -0
  68. package/dist/components/WordPress/WordPressLatestPostChip.js.map +1 -0
  69. package/dist/components/WordPress/WordPressLatestPostChip.module.js +9 -0
  70. package/dist/components/WordPress/WordPressLatestPostChip.module.js.map +1 -0
  71. package/dist/components/WordPress/WordPressLatestPostChip.module.scss +33 -0
  72. package/dist/components/WordPress/useWordPressCategories.d.ts +3 -0
  73. package/dist/components/WordPress/useWordPressCategories.d.ts.map +1 -0
  74. package/dist/components/WordPress/useWordPressCategories.js +19 -0
  75. package/dist/components/WordPress/useWordPressCategories.js.map +1 -0
  76. package/dist/components/WordPress/useWordPressPosts.d.ts +3 -0
  77. package/dist/components/WordPress/useWordPressPosts.d.ts.map +1 -0
  78. package/dist/components/WordPress/useWordPressPosts.js +23 -0
  79. package/dist/components/WordPress/useWordPressPosts.js.map +1 -0
  80. package/dist/features/curator/dashboard/components/CurationTaskCard.js +1 -1
  81. package/dist/features/curator/dashboard/components/CurationTaskCard.js.map +1 -1
  82. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
  83. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +6 -6
  84. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  85. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.d.ts.map +1 -1
  86. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js +24 -20
  87. package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js.map +1 -1
  88. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts +2 -2
  89. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts.map +1 -1
  90. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js +30 -21
  91. package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js.map +1 -1
  92. package/dist/features/entity/metadata-task/utils/constants.d.ts +1 -0
  93. package/dist/features/entity/metadata-task/utils/constants.d.ts.map +1 -1
  94. package/dist/features/entity/metadata-task/utils/constants.js +2 -2
  95. package/dist/features/entity/metadata-task/utils/constants.js.map +1 -1
  96. package/dist/tsconfig.build.tsbuildinfo +1 -1
  97. package/dist/utils/hooks/useShowDesktop.d.ts.map +1 -1
  98. package/dist/utils/hooks/useShowDesktop.js +4 -9
  99. package/dist/utils/hooks/useShowDesktop.js.map +1 -1
  100. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"Goals.js","names":[],"sources":["../../../src/components/Goals/Goals.tsx"],"sourcesContent":["import useGetQueryResultBundle from '@/synapse-queries/entity/useGetQueryResultBundle'\nimport { SynapseConstants } from '@/utils'\nimport { getFieldIndex } from '@/utils/functions/queryUtils'\nimport useGetGoalData from '@/utils/hooks/useGetGoalData'\nimport useShowDesktop from '@/utils/hooks/useShowDesktop'\nimport { QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport { useMemo } from 'react'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport GoalsDesktop from './Goals.Desktop'\nimport GoalsMobile from './Goals.Mobile'\nimport { Box } from '@mui/material'\n\nexport type GoalsProps = {\n entityId: string\n isAssetIcon?: boolean // If true, the asset will be used as an icon instead of a background image.\n linkText?: string\n}\n\nexport type GoalsDataProps = {\n countSql?: string\n title: string\n summary: string\n link: string\n asset: string\n isAssetIcon: boolean\n linkText?: string\n}\n\nenum ExpectedColumns {\n TABLEID = 'TableId', // Both TableId or CountSql are used to indicate what Table rows to count.\n COUNT_SQL = 'CountSql', // Code uses CountSql over TableId if defined (if the CountSql column is in the schema and filled in).\n TITLE = 'Title',\n SUMMARY = 'Summary',\n LINK = 'Link',\n ASSET = 'Asset',\n}\n\n// PORTALS-2367\nconst GOALS_DESKTOP_MIN_BREAKPOINT = 1200\n\nexport function Goals(props: GoalsProps) {\n const { entityId, isAssetIcon = false, linkText } = props\n const showDesktop = useShowDesktop(GOALS_DESKTOP_MIN_BREAKPOINT)\n const queryBundleRequest: QueryBundleRequest = {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n entityId,\n partMask:\n SynapseConstants.BUNDLE_MASK_QUERY_SELECT_COLUMNS |\n SynapseConstants.BUNDLE_MASK_QUERY_RESULTS,\n query: {\n sql: `select *\n from ${entityId}\n order by ItemOrder`,\n },\n }\n const { data: queryResultBundle } =\n useGetQueryResultBundle(queryBundleRequest)\n\n const { assets: goalAssets, error: goalError } = useGetGoalData(\n entityId,\n queryResultBundle,\n )\n\n const tableIdColumnIndex = getFieldIndex(\n ExpectedColumns.TABLEID,\n queryResultBundle,\n )\n const countSqlColumnIndex = getFieldIndex(\n ExpectedColumns.COUNT_SQL,\n queryResultBundle,\n )\n\n const titleColumnIndex = getFieldIndex(\n ExpectedColumns.TITLE,\n queryResultBundle,\n )\n const summaryColumnIndex = getFieldIndex(\n ExpectedColumns.SUMMARY,\n queryResultBundle,\n )\n const linkColumnIndex = getFieldIndex(ExpectedColumns.LINK, queryResultBundle)\n\n const goalsDataProps = useMemo(() => {\n return queryResultBundle?.queryResult!.queryResults.rows.map(\n (el, index): GoalsDataProps => {\n const values = el.values as string[]\n if (values.some(value => value === null)) {\n // We cast values above assuming there are no null values, emit a warning just in case.\n console.warn('Row has null value(s) when no nulls expected')\n }\n const tableId =\n tableIdColumnIndex > -1 ? values[tableIdColumnIndex] : undefined\n let countSql\n if (countSqlColumnIndex > -1 && values[countSqlColumnIndex]) {\n countSql = values[countSqlColumnIndex]\n } else if (tableId) {\n countSql = `SELECT * FROM ${tableId}`\n }\n const title = values[titleColumnIndex]\n const summary = values[summaryColumnIndex]\n const link = values[linkColumnIndex]\n // assume that we recieve assets in order of rows and there is an asset for each item\n // can revisit if this isn't the case.\n const asset = goalAssets?.[index] ?? ''\n return {\n countSql,\n title,\n summary,\n link,\n asset,\n isAssetIcon,\n }\n },\n )\n }, [\n countSqlColumnIndex,\n goalAssets,\n linkColumnIndex,\n queryResultBundle?.queryResult,\n summaryColumnIndex,\n tableIdColumnIndex,\n titleColumnIndex,\n ])\n\n if (goalError) {\n return <ErrorBanner error={goalError} />\n }\n\n if (!goalsDataProps) {\n return <></>\n }\n\n if (showDesktop) {\n return (\n <Box\n className={`Goals`}\n sx={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: '7px',\n alignItems: 'stretch',\n justifyContent: 'center',\n }}\n >\n {goalsDataProps.map((props, index) => (\n <GoalsDesktop key={index} {...props} linkText={linkText} />\n ))}\n </Box>\n )\n } else {\n return (\n <div className={`Goals`}>\n {goalsDataProps.map((props, index) => (\n <GoalsMobile key={index} {...props} linkText={linkText} />\n ))}\n </div>\n )\n }\n}\nexport default Goals\n"],"mappings":";;;;;;;;;;;;;AA4BA,IAAK,IAAL,yBAAA,GAAA;QACE,EAAA,UAAU,WACV,EAAA,YAAY,YACZ,EAAA,QAAQ,SACR,EAAA,UAAU,WACV,EAAA,OAAO,QACP,EAAA,QAAQ;EANL,KAAA,EAAA,CAOJ,EAGK,IAA+B;AAErC,SAAgB,EAAM,GAAmB;CACvC,IAAM,EAAE,aAAU,iBAAc,IAAO,gBAAa,GAC9C,IAAc,EAAe,EAA6B,EAa1D,EAAE,MAAM,MACZ,EAAwB;EAZxB,cAAc;EACd;EACA,UACE;EAEF,OAAO,EACL,KAAK;mBACQ,EAAS;iCAEvB;EAGuB,CAAmB,EAEvC,EAAE,QAAQ,GAAY,OAAO,MAAc,EAC/C,GACA,EACD,EAEK,IAAqB,EACzB,EAAgB,SAChB,EACD,EACK,IAAsB,EAC1B,EAAgB,WAChB,EACD,EAEK,IAAmB,EACvB,EAAgB,OAChB,EACD,EACK,IAAqB,EACzB,EAAgB,SAChB,EACD,EACK,IAAkB,EAAc,EAAgB,MAAM,EAAkB,EAExE,IAAiB,QACd,GAAmB,YAAa,aAAa,KAAK,KACtD,GAAI,MAA0B;EAC7B,IAAM,IAAS,EAAG;AAClB,EAAI,EAAO,MAAK,MAAS,MAAU,KAAK,IAEtC,QAAQ,KAAK,+CAA+C;EAE9D,IAAM,IACJ,IAAqB,KAAK,EAAO,KAAsB,KAAA,GACrD;AACJ,EAAI,IAAsB,MAAM,EAAO,KACrC,IAAW,EAAO,KACT,MACT,IAAW,iBAAiB;EAE9B,IAAM,IAAQ,EAAO,IACf,IAAU,EAAO,IACjB,IAAO,EAAO,IAGd,IAAQ,IAAa,MAAU;AACrC,SAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACD;GAEJ,EACA;EACD;EACA;EACA;EACA,GAAmB;EACnB;EACA;EACA;EACD,CAAC;AA4BA,QA1BE,IACK,kBAAC,GAAD,EAAa,OAAO,GAAa,CAAA,GAGrC,IAID,IAEA,kBAAC,GAAD;EACE,WAAW;EACX,IAAI;GACF,SAAS;GACT,UAAU;GACV,KAAK;GACL,YAAY;GACZ,gBAAgB;GACjB;YAEA,EAAe,KAAK,GAAO,MAC1B,kBAAC,GAAD;GAA0B,GAAI;GAAiB;GAAY,EAAxC,EAAwC,CAC3D;EACE,CAAA,GAIN,kBAAC,OAAD;EAAK,WAAW;YACb,EAAe,KAAK,GAAO,MAC1B,kBAAC,GAAD;GAAyB,GAAI;GAAiB;GAAY,EAAxC,EAAwC,CAC1D;EACE,CAAA,GA1BD,kBAAA,GAAA,EAAK,CAAA"}
1
+ {"version":3,"file":"Goals.js","names":[],"sources":["../../../src/components/Goals/Goals.tsx"],"sourcesContent":["import useGetQueryResultBundle from '@/synapse-queries/entity/useGetQueryResultBundle'\nimport { SynapseConstants } from '@/utils'\nimport { getFieldIndex } from '@/utils/functions/queryUtils'\nimport useGetGoalData from '@/utils/hooks/useGetGoalData'\nimport useShowDesktop from '@/utils/hooks/useShowDesktop'\nimport { QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport { useMemo } from 'react'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport GoalsDesktop from './Goals.Desktop'\nimport GoalsMobile from './Goals.Mobile'\nimport { Box } from '@mui/material'\n\nexport type GoalsProps = {\n entityId: string\n isAssetIcon?: boolean // If true, the asset will be used as an icon instead of a background image.\n linkText?: string\n itemsPerRow?: number\n}\n\nexport type GoalsDataProps = {\n countSql?: string\n title: string\n summary: string\n link: string\n asset: string\n isAssetIcon: boolean\n linkText?: string\n}\n\nenum ExpectedColumns {\n TABLEID = 'TableId', // Both TableId or CountSql are used to indicate what Table rows to count.\n COUNT_SQL = 'CountSql', // Code uses CountSql over TableId if defined (if the CountSql column is in the schema and filled in).\n TITLE = 'Title',\n SUMMARY = 'Summary',\n LINK = 'Link',\n ASSET = 'Asset',\n}\n\n// PORTALS-2367\nconst GOALS_DESKTOP_MIN_BREAKPOINT = 1200\n\nexport function Goals(props: GoalsProps) {\n const { entityId, isAssetIcon = false, linkText, itemsPerRow = 3 } = props\n const showDesktop = useShowDesktop(GOALS_DESKTOP_MIN_BREAKPOINT)\n const queryBundleRequest: QueryBundleRequest = {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n entityId,\n partMask:\n SynapseConstants.BUNDLE_MASK_QUERY_SELECT_COLUMNS |\n SynapseConstants.BUNDLE_MASK_QUERY_RESULTS,\n query: {\n sql: `select *\n from ${entityId}\n order by ItemOrder`,\n },\n }\n const { data: queryResultBundle } =\n useGetQueryResultBundle(queryBundleRequest)\n\n const { assets: goalAssets, error: goalError } = useGetGoalData(\n entityId,\n queryResultBundle,\n )\n\n const tableIdColumnIndex = getFieldIndex(\n ExpectedColumns.TABLEID,\n queryResultBundle,\n )\n const countSqlColumnIndex = getFieldIndex(\n ExpectedColumns.COUNT_SQL,\n queryResultBundle,\n )\n\n const titleColumnIndex = getFieldIndex(\n ExpectedColumns.TITLE,\n queryResultBundle,\n )\n const summaryColumnIndex = getFieldIndex(\n ExpectedColumns.SUMMARY,\n queryResultBundle,\n )\n const linkColumnIndex = getFieldIndex(ExpectedColumns.LINK, queryResultBundle)\n\n const goalsDataProps = useMemo(() => {\n return queryResultBundle?.queryResult!.queryResults.rows.map(\n (el, index): GoalsDataProps => {\n const values = el.values as string[]\n if (values.some(value => value === null)) {\n // We cast values above assuming there are no null values, emit a warning just in case.\n console.warn('Row has null value(s) when no nulls expected')\n }\n const tableId =\n tableIdColumnIndex > -1 ? values[tableIdColumnIndex] : undefined\n let countSql\n if (countSqlColumnIndex > -1 && values[countSqlColumnIndex]) {\n countSql = values[countSqlColumnIndex]\n } else if (tableId) {\n countSql = `SELECT * FROM ${tableId}`\n }\n const title = values[titleColumnIndex]\n const summary = values[summaryColumnIndex]\n const link = values[linkColumnIndex]\n // assume that we recieve assets in order of rows and there is an asset for each item\n // can revisit if this isn't the case.\n const asset = goalAssets?.[index] ?? ''\n return {\n countSql,\n title,\n summary,\n link,\n asset,\n isAssetIcon,\n }\n },\n )\n }, [\n countSqlColumnIndex,\n goalAssets,\n linkColumnIndex,\n queryResultBundle?.queryResult,\n summaryColumnIndex,\n tableIdColumnIndex,\n titleColumnIndex,\n ])\n\n if (goalError) {\n return <ErrorBanner error={goalError} />\n }\n\n if (!goalsDataProps) {\n return <></>\n }\n\n if (showDesktop) {\n // Each card has margin:10px (20px horizontal) from .Goals__Card CSS.\n // flex-basis must be the content width only; total row = N*(flex-basis+20) + (N-1)*gap.\n // Subtract 0.5px epsilon to absorb sub-pixel rounding and prevent wrapping.\n const horizontalMarginPerCard = 20\n const cardWidth = `calc((100% - ${\n itemsPerRow * horizontalMarginPerCard + (itemsPerRow - 1) * 7\n }px) / ${itemsPerRow} - 0.5px)`\n return (\n <Box\n className={`Goals`}\n sx={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: '7px',\n justifyContent: 'center',\n alignItems: 'stretch',\n }}\n >\n {goalsDataProps.map((props, index) => (\n <GoalsDesktop\n key={index}\n {...props}\n linkText={linkText}\n cardWidth={cardWidth}\n />\n ))}\n </Box>\n )\n } else {\n return (\n <div className={`Goals`}>\n {goalsDataProps.map((props, index) => (\n <GoalsMobile key={index} {...props} linkText={linkText} />\n ))}\n </div>\n )\n }\n}\nexport default Goals\n"],"mappings":";;;;;;;;;;;;;AA6BA,IAAK,IAAL,yBAAA,GAAA;QACE,EAAA,UAAU,WACV,EAAA,YAAY,YACZ,EAAA,QAAQ,SACR,EAAA,UAAU,WACV,EAAA,OAAO,QACP,EAAA,QAAQ;EANL,KAAA,EAAA,CAOJ,EAGK,IAA+B;AAErC,SAAgB,EAAM,GAAmB;CACvC,IAAM,EAAE,aAAU,iBAAc,IAAO,aAAU,iBAAc,MAAM,GAC/D,IAAc,EAAe,EAA6B,EAa1D,EAAE,MAAM,MACZ,EAAwB;EAZxB,cAAc;EACd;EACA,UACE;EAEF,OAAO,EACL,KAAK;mBACQ,EAAS;iCAEvB;EAGuB,CAAmB,EAEvC,EAAE,QAAQ,GAAY,OAAO,MAAc,EAC/C,GACA,EACD,EAEK,IAAqB,EACzB,EAAgB,SAChB,EACD,EACK,IAAsB,EAC1B,EAAgB,WAChB,EACD,EAEK,IAAmB,EACvB,EAAgB,OAChB,EACD,EACK,IAAqB,EACzB,EAAgB,SAChB,EACD,EACK,IAAkB,EAAc,EAAgB,MAAM,EAAkB,EAExE,IAAiB,QACd,GAAmB,YAAa,aAAa,KAAK,KACtD,GAAI,MAA0B;EAC7B,IAAM,IAAS,EAAG;AAClB,EAAI,EAAO,MAAK,MAAS,MAAU,KAAK,IAEtC,QAAQ,KAAK,+CAA+C;EAE9D,IAAM,IACJ,IAAqB,KAAK,EAAO,KAAsB,KAAA,GACrD;AACJ,EAAI,IAAsB,MAAM,EAAO,KACrC,IAAW,EAAO,KACT,MACT,IAAW,iBAAiB;EAE9B,IAAM,IAAQ,EAAO,IACf,IAAU,EAAO,IACjB,IAAO,EAAO,IAGd,IAAQ,IAAa,MAAU;AACrC,SAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACD;GAEJ,EACA;EACD;EACA;EACA;EACA,GAAmB;EACnB;EACA;EACA;EACD,CAAC;AAEF,KAAI,EACF,QAAO,kBAAC,GAAD,EAAa,OAAO,GAAa,CAAA;AAG1C,KAAI,CAAC,EACH,QAAO,kBAAA,GAAA,EAAK,CAAA;AAGd,KAAI,GAAa;EAKf,IAAM,IAAY,gBAChB,IAAc,MAA2B,IAAc,KAAK,EAC7D,QAAQ,EAAY;AACrB,SACE,kBAAC,GAAD;GACE,WAAW;GACX,IAAI;IACF,SAAS;IACT,UAAU;IACV,KAAK;IACL,gBAAgB;IAChB,YAAY;IACb;aAEA,EAAe,KAAK,GAAO,MAC1B,kBAAC,GAAD;IAEE,GAAI;IACM;IACC;IACX,EAJK,EAIL,CACF;GACE,CAAA;OAGR,QACE,kBAAC,OAAD;EAAK,WAAW;YACb,EAAe,KAAK,GAAO,MAC1B,kBAAC,GAAD;GAAyB,GAAI;GAAiB;GAAY,EAAxC,EAAwC,CAC1D;EACE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownTableOfContents.d.ts","sourceRoot":"","sources":["../../../../src/components/Markdown/widget/MarkdownTableOfContents.tsx"],"names":[],"mappings":"AASA,KAAK,4BAA4B,GAAG;IAClC,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAC7C,KAAK,EAAE,4BAA4B,2CAuBpC"}
1
+ {"version":3,"file":"MarkdownTableOfContents.d.ts","sourceRoot":"","sources":["../../../../src/components/Markdown/widget/MarkdownTableOfContents.tsx"],"names":[],"mappings":"AAWA,KAAK,4BAA4B,GAAG;IAClC,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAC7C,KAAK,EAAE,4BAA4B,2CAwBpC"}
@@ -1,6 +1,7 @@
1
- import { jsx as e } from "react/jsx-runtime";
1
+ import { stripHTML as e } from "../MarkdownUtils.js";
2
+ import { jsx as t } from "react/jsx-runtime";
2
3
  //#region src/components/Markdown/widget/MarkdownTableOfContents.tsx
3
- var t = {
4
+ var n = {
4
5
  1: "toc-indent1",
5
6
  2: "toc-indent2",
6
7
  3: "toc-indent3",
@@ -8,16 +9,19 @@ var t = {
8
9
  5: "toc-indent5",
9
10
  6: "toc-indent6"
10
11
  };
11
- function n(n) {
12
- let { originalMarkup: r } = n, i = [], a = /<h([1-6]) id="(.*)" .*toc="true">(.*)<\/h[1-6]>/gm, o = "";
13
- return r.replace(a, (n, r, a, s) => (o += s, i.push(/* @__PURE__ */ e("div", { children: /* @__PURE__ */ e("a", {
14
- role: "link",
15
- className: `link ${t[Number(r)]}`,
16
- "data-anchor": a,
17
- children: s
18
- }) }, s)), "")), /* @__PURE__ */ e("div", { children: i }, o);
12
+ function r(r) {
13
+ let { originalMarkup: i } = r, a = [], o = /<h([1-6]) id="(.*)" .*toc="true">(.*)<\/h[1-6]>/gm, s = "";
14
+ return i.replace(o, (r, i, o, c) => {
15
+ let l = e(c);
16
+ return s += l, a.push(/* @__PURE__ */ t("div", { children: /* @__PURE__ */ t("a", {
17
+ role: "link",
18
+ className: `link ${n[Number(i)]}`,
19
+ "data-anchor": o,
20
+ children: l
21
+ }) }, l)), "";
22
+ }), /* @__PURE__ */ t("div", { children: a }, s);
19
23
  }
20
24
  //#endregion
21
- export { n as default };
25
+ export { r as default };
22
26
 
23
27
  //# sourceMappingURL=MarkdownTableOfContents.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownTableOfContents.js","names":[],"sources":["../../../../src/components/Markdown/widget/MarkdownTableOfContents.tsx"],"sourcesContent":["const TOC_CLASS = {\n 1: 'toc-indent1',\n 2: 'toc-indent2',\n 3: 'toc-indent3',\n 4: 'toc-indent4',\n 5: 'toc-indent5',\n 6: 'toc-indent6',\n}\n\ntype MarkdownTableOfContentsProps = {\n originalMarkup: string\n}\n\nexport default function MarkdownTableOfContents(\n props: MarkdownTableOfContentsProps,\n) {\n const { originalMarkup } = props\n const elements: any[] = []\n const TOC_HEADER_REGEX_WITH_ID =\n /<h([1-6]) id=\"(.*)\" .*toc=\"true\">(.*)<\\/h[1-6]>/gm\n let text = ''\n originalMarkup.replace(TOC_HEADER_REGEX_WITH_ID, (p1, p2, p3, p4) => {\n text += p4\n elements.push(\n <div key={p4}>\n <a\n role=\"link\"\n className={`link ${TOC_CLASS[Number(p2) as keyof typeof TOC_CLASS]}`}\n data-anchor={p3}\n >\n {p4}\n </a>\n </div>,\n )\n return ''\n })\n return <div key={text}>{elements}</div>\n}\n"],"mappings":";;AAAA,IAAM,IAAY;CAChB,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAMD,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,sBAAmB,GACrB,IAAkB,EAAE,EACpB,IACJ,qDACE,IAAO;AAgBX,QAfA,EAAe,QAAQ,IAA2B,GAAI,GAAI,GAAI,OAC5D,KAAQ,GACR,EAAS,KACP,kBAAC,OAAD,EAAA,UACE,kBAAC,KAAD;EACE,MAAK;EACL,WAAW,QAAQ,EAAU,OAAO,EAAG;EACvC,eAAa;YAEZ;EACC,CAAA,EACA,EARI,EAQJ,CACP,EACM,IACP,EACK,kBAAC,OAAD,EAAA,UAAiB,GAAe,EAAtB,EAAsB"}
1
+ {"version":3,"file":"MarkdownTableOfContents.js","names":[],"sources":["../../../../src/components/Markdown/widget/MarkdownTableOfContents.tsx"],"sourcesContent":["import { stripHTML } from '../MarkdownUtils'\n\nconst TOC_CLASS = {\n 1: 'toc-indent1',\n 2: 'toc-indent2',\n 3: 'toc-indent3',\n 4: 'toc-indent4',\n 5: 'toc-indent5',\n 6: 'toc-indent6',\n}\n\ntype MarkdownTableOfContentsProps = {\n originalMarkup: string\n}\n\nexport default function MarkdownTableOfContents(\n props: MarkdownTableOfContentsProps,\n) {\n const { originalMarkup } = props\n const elements: any[] = []\n const TOC_HEADER_REGEX_WITH_ID =\n /<h([1-6]) id=\"(.*)\" .*toc=\"true\">(.*)<\\/h[1-6]>/gm\n let text = ''\n originalMarkup.replace(TOC_HEADER_REGEX_WITH_ID, (p1, p2, p3, p4) => {\n const headingText = stripHTML(p4)\n text += headingText\n elements.push(\n <div key={headingText}>\n <a\n role=\"link\"\n className={`link ${TOC_CLASS[Number(p2) as keyof typeof TOC_CLASS]}`}\n data-anchor={p3}\n >\n {headingText}\n </a>\n </div>,\n )\n return ''\n })\n return <div key={text}>{elements}</div>\n}\n"],"mappings":";;;AAEA,IAAM,IAAY;CAChB,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAMD,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,sBAAmB,GACrB,IAAkB,EAAE,EACpB,IACJ,qDACE,IAAO;AAiBX,QAhBA,EAAe,QAAQ,IAA2B,GAAI,GAAI,GAAI,MAAO;EACnE,IAAM,IAAc,EAAU,EAAG;AAajC,SAZA,KAAQ,GACR,EAAS,KACP,kBAAC,OAAD,EAAA,UACE,kBAAC,KAAD;GACE,MAAK;GACL,WAAW,QAAQ,EAAU,OAAO,EAAG;GACvC,eAAa;aAEZ;GACC,CAAA,EACA,EARI,EAQJ,CACP,EACM;GACP,EACK,kBAAC,OAAD,EAAA,UAAiB,GAAe,EAAtB,EAAsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useOnQueryDataChange.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapper/useOnQueryDataChange.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,iCAAiC,CAAA;AAIxC,KAAK,2BAA2B,GAAG;IACjC,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAA;CAC5C,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAC1C,OAAO,EAAE,2BAA2B,QAqCrC"}
1
+ {"version":3,"file":"useOnQueryDataChange.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapper/useOnQueryDataChange.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,iCAAiC,CAAA;AAIxC,KAAK,2BAA2B,GAAG;IACjC,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAA;CAC5C,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAC1C,OAAO,EAAE,2BAA2B,QA4CrC"}
@@ -1,28 +1,30 @@
1
1
  import { useTableQueryUseQueryOptions as e } from "./TableQueryUseQueryOptions.js";
2
- import { useEffect as t, useState as n } from "react";
3
- import { useQuery as r } from "@tanstack/react-query";
4
- import { useDeepCompareEffectNoCheck as i } from "use-deep-compare-effect";
2
+ import { useEffect as t, useRef as n, useState as r } from "react";
3
+ import { useQuery as i } from "@tanstack/react-query";
4
+ import { useDeepCompareEffectNoCheck as a } from "use-deep-compare-effect";
5
5
  //#region src/components/QueryWrapper/useOnQueryDataChange.ts
6
- function a(a) {
7
- let { queryBundleRequest: o, onChange: s } = a, { rowDataQueryOptions: c, queryMetadataQueryOptions: l } = e(o), { data: u, isLoading: d } = r({
8
- ...c,
6
+ function o(o) {
7
+ let { queryBundleRequest: s, onChange: c } = o, { rowDataQueryOptions: l, queryMetadataQueryOptions: u } = e(s), { data: d, isLoading: f } = i({
8
+ ...l,
9
9
  select: (e) => e.responseBody
10
- }), { data: f, isLoading: p } = r(l), [m, h] = n();
10
+ }), { data: p, isLoading: m } = i(u), [h, g] = r();
11
11
  t(() => {
12
- u && f && !d && !p && h({
13
- ...f,
14
- ...u
12
+ d && p && !f && !m && g({
13
+ ...p,
14
+ ...d
15
15
  });
16
16
  }, [
17
- f,
18
17
  p,
19
- u,
20
- d
21
- ]), i(() => {
22
- m && s && s(m);
23
- }, [m, s]);
18
+ m,
19
+ d,
20
+ f
21
+ ]);
22
+ let _ = n(c);
23
+ _.current = c, a(() => {
24
+ h && _.current(h);
25
+ }, [h]);
24
26
  }
25
27
  //#endregion
26
- export { a as default };
28
+ export { o as default };
27
29
 
28
30
  //# sourceMappingURL=useOnQueryDataChange.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useOnQueryDataChange.js","names":[],"sources":["../../../src/components/QueryWrapper/useOnQueryDataChange.ts"],"sourcesContent":["import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect'\nimport { useQuery } from '@tanstack/react-query'\nimport {\n QueryBundleRequest,\n QueryResultBundle,\n} from '@sage-bionetworks/synapse-types'\nimport { useTableQueryUseQueryOptions } from './TableQueryUseQueryOptions'\nimport { useEffect, useState } from 'react'\n\ntype UseOnQueryDataChangeOptions = {\n queryBundleRequest: QueryBundleRequest\n onChange: (data: QueryResultBundle) => void\n}\n\n/**\n * Calls the onChange callback with the current QueryResultBundle when the data for the passed query changes\n * @param options\n */\nexport default function useOnQueryDataChange(\n options: UseOnQueryDataChangeOptions,\n) {\n const { queryBundleRequest, onChange } = options\n const { rowDataQueryOptions, queryMetadataQueryOptions } =\n useTableQueryUseQueryOptions(queryBundleRequest)\n\n const { data: rowData, isLoading: rowDataIsLoading } = useQuery({\n ...rowDataQueryOptions,\n select: asyncJobResponse => asyncJobResponse.responseBody,\n })\n const { data: queryMetadata, isLoading: queryMetadataIsLoading } = useQuery(\n queryMetadataQueryOptions,\n )\n\n // SWC requires the entire QueryResultBundle to enable editing table data, so merge the data back into one object before\n // passing it to the onChange callback\n const [mergedData, setMergedData] = useState<QueryResultBundle>()\n useEffect(() => {\n if (\n rowData &&\n queryMetadata &&\n !rowDataIsLoading &&\n !queryMetadataIsLoading\n ) {\n setMergedData({\n ...queryMetadata,\n ...rowData,\n })\n }\n }, [queryMetadata, queryMetadataIsLoading, rowData, rowDataIsLoading])\n\n // mergedData is sometimes undefined, which useDeepCompareEffect doesn't like, so use useDeepCompareEffectNoCheck instead\n useDeepCompareEffectNoCheck(() => {\n if (mergedData && onChange) {\n onChange(mergedData)\n }\n }, [mergedData, onChange])\n}\n"],"mappings":";;;;;AAkBA,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,uBAAoB,gBAAa,GACnC,EAAE,wBAAqB,iCAC3B,EAA6B,EAAmB,EAE5C,EAAE,MAAM,GAAS,WAAW,MAAqB,EAAS;EAC9D,GAAG;EACH,SAAQ,MAAoB,EAAiB;EAC9C,CAAC,EACI,EAAE,MAAM,GAAe,WAAW,MAA2B,EACjE,EACD,EAIK,CAAC,GAAY,KAAiB,GAA6B;AAgBjE,CAfA,QAAgB;AACd,EACE,KACA,KACA,CAAC,KACD,CAAC,KAED,EAAc;GACZ,GAAG;GACH,GAAG;GACJ,CAAC;IAEH;EAAC;EAAe;EAAwB;EAAS;EAAiB,CAAC,EAGtE,QAAkC;AAChC,EAAI,KAAc,KAChB,EAAS,EAAW;IAErB,CAAC,GAAY,EAAS,CAAC"}
1
+ {"version":3,"file":"useOnQueryDataChange.js","names":[],"sources":["../../../src/components/QueryWrapper/useOnQueryDataChange.ts"],"sourcesContent":["import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect'\nimport { useQuery } from '@tanstack/react-query'\nimport {\n QueryBundleRequest,\n QueryResultBundle,\n} from '@sage-bionetworks/synapse-types'\nimport { useTableQueryUseQueryOptions } from './TableQueryUseQueryOptions'\nimport { useEffect, useRef, useState } from 'react'\n\ntype UseOnQueryDataChangeOptions = {\n queryBundleRequest: QueryBundleRequest\n onChange: (data: QueryResultBundle) => void\n}\n\n/**\n * Calls the onChange callback with the current QueryResultBundle when the data for the passed query changes\n * @param options\n */\nexport default function useOnQueryDataChange(\n options: UseOnQueryDataChangeOptions,\n) {\n const { queryBundleRequest, onChange } = options\n const { rowDataQueryOptions, queryMetadataQueryOptions } =\n useTableQueryUseQueryOptions(queryBundleRequest)\n\n const { data: rowData, isLoading: rowDataIsLoading } = useQuery({\n ...rowDataQueryOptions,\n select: asyncJobResponse => asyncJobResponse.responseBody,\n })\n const { data: queryMetadata, isLoading: queryMetadataIsLoading } = useQuery(\n queryMetadataQueryOptions,\n )\n\n // SWC requires the entire QueryResultBundle to enable editing table data, so merge the data back into one object before\n // passing it to the onChange callback\n const [mergedData, setMergedData] = useState<QueryResultBundle>()\n useEffect(() => {\n if (\n rowData &&\n queryMetadata &&\n !rowDataIsLoading &&\n !queryMetadataIsLoading\n ) {\n setMergedData({\n ...queryMetadata,\n ...rowData,\n })\n }\n }, [queryMetadata, queryMetadataIsLoading, rowData, rowDataIsLoading])\n\n // Use a ref so we always call the latest onChange without including it in the\n // effect dependency array. Including a frequently-recreated callback in deps\n // causes the effect to re-fire on every render, creating an infinite loop when\n // the parent updates state inside the callback.\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n\n // mergedData is sometimes undefined, which useDeepCompareEffect doesn't like, so use useDeepCompareEffectNoCheck instead\n useDeepCompareEffectNoCheck(() => {\n if (mergedData) {\n onChangeRef.current(mergedData)\n }\n }, [mergedData])\n}\n"],"mappings":";;;;;AAkBA,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,uBAAoB,gBAAa,GACnC,EAAE,wBAAqB,iCAC3B,EAA6B,EAAmB,EAE5C,EAAE,MAAM,GAAS,WAAW,MAAqB,EAAS;EAC9D,GAAG;EACH,SAAQ,MAAoB,EAAiB;EAC9C,CAAC,EACI,EAAE,MAAM,GAAe,WAAW,MAA2B,EACjE,EACD,EAIK,CAAC,GAAY,KAAiB,GAA6B;AACjE,SAAgB;AACd,EACE,KACA,KACA,CAAC,KACD,CAAC,KAED,EAAc;GACZ,GAAG;GACH,GAAG;GACJ,CAAC;IAEH;EAAC;EAAe;EAAwB;EAAS;EAAiB,CAAC;CAMtE,IAAM,IAAc,EAAO,EAAS;AAIpC,CAHA,EAAY,UAAU,GAGtB,QAAkC;AAChC,EAAI,KACF,EAAY,QAAQ,EAAW;IAEhC,CAAC,EAAW,CAAC"}
@@ -1 +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"}
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,CAuEnB;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"}
@@ -60,13 +60,13 @@ function p(e, t, n) {
60
60
  headers: i,
61
61
  rows: a
62
62
  }
63
- } : void 0;
63
+ } : void 0, s = e.facets, c = n && s ? [...s.filter((e) => n.some((t) => t.name === e.columnName)).sort((e, t) => n.findIndex((t) => t.name === e.columnName) - n.findIndex((e) => e.name === t.columnName)), ...s.filter((e) => !n.some((t) => t.name === e.columnName))] : s;
64
64
  return {
65
65
  concreteType: "org.sagebionetworks.repo.model.table.QueryResultBundle",
66
66
  queryCount: e.totalHits,
67
67
  selectColumns: i,
68
68
  queryResult: o,
69
- facets: e.facets
69
+ facets: c
70
70
  };
71
71
  }
72
72
  function m(t, n, i, a, s) {
@@ -1 +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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"}
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 // Reorder facets to match the columnModels order so downstream components\n // (e.g. FacetFilterControls) render facets in the expected column order.\n const rawFacets = results.facets as QueryResultBundle['facets']\n const orderedFacets =\n columnModels && rawFacets\n ? [\n ...rawFacets\n .filter(f => columnModels.some(cm => cm.name === f.columnName))\n .sort(\n (a, b) =>\n columnModels.findIndex(cm => cm.name === a.columnName) -\n columnModels.findIndex(cm => cm.name === b.columnName),\n ),\n ...rawFacets.filter(\n f => !columnModels.some(cm => cm.name === f.columnName),\n ),\n ]\n : rawFacets\n\n return {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryResultBundle',\n queryCount: results.totalHits,\n selectColumns: headers,\n queryResult,\n facets: orderedFacets,\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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"}
@@ -1 +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"}
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,EACL,iBAAiB,EAKlB,MAAM,OAAO,CAAA;AAwBd;;;;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;AA8NF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,2CAMhE"}
@@ -10,31 +10,31 @@ import { goToPage as c } from "../../utils/hooks/useImmutableTableQuery/TableQue
10
10
  import l from "../../utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js";
11
11
  import u from "../QueryWrapper/useHasFacetedSelectColumn.js";
12
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";
13
+ import { useCallback as p, useEffect as m, useMemo as h, useRef as g } from "react";
14
+ import { cloneDeep as _ } from "lodash-es";
15
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
16
+ import { useQuery as b } from "@tanstack/react-query";
17
+ import { useDeepCompareMemoize as x } from "use-deep-compare-effect";
18
+ import { Provider as S } from "jotai";
19
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;
20
+ var C = "search", w = `SELECT * FROM ${C}`;
21
+ function T({ onQueryResultBundleChange: e }) {
22
+ let { queryMetadataQueryOptions: t } = s(), { data: n } = b(t), r = g(e);
23
+ return r.current = e, m(() => {
24
+ n && r.current(JSON.stringify(n));
25
+ }, [n]), null;
26
26
  }
27
- function T(e) {
28
- return /* @__PURE__ */ _(n, { children: /* @__PURE__ */ _(E, { ...e }) });
27
+ function E(e) {
28
+ return /* @__PURE__ */ v(n, { children: /* @__PURE__ */ v(D, { ...e }) });
29
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({
30
+ function D(n) {
31
+ let { initQueryRequest: s, onQueryChange: m, onQueryResultBundleChange: g, isInfinite: b = !1, searchIndexId: S, shouldDeepLink: E = !1 } = n, { keyFactory: D, accessToken: O } = t(), { data: k } = i(S, 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: x({
33
33
  concreteType: "org.sagebionetworks.repo.model.table.QueryBundleRequest",
34
- entityId: S,
34
+ entityId: C,
35
35
  partMask: s.partMask ?? 0,
36
36
  query: {
37
- sql: C,
37
+ sql: w,
38
38
  selectedFacets: s.query?.selectedFacets,
39
39
  additionalFilters: s.query?.additionalFilters,
40
40
  limit: s.query?.limit,
@@ -43,11 +43,11 @@ function E(n) {
43
43
  }),
44
44
  onQueryChange: m,
45
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,
46
+ }), { rowDataQueryOptions: Z, rowDataInfiniteQueryOptions: Q, queryMetadataQueryOptions: $ } = f(U, S, j);
47
+ return /* @__PURE__ */ y(o, {
48
+ queryContext: x({
49
+ isInfinite: b,
50
+ entityId: j,
51
51
  versionNumber: void 0,
52
52
  nextQueryRequest: H,
53
53
  currentQueryRequest: U,
@@ -80,21 +80,21 @@ function E(n) {
80
80
  getRowDataQueryOptionsForPage: p((e) => d(c({
81
81
  type: "goToPage",
82
82
  pageNumber: e
83
- }, g(F())), D, O, T, N).rowDataQueryOptions, [
83
+ }, _(F())), D, O, S, N).rowDataQueryOptions, [
84
84
  F,
85
85
  D,
86
86
  O,
87
- T,
87
+ S,
88
88
  N
89
89
  ])
90
90
  }),
91
- children: [y && /* @__PURE__ */ _(w, { onQueryResultBundleChange: y }), n.children]
91
+ children: [g && /* @__PURE__ */ v(T, { onQueryResultBundleChange: g }), n.children]
92
92
  });
93
93
  }
94
- function D(e) {
95
- return /* @__PURE__ */ _(x, { children: /* @__PURE__ */ _(T, { ...e }) });
94
+ function O(e) {
95
+ return /* @__PURE__ */ v(S, { children: /* @__PURE__ */ v(E, { ...e }) });
96
96
  }
97
97
  //#endregion
98
- export { S as SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID, C as SEARCH_QUERY_WRAPPER_SYNTHETIC_SQL, D as SearchQueryWrapper };
98
+ export { C as SEARCH_QUERY_WRAPPER_SYNTHETIC_ENTITY_ID, w as SEARCH_QUERY_WRAPPER_SYNTHETIC_SQL, O as SearchQueryWrapper };
99
99
 
100
100
  //# sourceMappingURL=SearchQueryWrapper.js.map
@@ -1 +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"}
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 {\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} 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 // Use a ref so we always call the latest callback without including it in the\n // effect dependency array. Including a frequently-recreated callback in deps\n // causes the effect to re-fire on every render, creating an infinite loop when\n // the parent updates state inside the callback.\n const onQueryResultBundleChangeRef = useRef(onQueryResultBundleChange)\n onQueryResultBundleChangeRef.current = onQueryResultBundleChange\n useEffect(() => {\n if (data) {\n onQueryResultBundleChangeRef.current(JSON.stringify(data))\n }\n }, [data])\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: synapseId,\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":";;;;;;;;;;;;;;;;;;;AA6CA,IAAa,IAA2C,UAC3C,IAAqC,iBAAiB;AAgCnE,SAAS,EAAsC,EAC7C,gCAGC;CACD,IAAM,EAAE,iCAA8B,GAAiB,EAQjD,EAAE,YAAS,EAAS,EAAU,EAK9B,IAA+B,EAAO,EAA0B;AAOtE,QANA,EAA6B,UAAU,GACvC,QAAgB;AACd,EAAI,KACF,EAA6B,QAAQ,KAAK,UAAU,EAAK,CAAC;IAE3D,CAAC,EAAK,CAAC,EACH;;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;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"}
@@ -24,7 +24,7 @@ type SearchQueryWrapperPlotNavOwnProps = {
24
24
  initialLimit?: number;
25
25
  hideTopLevelControls?: boolean;
26
26
  };
27
- export type SearchQueryWrapperPlotNavProps = SearchQueryWrapperPlotNavOwnProps & PlotsContainerProps & Pick<QueryVisualizationWrapperProps, 'defaultShowPlots' | 'visibleColumnCount' | 'columnAliases' | 'rgbIndex' | 'showLastUpdatedOn' | 'noContentPlaceholderType' | 'unitDescription' | 'helpConfiguration' | 'hideCopyToClipboard' | 'hideVisualizationsControl'> & Pick<TopLevelControlsProps, 'name' | 'hideQueryCount'> & {
27
+ export type SearchQueryWrapperPlotNavProps = SearchQueryWrapperPlotNavOwnProps & PlotsContainerProps & Pick<QueryVisualizationWrapperProps, 'defaultShowPlots' | 'visibleColumnCount' | 'columnAliases' | 'rgbIndex' | 'showLastUpdatedOn' | 'noContentPlaceholderType' | 'unitDescription' | 'helpConfiguration' | 'hideCopyToClipboard' | 'hideVisualizationsControl' | 'hideSearchBarControl' | 'defaultShowSearchBar'> & Pick<TopLevelControlsProps, 'name' | 'hideQueryCount'> & {
28
28
  /** Optional initial query parameters. Only selectedFacets, additionalFilters, limit, and offset are used. */
29
29
  initQueryRequest?: SearchQueryWrapperProps['initQueryRequest'];
30
30
  /** Called when the query result bundle changes (e.g. to report result counts to a parent). */
@@ -1 +1 @@
1
- {"version":3,"file":"SearchQueryWrapperPlotNav.d.ts","sourceRoot":"","sources":["../../../src/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAEL,8BAA8B,EAC/B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAA;AACtF,OAAO,EAEL,uBAAuB,EACxB,MAAM,0CAA0C,CAAA;AAIjD,KAAK,iCAAiC,GAAG;IACvC,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2HAA2H;IAC3H,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kBAAkB,CAAC,EAAE,yBAAyB,CAAA;IAC9C,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,eAAe,CAAC,EAAE,wBAAwB,CAAC,iBAAiB,CAAC,CAAA;IAC7D,4BAA4B,CAAC,EAAE,wBAAwB,CAAC,8BAA8B,CAAC,CAAA;IACvF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAI/B,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG,iCAAiC,GAC5E,mBAAmB,GACnB,IAAI,CACF,8BAA8B,EAC5B,kBAAkB,GAClB,oBAAoB,GACpB,eAAe,GACf,UAAU,GACV,mBAAmB,GACnB,0BAA0B,GAC1B,iBAAiB,GACjB,mBAAmB,GACnB,qBAAqB,GACrB,2BAA2B,CAC9B,GACD,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,gBAAgB,CAAC,GAAG;IACvD,6GAA6G;IAC7G,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAA;IAC9D,8FAA8F;IAC9F,yBAAyB,CAAC,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAA;IAChF,+EAA+E;IAC/E,cAAc,CAAC,EAAE,uBAAuB,CAAC,gBAAgB,CAAC,CAAA;CAC3D,CAAA;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACvD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd,GAAG,MAAM,IAAI,8BAA8B,CAE3C;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,KAAK,EAAE,8BAA8B,2CAiGtC"}
1
+ {"version":3,"file":"SearchQueryWrapperPlotNav.d.ts","sourceRoot":"","sources":["../../../src/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAEL,8BAA8B,EAC/B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAA;AACtF,OAAO,EAEL,uBAAuB,EACxB,MAAM,0CAA0C,CAAA;AAIjD,KAAK,iCAAiC,GAAG;IACvC,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2HAA2H;IAC3H,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kBAAkB,CAAC,EAAE,yBAAyB,CAAA;IAC9C,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,eAAe,CAAC,EAAE,wBAAwB,CAAC,iBAAiB,CAAC,CAAA;IAC7D,4BAA4B,CAAC,EAAE,wBAAwB,CAAC,8BAA8B,CAAC,CAAA;IACvF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAI/B,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG,iCAAiC,GAC5E,mBAAmB,GACnB,IAAI,CACF,8BAA8B,EAC5B,kBAAkB,GAClB,oBAAoB,GACpB,eAAe,GACf,UAAU,GACV,mBAAmB,GACnB,0BAA0B,GAC1B,iBAAiB,GACjB,mBAAmB,GACnB,qBAAqB,GACrB,2BAA2B,GAC3B,sBAAsB,GACtB,sBAAsB,CACzB,GACD,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,gBAAgB,CAAC,GAAG;IACvD,6GAA6G;IAC7G,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAA;IAC9D,8FAA8F;IAC9F,yBAAyB,CAAC,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAA;IAChF,+EAA+E;IAC/E,cAAc,CAAC,EAAE,uBAAuB,CAAC,gBAAgB,CAAC,CAAA;CAC3D,CAAA;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACvD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd,GAAG,MAAM,IAAI,8BAA8B,CAE3C;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,KAAK,EAAE,8BAA8B,2CAmGtC"}
@@ -39,8 +39,8 @@ function d(u) {
39
39
  visibleColumnCount: u.visibleColumnCount,
40
40
  defaultShowPlots: u.defaultShowPlots,
41
41
  hideCopyToClipboard: u.hideCopyToClipboard,
42
- hideSearchBarControl: !1,
43
- defaultShowSearchBar: !0,
42
+ hideSearchBarControl: u.hideSearchBarControl ?? !1,
43
+ defaultShowSearchBar: u.defaultShowSearchBar ?? !0,
44
44
  showLastUpdatedOn: u.showLastUpdatedOn,
45
45
  noContentPlaceholderType: u.noContentPlaceholderType ?? e.INTERACTIVE,
46
46
  children: /* @__PURE__ */ c(r, {
@@ -60,6 +60,8 @@ function d(u) {
60
60
  isFullTextSearchEnabled: !0,
61
61
  searchConfiguration: { ftsConfig: {
62
62
  textMatchesMode: "NATURAL_LANGUAGE",
63
+ minSearchQueryLength: 1,
64
+ replaceExistingFilter: !0,
63
65
  getSuggestions: v ? b : void 0
64
66
  } }
65
67
  })
@@ -1 +1 @@
1
- {"version":3,"file":"SearchQueryWrapperPlotNav.js","names":[],"sources":["../../../src/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.tsx"],"sourcesContent":["import { NoContentPlaceholderType } from '@/components/SynapseTable/NoContentPlaceholderType'\nimport { DEFAULT_PAGE_SIZE } from '@/utils/SynapseConstants'\nimport { Suspense, useRef } from 'react'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport { CardConfiguration } from '../CardContainer/CardConfiguration'\nimport {\n QueryVisualizationWrapper,\n QueryVisualizationWrapperProps,\n} from '../QueryVisualizationWrapper'\nimport QueryWrapperLoadingScreen from '../QueryWrapper/QueryWrapperLoadingScreen'\nimport { SynapseTableConfiguration } from '../SynapseTable'\nimport { TopLevelControlsProps } from '../SynapseTable/TopLevelControls/TopLevelControls'\nimport { PlotsContainerProps } from '../widgets/facet-nav/PlotsContainer'\nimport { FacetFilterControlsProps } from '../widgets/query-filter/FacetFilterControls'\nimport {\n SearchQueryWrapper,\n SearchQueryWrapperProps,\n} from '../SearchQueryWrapper/SearchQueryWrapper'\nimport { QueryWrapperPlotNavContents } from '../QueryWrapperPlotNav/QueryWrapperPlotNav'\nimport { useGetSuggestionsForSearchIndex } from '../SearchQueryWrapper/SearchQueryUseQueryOptions'\n\ntype SearchQueryWrapperPlotNavOwnProps = {\n /** The ID of the SearchIndex entity to query. */\n searchIndexId: string\n /**\n * The name of the field to use for autocomplete suggestions.\n * When provided, the search bar will show a dropdown of suggestions as the user types,\n * populated by querying the search index with this field restricted via POST /search/autocomplete.\n */\n autocompleteFieldName?: string\n /** Whether the displayed results should be paginated or infinite. Default for cards is true, default for table is false */\n isInfinite?: boolean\n tableConfiguration?: SynapseTableConfiguration\n cardConfiguration?: CardConfiguration\n facetsToPlot?: string[]\n availableFacets?: FacetFilterControlsProps['availableFacets']\n initialExpandedFacetControls?: FacetFilterControlsProps['initialExpandedFacetControls']\n initialLimit?: number\n hideTopLevelControls?: boolean\n // Note: hideDownload, hideSqlEditorControl are intentionally\n // excluded — they are hardcoded to true because these controls are not applicable to the\n // SearchQueryServicesApi (no file download, no SQL editing).\n}\n\nexport type SearchQueryWrapperPlotNavProps = SearchQueryWrapperPlotNavOwnProps &\n PlotsContainerProps &\n Pick<\n QueryVisualizationWrapperProps,\n | 'defaultShowPlots'\n | 'visibleColumnCount'\n | 'columnAliases'\n | 'rgbIndex'\n | 'showLastUpdatedOn'\n | 'noContentPlaceholderType'\n | 'unitDescription'\n | 'helpConfiguration'\n | 'hideCopyToClipboard'\n | 'hideVisualizationsControl'\n > &\n Pick<TopLevelControlsProps, 'name' | 'hideQueryCount'> & {\n /** Optional initial query parameters. Only selectedFacets, additionalFilters, limit, and offset are used. */\n initQueryRequest?: SearchQueryWrapperProps['initQueryRequest']\n /** Called when the query result bundle changes (e.g. to report result counts to a parent). */\n onQueryResultBundleChange?: SearchQueryWrapperProps['onQueryResultBundleChange']\n /** Whether the URL should update when the query is modified (deep linking). */\n shouldDeepLink?: SearchQueryWrapperProps['shouldDeepLink']\n }\n\n/**\n * Type guard that identifies a SearchQueryWrapperPlotNavProps from the union\n * `QueryWrapperPlotNavProps | SearchQueryWrapperPlotNavProps`.\n *\n * Two conditions are checked to be robust against future API changes:\n * 1. The config has `searchIndexId` (present only on SearchQueryWrapperPlotNavProps).\n * 2. The config does NOT have `sql` (always present on QueryWrapperPlotNavProps via\n * QueryOrDeprecatedSearchParams), so that if QueryWrapperPlotNavProps ever gains a\n * `searchIndexId` field the guard remains correct.\n */\nexport function isSearchQueryWrapperPlotNavProps(config: {\n searchIndexId?: unknown\n sql?: unknown\n}): config is SearchQueryWrapperPlotNavProps {\n return 'searchIndexId' in config && !('sql' in config)\n}\n\n/**\n * A component similar to QueryWrapperPlotNav that sources its data from the SearchQueryServicesApi\n * rather than the standard Synapse Table Services. Facets, table/card rendering, and plots are\n * all reused from the existing component library.\n */\nexport default function SearchQueryWrapperPlotNav(\n props: SearchQueryWrapperPlotNavProps,\n) {\n const {\n tableConfiguration,\n isInfinite = !tableConfiguration,\n unitDescription,\n helpConfiguration,\n initQueryRequest: initQueryRequestFromProps,\n onQueryResultBundleChange,\n searchIndexId,\n autocompleteFieldName,\n shouldDeepLink,\n } = props\n\n const getSuggestions = useGetSuggestionsForSearchIndex(\n searchIndexId,\n autocompleteFieldName,\n )\n\n const initQueryRequest: SearchQueryWrapperProps['initQueryRequest'] =\n useDeepCompareMemoize({\n partMask: initQueryRequestFromProps?.partMask ?? 0,\n query: {\n selectedFacets: initQueryRequestFromProps?.query?.selectedFacets,\n additionalFilters: initQueryRequestFromProps?.query?.additionalFilters,\n limit: initQueryRequestFromProps?.query?.limit ?? DEFAULT_PAGE_SIZE,\n offset: initQueryRequestFromProps?.query?.offset ?? 0,\n },\n })\n\n // Remount SearchQueryWrapper when initQueryRequest content changes.\n // useDeepCompareMemoize returns the same reference when content is equal, so reference\n // comparison is sufficient here. A counter is used rather than JSON.stringify to avoid\n // serializing the object on every render.\n const mountKeyRef = useRef(0)\n const prevInitQueryRef = useRef(initQueryRequest)\n if (prevInitQueryRef.current !== initQueryRequest) {\n mountKeyRef.current += 1\n prevInitQueryRef.current = initQueryRequest\n }\n\n return (\n <SearchQueryWrapper\n key={mountKeyRef.current}\n searchIndexId={searchIndexId}\n initQueryRequest={initQueryRequest}\n isInfinite={isInfinite}\n onQueryResultBundleChange={onQueryResultBundleChange}\n shouldDeepLink={shouldDeepLink}\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 hideSearchBarControl={false}\n defaultShowSearchBar={true}\n showLastUpdatedOn={props.showLastUpdatedOn}\n noContentPlaceholderType={\n props.noContentPlaceholderType ??\n NoContentPlaceholderType.INTERACTIVE\n }\n >\n <QueryWrapperPlotNavContents\n tableConfiguration={tableConfiguration}\n name={props.name}\n cardConfiguration={props.cardConfiguration}\n facetsToPlot={props.facetsToPlot}\n availableFacets={props.availableFacets}\n initialExpandedFacetControls={props.initialExpandedFacetControls}\n hideDownload={true}\n hideQueryCount={props.hideQueryCount ?? false}\n hideSqlEditorControl={true}\n hideVisualizationsControl={props.hideVisualizationsControl}\n initialLimit={props.initialLimit}\n initialPlotTypeByFacetColumnName={\n props.initialPlotTypeByFacetColumnName\n }\n hideTopLevelControls={props.hideTopLevelControls}\n isFullTextSearchEnabled={true}\n searchConfiguration={{\n ftsConfig: {\n textMatchesMode: 'NATURAL_LANGUAGE',\n getSuggestions: autocompleteFieldName\n ? getSuggestions\n : undefined,\n },\n }}\n />\n </QueryVisualizationWrapper>\n </Suspense>\n </SearchQueryWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;AA8EA,SAAgB,EAAiC,GAGJ;AAC3C,QAAO,mBAAmB,KAAU,EAAE,SAAS;;AAQjD,SAAwB,EACtB,GACA;CACA,IAAM,EACJ,uBACA,gBAAa,CAAC,GACd,oBACA,sBACA,kBAAkB,GAClB,8BACA,kBACA,0BACA,sBACE,GAEE,IAAiB,EACrB,GACA,EACD,EAEK,IACJ,EAAsB;EACpB,UAAU,GAA2B,YAAY;EACjD,OAAO;GACL,gBAAgB,GAA2B,OAAO;GAClD,mBAAmB,GAA2B,OAAO;GACrD,OAAO,GAA2B,OAAO,SAAA;GACzC,QAAQ,GAA2B,OAAO,UAAU;GACrD;EACF,CAAC,EAME,IAAc,EAAO,EAAE,EACvB,IAAmB,EAAO,EAAiB;AAMjD,QALI,EAAiB,YAAY,MAC/B,EAAY,WAAW,GACvB,EAAiB,UAAU,IAI3B,kBAAC,GAAD;EAEiB;EACG;EACN;EACe;EACX;YAEhB,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,EAA6B,CAAA;aAC/C,kBAAC,GAAD;IACmB;IACjB,UAAU,EAAM;IAChB,eAAe,EAAM;IACF;IACnB,oBAAoB,EAAM;IAC1B,kBAAkB,EAAM;IACxB,qBAAqB,EAAM;IAC3B,sBAAsB;IACtB,sBAAsB;IACtB,mBAAmB,EAAM;IACzB,0BACE,EAAM,4BACN,EAAyB;cAG3B,kBAAC,GAAD;KACsB;KACpB,MAAM,EAAM;KACZ,mBAAmB,EAAM;KACzB,cAAc,EAAM;KACpB,iBAAiB,EAAM;KACvB,8BAA8B,EAAM;KACpC,cAAc;KACd,gBAAgB,EAAM,kBAAkB;KACxC,sBAAsB;KACtB,2BAA2B,EAAM;KACjC,cAAc,EAAM;KACpB,kCACE,EAAM;KAER,sBAAsB,EAAM;KAC5B,yBAAyB;KACzB,qBAAqB,EACnB,WAAW;MACT,iBAAiB;MACjB,gBAAgB,IACZ,IACA,KAAA;MACL,EACF;KACD,CAAA;IACwB,CAAA;GACnB,CAAA;EACQ,EApDd,EAAY,QAoDE"}
1
+ {"version":3,"file":"SearchQueryWrapperPlotNav.js","names":[],"sources":["../../../src/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.tsx"],"sourcesContent":["import { NoContentPlaceholderType } from '@/components/SynapseTable/NoContentPlaceholderType'\nimport { DEFAULT_PAGE_SIZE } from '@/utils/SynapseConstants'\nimport { Suspense, useRef } from 'react'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport { CardConfiguration } from '../CardContainer/CardConfiguration'\nimport {\n QueryVisualizationWrapper,\n QueryVisualizationWrapperProps,\n} from '../QueryVisualizationWrapper'\nimport QueryWrapperLoadingScreen from '../QueryWrapper/QueryWrapperLoadingScreen'\nimport { SynapseTableConfiguration } from '../SynapseTable'\nimport { TopLevelControlsProps } from '../SynapseTable/TopLevelControls/TopLevelControls'\nimport { PlotsContainerProps } from '../widgets/facet-nav/PlotsContainer'\nimport { FacetFilterControlsProps } from '../widgets/query-filter/FacetFilterControls'\nimport {\n SearchQueryWrapper,\n SearchQueryWrapperProps,\n} from '../SearchQueryWrapper/SearchQueryWrapper'\nimport { QueryWrapperPlotNavContents } from '../QueryWrapperPlotNav/QueryWrapperPlotNav'\nimport { useGetSuggestionsForSearchIndex } from '../SearchQueryWrapper/SearchQueryUseQueryOptions'\n\ntype SearchQueryWrapperPlotNavOwnProps = {\n /** The ID of the SearchIndex entity to query. */\n searchIndexId: string\n /**\n * The name of the field to use for autocomplete suggestions.\n * When provided, the search bar will show a dropdown of suggestions as the user types,\n * populated by querying the search index with this field restricted via POST /search/autocomplete.\n */\n autocompleteFieldName?: string\n /** Whether the displayed results should be paginated or infinite. Default for cards is true, default for table is false */\n isInfinite?: boolean\n tableConfiguration?: SynapseTableConfiguration\n cardConfiguration?: CardConfiguration\n facetsToPlot?: string[]\n availableFacets?: FacetFilterControlsProps['availableFacets']\n initialExpandedFacetControls?: FacetFilterControlsProps['initialExpandedFacetControls']\n initialLimit?: number\n hideTopLevelControls?: boolean\n // Note: hideDownload, hideSqlEditorControl are intentionally\n // excluded — they are hardcoded to true because these controls are not applicable to the\n // SearchQueryServicesApi (no file download, no SQL editing).\n}\n\nexport type SearchQueryWrapperPlotNavProps = SearchQueryWrapperPlotNavOwnProps &\n PlotsContainerProps &\n Pick<\n QueryVisualizationWrapperProps,\n | 'defaultShowPlots'\n | 'visibleColumnCount'\n | 'columnAliases'\n | 'rgbIndex'\n | 'showLastUpdatedOn'\n | 'noContentPlaceholderType'\n | 'unitDescription'\n | 'helpConfiguration'\n | 'hideCopyToClipboard'\n | 'hideVisualizationsControl'\n | 'hideSearchBarControl'\n | 'defaultShowSearchBar'\n > &\n Pick<TopLevelControlsProps, 'name' | 'hideQueryCount'> & {\n /** Optional initial query parameters. Only selectedFacets, additionalFilters, limit, and offset are used. */\n initQueryRequest?: SearchQueryWrapperProps['initQueryRequest']\n /** Called when the query result bundle changes (e.g. to report result counts to a parent). */\n onQueryResultBundleChange?: SearchQueryWrapperProps['onQueryResultBundleChange']\n /** Whether the URL should update when the query is modified (deep linking). */\n shouldDeepLink?: SearchQueryWrapperProps['shouldDeepLink']\n }\n\n/**\n * Type guard that identifies a SearchQueryWrapperPlotNavProps from the union\n * `QueryWrapperPlotNavProps | SearchQueryWrapperPlotNavProps`.\n *\n * Two conditions are checked to be robust against future API changes:\n * 1. The config has `searchIndexId` (present only on SearchQueryWrapperPlotNavProps).\n * 2. The config does NOT have `sql` (always present on QueryWrapperPlotNavProps via\n * QueryOrDeprecatedSearchParams), so that if QueryWrapperPlotNavProps ever gains a\n * `searchIndexId` field the guard remains correct.\n */\nexport function isSearchQueryWrapperPlotNavProps(config: {\n searchIndexId?: unknown\n sql?: unknown\n}): config is SearchQueryWrapperPlotNavProps {\n return 'searchIndexId' in config && !('sql' in config)\n}\n\n/**\n * A component similar to QueryWrapperPlotNav that sources its data from the SearchQueryServicesApi\n * rather than the standard Synapse Table Services. Facets, table/card rendering, and plots are\n * all reused from the existing component library.\n */\nexport default function SearchQueryWrapperPlotNav(\n props: SearchQueryWrapperPlotNavProps,\n) {\n const {\n tableConfiguration,\n isInfinite = !tableConfiguration,\n unitDescription,\n helpConfiguration,\n initQueryRequest: initQueryRequestFromProps,\n onQueryResultBundleChange,\n searchIndexId,\n autocompleteFieldName,\n shouldDeepLink,\n } = props\n\n const getSuggestions = useGetSuggestionsForSearchIndex(\n searchIndexId,\n autocompleteFieldName,\n )\n\n const initQueryRequest: SearchQueryWrapperProps['initQueryRequest'] =\n useDeepCompareMemoize({\n partMask: initQueryRequestFromProps?.partMask ?? 0,\n query: {\n selectedFacets: initQueryRequestFromProps?.query?.selectedFacets,\n additionalFilters: initQueryRequestFromProps?.query?.additionalFilters,\n limit: initQueryRequestFromProps?.query?.limit ?? DEFAULT_PAGE_SIZE,\n offset: initQueryRequestFromProps?.query?.offset ?? 0,\n },\n })\n\n // Remount SearchQueryWrapper when initQueryRequest content changes.\n // useDeepCompareMemoize returns the same reference when content is equal, so reference\n // comparison is sufficient here. A counter is used rather than JSON.stringify to avoid\n // serializing the object on every render.\n const mountKeyRef = useRef(0)\n const prevInitQueryRef = useRef(initQueryRequest)\n if (prevInitQueryRef.current !== initQueryRequest) {\n mountKeyRef.current += 1\n prevInitQueryRef.current = initQueryRequest\n }\n\n return (\n <SearchQueryWrapper\n key={mountKeyRef.current}\n searchIndexId={searchIndexId}\n initQueryRequest={initQueryRequest}\n isInfinite={isInfinite}\n onQueryResultBundleChange={onQueryResultBundleChange}\n shouldDeepLink={shouldDeepLink}\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 hideSearchBarControl={props.hideSearchBarControl ?? false}\n defaultShowSearchBar={props.defaultShowSearchBar ?? true}\n showLastUpdatedOn={props.showLastUpdatedOn}\n noContentPlaceholderType={\n props.noContentPlaceholderType ??\n NoContentPlaceholderType.INTERACTIVE\n }\n >\n <QueryWrapperPlotNavContents\n tableConfiguration={tableConfiguration}\n name={props.name}\n cardConfiguration={props.cardConfiguration}\n facetsToPlot={props.facetsToPlot}\n availableFacets={props.availableFacets}\n initialExpandedFacetControls={props.initialExpandedFacetControls}\n hideDownload={true}\n hideQueryCount={props.hideQueryCount ?? false}\n hideSqlEditorControl={true}\n hideVisualizationsControl={props.hideVisualizationsControl}\n initialLimit={props.initialLimit}\n initialPlotTypeByFacetColumnName={\n props.initialPlotTypeByFacetColumnName\n }\n hideTopLevelControls={props.hideTopLevelControls}\n isFullTextSearchEnabled={true}\n searchConfiguration={{\n ftsConfig: {\n textMatchesMode: 'NATURAL_LANGUAGE',\n minSearchQueryLength: 1,\n replaceExistingFilter: true,\n getSuggestions: autocompleteFieldName\n ? getSuggestions\n : undefined,\n },\n }}\n />\n </QueryVisualizationWrapper>\n </Suspense>\n </SearchQueryWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;AAgFA,SAAgB,EAAiC,GAGJ;AAC3C,QAAO,mBAAmB,KAAU,EAAE,SAAS;;AAQjD,SAAwB,EACtB,GACA;CACA,IAAM,EACJ,uBACA,gBAAa,CAAC,GACd,oBACA,sBACA,kBAAkB,GAClB,8BACA,kBACA,0BACA,sBACE,GAEE,IAAiB,EACrB,GACA,EACD,EAEK,IACJ,EAAsB;EACpB,UAAU,GAA2B,YAAY;EACjD,OAAO;GACL,gBAAgB,GAA2B,OAAO;GAClD,mBAAmB,GAA2B,OAAO;GACrD,OAAO,GAA2B,OAAO,SAAA;GACzC,QAAQ,GAA2B,OAAO,UAAU;GACrD;EACF,CAAC,EAME,IAAc,EAAO,EAAE,EACvB,IAAmB,EAAO,EAAiB;AAMjD,QALI,EAAiB,YAAY,MAC/B,EAAY,WAAW,GACvB,EAAiB,UAAU,IAI3B,kBAAC,GAAD;EAEiB;EACG;EACN;EACe;EACX;YAEhB,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,EAA6B,CAAA;aAC/C,kBAAC,GAAD;IACmB;IACjB,UAAU,EAAM;IAChB,eAAe,EAAM;IACF;IACnB,oBAAoB,EAAM;IAC1B,kBAAkB,EAAM;IACxB,qBAAqB,EAAM;IAC3B,sBAAsB,EAAM,wBAAwB;IACpD,sBAAsB,EAAM,wBAAwB;IACpD,mBAAmB,EAAM;IACzB,0BACE,EAAM,4BACN,EAAyB;cAG3B,kBAAC,GAAD;KACsB;KACpB,MAAM,EAAM;KACZ,mBAAmB,EAAM;KACzB,cAAc,EAAM;KACpB,iBAAiB,EAAM;KACvB,8BAA8B,EAAM;KACpC,cAAc;KACd,gBAAgB,EAAM,kBAAkB;KACxC,sBAAsB;KACtB,2BAA2B,EAAM;KACjC,cAAc,EAAM;KACpB,kCACE,EAAM;KAER,sBAAsB,EAAM;KAC5B,yBAAyB;KACzB,qBAAqB,EACnB,WAAW;MACT,iBAAiB;MACjB,sBAAsB;MACtB,uBAAuB;MACvB,gBAAgB,IACZ,IACA,KAAA;MACL,EACF;KACD,CAAA;IACwB,CAAA;GACnB,CAAA;EACQ,EAtDd,EAAY,QAsDE"}
@@ -1 +1 @@
1
- {"version":3,"file":"WordPressNews.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseHomepageV2/WordPressNews.tsx"],"names":[],"mappings":"AASA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAgCD,wBAAgB,aAAa,CAAC,EAC5B,gBAAgB,EAChB,SAAc,EACd,iBAAwB,EACxB,OAAO,GACR,EAAE,kBAAkB,2CAoCpB"}
1
+ {"version":3,"file":"WordPressNews.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseHomepageV2/WordPressNews.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,aAAa,CAAC,EAC5B,gBAAgB,EAChB,SAAc,EACd,iBAAwB,EACxB,OAAO,GACR,EAAE,kBAAkB,2CA6BpB"}