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":"EntityDownloadButton.js","names":[],"sources":["../../../src/components/EntityDownloadButton/EntityDownloadButton.tsx"],"sourcesContent":["import { useGetEntity, useGetVersions } from '@/synapse-queries'\nimport {\n useAddFileToDownloadList,\n useGetAddToDownloadListStats,\n} from '@/synapse-queries/index'\nimport { useSynapseContext } from '@/utils'\nimport {\n entityTypeToFriendlyName,\n hasFilesInView,\n isContainerType,\n isDataset,\n isEntityView,\n isVersionableEntity,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useDirectDownloadHandler } from '@/utils/hooks/useDirectDownloadHandler'\nimport { isFileEntity } from '@/utils/types/IsType'\nimport { DownloadOutlined as DownloadIcon } from '@mui/icons-material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n FileHandleAssociateType,\n QueryBundleRequest,\n} from '@sage-bionetworks/synapse-types'\nimport { RefObject, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { displayFilesWereAddedToDownloadListSuccess } from '../download_list/DownloadConfirmationUtils'\nimport { EntityDownloadConfirmation } from '../EntityDownloadConfirmation'\nimport { DropdownMenu, DropdownMenuItem } from '../menu/DropdownMenu'\nimport { ModalDownload } from '../ModalDownload/ModalDownload'\nimport { ProgrammaticInstructionsModal } from '../ProgrammaticInstructionsModal/ProgrammaticInstructionsModal'\nimport { displayToast } from '../ToastMessage/index'\n\n// WIP\n// Per Nick Grosenbacher: For this to be reusable, I think we would also need to accept versionNumber as a prop. Where we would have the following behavior:\n// - If the version number is present, use it\n// - If the version number is null, do not use it,\n// - If the version number is undefined, then we would try to do the 'smart' thing-- get the latest version for datasets, otherwise don't use it.\n\n// Have to keep these consts outside of getProgrammaticAccessCode because\n// they are being called in ProgrammaticTableDownload.tsx\n// Python client import and login instructions\nexport const PYTHON_CLIENT_IMPORT_AND_LOGIN = `import synapseclient\nsyn = synapseclient.Synapse()\nsyn.login(authToken=\"YOUR_TOKEN_HERE\")`\n\n// R client import and login instructions\nexport const R_CLIENT_IMPORT_AND_LOGIN = `library(synapser)\nsynLogin(authToken=\"YOUR_TOKEN_HERE\")`\n\ntype ProgrammaticAccessCode = {\n cliCode: string | undefined\n rCode: string | undefined\n pythonCode: string | undefined\n}\n\n// Generate programmatic access code snippet content based on entity type\nfunction getProgrammaticAccessCode(\n type: EntityType,\n entityId: string,\n version: number | undefined,\n): ProgrammaticAccessCode {\n const id =\n type === EntityType.dataset && version ? `${entityId}.${version}` : entityId\n switch (type) {\n case EntityType.file:\n case EntityType.folder:\n case EntityType.project:\n case EntityType.link:\n return {\n cliCode: `synapse get -r ${entityId}`,\n rCode: `${R_CLIENT_IMPORT_AND_LOGIN} \\n\n# Download file\nsynGet('${entityId}')`,\n pythonCode: `${PYTHON_CLIENT_IMPORT_AND_LOGIN} \\n\n# Download file\nsyn.get('${entityId}')`,\n }\n case EntityType.dockerrepo:\n return {\n cliCode: `docker login -u <synapse username> -p <synapse password> docker.synapse.org \\n\ndocker pull docker.synapse.org/${entityId}/myrepo`,\n rCode: undefined,\n pythonCode: undefined,\n }\n case EntityType.dataset:\n case EntityType.entityview:\n case EntityType.datasetcollection:\n case EntityType.table:\n case EntityType.materializedview:\n case EntityType.submissionview:\n case EntityType.virtualtable:\n case EntityType.recordset:\n return {\n cliCode: `synapse get -q \"SELECT * FROM ${id}\"`,\n rCode: `${R_CLIENT_IMPORT_AND_LOGIN} \\n\nquery <- synTableQuery(\"SELECT * FROM ${id}\")\nread.table(query$filepath, sep=\",\")`,\n pythonCode: `${PYTHON_CLIENT_IMPORT_AND_LOGIN} \\n\nquery = syn.tableQuery(\"SELECT * FROM ${id}\")\nquery.asDataFrame()`,\n }\n default:\n throw new Error(`Unhandled EntityType: ${type}`)\n }\n}\n\nenum DownloadAction {\n downloadFile,\n addToCart,\n programmaticAccess,\n programmaticAccessDocker,\n exportTable,\n}\n\n// Function that creates menu items for download actions\nfunction getMenuItemForAction(\n entityId: string,\n entityName: string,\n entityType: EntityType,\n downloadAction: DownloadAction,\n setShowProgrammaticAccess: (show: boolean) => void,\n setShowExportMetadata: (show: boolean) => void,\n addFileToDownloadList: (params: {\n entityId: string\n entityVersionNumber: number | undefined\n }) => void,\n setShowDownloadConfirmation: (show: boolean) => void,\n versionNumber?: number,\n addToCartDisabled?: boolean,\n onDownloadFile?: () => void,\n isAuthenticated?: boolean,\n): DropdownMenuItem {\n switch (downloadAction) {\n case DownloadAction.downloadFile:\n return {\n text: 'Download File',\n onClick: () => {\n if (onDownloadFile) onDownloadFile()\n },\n tooltipText: isAuthenticated\n ? 'Download this file directly'\n : 'Sign in to download this file',\n disabled: !isAuthenticated,\n }\n case DownloadAction.addToCart:\n return {\n text: 'Add to Download List',\n disabled: addToCartDisabled,\n tooltipText: getAddToCartTooltip(entityType, !!addToCartDisabled),\n onClick: () => {\n if (\n entityType === EntityType.file ||\n entityType === EntityType.recordset\n ) {\n addFileToDownloadList({\n entityId,\n entityVersionNumber: versionNumber,\n })\n } else {\n setShowDownloadConfirmation(true)\n }\n },\n }\n case DownloadAction.programmaticAccess:\n return {\n text: 'Programmatic Access',\n onClick: () => {\n setShowProgrammaticAccess(true)\n },\n tooltipText: 'View programmatic access options',\n }\n case DownloadAction.programmaticAccessDocker:\n return {\n text: 'Programmatic Access (Docker)',\n onClick: () => {\n setShowProgrammaticAccess(true)\n },\n tooltipText: 'View programmatic options to pull Docker image',\n }\n case DownloadAction.exportTable:\n return {\n text: 'Export Table',\n onClick: () => {\n setShowExportMetadata(true)\n },\n tooltipText: 'Export table data',\n }\n }\n}\n\n/**\n * Determines the tooltip message based on the entity type and its \"add to cart\" status.\n */\nconst getAddToCartTooltip = (\n entityType: EntityType,\n isDisabled: boolean,\n): string => {\n if (!isDisabled) {\n return 'Add file(s) to your download list'\n }\n const entityFriendlyName = entityTypeToFriendlyName(entityType)\n return `This ${entityFriendlyName} has no accessible files`\n}\n\n// Function that returns DropdownMenuItem\nexport function getDownloadActionsForEntityType(\n type: EntityType,\n): DownloadAction[][] {\n switch (type) {\n case EntityType.file:\n case EntityType.recordset:\n return [\n [DownloadAction.downloadFile],\n [DownloadAction.addToCart, DownloadAction.programmaticAccess],\n ]\n case EntityType.project:\n case EntityType.folder:\n return [[DownloadAction.addToCart, DownloadAction.programmaticAccess]]\n case EntityType.dockerrepo:\n return [[DownloadAction.programmaticAccessDocker]]\n case EntityType.entityview:\n case EntityType.dataset:\n return [\n [\n DownloadAction.exportTable,\n DownloadAction.programmaticAccess,\n DownloadAction.addToCart,\n ],\n ]\n case EntityType.datasetcollection:\n case EntityType.table:\n case EntityType.materializedview:\n case EntityType.submissionview:\n case EntityType.virtualtable:\n return [[DownloadAction.exportTable, DownloadAction.programmaticAccess]]\n case EntityType.link:\n return [[DownloadAction.programmaticAccess]]\n case EntityType.searchindex:\n return []\n default:\n // this will fail if a new EntityType is added and not handled\n throw new Error(`Unhandled EntityType: ${type}`)\n }\n}\n\n// get the appropriate version number for download based on entity type\n// for datasets: returns the most recent released version if any exist, undefined otherwise\n// for other entities: returns the current version number\nfunction useGetLatestVersionNumber(entityId: string, entityType: EntityType) {\n // get entity data\n const { data: entityData, isLoading: entityDataLoading } =\n useGetEntity(entityId) // No version = latest\n\n // for datasets, check if any versions exist and use the most recent one\n const mustGetVersion = entityType === EntityType.dataset\n const { data: versionsData, isLoading: versionsLoading } = useGetVersions(\n entityId,\n 0,\n 1,\n {\n enabled: mustGetVersion,\n },\n )\n\n let latestVersionNumber: number | undefined\n\n if (mustGetVersion) {\n // for datasets, check if any versions exist\n if (versionsData?.results && versionsData.results.length > 0) {\n // Use the most recent released version (first in the list, since versions are returned in descending order)\n latestVersionNumber = versionsData.results[0].versionNumber\n } else {\n // no versions exist, use undefined (will use current/draft version)\n latestVersionNumber = undefined\n }\n } else {\n // for non-datasets, use the entity's version number\n latestVersionNumber =\n entityData && isVersionableEntity(entityData)\n ? entityData.versionNumber\n : undefined\n }\n\n const isLoading = entityDataLoading || versionsLoading\n\n return { latestVersionNumber, isLoading }\n}\n\n// create default queryBundleRequest with appropriate SQL\nfunction getDefaultQueryBundleRequestForEntity(\n entityId: string,\n versionNumber: number | undefined,\n entityType: EntityType,\n): QueryBundleRequest {\n let sql: string\n\n if (entityType === EntityType.dataset) {\n // for datasets:\n // - if a version number exists (released version), use it: syn123.5\n // - if no version number (no released versions), use current/draft: syn123\n sql = versionNumber\n ? `SELECT * FROM ${entityId}.${versionNumber}`\n : `SELECT * FROM ${entityId}`\n } else {\n // For non-datasets, always use entity ID without version\n sql = `SELECT * FROM ${entityId}`\n }\n\n return {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n entityId: `${entityId}`,\n query: {\n sql: sql,\n },\n partMask: 0,\n }\n}\n\nexport function EntityDownloadButton(props: {\n entityId: string\n name: string\n entityType: EntityType\n downloadConfirmationContainer?: RefObject<HTMLElement | null>\n disabled?: boolean\n}) {\n // get the appropriate version number for the entity\n const { latestVersionNumber } = useGetLatestVersionNumber(\n props.entityId,\n props.entityType,\n )\n // create queryBundleRequest with appropriate SQL based on entity type and version\n const defaultQueryBundleRequest = getDefaultQueryBundleRequestForEntity(\n props.entityId,\n latestVersionNumber,\n props.entityType,\n )\n\n // Get context and download functionality\n const { downloadCartPageUrl, isAuthenticated } = useSynapseContext()\n const { mutate: addFileToDownloadList } = useAddFileToDownloadList({\n onSuccess: data => {\n if (data.numberOfFilesAdded > 0) {\n displayFilesWereAddedToDownloadListSuccess(downloadCartPageUrl)\n } else {\n displayToast('0 Files added to your Download List', 'info')\n }\n },\n onError: error => {\n displayToast(error.reason, 'danger')\n },\n })\n\n // state to manage programmatic access modal visibility\n const [showProgrammaticAccess, setShowProgrammaticAccess] =\n useState<boolean>(false)\n\n // state to manage download confirmation visibility and loading\n const [showDownloadConfirmation, setShowDownloadConfirmation] =\n useState<boolean>(false)\n const [downloadConfirmationLoading, setDownloadConfirmationLoading] =\n useState<boolean>(false)\n\n const handleCloseProgrammaticAccess = () => {\n setShowProgrammaticAccess(false)\n }\n\n const isFolderOrProject = isContainerType(props.entityType)\n\n const {\n data: folderOrProjectStats,\n isLoading: isLoadingFolderOrProjectStats,\n } = useGetAddToDownloadListStats(\n {\n concreteType:\n 'org.sagebionetworks.repo.model.download.AddToDownloadListStatsRequest',\n request: {\n parentId: props.entityId,\n concreteType:\n 'org.sagebionetworks.repo.model.download.AddToDownloadListRequest',\n recursive: true,\n },\n },\n {\n enabled: isFolderOrProject,\n },\n )\n\n const folderOrProjectHasNoFiles =\n isFolderOrProject &&\n (isLoadingFolderOrProjectStats || folderOrProjectStats?.fileCount === 0)\n\n const { data: entityData } = useGetEntity(props.entityId)\n\n const { downloadFile } = useDirectDownloadHandler()\n\n const fileHandleId =\n entityData && isFileEntity(entityData)\n ? entityData.dataFileHandleId\n : undefined\n\n const onDownloadFile = fileHandleId\n ? () => {\n void downloadFile({\n fileHandleId,\n associatedObjectId: props.entityId,\n associatedObjectType: FileHandleAssociateType.FileEntity,\n })\n }\n : undefined\n\n const entityViewHasNoFiles =\n entityData && isEntityView(entityData) && !hasFilesInView(entityData)\n\n const datasetHasNoFiles =\n entityData &&\n isDataset(entityData) &&\n (!entityData.items || entityData.items.length === 0)\n\n const addToCartDisabled =\n folderOrProjectHasNoFiles || entityViewHasNoFiles || datasetHasNoFiles\n\n // state to manage export metadata modal visibility\n const [showExportMetadata, setShowExportMetadata] = useState<boolean>(false)\n\n const handleCloseExportMetadata = () => {\n setShowExportMetadata(false)\n }\n\n // Create download menu items\n const downloadActions = getDownloadActionsForEntityType(props.entityType)\n const downloadMenuItems = downloadActions.map(actionGroup =>\n actionGroup.map(action =>\n getMenuItemForAction(\n props.entityId,\n props.name,\n props.entityType,\n action,\n setShowProgrammaticAccess,\n setShowExportMetadata,\n addFileToDownloadList,\n setShowDownloadConfirmation,\n latestVersionNumber,\n addToCartDisabled,\n onDownloadFile,\n isAuthenticated,\n ),\n ),\n )\n\n // Return programmatic access modal content\n const { cliCode, rCode, pythonCode } = getProgrammaticAccessCode(\n props.entityType,\n props.entityId,\n latestVersionNumber,\n )\n\n const downloadConfirmation = showDownloadConfirmation ? (\n <EntityDownloadConfirmation\n entityId={props.entityId}\n handleClose={() => setShowDownloadConfirmation(false)}\n onIsLoadingChange={setDownloadConfirmationLoading}\n />\n ) : null\n\n return (\n <>\n <DropdownMenu\n items={downloadMenuItems}\n dropdownButtonText=\"Download\"\n buttonTooltip=\"Download options for this entity\"\n buttonProps={{\n variant: 'outlined',\n startIcon: <DownloadIcon />,\n disabled: props.disabled || downloadConfirmationLoading,\n }}\n />\n {downloadConfirmation &&\n (props.downloadConfirmationContainer?.current\n ? createPortal(\n downloadConfirmation,\n props.downloadConfirmationContainer.current,\n )\n : downloadConfirmation)}\n <ProgrammaticInstructionsModal\n show={showProgrammaticAccess}\n title={`Programmatic Access: ${props.name}`}\n onClose={handleCloseProgrammaticAccess}\n pythonCode={pythonCode}\n rCode={rCode}\n cliCode={cliCode}\n helpUrl=\"https://help.synapse.org/docs/Synapse-Docker-Registry.2011037752.html#SynapseDockerRegistry-UsingDockerImagesStoredintheSynapseDockerRegistry\"\n />\n {showExportMetadata && (\n <ModalDownload\n queryBundleRequest={defaultQueryBundleRequest}\n onClose={handleCloseExportMetadata}\n />\n )}\n </>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityDownloadButton.js","names":[],"sources":["../../../src/components/EntityDownloadButton/EntityDownloadButton.tsx"],"sourcesContent":["import { useGetEntity, useGetVersions } from '@/synapse-queries'\nimport {\n useAddFileToDownloadList,\n useGetAddToDownloadListStats,\n} from '@/synapse-queries/index'\nimport { useSynapseContext } from '@/utils'\nimport {\n entityTypeToFriendlyName,\n hasFilesInView,\n isContainerType,\n isDataset,\n isEntityView,\n isVersionableEntity,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useDirectDownloadHandler } from '@/utils/hooks/useDirectDownloadHandler'\nimport { isFileEntity } from '@/utils/types/IsType'\nimport { DownloadOutlined as DownloadIcon } from '@mui/icons-material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n FileHandleAssociateType,\n QueryBundleRequest,\n} from '@sage-bionetworks/synapse-types'\nimport { RefObject, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { displayFilesWereAddedToDownloadListSuccess } from '../download_list/DownloadConfirmationUtils'\nimport { EntityDownloadConfirmation } from '../EntityDownloadConfirmation'\nimport { DropdownMenu, DropdownMenuItem } from '../menu/DropdownMenu'\nimport { ModalDownload } from '../ModalDownload/ModalDownload'\nimport { ProgrammaticInstructionsModal } from '../ProgrammaticInstructionsModal/ProgrammaticInstructionsModal'\nimport { displayToast } from '../ToastMessage/index'\n\n// WIP\n// Per Nick Grosenbacher: For this to be reusable, I think we would also need to accept versionNumber as a prop. Where we would have the following behavior:\n// - If the version number is present, use it\n// - If the version number is null, do not use it,\n// - If the version number is undefined, then we would try to do the 'smart' thing-- get the latest version for datasets, otherwise don't use it.\n\n// Have to keep these consts outside of getProgrammaticAccessCode because\n// they are being called in ProgrammaticTableDownload.tsx\n// Python client import and login instructions\nexport const PYTHON_CLIENT_IMPORT_AND_LOGIN = `import synapseclient\nsyn = synapseclient.Synapse()\nsyn.login(authToken=\"YOUR_TOKEN_HERE\")`\n\n// R client import and login instructions\nexport const R_CLIENT_IMPORT_AND_LOGIN = `library(synapser)\nsynLogin(authToken=\"YOUR_TOKEN_HERE\")`\n\ntype ProgrammaticAccessCode = {\n cliCode: string | undefined\n rCode: string | undefined\n pythonCode: string | undefined\n}\n\n// Generate programmatic access code snippet content based on entity type\nexport function getProgrammaticAccessCode(\n type: EntityType,\n entityId: string,\n version: number | undefined,\n): ProgrammaticAccessCode {\n const id =\n type === EntityType.dataset && version ? `${entityId}.${version}` : entityId\n switch (type) {\n case EntityType.file:\n case EntityType.folder:\n case EntityType.project:\n case EntityType.link:\n return {\n cliCode: `synapse get -r ${entityId}`,\n rCode: `${R_CLIENT_IMPORT_AND_LOGIN} \\n\n# Download file\nsynGet('${entityId}')`,\n pythonCode: `${PYTHON_CLIENT_IMPORT_AND_LOGIN} \\n\n# Download file\nsyn.get('${entityId}')`,\n }\n case EntityType.dockerrepo:\n return {\n cliCode: `docker login -u <synapse username> -p <synapse password> docker.synapse.org \\n\ndocker pull docker.synapse.org/${entityId}/myrepo`,\n rCode: undefined,\n pythonCode: undefined,\n }\n case EntityType.dataset:\n case EntityType.entityview:\n case EntityType.datasetcollection:\n case EntityType.table:\n case EntityType.materializedview:\n case EntityType.submissionview:\n case EntityType.virtualtable:\n case EntityType.recordset:\n return {\n cliCode: `synapse get -q \"SELECT * FROM ${id}\"`,\n rCode: `${R_CLIENT_IMPORT_AND_LOGIN} \\n\nquery <- synTableQuery(\"SELECT * FROM ${id}\")\nread.table(query$filepath, sep=\",\")`,\n pythonCode: `${PYTHON_CLIENT_IMPORT_AND_LOGIN} \\n\nquery = syn.tableQuery(\"SELECT * FROM ${id}\")\nquery.asDataFrame()`,\n }\n case EntityType.searchindex:\n return {\n cliCode: undefined,\n rCode: undefined,\n pythonCode: undefined,\n }\n default:\n throw new Error(`Unhandled EntityType: ${type}`)\n }\n}\n\nenum DownloadAction {\n downloadFile,\n addToCart,\n programmaticAccess,\n programmaticAccessDocker,\n exportTable,\n}\n\n// Function that creates menu items for download actions\nfunction getMenuItemForAction(\n entityId: string,\n entityName: string,\n entityType: EntityType,\n downloadAction: DownloadAction,\n setShowProgrammaticAccess: (show: boolean) => void,\n setShowExportMetadata: (show: boolean) => void,\n addFileToDownloadList: (params: {\n entityId: string\n entityVersionNumber: number | undefined\n }) => void,\n setShowDownloadConfirmation: (show: boolean) => void,\n versionNumber?: number,\n addToCartDisabled?: boolean,\n onDownloadFile?: () => void,\n isAuthenticated?: boolean,\n): DropdownMenuItem {\n switch (downloadAction) {\n case DownloadAction.downloadFile:\n return {\n text: 'Download File',\n onClick: () => {\n if (onDownloadFile) onDownloadFile()\n },\n tooltipText: isAuthenticated\n ? 'Download this file directly'\n : 'Sign in to download this file',\n disabled: !isAuthenticated,\n }\n case DownloadAction.addToCart:\n return {\n text: 'Add to Download List',\n disabled: addToCartDisabled,\n tooltipText: getAddToCartTooltip(entityType, !!addToCartDisabled),\n onClick: () => {\n if (\n entityType === EntityType.file ||\n entityType === EntityType.recordset\n ) {\n addFileToDownloadList({\n entityId,\n entityVersionNumber: versionNumber,\n })\n } else {\n setShowDownloadConfirmation(true)\n }\n },\n }\n case DownloadAction.programmaticAccess:\n return {\n text: 'Programmatic Access',\n onClick: () => {\n setShowProgrammaticAccess(true)\n },\n tooltipText: 'View programmatic access options',\n }\n case DownloadAction.programmaticAccessDocker:\n return {\n text: 'Programmatic Access (Docker)',\n onClick: () => {\n setShowProgrammaticAccess(true)\n },\n tooltipText: 'View programmatic options to pull Docker image',\n }\n case DownloadAction.exportTable:\n return {\n text: 'Export Table',\n onClick: () => {\n setShowExportMetadata(true)\n },\n tooltipText: 'Export table data',\n }\n }\n}\n\n/**\n * Determines the tooltip message based on the entity type and its \"add to cart\" status.\n */\nconst getAddToCartTooltip = (\n entityType: EntityType,\n isDisabled: boolean,\n): string => {\n if (!isDisabled) {\n return 'Add file(s) to your download list'\n }\n const entityFriendlyName = entityTypeToFriendlyName(entityType)\n return `This ${entityFriendlyName} has no accessible files`\n}\n\n// Function that returns DropdownMenuItem\nexport function getDownloadActionsForEntityType(\n type: EntityType,\n): DownloadAction[][] {\n switch (type) {\n case EntityType.file:\n case EntityType.recordset:\n return [\n [DownloadAction.downloadFile],\n [DownloadAction.addToCart, DownloadAction.programmaticAccess],\n ]\n case EntityType.project:\n case EntityType.folder:\n return [[DownloadAction.addToCart, DownloadAction.programmaticAccess]]\n case EntityType.dockerrepo:\n return [[DownloadAction.programmaticAccessDocker]]\n case EntityType.entityview:\n case EntityType.dataset:\n return [\n [\n DownloadAction.exportTable,\n DownloadAction.programmaticAccess,\n DownloadAction.addToCart,\n ],\n ]\n case EntityType.datasetcollection:\n case EntityType.table:\n case EntityType.materializedview:\n case EntityType.submissionview:\n case EntityType.virtualtable:\n return [[DownloadAction.exportTable, DownloadAction.programmaticAccess]]\n case EntityType.link:\n return [[DownloadAction.programmaticAccess]]\n case EntityType.searchindex:\n return []\n default:\n // this will fail if a new EntityType is added and not handled\n throw new Error(`Unhandled EntityType: ${type}`)\n }\n}\n\n// get the appropriate version number for download based on entity type\n// for datasets: returns the most recent released version if any exist, undefined otherwise\n// for other entities: returns the current version number\nfunction useGetLatestVersionNumber(entityId: string, entityType: EntityType) {\n // get entity data\n const { data: entityData, isLoading: entityDataLoading } =\n useGetEntity(entityId) // No version = latest\n\n // for datasets, check if any versions exist and use the most recent one\n const mustGetVersion = entityType === EntityType.dataset\n const { data: versionsData, isLoading: versionsLoading } = useGetVersions(\n entityId,\n 0,\n 1,\n {\n enabled: mustGetVersion,\n },\n )\n\n let latestVersionNumber: number | undefined\n\n if (mustGetVersion) {\n // for datasets, check if any versions exist\n if (versionsData?.results && versionsData.results.length > 0) {\n // Use the most recent released version (first in the list, since versions are returned in descending order)\n latestVersionNumber = versionsData.results[0].versionNumber\n } else {\n // no versions exist, use undefined (will use current/draft version)\n latestVersionNumber = undefined\n }\n } else {\n // for non-datasets, use the entity's version number\n latestVersionNumber =\n entityData && isVersionableEntity(entityData)\n ? entityData.versionNumber\n : undefined\n }\n\n const isLoading = entityDataLoading || versionsLoading\n\n return { latestVersionNumber, isLoading }\n}\n\n// create default queryBundleRequest with appropriate SQL\nfunction getDefaultQueryBundleRequestForEntity(\n entityId: string,\n versionNumber: number | undefined,\n entityType: EntityType,\n): QueryBundleRequest {\n let sql: string\n\n if (entityType === EntityType.dataset) {\n // for datasets:\n // - if a version number exists (released version), use it: syn123.5\n // - if no version number (no released versions), use current/draft: syn123\n sql = versionNumber\n ? `SELECT * FROM ${entityId}.${versionNumber}`\n : `SELECT * FROM ${entityId}`\n } else {\n // For non-datasets, always use entity ID without version\n sql = `SELECT * FROM ${entityId}`\n }\n\n return {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n entityId: `${entityId}`,\n query: {\n sql: sql,\n },\n partMask: 0,\n }\n}\n\nexport function EntityDownloadButton(props: {\n entityId: string\n name: string\n entityType: EntityType\n downloadConfirmationContainer?: RefObject<HTMLElement | null>\n disabled?: boolean\n}) {\n // get the appropriate version number for the entity\n const { latestVersionNumber } = useGetLatestVersionNumber(\n props.entityId,\n props.entityType,\n )\n // create queryBundleRequest with appropriate SQL based on entity type and version\n const defaultQueryBundleRequest = getDefaultQueryBundleRequestForEntity(\n props.entityId,\n latestVersionNumber,\n props.entityType,\n )\n\n // Get context and download functionality\n const { downloadCartPageUrl, isAuthenticated } = useSynapseContext()\n const { mutate: addFileToDownloadList } = useAddFileToDownloadList({\n onSuccess: data => {\n if (data.numberOfFilesAdded > 0) {\n displayFilesWereAddedToDownloadListSuccess(downloadCartPageUrl)\n } else {\n displayToast('0 Files added to your Download List', 'info')\n }\n },\n onError: error => {\n displayToast(error.reason, 'danger')\n },\n })\n\n // state to manage programmatic access modal visibility\n const [showProgrammaticAccess, setShowProgrammaticAccess] =\n useState<boolean>(false)\n\n // state to manage download confirmation visibility and loading\n const [showDownloadConfirmation, setShowDownloadConfirmation] =\n useState<boolean>(false)\n const [downloadConfirmationLoading, setDownloadConfirmationLoading] =\n useState<boolean>(false)\n\n const handleCloseProgrammaticAccess = () => {\n setShowProgrammaticAccess(false)\n }\n\n const isFolderOrProject = isContainerType(props.entityType)\n\n const {\n data: folderOrProjectStats,\n isLoading: isLoadingFolderOrProjectStats,\n } = useGetAddToDownloadListStats(\n {\n concreteType:\n 'org.sagebionetworks.repo.model.download.AddToDownloadListStatsRequest',\n request: {\n parentId: props.entityId,\n concreteType:\n 'org.sagebionetworks.repo.model.download.AddToDownloadListRequest',\n recursive: true,\n },\n },\n {\n enabled: isFolderOrProject,\n },\n )\n\n const folderOrProjectHasNoFiles =\n isFolderOrProject &&\n (isLoadingFolderOrProjectStats || folderOrProjectStats?.fileCount === 0)\n\n const { data: entityData } = useGetEntity(props.entityId)\n\n const { downloadFile } = useDirectDownloadHandler()\n\n const fileHandleId =\n entityData && isFileEntity(entityData)\n ? entityData.dataFileHandleId\n : undefined\n\n const onDownloadFile = fileHandleId\n ? () => {\n void downloadFile({\n fileHandleId,\n associatedObjectId: props.entityId,\n associatedObjectType: FileHandleAssociateType.FileEntity,\n })\n }\n : undefined\n\n const entityViewHasNoFiles =\n entityData && isEntityView(entityData) && !hasFilesInView(entityData)\n\n const datasetHasNoFiles =\n entityData &&\n isDataset(entityData) &&\n (!entityData.items || entityData.items.length === 0)\n\n const addToCartDisabled =\n folderOrProjectHasNoFiles || entityViewHasNoFiles || datasetHasNoFiles\n\n // state to manage export metadata modal visibility\n const [showExportMetadata, setShowExportMetadata] = useState<boolean>(false)\n\n const handleCloseExportMetadata = () => {\n setShowExportMetadata(false)\n }\n\n // Create download menu items\n const downloadActions = getDownloadActionsForEntityType(props.entityType)\n const downloadMenuItems = downloadActions.map(actionGroup =>\n actionGroup.map(action =>\n getMenuItemForAction(\n props.entityId,\n props.name,\n props.entityType,\n action,\n setShowProgrammaticAccess,\n setShowExportMetadata,\n addFileToDownloadList,\n setShowDownloadConfirmation,\n latestVersionNumber,\n addToCartDisabled,\n onDownloadFile,\n isAuthenticated,\n ),\n ),\n )\n\n // Return programmatic access modal content\n const { cliCode, rCode, pythonCode } = getProgrammaticAccessCode(\n props.entityType,\n props.entityId,\n latestVersionNumber,\n )\n\n const downloadConfirmation = showDownloadConfirmation ? (\n <EntityDownloadConfirmation\n entityId={props.entityId}\n handleClose={() => setShowDownloadConfirmation(false)}\n onIsLoadingChange={setDownloadConfirmationLoading}\n />\n ) : null\n\n return (\n <>\n <DropdownMenu\n items={downloadMenuItems}\n dropdownButtonText=\"Download\"\n buttonTooltip=\"Download options for this entity\"\n buttonProps={{\n variant: 'outlined',\n startIcon: <DownloadIcon />,\n disabled: props.disabled || downloadConfirmationLoading,\n }}\n />\n {downloadConfirmation &&\n (props.downloadConfirmationContainer?.current\n ? createPortal(\n downloadConfirmation,\n props.downloadConfirmationContainer.current,\n )\n : downloadConfirmation)}\n <ProgrammaticInstructionsModal\n show={showProgrammaticAccess}\n title={`Programmatic Access: ${props.name}`}\n onClose={handleCloseProgrammaticAccess}\n pythonCode={pythonCode}\n rCode={rCode}\n cliCode={cliCode}\n helpUrl=\"https://help.synapse.org/docs/Synapse-Docker-Registry.2011037752.html#SynapseDockerRegistry-UsingDockerImagesStoredintheSynapseDockerRegistry\"\n />\n {showExportMetadata && (\n <ModalDownload\n queryBundleRequest={defaultQueryBundleRequest}\n onClose={handleCloseExportMetadata}\n />\n )}\n </>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FullTextSearch.d.ts","sourceRoot":"","sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"names":[],"mappings":"AACA,OAAO,KAMN,MAAM,OAAO,CAAA;AASd,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAMpD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,GACV,EAAE,mBAAmB,GAAG,KAAK,CAAC,SAAS,CA2KvC;AAED,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"FullTextSearch.d.ts","sourceRoot":"","sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"names":[],"mappings":"AACA,OAAO,KAMN,MAAM,OAAO,CAAA;AASd,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAMpD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,GACV,EAAE,mBAAmB,GAAG,KAAK,CAAC,SAAS,CA6KvC;AAED,eAAe,cAAc,CAAA"}
@@ -15,26 +15,34 @@ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
15
15
  //#region src/components/FullTextSearch/FullTextSearch.tsx
16
16
  var _ = 3, v = 300;
17
17
  function y({ ftsConfig: y }) {
18
- let { executeQueryRequest: b } = r(), { showSearchBar: x } = a(), [S, C] = u(""), [w, T] = u([]), E = l(null), { data: D } = i(), O = D?.columnModels;
18
+ let { executeQueryRequest: b } = r(), { showSearchBar: x } = a(), [S, C] = u(""), [w, T] = u([]), E = l(null), D = y?.minSearchQueryLength ?? _, { data: O } = i(), k = O?.columnModels;
19
19
  c(() => {
20
- (!y?.getSuggestions || S.trim().length < _) && T([]);
21
- }, [y?.getSuggestions, S]), e(() => {
22
- !y?.getSuggestions || S.trim().length < _ || y.getSuggestions(S).then(T).catch(() => T([]));
23
- }, [S, y], v);
24
- let k = (e) => {
25
- b((t) => o(t, O, e, y)), C(""), T([]);
26
- }, A = (e) => {
27
- e.preventDefault(), S.trim().length < _ ? E.current?.setCustomValidity(`Search term must have a minimum of ${_} characters`) : k(S);
20
+ (!y?.getSuggestions || S.trim().length < D) && T([]);
21
+ }, [
22
+ y?.getSuggestions,
23
+ D,
24
+ S
25
+ ]), e(() => {
26
+ !y?.getSuggestions || S.trim().length < D || y.getSuggestions(S).then(T).catch(() => T([]));
27
+ }, [
28
+ S,
29
+ y,
30
+ D
31
+ ], v);
32
+ let A = (e) => {
33
+ b((t) => o(t, k, e, y)), C(""), T([]);
28
34
  }, j = (e) => {
35
+ e.preventDefault(), S.trim().length < D ? E.current?.setCustomValidity(`Search term must have a minimum of ${D} characters`) : A(S);
36
+ }, M = (e) => {
29
37
  E.current?.setCustomValidity(""), C(e.currentTarget.value);
30
- }, M = /* @__PURE__ */ h(n, {
38
+ }, N = /* @__PURE__ */ h(n, {
31
39
  icon: "search",
32
40
  wrap: !1,
33
41
  sx: {
34
42
  mr: 1,
35
43
  color: "grey.600"
36
44
  }
37
- }), N = /* @__PURE__ */ g(m, { children: [S.length > 0 && /* @__PURE__ */ h(s, {
45
+ }), P = /* @__PURE__ */ g(m, { children: [S.length > 0 && /* @__PURE__ */ h(s, {
38
46
  icon: "close",
39
47
  size: "small",
40
48
  onClick: () => {
@@ -54,7 +62,7 @@ function y({ ftsConfig: y }) {
54
62
  exit: 300
55
63
  },
56
64
  children: /* @__PURE__ */ h("form", {
57
- onSubmit: A,
65
+ onSubmit: j,
58
66
  children: y?.getSuggestions ? /* @__PURE__ */ h(d, {
59
67
  freeSolo: !0,
60
68
  disableClearable: !0,
@@ -64,7 +72,7 @@ function y({ ftsConfig: y }) {
64
72
  n === "input" && (E.current?.setCustomValidity(""), C(t));
65
73
  },
66
74
  onChange: (e, t) => {
67
- typeof t == "string" && t.trim().length >= _ && k(t);
75
+ typeof t == "string" && t.trim().length >= D && A(t);
68
76
  },
69
77
  renderInput: (e) => /* @__PURE__ */ h(p, {
70
78
  ...e,
@@ -75,28 +83,28 @@ function y({ ftsConfig: y }) {
75
83
  slotProps: {
76
84
  input: {
77
85
  ...e.InputProps,
78
- startAdornment: M,
79
- endAdornment: N
86
+ startAdornment: N,
87
+ endAdornment: P
80
88
  },
81
89
  htmlInput: {
82
90
  ...e.inputProps,
83
- minLength: _
91
+ minLength: D
84
92
  }
85
93
  }
86
94
  })
87
95
  }) : /* @__PURE__ */ h(p, {
88
96
  sx: { width: "100%" },
89
- onChange: j,
97
+ onChange: M,
90
98
  placeholder: "Enter Search Terms",
91
99
  value: S,
92
100
  type: "text",
93
101
  slotProps: {
94
102
  input: {
95
- startAdornment: M,
96
- endAdornment: N
103
+ startAdornment: N,
104
+ endAdornment: P
97
105
  },
98
106
  htmlInput: {
99
- minLength: _,
107
+ minLength: D,
100
108
  ref: E
101
109
  }
102
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FullTextSearch.js","names":[],"sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"sourcesContent":["import { Autocomplete, Collapse, TextField } from '@mui/material'\nimport React, {\n ChangeEvent,\n SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { useDebouncedEffect } from '@/utils/hooks'\nimport { HelpPopover } from '../HelpPopover/HelpPopover'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { IconSvgButton } from '../IconSvgButton'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { updateQueryUsingSearchTerm } from './FullTextSearchUtils'\nimport { FTSConfig } from '../SynapseTable/SearchV2'\n\n// See PLFM-7011\nconst MIN_SEARCH_QUERY_LENGTH = 3\nconst SUGGESTION_DEBOUNCE_MS = 300\n\nexport type FullTextSearchProps = {\n ftsConfig?: FTSConfig\n}\n\nexport function FullTextSearch({\n ftsConfig,\n}: FullTextSearchProps): React.ReactNode {\n const { executeQueryRequest } = useQueryContext()\n const { showSearchBar } = useQueryVisualizationContext()\n const [searchText, setSearchText] = useState('')\n const [suggestions, setSuggestions] = useState<string[]>([])\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n const { data } = useGetQueryMetadata()\n const columnModels = data?.columnModels\n\n // Clear suggestions immediately when the search text is too short\n useEffect(() => {\n if (\n !ftsConfig?.getSuggestions ||\n searchText.trim().length < MIN_SEARCH_QUERY_LENGTH\n ) {\n setSuggestions([])\n }\n }, [ftsConfig?.getSuggestions, searchText])\n\n // Fetch autocomplete suggestions whenever searchText changes (debounced)\n useDebouncedEffect(\n () => {\n if (\n !ftsConfig?.getSuggestions ||\n searchText.trim().length < MIN_SEARCH_QUERY_LENGTH\n ) {\n return\n }\n ftsConfig\n .getSuggestions(searchText)\n .then(setSuggestions)\n .catch(() => setSuggestions([]))\n },\n [searchText, ftsConfig],\n SUGGESTION_DEBOUNCE_MS,\n )\n\n const executeSearch = (text: string) => {\n executeQueryRequest(queryBundleRequest =>\n updateQueryUsingSearchTerm(\n queryBundleRequest,\n columnModels,\n text,\n ftsConfig,\n ),\n )\n setSearchText('')\n setSuggestions([])\n }\n\n const search = (event: SyntheticEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n // The HTML validation doesn't trim the string, so we add an extra check.\n // We don't auto-trim the form text ourselves because the user may still be focused on the input.\n if (searchText.trim().length < MIN_SEARCH_QUERY_LENGTH) {\n searchInputRef.current?.setCustomValidity(\n `Search term must have a minimum of ${MIN_SEARCH_QUERY_LENGTH} characters`,\n )\n } else {\n executeSearch(searchText)\n }\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n searchInputRef.current?.setCustomValidity('')\n setSearchText(event.currentTarget.value)\n }\n\n const startAdornment = (\n <IconSvg\n icon=\"search\"\n wrap={false}\n sx={{\n mr: 1,\n color: 'grey.600',\n }}\n />\n )\n\n const endAdornment = (\n <>\n {searchText.length > 0 && (\n <IconSvgButton\n icon=\"close\"\n size=\"small\"\n onClick={() => {\n setSearchText('')\n setSuggestions([])\n }}\n />\n )}\n {ftsConfig?.searchHelpURL && (\n <HelpPopover\n markdownText={'This search bar is powered by MySQL Full Text Search.'}\n helpUrl={ftsConfig.searchHelpURL}\n placement=\"left\"\n />\n )}\n </>\n )\n\n return (\n <div className={`QueryWrapperFullTextSearchInput`}>\n <Collapse in={showSearchBar} timeout={{ enter: 300, exit: 300 }}>\n <form onSubmit={search}>\n {ftsConfig?.getSuggestions ? (\n <Autocomplete\n freeSolo\n disableClearable\n options={suggestions}\n inputValue={searchText}\n onInputChange={(_, newValue, reason) => {\n if (reason !== 'input') return\n searchInputRef.current?.setCustomValidity('')\n setSearchText(newValue)\n }}\n onChange={(_, newValue) => {\n // Auto-execute search when a suggestion is selected from the dropdown\n if (\n typeof newValue === 'string' &&\n newValue.trim().length >= MIN_SEARCH_QUERY_LENGTH\n ) {\n executeSearch(newValue)\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n inputRef={searchInputRef}\n sx={{ width: '100%' }}\n placeholder=\"Enter Search Terms\"\n type=\"text\"\n slotProps={{\n input: {\n ...params.InputProps,\n startAdornment,\n endAdornment,\n },\n htmlInput: {\n ...params.inputProps,\n minLength: MIN_SEARCH_QUERY_LENGTH,\n },\n }}\n />\n )}\n />\n ) : (\n <TextField\n sx={{ width: '100%' }}\n onChange={handleChange}\n placeholder=\"Enter Search Terms\"\n value={searchText}\n type=\"text\"\n slotProps={{\n input: {\n startAdornment,\n endAdornment,\n },\n htmlInput: {\n minLength: MIN_SEARCH_QUERY_LENGTH,\n ref: searchInputRef,\n },\n }}\n />\n )}\n </form>\n </Collapse>\n </div>\n )\n}\n\nexport default FullTextSearch\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,IAAM,IAA0B,GAC1B,IAAyB;AAM/B,SAAgB,EAAe,EAC7B,gBACuC;CACvC,IAAM,EAAE,2BAAwB,GAAiB,EAC3C,EAAE,qBAAkB,GAA8B,EAClD,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAa,KAAkB,EAAmB,EAAE,CAAC,EACtD,IAAiB,EAAyB,KAAK,EAE/C,EAAE,YAAS,GAAqB,EAChC,IAAe,GAAM;AAa3B,CAVA,QAAgB;AACd,GACE,CAAC,GAAW,kBACZ,EAAW,MAAM,CAAC,SAAS,MAE3B,EAAe,EAAE,CAAC;IAEnB,CAAC,GAAW,gBAAgB,EAAW,CAAC,EAG3C,QACQ;AAEF,GAAC,GAAW,kBACZ,EAAW,MAAM,CAAC,SAAS,KAI7B,EACG,eAAe,EAAW,CAC1B,KAAK,EAAe,CACpB,YAAY,EAAe,EAAE,CAAC,CAAC;IAEpC,CAAC,GAAY,EAAU,EACvB,EACD;CAED,IAAM,KAAiB,MAAiB;AAUtC,EATA,GAAoB,MAClB,EACE,GACA,GACA,GACA,EACD,CACF,EACD,EAAc,GAAG,EACjB,EAAe,EAAE,CAAC;IAGd,KAAU,MAA2C;AAKzD,EAJA,EAAM,gBAAgB,EAIlB,EAAW,MAAM,CAAC,SAAS,IAC7B,EAAe,SAAS,kBACtB,sCAAsC,EAAwB,aAC/D,GAED,EAAc,EAAW;IAIvB,KAAgB,MAAyC;AAE7D,EADA,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAM,cAAc,MAAM;IAGpC,IACJ,kBAAC,GAAD;EACE,MAAK;EACL,MAAM;EACN,IAAI;GACF,IAAI;GACJ,OAAO;GACR;EACD,CAAA,EAGE,IACJ,kBAAA,GAAA,EAAA,UAAA,CACG,EAAW,SAAS,KACnB,kBAAC,GAAD;EACE,MAAK;EACL,MAAK;EACL,eAAe;AAEb,GADA,EAAc,GAAG,EACjB,EAAe,EAAE,CAAC;;EAEpB,CAAA,EAEH,GAAW,iBACV,kBAAC,GAAD;EACE,cAAc;EACd,SAAS,EAAU;EACnB,WAAU;EACV,CAAA,CAEH,EAAA,CAAA;AAGL,QACE,kBAAC,OAAD;EAAK,WAAW;YACd,kBAAC,GAAD;GAAU,IAAI;GAAe,SAAS;IAAE,OAAO;IAAK,MAAM;IAAK;aAC7D,kBAAC,QAAD;IAAM,UAAU;cACb,GAAW,iBACV,kBAAC,GAAD;KACE,UAAA;KACA,kBAAA;KACA,SAAS;KACT,YAAY;KACZ,gBAAgB,GAAG,GAAU,MAAW;AAClC,YAAW,YACf,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAS;;KAEzB,WAAW,GAAG,MAAa;AAEzB,MACE,OAAO,KAAa,YACpB,EAAS,MAAM,CAAC,UAAU,KAE1B,EAAc,EAAS;;KAG3B,cAAa,MACX,kBAAC,GAAD;MACE,GAAI;MACJ,UAAU;MACV,IAAI,EAAE,OAAO,QAAQ;MACrB,aAAY;MACZ,MAAK;MACL,WAAW;OACT,OAAO;QACL,GAAG,EAAO;QACV;QACA;QACD;OACD,WAAW;QACT,GAAG,EAAO;QACV,WAAW;QACZ;OACF;MACD,CAAA;KAEJ,CAAA,GAEF,kBAAC,GAAD;KACE,IAAI,EAAE,OAAO,QAAQ;KACrB,UAAU;KACV,aAAY;KACZ,OAAO;KACP,MAAK;KACL,WAAW;MACT,OAAO;OACL;OACA;OACD;MACD,WAAW;OACT,WAAW;OACX,KAAK;OACN;MACF;KACD,CAAA;IAEC,CAAA;GACE,CAAA;EACP,CAAA"}
1
+ {"version":3,"file":"FullTextSearch.js","names":[],"sources":["../../../src/components/FullTextSearch/FullTextSearch.tsx"],"sourcesContent":["import { Autocomplete, Collapse, TextField } from '@mui/material'\nimport React, {\n ChangeEvent,\n SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { useDebouncedEffect } from '@/utils/hooks'\nimport { HelpPopover } from '../HelpPopover/HelpPopover'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { IconSvgButton } from '../IconSvgButton'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { updateQueryUsingSearchTerm } from './FullTextSearchUtils'\nimport { FTSConfig } from '../SynapseTable/SearchV2'\n\n// See PLFM-7011\nconst MIN_SEARCH_QUERY_LENGTH = 3\nconst SUGGESTION_DEBOUNCE_MS = 300\n\nexport type FullTextSearchProps = {\n ftsConfig?: FTSConfig\n}\n\nexport function FullTextSearch({\n ftsConfig,\n}: FullTextSearchProps): React.ReactNode {\n const { executeQueryRequest } = useQueryContext()\n const { showSearchBar } = useQueryVisualizationContext()\n const [searchText, setSearchText] = useState('')\n const [suggestions, setSuggestions] = useState<string[]>([])\n const searchInputRef = useRef<HTMLInputElement>(null)\n const minSearchQueryLength: number =\n ftsConfig?.minSearchQueryLength ?? MIN_SEARCH_QUERY_LENGTH\n\n const { data } = useGetQueryMetadata()\n const columnModels = data?.columnModels\n\n // Clear suggestions immediately when the search text is too short\n useEffect(() => {\n if (\n !ftsConfig?.getSuggestions ||\n searchText.trim().length < minSearchQueryLength\n ) {\n setSuggestions([])\n }\n }, [ftsConfig?.getSuggestions, minSearchQueryLength, searchText])\n\n // Fetch autocomplete suggestions whenever searchText changes (debounced)\n useDebouncedEffect(\n () => {\n if (\n !ftsConfig?.getSuggestions ||\n searchText.trim().length < minSearchQueryLength\n ) {\n return\n }\n ftsConfig\n .getSuggestions(searchText)\n .then(setSuggestions)\n .catch(() => setSuggestions([]))\n },\n [searchText, ftsConfig, minSearchQueryLength],\n SUGGESTION_DEBOUNCE_MS,\n )\n\n const executeSearch = (text: string) => {\n executeQueryRequest(queryBundleRequest =>\n updateQueryUsingSearchTerm(\n queryBundleRequest,\n columnModels,\n text,\n ftsConfig,\n ),\n )\n setSearchText('')\n setSuggestions([])\n }\n\n const search = (event: SyntheticEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n // The HTML validation doesn't trim the string, so we add an extra check.\n // We don't auto-trim the form text ourselves because the user may still be focused on the input.\n if (searchText.trim().length < minSearchQueryLength) {\n searchInputRef.current?.setCustomValidity(\n `Search term must have a minimum of ${minSearchQueryLength} characters`,\n )\n } else {\n executeSearch(searchText)\n }\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n searchInputRef.current?.setCustomValidity('')\n setSearchText(event.currentTarget.value)\n }\n\n const startAdornment = (\n <IconSvg\n icon=\"search\"\n wrap={false}\n sx={{\n mr: 1,\n color: 'grey.600',\n }}\n />\n )\n\n const endAdornment = (\n <>\n {searchText.length > 0 && (\n <IconSvgButton\n icon=\"close\"\n size=\"small\"\n onClick={() => {\n setSearchText('')\n setSuggestions([])\n }}\n />\n )}\n {ftsConfig?.searchHelpURL && (\n <HelpPopover\n markdownText={'This search bar is powered by MySQL Full Text Search.'}\n helpUrl={ftsConfig.searchHelpURL}\n placement=\"left\"\n />\n )}\n </>\n )\n\n return (\n <div className={`QueryWrapperFullTextSearchInput`}>\n <Collapse in={showSearchBar} timeout={{ enter: 300, exit: 300 }}>\n <form onSubmit={search}>\n {ftsConfig?.getSuggestions ? (\n <Autocomplete\n freeSolo\n disableClearable\n options={suggestions}\n inputValue={searchText}\n onInputChange={(_, newValue, reason) => {\n if (reason !== 'input') return\n searchInputRef.current?.setCustomValidity('')\n setSearchText(newValue)\n }}\n onChange={(_, newValue) => {\n // Auto-execute search when a suggestion is selected from the dropdown\n if (\n typeof newValue === 'string' &&\n newValue.trim().length >= minSearchQueryLength\n ) {\n executeSearch(newValue)\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n inputRef={searchInputRef}\n sx={{ width: '100%' }}\n placeholder=\"Enter Search Terms\"\n type=\"text\"\n slotProps={{\n input: {\n ...params.InputProps,\n startAdornment,\n endAdornment,\n },\n htmlInput: {\n ...params.inputProps,\n minLength: minSearchQueryLength,\n },\n }}\n />\n )}\n />\n ) : (\n <TextField\n sx={{ width: '100%' }}\n onChange={handleChange}\n placeholder=\"Enter Search Terms\"\n value={searchText}\n type=\"text\"\n slotProps={{\n input: {\n startAdornment,\n endAdornment,\n },\n htmlInput: {\n minLength: minSearchQueryLength,\n ref: searchInputRef,\n },\n }}\n />\n )}\n </form>\n </Collapse>\n </div>\n )\n}\n\nexport default FullTextSearch\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,IAAM,IAA0B,GAC1B,IAAyB;AAM/B,SAAgB,EAAe,EAC7B,gBACuC;CACvC,IAAM,EAAE,2BAAwB,GAAiB,EAC3C,EAAE,qBAAkB,GAA8B,EAClD,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAa,KAAkB,EAAmB,EAAE,CAAC,EACtD,IAAiB,EAAyB,KAAK,EAC/C,IACJ,GAAW,wBAAwB,GAE/B,EAAE,YAAS,GAAqB,EAChC,IAAe,GAAM;AAa3B,CAVA,QAAgB;AACd,GACE,CAAC,GAAW,kBACZ,EAAW,MAAM,CAAC,SAAS,MAE3B,EAAe,EAAE,CAAC;IAEnB;EAAC,GAAW;EAAgB;EAAsB;EAAW,CAAC,EAGjE,QACQ;AAEF,GAAC,GAAW,kBACZ,EAAW,MAAM,CAAC,SAAS,KAI7B,EACG,eAAe,EAAW,CAC1B,KAAK,EAAe,CACpB,YAAY,EAAe,EAAE,CAAC,CAAC;IAEpC;EAAC;EAAY;EAAW;EAAqB,EAC7C,EACD;CAED,IAAM,KAAiB,MAAiB;AAUtC,EATA,GAAoB,MAClB,EACE,GACA,GACA,GACA,EACD,CACF,EACD,EAAc,GAAG,EACjB,EAAe,EAAE,CAAC;IAGd,KAAU,MAA2C;AAKzD,EAJA,EAAM,gBAAgB,EAIlB,EAAW,MAAM,CAAC,SAAS,IAC7B,EAAe,SAAS,kBACtB,sCAAsC,EAAqB,aAC5D,GAED,EAAc,EAAW;IAIvB,KAAgB,MAAyC;AAE7D,EADA,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAM,cAAc,MAAM;IAGpC,IACJ,kBAAC,GAAD;EACE,MAAK;EACL,MAAM;EACN,IAAI;GACF,IAAI;GACJ,OAAO;GACR;EACD,CAAA,EAGE,IACJ,kBAAA,GAAA,EAAA,UAAA,CACG,EAAW,SAAS,KACnB,kBAAC,GAAD;EACE,MAAK;EACL,MAAK;EACL,eAAe;AAEb,GADA,EAAc,GAAG,EACjB,EAAe,EAAE,CAAC;;EAEpB,CAAA,EAEH,GAAW,iBACV,kBAAC,GAAD;EACE,cAAc;EACd,SAAS,EAAU;EACnB,WAAU;EACV,CAAA,CAEH,EAAA,CAAA;AAGL,QACE,kBAAC,OAAD;EAAK,WAAW;YACd,kBAAC,GAAD;GAAU,IAAI;GAAe,SAAS;IAAE,OAAO;IAAK,MAAM;IAAK;aAC7D,kBAAC,QAAD;IAAM,UAAU;cACb,GAAW,iBACV,kBAAC,GAAD;KACE,UAAA;KACA,kBAAA;KACA,SAAS;KACT,YAAY;KACZ,gBAAgB,GAAG,GAAU,MAAW;AAClC,YAAW,YACf,EAAe,SAAS,kBAAkB,GAAG,EAC7C,EAAc,EAAS;;KAEzB,WAAW,GAAG,MAAa;AAEzB,MACE,OAAO,KAAa,YACpB,EAAS,MAAM,CAAC,UAAU,KAE1B,EAAc,EAAS;;KAG3B,cAAa,MACX,kBAAC,GAAD;MACE,GAAI;MACJ,UAAU;MACV,IAAI,EAAE,OAAO,QAAQ;MACrB,aAAY;MACZ,MAAK;MACL,WAAW;OACT,OAAO;QACL,GAAG,EAAO;QACV;QACA;QACD;OACD,WAAW;QACT,GAAG,EAAO;QACV,WAAW;QACZ;OACF;MACD,CAAA;KAEJ,CAAA,GAEF,kBAAC,GAAD;KACE,IAAI,EAAE,OAAO,QAAQ;KACrB,UAAU;KACV,aAAY;KACZ,OAAO;KACP,MAAK;KACL,WAAW;MACT,OAAO;OACL;OACA;OACD;MACD,WAAW;OACT,WAAW;OACX,KAAK;OACN;MACF;KACD,CAAA;IAEC,CAAA;GACE,CAAA;EACP,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"FullTextSearchUtils.d.ts","sourceRoot":"","sources":["../../../src/components/FullTextSearch/FullTextSearchUtils.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EAGX,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGpD;;;GAGG;AACH,wBAAgB,4CAA4C,CAC1D,gBAAgB,EAAE,MAAM,UAYzB;AAID,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,SAEV,0BAgBF;AAED,wBAAgB,0BAA0B,CACxC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,EACvC,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,SAAS,GACpB,kBAAkB,CA8CpB"}
1
+ {"version":3,"file":"FullTextSearchUtils.d.ts","sourceRoot":"","sources":["../../../src/components/FullTextSearch/FullTextSearchUtils.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EAGX,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGpD;;;GAGG;AACH,wBAAgB,4CAA4C,CAC1D,gBAAgB,EAAE,MAAM,UAYzB;AAID,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,SAEV,0BAgBF;AAED,wBAAgB,0BAA0B,CACxC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,EACvC,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,SAAS,GACpB,kBAAkB,CA2DpB"}
@@ -32,8 +32,13 @@ function o(n, i, o, s) {
32
32
  c.push(e);
33
33
  } else {
34
34
  let e = a(o, s);
35
- if (c.find((t) => t.concreteType == e.concreteType && t.searchExpression == e.searchExpression)) return n;
36
- c.push(e);
35
+ if (s?.replaceExistingFilter) {
36
+ for (let t = c.length - 1; t >= 0; t--) c[t].concreteType === e.concreteType && c.splice(t, 1);
37
+ c.push(e);
38
+ } else {
39
+ if (c.find((t) => t.concreteType == e.concreteType && t.searchExpression == e.searchExpression)) return n;
40
+ c.push(e);
41
+ }
37
42
  }
38
43
  return n.query.additionalFilters = c, n;
39
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FullTextSearchUtils.js","names":[],"sources":["../../../src/components/FullTextSearch/FullTextSearchUtils.ts"],"sourcesContent":["import { SYNAPSE_ENTITY_ID_REGEX } from '@/utils/functions/RegularExpressions'\nimport {\n ColumnModel,\n ColumnSingleValueFilterOperator,\n ColumnSingleValueQueryFilter,\n QueryBundleRequest,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport { getFileColumnModelId } from '../SynapseTable/SynapseTableUtils'\nimport { FTSConfig } from '../SynapseTable/SearchV2'\nimport { getWordCount } from '../TextField/TextFieldWithWordLimit'\n\n/**\n * Expects a search expression of the form: \"searchText\" @3\n * In this example, this function will return the following string via a regex: searchText\n */\nexport function getSearchTextFromBooleanModeSearchExpression(\n searchExpression: string,\n) {\n /**\n * ^\"(.+?)\": Matches the opening double quote and lazily captures any characters until the next quote.\n * \\s*@\\d+$: Matches optional whitespace, the @ symbol, and one or more digits at the end.\n */\n const match = searchExpression.match(/^\"(.+?)\"\\s*@\\d+$/)\n if (match) {\n return match[1]\n } else {\n return ''\n }\n}\n\n// Convert the user-provided searchText into a search expression given the current FTS configuration.\n// If configured to search using BOOLEAN mode, search expression will wrap the search text in double quotes and include the distance.\nexport function getTextMatchesQueryFilter(\n searchText: string,\n ftsConfig: FTSConfig = {\n textMatchesMode: 'NATURAL_LANGUAGE',\n },\n) {\n const { textMatchesMode, distance = 0 } = ftsConfig\n let searchExpression = searchText\n if (textMatchesMode == 'BOOLEAN') {\n //split by non-word character and ignore empty strings\n const searchTextWordLength = getWordCount(searchText)\n const distanceToUse = Math.max(distance, searchTextWordLength)\n searchExpression = `\"${searchText.replaceAll('\"', '')}\" @${distanceToUse}`\n }\n const textMatchesQueryFilter: TextMatchesQueryFilter = {\n concreteType: 'org.sagebionetworks.repo.model.table.TextMatchesQueryFilter',\n searchExpression,\n searchMode: ftsConfig.textMatchesMode,\n }\n return textMatchesQueryFilter\n}\n\nexport function updateQueryUsingSearchTerm(\n queryBundleRequest: QueryBundleRequest,\n columnModels: ColumnModel[] | undefined,\n searchText: string,\n ftsConfig?: FTSConfig,\n): QueryBundleRequest {\n const { additionalFilters = [] } = queryBundleRequest.query\n const synIdColumnModelId = getFileColumnModelId(columnModels)\n const isSynapseID = searchText.match(SYNAPSE_ENTITY_ID_REGEX)\n if (isSynapseID && synIdColumnModelId) {\n const idColumnModel = columnModels?.filter(\n el => el.id === synIdColumnModelId,\n )\n const singleValueQueryFilter: ColumnSingleValueQueryFilter = {\n concreteType:\n 'org.sagebionetworks.repo.model.table.ColumnSingleValueQueryFilter',\n columnName: idColumnModel![0].name,\n operator: ColumnSingleValueFilterOperator.IN,\n values: [searchText],\n }\n // Replace the active filter on the column, if one exists\n const matchingFilter = additionalFilters.find(\n filter =>\n filter.concreteType == singleValueQueryFilter.concreteType &&\n filter.columnName == singleValueQueryFilter.columnName,\n ) as ColumnSingleValueQueryFilter\n if (matchingFilter) {\n if (!matchingFilter.values.includes(searchText)) {\n matchingFilter.values.push(searchText)\n }\n return queryBundleRequest\n }\n additionalFilters.push(singleValueQueryFilter)\n } else {\n const textMatchesQueryFilter = getTextMatchesQueryFilter(\n searchText,\n ftsConfig,\n )\n // PORTALS-2093: does this additional filter already exist?\n const found = additionalFilters.find(\n filter =>\n filter.concreteType == textMatchesQueryFilter.concreteType &&\n filter.searchExpression == textMatchesQueryFilter.searchExpression,\n )\n if (found) {\n return queryBundleRequest\n }\n additionalFilters.push(textMatchesQueryFilter)\n }\n queryBundleRequest.query.additionalFilters = additionalFilters\n return queryBundleRequest\n}\n"],"mappings":";;;;;AAgBA,SAAgB,EACd,GACA;CAKA,IAAM,IAAQ,EAAiB,MAAM,mBAAmB;AAItD,QAHE,IACK,EAAM,KAEN;;AAMX,SAAgB,EACd,GACA,IAAuB,EACrB,iBAAiB,oBAClB,EACD;CACA,IAAM,EAAE,oBAAiB,cAAW,MAAM,GACtC,IAAmB;AACvB,KAAI,KAAmB,WAAW;EAEhC,IAAM,IAAuB,EAAa,EAAW,EAC/C,IAAgB,KAAK,IAAI,GAAU,EAAqB;AAC9D,MAAmB,IAAI,EAAW,WAAW,MAAK,GAAG,CAAC,KAAK;;AAO7D,QAAO;EAJL,cAAc;EACd;EACA,YAAY,EAAU;EAEjB;;AAGT,SAAgB,EACd,GACA,GACA,GACA,GACoB;CACpB,IAAM,EAAE,uBAAoB,EAAE,KAAK,EAAmB,OAChD,IAAqB,EAAqB,EAAa;AAE7D,KADoB,EAAW,MAAM,EACjC,IAAe,GAAoB;EAIrC,IAAM,IAAuD;GAC3D,cACE;GACF,aANoB,GAAc,QAClC,MAAM,EAAG,OAAO,EACjB,EAI4B,GAAG;GAC9B,UAAU,EAAgC;GAC1C,QAAQ,CAAC,EAAW;GACrB,EAEK,IAAiB,EAAkB,MACvC,MACE,EAAO,gBAAgB,EAAuB,gBAC9C,EAAO,cAAc,EAAuB,WAC/C;AACD,MAAI,EAIF,QAHK,EAAe,OAAO,SAAS,EAAW,IAC7C,EAAe,OAAO,KAAK,EAAW,EAEjC;AAET,IAAkB,KAAK,EAAuB;QACzC;EACL,IAAM,IAAyB,EAC7B,GACA,EACD;AAOD,MALc,EAAkB,MAC9B,MACE,EAAO,gBAAgB,EAAuB,gBAC9C,EAAO,oBAAoB,EAAuB,iBAElD,CACF,QAAO;AAET,IAAkB,KAAK,EAAuB;;AAGhD,QADA,EAAmB,MAAM,oBAAoB,GACtC"}
1
+ {"version":3,"file":"FullTextSearchUtils.js","names":[],"sources":["../../../src/components/FullTextSearch/FullTextSearchUtils.ts"],"sourcesContent":["import { SYNAPSE_ENTITY_ID_REGEX } from '@/utils/functions/RegularExpressions'\nimport {\n ColumnModel,\n ColumnSingleValueFilterOperator,\n ColumnSingleValueQueryFilter,\n QueryBundleRequest,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport { getFileColumnModelId } from '../SynapseTable/SynapseTableUtils'\nimport { FTSConfig } from '../SynapseTable/SearchV2'\nimport { getWordCount } from '../TextField/TextFieldWithWordLimit'\n\n/**\n * Expects a search expression of the form: \"searchText\" @3\n * In this example, this function will return the following string via a regex: searchText\n */\nexport function getSearchTextFromBooleanModeSearchExpression(\n searchExpression: string,\n) {\n /**\n * ^\"(.+?)\": Matches the opening double quote and lazily captures any characters until the next quote.\n * \\s*@\\d+$: Matches optional whitespace, the @ symbol, and one or more digits at the end.\n */\n const match = searchExpression.match(/^\"(.+?)\"\\s*@\\d+$/)\n if (match) {\n return match[1]\n } else {\n return ''\n }\n}\n\n// Convert the user-provided searchText into a search expression given the current FTS configuration.\n// If configured to search using BOOLEAN mode, search expression will wrap the search text in double quotes and include the distance.\nexport function getTextMatchesQueryFilter(\n searchText: string,\n ftsConfig: FTSConfig = {\n textMatchesMode: 'NATURAL_LANGUAGE',\n },\n) {\n const { textMatchesMode, distance = 0 } = ftsConfig\n let searchExpression = searchText\n if (textMatchesMode == 'BOOLEAN') {\n //split by non-word character and ignore empty strings\n const searchTextWordLength = getWordCount(searchText)\n const distanceToUse = Math.max(distance, searchTextWordLength)\n searchExpression = `\"${searchText.replaceAll('\"', '')}\" @${distanceToUse}`\n }\n const textMatchesQueryFilter: TextMatchesQueryFilter = {\n concreteType: 'org.sagebionetworks.repo.model.table.TextMatchesQueryFilter',\n searchExpression,\n searchMode: ftsConfig.textMatchesMode,\n }\n return textMatchesQueryFilter\n}\n\nexport function updateQueryUsingSearchTerm(\n queryBundleRequest: QueryBundleRequest,\n columnModels: ColumnModel[] | undefined,\n searchText: string,\n ftsConfig?: FTSConfig,\n): QueryBundleRequest {\n const { additionalFilters = [] } = queryBundleRequest.query\n const synIdColumnModelId = getFileColumnModelId(columnModels)\n const isSynapseID = searchText.match(SYNAPSE_ENTITY_ID_REGEX)\n if (isSynapseID && synIdColumnModelId) {\n const idColumnModel = columnModels?.filter(\n el => el.id === synIdColumnModelId,\n )\n const singleValueQueryFilter: ColumnSingleValueQueryFilter = {\n concreteType:\n 'org.sagebionetworks.repo.model.table.ColumnSingleValueQueryFilter',\n columnName: idColumnModel![0].name,\n operator: ColumnSingleValueFilterOperator.IN,\n values: [searchText],\n }\n // Replace the active filter on the column, if one exists\n const matchingFilter = additionalFilters.find(\n filter =>\n filter.concreteType == singleValueQueryFilter.concreteType &&\n filter.columnName == singleValueQueryFilter.columnName,\n ) as ColumnSingleValueQueryFilter\n if (matchingFilter) {\n if (!matchingFilter.values.includes(searchText)) {\n matchingFilter.values.push(searchText)\n }\n return queryBundleRequest\n }\n additionalFilters.push(singleValueQueryFilter)\n } else {\n const textMatchesQueryFilter = getTextMatchesQueryFilter(\n searchText,\n ftsConfig,\n )\n if (ftsConfig?.replaceExistingFilter) {\n // Remove all existing TextMatchesQueryFilters, then add the new one\n for (let i = additionalFilters.length - 1; i >= 0; i--) {\n if (\n additionalFilters[i].concreteType ===\n textMatchesQueryFilter.concreteType\n ) {\n additionalFilters.splice(i, 1)\n }\n }\n additionalFilters.push(textMatchesQueryFilter)\n } else {\n // PORTALS-2093: does this additional filter already exist?\n const found = additionalFilters.find(\n filter =>\n filter.concreteType == textMatchesQueryFilter.concreteType &&\n filter.searchExpression == textMatchesQueryFilter.searchExpression,\n )\n if (found) {\n return queryBundleRequest\n }\n additionalFilters.push(textMatchesQueryFilter)\n }\n }\n queryBundleRequest.query.additionalFilters = additionalFilters\n return queryBundleRequest\n}\n"],"mappings":";;;;;AAgBA,SAAgB,EACd,GACA;CAKA,IAAM,IAAQ,EAAiB,MAAM,mBAAmB;AAItD,QAHE,IACK,EAAM,KAEN;;AAMX,SAAgB,EACd,GACA,IAAuB,EACrB,iBAAiB,oBAClB,EACD;CACA,IAAM,EAAE,oBAAiB,cAAW,MAAM,GACtC,IAAmB;AACvB,KAAI,KAAmB,WAAW;EAEhC,IAAM,IAAuB,EAAa,EAAW,EAC/C,IAAgB,KAAK,IAAI,GAAU,EAAqB;AAC9D,MAAmB,IAAI,EAAW,WAAW,MAAK,GAAG,CAAC,KAAK;;AAO7D,QAAO;EAJL,cAAc;EACd;EACA,YAAY,EAAU;EAEjB;;AAGT,SAAgB,EACd,GACA,GACA,GACA,GACoB;CACpB,IAAM,EAAE,uBAAoB,EAAE,KAAK,EAAmB,OAChD,IAAqB,EAAqB,EAAa;AAE7D,KADoB,EAAW,MAAM,EACjC,IAAe,GAAoB;EAIrC,IAAM,IAAuD;GAC3D,cACE;GACF,aANoB,GAAc,QAClC,MAAM,EAAG,OAAO,EACjB,EAI4B,GAAG;GAC9B,UAAU,EAAgC;GAC1C,QAAQ,CAAC,EAAW;GACrB,EAEK,IAAiB,EAAkB,MACvC,MACE,EAAO,gBAAgB,EAAuB,gBAC9C,EAAO,cAAc,EAAuB,WAC/C;AACD,MAAI,EAIF,QAHK,EAAe,OAAO,SAAS,EAAW,IAC7C,EAAe,OAAO,KAAK,EAAW,EAEjC;AAET,IAAkB,KAAK,EAAuB;QACzC;EACL,IAAM,IAAyB,EAC7B,GACA,EACD;AACD,MAAI,GAAW,uBAAuB;AAEpC,QAAK,IAAI,IAAI,EAAkB,SAAS,GAAG,KAAK,GAAG,IACjD,CACE,EAAkB,GAAG,iBACrB,EAAuB,gBAEvB,EAAkB,OAAO,GAAG,EAAE;AAGlC,KAAkB,KAAK,EAAuB;SACzC;AAOL,OALc,EAAkB,MAC9B,MACE,EAAO,gBAAgB,EAAuB,gBAC9C,EAAO,oBAAoB,EAAuB,iBAElD,CACF,QAAO;AAET,KAAkB,KAAK,EAAuB;;;AAIlD,QADA,EAAmB,MAAM,oBAAoB,GACtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BioregistryRules.d.ts","sourceRoot":"","sources":["../../../src/components/GenericCard/BioregistryRules.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB;;qBAFL,MAAM;GAi0B7B,CAAA"}
1
+ {"version":3,"file":"BioregistryRules.d.ts","sourceRoot":"","sources":["../../../src/components/GenericCard/BioregistryRules.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB;;qBAFL,MAAM;GAy0B7B,CAAA"}
@@ -256,6 +256,14 @@ var e = (e) => `https://bioregistry.io/${e}`, t = [
256
256
  regex: /(edam:(?:data|topic|operation|format)\_\d{4})/,
257
257
  onMatch: e
258
258
  },
259
+ {
260
+ regex: /(edam.data:\d+)/,
261
+ onMatch: e
262
+ },
263
+ {
264
+ regex: /(edam.topic:\d+)/,
265
+ onMatch: e
266
+ },
259
267
  {
260
268
  regex: /(ega.dataset:EGAD\d{11})/,
261
269
  onMatch: e
@@ -521,7 +529,7 @@ var e = (e) => `https://bioregistry.io/${e}`, t = [
521
529
  onMatch: e
522
530
  },
523
531
  {
524
- regex: /(ncit:[CRPA]\d+)/,
532
+ regex: /(ncit:(?:C|R|P|A|NHC)\d+)/,
525
533
  onMatch: e
526
534
  },
527
535
  {
@@ -1 +1 @@
1
- {"version":3,"file":"BioregistryRules.js","names":[],"sources":["../../../src/components/GenericCard/BioregistryRules.ts"],"sourcesContent":["/* eslint-disable no-useless-escape */\n// This file is auto-generated. Do not edit manually.\n// Generated from bioregistry.io API based on collection.yaml\n\nconst onMatch = (value: string) => `https://bioregistry.io/${value}`\n\nexport const bioregistryRules = [\n {\n regex: /(ado:\\d{7})/,\n onMatch,\n },\n {\n regex: /(agrkb:[1-9][0-9]{14})/,\n onMatch,\n },\n {\n regex: /(anzctr:ACTRN\\d+)/,\n onMatch,\n },\n {\n regex: /(arrayexpress:[AEP]-\\w{4}-\\d+)/,\n onMatch,\n },\n {\n regex: /(arxiv:(?:\\w+(?:\\-\\w+)?(?:\\.\\w+)?\\/?)?\\d{4,7}(?:\\.\\d+(?:v\\d+)?)?)/,\n onMatch,\n },\n {\n regex: /(atc:[A-Z](?:\\d+(?:[A-Z]{1,2}(?:\\d+)?)?)?)/,\n onMatch,\n },\n {\n regex: /(atcc:(?:[a-zA-Z]+-)?\\d+(?:\\.\\d)?)/,\n onMatch,\n },\n {\n regex: /(bacdive:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(bfo:\\d{7})/,\n onMatch,\n },\n {\n regex: /(bgee.gene:[A-Za-z0-9]+)/,\n onMatch,\n },\n {\n regex: /(biocyc:[A-Z-0-9]+(?:\\:)?[A-Za-z0-9+_.%-:]+)/,\n onMatch,\n },\n {\n regex: /(biogrid:\\d+)/,\n onMatch,\n },\n {\n regex: /(bioportal:(?:(?:\\d+)|(?:\\w+)))/,\n onMatch,\n },\n {\n regex: /(bioproject:PRJ[DEN][A-Z]\\d+)/,\n onMatch,\n },\n {\n regex: /(biorxiv:(?:\\d{4}\\.\\d{2}\\.\\d{2}\\.)?\\d{6,8}(?:v\\d{1,3})?)/,\n onMatch,\n },\n {\n regex: /(biosample:SAM[NED](?:\\w)?\\d+)/,\n onMatch,\n },\n {\n regex: /(biostudies:S-[A-Z]{4}[\\-\\_A-Z\\d]+)/,\n onMatch,\n },\n {\n regex: /(bmrb:(?:bmr|bmse|bmst)?[0-9]{1,6})/,\n onMatch,\n },\n {\n regex:\n /(brenda:(?:(?:\\d+\\.-\\.-\\.-)|(?:\\d+\\.\\d+\\.-\\.-)|(?:\\d+\\.\\d+\\.\\d+\\.-)|(?:\\d+\\.\\d+\\.\\d+\\.\\d+)))/,\n onMatch,\n },\n {\n regex: /(brenda.ligand:\\d+)/,\n onMatch,\n },\n {\n regex: /(brenda.ligandgroup:\\d+)/,\n onMatch,\n },\n {\n regex: /(bto:\\d{7})/,\n onMatch,\n },\n {\n regex: /(cath:[1-6]\\.[0-9]+\\.[0-9]+\\.[0-9]+)/,\n onMatch,\n },\n {\n regex: /(cbioportal:[a-z0-9\\_]+)/,\n onMatch,\n },\n {\n regex: /(cdd:(?:cd)?\\d{5})/,\n onMatch,\n },\n {\n regex: /(cellimage:\\d+)/,\n onMatch,\n },\n {\n regex:\n /(cellxgene.collection:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/,\n onMatch,\n },\n {\n regex: /(chebi:\\d+)/,\n onMatch,\n },\n {\n regex: /(chembl:CHEMBL\\d+)/,\n onMatch,\n },\n {\n regex: /(chembl.compound:CHEMBL\\d+)/,\n onMatch,\n },\n {\n regex: /(chemspider:\\d+)/,\n onMatch,\n },\n {\n regex: /(civic.aid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.did:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.eid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.gid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.sid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.tid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.vid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(clinicaltrials:NCT\\d{8})/,\n onMatch,\n },\n {\n regex: /(clinvar:\\d+)/,\n onMatch,\n },\n {\n regex: /(clinvar.record:RCV\\d+(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(complexportal:CPX-[0-9]+)/,\n onMatch,\n },\n {\n regex: /(cosmic:[A-Z0-9][A-Z0-9-]*)/,\n onMatch,\n },\n {\n regex: /(cosmic.cell:\\d+)/,\n onMatch,\n },\n {\n regex: /(cpt:\\d+)/,\n onMatch,\n },\n {\n regex: /(ctd.chemical:[CD]\\d+)/,\n onMatch,\n },\n {\n regex: /(ctri:CTRI\\/\\d{4}\\/\\d{2,3}\\/\\d+)/,\n onMatch,\n },\n {\n regex: /(cvx:\\d+)/,\n onMatch,\n },\n {\n regex: /(dbgap:phs[0-9]{6}(?:.v\\d+.p\\d+)?)/,\n onMatch,\n },\n {\n regex: /(dbsnp:rs\\d+)/,\n onMatch,\n },\n {\n regex: /(decipher:\\d+)/,\n onMatch,\n },\n {\n regex: /(depmap:ACH-\\d+)/,\n onMatch,\n },\n {\n regex: /(dhba:\\d+)/,\n onMatch,\n },\n {\n regex: /(disprot:DP\\d{5})/,\n onMatch,\n },\n {\n regex: /(dmba:\\d+)/,\n onMatch,\n },\n {\n regex: /(doi:10.\\d{2,9}\\/.*)/,\n onMatch,\n },\n {\n regex: /(doid:\\d+)/,\n onMatch,\n },\n {\n regex: /(drks:DRKS\\d+)/,\n onMatch,\n },\n {\n regex: /(drugbank:DB\\d{5})/,\n onMatch,\n },\n {\n regex: /(drugcentral:\\d+)/,\n onMatch,\n },\n {\n regex: /(duo:\\d{7})/,\n onMatch,\n },\n {\n regex:\n /(ec:\\d{1,2}(?:(?:(?:\\.\\d{1,3}){1,3})|(?:\\.\\d+){2}\\.[nB]\\d{1,3}|\\.-\\.-\\.-|\\.\\d{1,3}\\.-\\.-|\\.\\d{1,3}\\.\\d{1,3}\\.-)?)/,\n onMatch,\n },\n {\n regex: /(ecacc:\\d+)/,\n onMatch,\n },\n {\n regex: /(edam:(?:data|topic|operation|format)\\_\\d{4})/,\n onMatch,\n },\n {\n regex: /(ega.dataset:EGAD\\d{11})/,\n onMatch,\n },\n {\n regex: /(ega.study:EGAS\\d{11})/,\n onMatch,\n },\n {\n regex: /(emdb:EMD-\\d{4,5})/,\n onMatch,\n },\n {\n regex: /(empiar:\\d+)/,\n onMatch,\n },\n {\n regex: /(ena.embl:[A-Z]+[0-9]+(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex:\n /(ensembl:(?:(?:ENS[FPTG]\\d{11}(?:\\.\\d+)?)|(?:FB\\w{2}\\d{7})|(?:Y[A-Z]{2}\\d{3}[a-zA-Z](?:\\-[A-Z])?)|(?:[A-Z_a-z0-9]+(?:\\.)?(?:t)?(?:\\d+)?(?:[a-z])?)))/,\n onMatch,\n },\n {\n regex: /(ensembl.metazoa:\\w+(?:\\.)?\\d+)/,\n onMatch,\n },\n {\n regex: /(ensembl.plant:\\w+(?:\\.\\d+)?(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(euclinicaltrials:\\d{4}\\-\\d{6}\\-\\d{2})/,\n onMatch,\n },\n {\n regex: /(eupath:\\d{7})/,\n onMatch,\n },\n {\n regex: /(exac.variant:\\d{1,2}\\-\\d+\\-[GATC]\\-[GATC])/,\n onMatch,\n },\n {\n regex: /(fairsharing:(?:bsg-[dscp]?\\d{6})|(?:FAIRsharing\\.\\w+))/,\n onMatch,\n },\n {\n regex: /(flybase:FB\\w{2}\\d{7})/,\n onMatch,\n },\n {\n regex: /(fma:\\d+)/,\n onMatch,\n },\n {\n regex: /(funderregistry:\\d+)/,\n onMatch,\n },\n {\n regex: /(gard:\\d+)/,\n onMatch,\n },\n {\n regex: /(gbif:\\d+)/,\n onMatch,\n },\n {\n regex: /(gdc:[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12})/,\n onMatch,\n },\n {\n regex: /(genecards:[A-Za-z-0-9_]+(?:\\@)?)/,\n onMatch,\n },\n {\n regex: /(geo:G(?:PL|SM|SE|DS)\\d+)/,\n onMatch,\n },\n {\n regex: /(go:\\d{7})/,\n onMatch,\n },\n {\n regex: /(gramene.gene:GR\\:\\d+)/,\n onMatch,\n },\n {\n regex: /(gramene.growthstage:\\d{7})/,\n onMatch,\n },\n {\n regex: /(gramene.protein:\\d+)/,\n onMatch,\n },\n {\n regex: /(gtdb:[cdfgops]__\\w+\\S+)/,\n onMatch,\n },\n {\n regex: /(hba:\\d+)/,\n onMatch,\n },\n {\n regex: /(hc.trial:\\d+)/,\n onMatch,\n },\n {\n regex: /(hgnc:\\d{1,5})/,\n onMatch,\n },\n {\n regex: /(hl7.v2codesystem:\\d+)/,\n onMatch,\n },\n {\n regex: /(hmdb:HMDB\\d+)/,\n onMatch,\n },\n {\n regex:\n /(icd10:(?:(?:[XVI]+)|(?:[A-Z][0-9]+(?:(?:-[A-Z][0-9]+)|(?:\\.[0-9]))?)))/,\n onMatch,\n },\n {\n regex:\n /(icd9:(?:(?:\\d{1,3}-\\d{1,3})|(?:(?:\\d\\d\\d|V\\d\\d|E[8-9]\\d\\d)(?:\\.\\d{1,2})?)))/,\n onMatch,\n },\n {\n regex: /(icdc:\\d{6})/,\n onMatch,\n },\n {\n regex: /(icf:\\d+)/,\n onMatch,\n },\n {\n regex: /(idr:[0-9]{4})/,\n onMatch,\n },\n {\n regex: /(imgt.hla:[A-Z0-9*:]+)/,\n onMatch,\n },\n {\n regex:\n /(inchi:InChI\\=1S?\\/[A-Za-z0-9\\.]+(?:\\+[0-9]+)?(?:\\/[cnpqbtmsih][A-Za-z0-9\\-\\+\\(?:\\)\\,\\/\\?\\;\\.]+)*)/,\n onMatch,\n },\n {\n regex: /(inchikey:[A-Z]{14}\\-[A-Z]{10}(?:\\-[A-Z])?)/,\n onMatch,\n },\n {\n regex:\n /(insdc:(?:[A-Z]\\d{5}|[A-Z]{2}\\d{6}|[A-Z]{4,6}\\d{8,10}|[A-J][A-Z]{2}\\d{5})(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(insdc.sra:[SED]R[APRSXZ]\\d+)/,\n onMatch,\n },\n {\n regex: /(intact:EBI\\-[0-9]+)/,\n onMatch,\n },\n {\n regex: /(interpro:IPR\\d{6})/,\n onMatch,\n },\n {\n regex: /(iso.3166:\\d+)/,\n onMatch,\n },\n {\n regex: /(isrctn:ISRCTN\\d+)/,\n onMatch,\n },\n {\n regex: /(itis:\\d+)/,\n onMatch,\n },\n {\n regex: /(jaxmice:\\d{6})/,\n onMatch,\n },\n {\n regex:\n /(kegg:(?:(?:[CHDEGTMKR]\\d+)|(?:\\w+:[\\w\\d\\.-]*)|(?:\\w{2,4}\\d{5})|(?:[a-z]{3,5})))/,\n onMatch,\n },\n {\n regex: /(kegg.compound:C\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.disease:H\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.drug:D\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.glycan:G\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.pathway:\\w{2,4}\\d{5})/,\n onMatch,\n },\n {\n regex: /(kegg.reaction:R\\d+)/,\n onMatch,\n },\n {\n regex: /(loinc:(?:\\d|\\w)+-\\d)/,\n onMatch,\n },\n {\n regex: /(massive:MSV\\d+)/,\n onMatch,\n },\n {\n regex: /(mba:\\d+)/,\n onMatch,\n },\n {\n regex: /(mesh:(?:C|D|Q)\\d+)/,\n onMatch,\n },\n {\n regex: /(metabolights:MTBL[CS]\\d+)/,\n onMatch,\n },\n {\n regex: /(metacyc.compound:[A-Za-z0-9+_.%-:]+)/,\n onMatch,\n },\n {\n regex: /(mgi:\\d+)/,\n onMatch,\n },\n {\n regex: /(mir:\\d{8})/,\n onMatch,\n },\n {\n regex: /(mirbase:MI\\d{7})/,\n onMatch,\n },\n {\n regex: /(mondo:\\d{7})/,\n onMatch,\n },\n {\n regex: /(ncbigene:\\d+)/,\n onMatch,\n },\n {\n regex: /(ncbiprotein:\\w+_?\\d+(?:.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(ncbitaxon:(?:(?:\\d+)|(?:[a-zA-Z_]+)))/,\n onMatch,\n },\n {\n regex: /(ncit:[CRPA]\\d+)/,\n onMatch,\n },\n {\n regex: /(ndc:\\d+\\-\\d+\\-\\d+)/,\n onMatch,\n },\n {\n regex: /(ndfrt:N[0-9]{10})/,\n onMatch,\n },\n {\n regex: /(nextprot:NX_\\w+)/,\n onMatch,\n },\n {\n regex: /(nihreporter.project:\\d+)/,\n onMatch,\n },\n {\n regex: /(nord:\\d+)/,\n onMatch,\n },\n {\n regex: /(omim:\\d+)/,\n onMatch,\n },\n {\n regex: /(omop:\\d+)/,\n onMatch,\n },\n {\n regex: /(orcid:\\d{4}-\\d{4}-\\d{4}-\\d{3}(?:\\d|X))/,\n onMatch,\n },\n {\n regex: /(orphanet:C?\\d+)/,\n onMatch,\n },\n {\n regex: /(orphanet.ordo:C?\\d+)/,\n onMatch,\n },\n {\n regex: /(osf:[a-z0-9]{5})/,\n onMatch,\n },\n {\n regex: /(panther.family:PTHR\\d{5}(?:\\:SF\\d{1,3})?)/,\n onMatch,\n },\n {\n regex: /(panther.pathway:P\\d{5})/,\n onMatch,\n },\n {\n regex: /(panther.pthcmp:(?:G|P|U|C|S)\\d{5})/,\n onMatch,\n },\n {\n regex: /(pba:\\d+)/,\n onMatch,\n },\n {\n regex: /(pdb:[0-9][A-Za-z0-9]{3})/,\n onMatch,\n },\n {\n regex: /(pdb-ccd:\\w{1,3})/,\n onMatch,\n },\n {\n regex: /(pdb.ligand:[A-Za-z0-9]+)/,\n onMatch,\n },\n {\n regex: /(pdc.study:PDC\\d+)/,\n onMatch,\n },\n {\n regex: /(peco:\\d{7})/,\n onMatch,\n },\n {\n regex: /(peptideatlas.dataset:PASS\\d{5})/,\n onMatch,\n },\n {\n regex: /(pfam:PF\\d{5})/,\n onMatch,\n },\n {\n regex: /(pfam.clan:CL\\d+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.disease:PA\\d+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.drug:PA\\d+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.gene:PA\\w+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.pathways:PA\\d+)/,\n onMatch,\n },\n {\n regex: /(pmc:PMC\\d+(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(pombase:S\\w+(?:\\.)?\\w+(?:\\.)?)/,\n onMatch,\n },\n {\n regex: /(pride.project:P(?:X|R|A)D\\d{6})/,\n onMatch,\n },\n {\n regex: /(pubchem.compound:\\d+)/,\n onMatch,\n },\n {\n regex: /(pubmed:\\d+)/,\n onMatch,\n },\n {\n regex: /(px:(?:R)?PXD\\d{6})/,\n onMatch,\n },\n {\n regex: /(radlex:RID\\d+)/,\n onMatch,\n },\n {\n regex: /(reactome:R-[A-Z]{3}-\\d+(?:-\\d+)?(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(rebec:RBR-\\w+)/,\n onMatch,\n },\n {\n regex:\n /(refseq:(?:(?:(?:AC|AP|NC|NG|NM|NP|NR|NT|NW|WP|XM|XP|XR|YP|ZP)_\\d+)|(?:NZ_[A-Z]{2,4}\\d+))(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(rfam:RF\\d{5})/,\n onMatch,\n },\n {\n regex: /(rfc:\\d+)/,\n onMatch,\n },\n {\n regex: /(rgd:\\d{4,})/,\n onMatch,\n },\n {\n regex: /(rhea:\\d{5})/,\n onMatch,\n },\n {\n regex: /(rnacentral:URS[0-9A-F]{10}(?:\\_\\d+)?)/,\n onMatch,\n },\n {\n regex: /(ror:0[a-hj-km-np-tv-z|0-9]{6}[0-9]{2})/,\n onMatch,\n },\n {\n regex: /(rrid:[a-zA-Z]+.+)/,\n onMatch,\n },\n {\n regex: /(rrrc:\\d+)/,\n onMatch,\n },\n {\n regex: /(rxnorm:[0-9]{1,7})/,\n onMatch,\n },\n {\n regex: /(scop:\\d+)/,\n onMatch,\n },\n {\n regex: /(sgd:(?:(?:S\\d+$)|(?:Y[A-Z]{2}\\d{3}[a-zA-Z](?:\\-[A-Z])?)))/,\n onMatch,\n },\n {\n regex: /(signor:SIGNOR\\-[A-Z]+\\d+)/,\n onMatch,\n },\n {\n regex: /(snomedct:(?:\\w+)?\\d+)/,\n onMatch,\n },\n {\n regex: /(so:\\d{7})/,\n onMatch,\n },\n {\n regex: /(ssbd.dataset:\\d+)/,\n onMatch,\n },\n {\n regex: /(ssbd.project:\\d+)/,\n onMatch,\n },\n {\n regex: /(stitch:\\w{14})/,\n onMatch,\n },\n {\n regex:\n /(string:(?:(?:[A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])|(?:[0-9][A-Za-z0-9]{3})))/,\n onMatch,\n },\n {\n regex: /(tao:\\d{7})/,\n onMatch,\n },\n {\n regex: /(tcdb:\\d+(?:\\.[A-Z])?(?:\\.\\d+)?(?:\\.\\d+)?(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(tcia.collection:[A-Za-z0-9][A-Za-z0-9_\\-\\.]*[A-Za-z0-9])/,\n onMatch,\n },\n {\n regex: /(uberon:\\d+)/,\n onMatch,\n },\n {\n regex: /(unii:[A-Z0-9]+)/,\n onMatch,\n },\n {\n regex: /(uniparc:UPI[A-F0-9]{10})/,\n onMatch,\n },\n {\n regex:\n /(uniprot:(?:(?:[A-N,R-Z][0-9](?:[A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(?:\\.\\d+)?(?:-\\d+)?(?:#PRO_\\d+)?))/,\n onMatch,\n },\n {\n regex:\n /(uniprot.isoform:(?:[A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(?:\\-\\d+))/,\n onMatch,\n },\n {\n regex: /(uniprot.proteome:UP\\d{9})/,\n onMatch,\n },\n {\n regex:\n /(uniref:UniRef(?:100|90|50)_(?:[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9](?:[A-Z][A-Z0-9]{2}[0-9]){1,2}|UPI[A-F0-9]{10}))/,\n onMatch,\n },\n {\n regex: /(wikidata:(?:Q|P|E|L)\\d+)/,\n onMatch,\n },\n {\n regex: /(wikigenes:\\d+)/,\n onMatch,\n },\n {\n regex: /(wikipathways:WP\\d{1,5}(?:\\_r\\d+)?)/,\n onMatch,\n },\n {\n regex: /(wormbase:(?:CE[0-9]{5}|WB[A-Z][a-z]+\\d+))/,\n onMatch,\n },\n {\n regex: /(xenbase:XB\\-\\w+\\-\\d+)/,\n onMatch,\n },\n {\n regex: /(zenodo.record:\\d+)/,\n onMatch,\n },\n {\n regex: /(zfin:ZDB\\-\\w+\\-\\d+\\-\\d+)/,\n onMatch,\n },\n {\n regex: /(zinc:(?:ZINC)?\\d+)/,\n onMatch,\n },\n]\n"],"mappings":";AAIA,IAAM,KAAW,MAAkB,0BAA0B,KAEhD,IAAmB;CAC9B;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACF"}
1
+ {"version":3,"file":"BioregistryRules.js","names":[],"sources":["../../../src/components/GenericCard/BioregistryRules.ts"],"sourcesContent":["/* eslint-disable no-useless-escape */\n// This file is auto-generated. Do not edit manually.\n// Generated from bioregistry.io API based on collection.yaml\n\nconst onMatch = (value: string) => `https://bioregistry.io/${value}`\n\nexport const bioregistryRules = [\n {\n regex: /(ado:\\d{7})/,\n onMatch,\n },\n {\n regex: /(agrkb:[1-9][0-9]{14})/,\n onMatch,\n },\n {\n regex: /(anzctr:ACTRN\\d+)/,\n onMatch,\n },\n {\n regex: /(arrayexpress:[AEP]-\\w{4}-\\d+)/,\n onMatch,\n },\n {\n regex: /(arxiv:(?:\\w+(?:\\-\\w+)?(?:\\.\\w+)?\\/?)?\\d{4,7}(?:\\.\\d+(?:v\\d+)?)?)/,\n onMatch,\n },\n {\n regex: /(atc:[A-Z](?:\\d+(?:[A-Z]{1,2}(?:\\d+)?)?)?)/,\n onMatch,\n },\n {\n regex: /(atcc:(?:[a-zA-Z]+-)?\\d+(?:\\.\\d)?)/,\n onMatch,\n },\n {\n regex: /(bacdive:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(bfo:\\d{7})/,\n onMatch,\n },\n {\n regex: /(bgee.gene:[A-Za-z0-9]+)/,\n onMatch,\n },\n {\n regex: /(biocyc:[A-Z-0-9]+(?:\\:)?[A-Za-z0-9+_.%-:]+)/,\n onMatch,\n },\n {\n regex: /(biogrid:\\d+)/,\n onMatch,\n },\n {\n regex: /(bioportal:(?:(?:\\d+)|(?:\\w+)))/,\n onMatch,\n },\n {\n regex: /(bioproject:PRJ[DEN][A-Z]\\d+)/,\n onMatch,\n },\n {\n regex: /(biorxiv:(?:\\d{4}\\.\\d{2}\\.\\d{2}\\.)?\\d{6,8}(?:v\\d{1,3})?)/,\n onMatch,\n },\n {\n regex: /(biosample:SAM[NED](?:\\w)?\\d+)/,\n onMatch,\n },\n {\n regex: /(biostudies:S-[A-Z]{4}[\\-\\_A-Z\\d]+)/,\n onMatch,\n },\n {\n regex: /(bmrb:(?:bmr|bmse|bmst)?[0-9]{1,6})/,\n onMatch,\n },\n {\n regex:\n /(brenda:(?:(?:\\d+\\.-\\.-\\.-)|(?:\\d+\\.\\d+\\.-\\.-)|(?:\\d+\\.\\d+\\.\\d+\\.-)|(?:\\d+\\.\\d+\\.\\d+\\.\\d+)))/,\n onMatch,\n },\n {\n regex: /(brenda.ligand:\\d+)/,\n onMatch,\n },\n {\n regex: /(brenda.ligandgroup:\\d+)/,\n onMatch,\n },\n {\n regex: /(bto:\\d{7})/,\n onMatch,\n },\n {\n regex: /(cath:[1-6]\\.[0-9]+\\.[0-9]+\\.[0-9]+)/,\n onMatch,\n },\n {\n regex: /(cbioportal:[a-z0-9\\_]+)/,\n onMatch,\n },\n {\n regex: /(cdd:(?:cd)?\\d{5})/,\n onMatch,\n },\n {\n regex: /(cellimage:\\d+)/,\n onMatch,\n },\n {\n regex:\n /(cellxgene.collection:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/,\n onMatch,\n },\n {\n regex: /(chebi:\\d+)/,\n onMatch,\n },\n {\n regex: /(chembl:CHEMBL\\d+)/,\n onMatch,\n },\n {\n regex: /(chembl.compound:CHEMBL\\d+)/,\n onMatch,\n },\n {\n regex: /(chemspider:\\d+)/,\n onMatch,\n },\n {\n regex: /(civic.aid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.did:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.eid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.gid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.sid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.tid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(civic.vid:[0-9]+)/,\n onMatch,\n },\n {\n regex: /(clinicaltrials:NCT\\d{8})/,\n onMatch,\n },\n {\n regex: /(clinvar:\\d+)/,\n onMatch,\n },\n {\n regex: /(clinvar.record:RCV\\d+(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(complexportal:CPX-[0-9]+)/,\n onMatch,\n },\n {\n regex: /(cosmic:[A-Z0-9][A-Z0-9-]*)/,\n onMatch,\n },\n {\n regex: /(cosmic.cell:\\d+)/,\n onMatch,\n },\n {\n regex: /(cpt:\\d+)/,\n onMatch,\n },\n {\n regex: /(ctd.chemical:[CD]\\d+)/,\n onMatch,\n },\n {\n regex: /(ctri:CTRI\\/\\d{4}\\/\\d{2,3}\\/\\d+)/,\n onMatch,\n },\n {\n regex: /(cvx:\\d+)/,\n onMatch,\n },\n {\n regex: /(dbgap:phs[0-9]{6}(?:.v\\d+.p\\d+)?)/,\n onMatch,\n },\n {\n regex: /(dbsnp:rs\\d+)/,\n onMatch,\n },\n {\n regex: /(decipher:\\d+)/,\n onMatch,\n },\n {\n regex: /(depmap:ACH-\\d+)/,\n onMatch,\n },\n {\n regex: /(dhba:\\d+)/,\n onMatch,\n },\n {\n regex: /(disprot:DP\\d{5})/,\n onMatch,\n },\n {\n regex: /(dmba:\\d+)/,\n onMatch,\n },\n {\n regex: /(doi:10.\\d{2,9}\\/.*)/,\n onMatch,\n },\n {\n regex: /(doid:\\d+)/,\n onMatch,\n },\n {\n regex: /(drks:DRKS\\d+)/,\n onMatch,\n },\n {\n regex: /(drugbank:DB\\d{5})/,\n onMatch,\n },\n {\n regex: /(drugcentral:\\d+)/,\n onMatch,\n },\n {\n regex: /(duo:\\d{7})/,\n onMatch,\n },\n {\n regex:\n /(ec:\\d{1,2}(?:(?:(?:\\.\\d{1,3}){1,3})|(?:\\.\\d+){2}\\.[nB]\\d{1,3}|\\.-\\.-\\.-|\\.\\d{1,3}\\.-\\.-|\\.\\d{1,3}\\.\\d{1,3}\\.-)?)/,\n onMatch,\n },\n {\n regex: /(ecacc:\\d+)/,\n onMatch,\n },\n {\n regex: /(edam:(?:data|topic|operation|format)\\_\\d{4})/,\n onMatch,\n },\n {\n regex: /(edam.data:\\d+)/,\n onMatch,\n },\n {\n regex: /(edam.topic:\\d+)/,\n onMatch,\n },\n {\n regex: /(ega.dataset:EGAD\\d{11})/,\n onMatch,\n },\n {\n regex: /(ega.study:EGAS\\d{11})/,\n onMatch,\n },\n {\n regex: /(emdb:EMD-\\d{4,5})/,\n onMatch,\n },\n {\n regex: /(empiar:\\d+)/,\n onMatch,\n },\n {\n regex: /(ena.embl:[A-Z]+[0-9]+(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex:\n /(ensembl:(?:(?:ENS[FPTG]\\d{11}(?:\\.\\d+)?)|(?:FB\\w{2}\\d{7})|(?:Y[A-Z]{2}\\d{3}[a-zA-Z](?:\\-[A-Z])?)|(?:[A-Z_a-z0-9]+(?:\\.)?(?:t)?(?:\\d+)?(?:[a-z])?)))/,\n onMatch,\n },\n {\n regex: /(ensembl.metazoa:\\w+(?:\\.)?\\d+)/,\n onMatch,\n },\n {\n regex: /(ensembl.plant:\\w+(?:\\.\\d+)?(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(euclinicaltrials:\\d{4}\\-\\d{6}\\-\\d{2})/,\n onMatch,\n },\n {\n regex: /(eupath:\\d{7})/,\n onMatch,\n },\n {\n regex: /(exac.variant:\\d{1,2}\\-\\d+\\-[GATC]\\-[GATC])/,\n onMatch,\n },\n {\n regex: /(fairsharing:(?:bsg-[dscp]?\\d{6})|(?:FAIRsharing\\.\\w+))/,\n onMatch,\n },\n {\n regex: /(flybase:FB\\w{2}\\d{7})/,\n onMatch,\n },\n {\n regex: /(fma:\\d+)/,\n onMatch,\n },\n {\n regex: /(funderregistry:\\d+)/,\n onMatch,\n },\n {\n regex: /(gard:\\d+)/,\n onMatch,\n },\n {\n regex: /(gbif:\\d+)/,\n onMatch,\n },\n {\n regex: /(gdc:[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12})/,\n onMatch,\n },\n {\n regex: /(genecards:[A-Za-z-0-9_]+(?:\\@)?)/,\n onMatch,\n },\n {\n regex: /(geo:G(?:PL|SM|SE|DS)\\d+)/,\n onMatch,\n },\n {\n regex: /(go:\\d{7})/,\n onMatch,\n },\n {\n regex: /(gramene.gene:GR\\:\\d+)/,\n onMatch,\n },\n {\n regex: /(gramene.growthstage:\\d{7})/,\n onMatch,\n },\n {\n regex: /(gramene.protein:\\d+)/,\n onMatch,\n },\n {\n regex: /(gtdb:[cdfgops]__\\w+\\S+)/,\n onMatch,\n },\n {\n regex: /(hba:\\d+)/,\n onMatch,\n },\n {\n regex: /(hc.trial:\\d+)/,\n onMatch,\n },\n {\n regex: /(hgnc:\\d{1,5})/,\n onMatch,\n },\n {\n regex: /(hl7.v2codesystem:\\d+)/,\n onMatch,\n },\n {\n regex: /(hmdb:HMDB\\d+)/,\n onMatch,\n },\n {\n regex:\n /(icd10:(?:(?:[XVI]+)|(?:[A-Z][0-9]+(?:(?:-[A-Z][0-9]+)|(?:\\.[0-9]))?)))/,\n onMatch,\n },\n {\n regex:\n /(icd9:(?:(?:\\d{1,3}-\\d{1,3})|(?:(?:\\d\\d\\d|V\\d\\d|E[8-9]\\d\\d)(?:\\.\\d{1,2})?)))/,\n onMatch,\n },\n {\n regex: /(icdc:\\d{6})/,\n onMatch,\n },\n {\n regex: /(icf:\\d+)/,\n onMatch,\n },\n {\n regex: /(idr:[0-9]{4})/,\n onMatch,\n },\n {\n regex: /(imgt.hla:[A-Z0-9*:]+)/,\n onMatch,\n },\n {\n regex:\n /(inchi:InChI\\=1S?\\/[A-Za-z0-9\\.]+(?:\\+[0-9]+)?(?:\\/[cnpqbtmsih][A-Za-z0-9\\-\\+\\(?:\\)\\,\\/\\?\\;\\.]+)*)/,\n onMatch,\n },\n {\n regex: /(inchikey:[A-Z]{14}\\-[A-Z]{10}(?:\\-[A-Z])?)/,\n onMatch,\n },\n {\n regex:\n /(insdc:(?:[A-Z]\\d{5}|[A-Z]{2}\\d{6}|[A-Z]{4,6}\\d{8,10}|[A-J][A-Z]{2}\\d{5})(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(insdc.sra:[SED]R[APRSXZ]\\d+)/,\n onMatch,\n },\n {\n regex: /(intact:EBI\\-[0-9]+)/,\n onMatch,\n },\n {\n regex: /(interpro:IPR\\d{6})/,\n onMatch,\n },\n {\n regex: /(iso.3166:\\d+)/,\n onMatch,\n },\n {\n regex: /(isrctn:ISRCTN\\d+)/,\n onMatch,\n },\n {\n regex: /(itis:\\d+)/,\n onMatch,\n },\n {\n regex: /(jaxmice:\\d{6})/,\n onMatch,\n },\n {\n regex:\n /(kegg:(?:(?:[CHDEGTMKR]\\d+)|(?:\\w+:[\\w\\d\\.-]*)|(?:\\w{2,4}\\d{5})|(?:[a-z]{3,5})))/,\n onMatch,\n },\n {\n regex: /(kegg.compound:C\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.disease:H\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.drug:D\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.glycan:G\\d+)/,\n onMatch,\n },\n {\n regex: /(kegg.pathway:\\w{2,4}\\d{5})/,\n onMatch,\n },\n {\n regex: /(kegg.reaction:R\\d+)/,\n onMatch,\n },\n {\n regex: /(loinc:(?:\\d|\\w)+-\\d)/,\n onMatch,\n },\n {\n regex: /(massive:MSV\\d+)/,\n onMatch,\n },\n {\n regex: /(mba:\\d+)/,\n onMatch,\n },\n {\n regex: /(mesh:(?:C|D|Q)\\d+)/,\n onMatch,\n },\n {\n regex: /(metabolights:MTBL[CS]\\d+)/,\n onMatch,\n },\n {\n regex: /(metacyc.compound:[A-Za-z0-9+_.%-:]+)/,\n onMatch,\n },\n {\n regex: /(mgi:\\d+)/,\n onMatch,\n },\n {\n regex: /(mir:\\d{8})/,\n onMatch,\n },\n {\n regex: /(mirbase:MI\\d{7})/,\n onMatch,\n },\n {\n regex: /(mondo:\\d{7})/,\n onMatch,\n },\n {\n regex: /(ncbigene:\\d+)/,\n onMatch,\n },\n {\n regex: /(ncbiprotein:\\w+_?\\d+(?:.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(ncbitaxon:(?:(?:\\d+)|(?:[a-zA-Z_]+)))/,\n onMatch,\n },\n {\n regex: /(ncit:(?:C|R|P|A|NHC)\\d+)/,\n onMatch,\n },\n {\n regex: /(ndc:\\d+\\-\\d+\\-\\d+)/,\n onMatch,\n },\n {\n regex: /(ndfrt:N[0-9]{10})/,\n onMatch,\n },\n {\n regex: /(nextprot:NX_\\w+)/,\n onMatch,\n },\n {\n regex: /(nihreporter.project:\\d+)/,\n onMatch,\n },\n {\n regex: /(nord:\\d+)/,\n onMatch,\n },\n {\n regex: /(omim:\\d+)/,\n onMatch,\n },\n {\n regex: /(omop:\\d+)/,\n onMatch,\n },\n {\n regex: /(orcid:\\d{4}-\\d{4}-\\d{4}-\\d{3}(?:\\d|X))/,\n onMatch,\n },\n {\n regex: /(orphanet:C?\\d+)/,\n onMatch,\n },\n {\n regex: /(orphanet.ordo:C?\\d+)/,\n onMatch,\n },\n {\n regex: /(osf:[a-z0-9]{5})/,\n onMatch,\n },\n {\n regex: /(panther.family:PTHR\\d{5}(?:\\:SF\\d{1,3})?)/,\n onMatch,\n },\n {\n regex: /(panther.pathway:P\\d{5})/,\n onMatch,\n },\n {\n regex: /(panther.pthcmp:(?:G|P|U|C|S)\\d{5})/,\n onMatch,\n },\n {\n regex: /(pba:\\d+)/,\n onMatch,\n },\n {\n regex: /(pdb:[0-9][A-Za-z0-9]{3})/,\n onMatch,\n },\n {\n regex: /(pdb-ccd:\\w{1,3})/,\n onMatch,\n },\n {\n regex: /(pdb.ligand:[A-Za-z0-9]+)/,\n onMatch,\n },\n {\n regex: /(pdc.study:PDC\\d+)/,\n onMatch,\n },\n {\n regex: /(peco:\\d{7})/,\n onMatch,\n },\n {\n regex: /(peptideatlas.dataset:PASS\\d{5})/,\n onMatch,\n },\n {\n regex: /(pfam:PF\\d{5})/,\n onMatch,\n },\n {\n regex: /(pfam.clan:CL\\d+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.disease:PA\\d+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.drug:PA\\d+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.gene:PA\\w+)/,\n onMatch,\n },\n {\n regex: /(pharmgkb.pathways:PA\\d+)/,\n onMatch,\n },\n {\n regex: /(pmc:PMC\\d+(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(pombase:S\\w+(?:\\.)?\\w+(?:\\.)?)/,\n onMatch,\n },\n {\n regex: /(pride.project:P(?:X|R|A)D\\d{6})/,\n onMatch,\n },\n {\n regex: /(pubchem.compound:\\d+)/,\n onMatch,\n },\n {\n regex: /(pubmed:\\d+)/,\n onMatch,\n },\n {\n regex: /(px:(?:R)?PXD\\d{6})/,\n onMatch,\n },\n {\n regex: /(radlex:RID\\d+)/,\n onMatch,\n },\n {\n regex: /(reactome:R-[A-Z]{3}-\\d+(?:-\\d+)?(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(rebec:RBR-\\w+)/,\n onMatch,\n },\n {\n regex:\n /(refseq:(?:(?:(?:AC|AP|NC|NG|NM|NP|NR|NT|NW|WP|XM|XP|XR|YP|ZP)_\\d+)|(?:NZ_[A-Z]{2,4}\\d+))(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(rfam:RF\\d{5})/,\n onMatch,\n },\n {\n regex: /(rfc:\\d+)/,\n onMatch,\n },\n {\n regex: /(rgd:\\d{4,})/,\n onMatch,\n },\n {\n regex: /(rhea:\\d{5})/,\n onMatch,\n },\n {\n regex: /(rnacentral:URS[0-9A-F]{10}(?:\\_\\d+)?)/,\n onMatch,\n },\n {\n regex: /(ror:0[a-hj-km-np-tv-z|0-9]{6}[0-9]{2})/,\n onMatch,\n },\n {\n regex: /(rrid:[a-zA-Z]+.+)/,\n onMatch,\n },\n {\n regex: /(rrrc:\\d+)/,\n onMatch,\n },\n {\n regex: /(rxnorm:[0-9]{1,7})/,\n onMatch,\n },\n {\n regex: /(scop:\\d+)/,\n onMatch,\n },\n {\n regex: /(sgd:(?:(?:S\\d+$)|(?:Y[A-Z]{2}\\d{3}[a-zA-Z](?:\\-[A-Z])?)))/,\n onMatch,\n },\n {\n regex: /(signor:SIGNOR\\-[A-Z]+\\d+)/,\n onMatch,\n },\n {\n regex: /(snomedct:(?:\\w+)?\\d+)/,\n onMatch,\n },\n {\n regex: /(so:\\d{7})/,\n onMatch,\n },\n {\n regex: /(ssbd.dataset:\\d+)/,\n onMatch,\n },\n {\n regex: /(ssbd.project:\\d+)/,\n onMatch,\n },\n {\n regex: /(stitch:\\w{14})/,\n onMatch,\n },\n {\n regex:\n /(string:(?:(?:[A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])|(?:[0-9][A-Za-z0-9]{3})))/,\n onMatch,\n },\n {\n regex: /(tao:\\d{7})/,\n onMatch,\n },\n {\n regex: /(tcdb:\\d+(?:\\.[A-Z])?(?:\\.\\d+)?(?:\\.\\d+)?(?:\\.\\d+)?)/,\n onMatch,\n },\n {\n regex: /(tcia.collection:[A-Za-z0-9][A-Za-z0-9_\\-\\.]*[A-Za-z0-9])/,\n onMatch,\n },\n {\n regex: /(uberon:\\d+)/,\n onMatch,\n },\n {\n regex: /(unii:[A-Z0-9]+)/,\n onMatch,\n },\n {\n regex: /(uniparc:UPI[A-F0-9]{10})/,\n onMatch,\n },\n {\n regex:\n /(uniprot:(?:(?:[A-N,R-Z][0-9](?:[A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(?:\\.\\d+)?(?:-\\d+)?(?:#PRO_\\d+)?))/,\n onMatch,\n },\n {\n regex:\n /(uniprot.isoform:(?:[A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|(?:[O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(?:\\-\\d+))/,\n onMatch,\n },\n {\n regex: /(uniprot.proteome:UP\\d{9})/,\n onMatch,\n },\n {\n regex:\n /(uniref:UniRef(?:100|90|50)_(?:[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9](?:[A-Z][A-Z0-9]{2}[0-9]){1,2}|UPI[A-F0-9]{10}))/,\n onMatch,\n },\n {\n regex: /(wikidata:(?:Q|P|E|L)\\d+)/,\n onMatch,\n },\n {\n regex: /(wikigenes:\\d+)/,\n onMatch,\n },\n {\n regex: /(wikipathways:WP\\d{1,5}(?:\\_r\\d+)?)/,\n onMatch,\n },\n {\n regex: /(wormbase:(?:CE[0-9]{5}|WB[A-Z][a-z]+\\d+))/,\n onMatch,\n },\n {\n regex: /(xenbase:XB\\-\\w+\\-\\d+)/,\n onMatch,\n },\n {\n regex: /(zenodo.record:\\d+)/,\n onMatch,\n },\n {\n regex: /(zfin:ZDB\\-\\w+\\-\\d+\\-\\d+)/,\n onMatch,\n },\n {\n regex: /(zinc:(?:ZINC)?\\d+)/,\n onMatch,\n },\n]\n"],"mappings":";AAIA,IAAM,KAAW,MAAkB,0BAA0B,KAEhD,IAAmB;CAC9B;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OACE;EACF;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACD;EACE,OAAO;EACP;EACD;CACF"}
@@ -1,3 +1,5 @@
1
1
  import { GoalsDataProps } from './Goals';
2
- export default function GoalsDesktop({ asset, link, summary, countSql, title, isAssetIcon, linkText, }: GoalsDataProps): import("react/jsx-runtime").JSX.Element;
2
+ export default function GoalsDesktop({ asset, link, summary, countSql, title, isAssetIcon, linkText, cardWidth, }: GoalsDataProps & {
3
+ cardWidth?: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
3
5
  //# sourceMappingURL=Goals.Desktop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Goals.Desktop.d.ts","sourceRoot":"","sources":["../../../src/components/Goals/Goals.Desktop.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAIxC,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,KAAK,EACL,WAAW,EACX,QAAoB,GACrB,EAAE,cAAc,2CA2ChB"}
1
+ {"version":3,"file":"Goals.Desktop.d.ts","sourceRoot":"","sources":["../../../src/components/Goals/Goals.Desktop.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAIxC,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,KAAK,EACL,WAAW,EACX,QAAoB,EACpB,SAAS,GACV,EAAE,cAAc,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CA2CzC"}
@@ -2,13 +2,12 @@ import { QueryCount as e } from "../QueryCount/QueryCount.js";
2
2
  import { Box as t, Button as n } from "@mui/material";
3
3
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
4
4
  //#region src/components/Goals/Goals.Desktop.tsx
5
- function a({ asset: a, link: o, summary: s, countSql: c, title: l, isAssetIcon: u, linkText: d = "Explore" }) {
5
+ function a({ asset: a, link: o, summary: s, countSql: c, title: l, isAssetIcon: u, linkText: d = "Explore", cardWidth: f }) {
6
6
  return /* @__PURE__ */ i(t, {
7
7
  className: "Goals__Card",
8
8
  sx: {
9
9
  cursor: "pointer",
10
- maxWidth: "335px",
11
- width: "335px"
10
+ flex: `0 0 ${f ?? "auto"}`
12
11
  },
13
12
  onClick: () => window.open(o, "_self"),
14
13
  children: [/* @__PURE__ */ r("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"Goals.Desktop.js","names":[],"sources":["../../../src/components/Goals/Goals.Desktop.tsx"],"sourcesContent":["import { GoalsDataProps } from './Goals'\nimport QueryCount from '../QueryCount/QueryCount'\nimport { Box, Button } from '@mui/material'\n\nexport default function GoalsDesktop({\n asset,\n link,\n summary,\n countSql,\n title,\n isAssetIcon,\n linkText = 'Explore',\n}: GoalsDataProps) {\n return (\n <Box\n className=\"Goals__Card\"\n sx={{ cursor: 'pointer', maxWidth: '335px', width: '335px' }}\n onClick={() => window.open(link, '_self')}\n >\n <div\n className=\"Goals__Card__header\"\n style={{ background: isAssetIcon ? undefined : `url('${asset}')` }}\n >\n <p>\n <span className=\"Goals__Card__header__title\">\n {isAssetIcon && asset && (\n <img\n style={{ marginRight: '10px' }}\n className=\"Goals__Card__header__icon\"\n src={asset}\n alt={`${title} icon`}\n />\n )}\n {title}\n </span>\n {countSql && (\n <span className=\"Goals__Card__header__count\">\n <QueryCount parens={false} query={{ sql: countSql }} />\n </span>\n )}\n </p>\n </div>\n <div className=\"Goals__Card__summary\">\n <p> {summary} </p>\n <Button\n className=\"Goals__Card__summary__link\"\n variant=\"outlined\"\n color=\"secondary\"\n href={link}\n >\n {linkText}\n </Button>\n </div>\n </Box>\n )\n}\n"],"mappings":";;;;AAIA,SAAwB,EAAa,EACnC,UACA,SACA,YACA,aACA,UACA,gBACA,cAAW,aACM;AACjB,QACE,kBAAC,GAAD;EACE,WAAU;EACV,IAAI;GAAE,QAAQ;GAAW,UAAU;GAAS,OAAO;GAAS;EAC5D,eAAe,OAAO,KAAK,GAAM,QAAQ;YAH3C,CAKE,kBAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,YAAY,IAAc,KAAA,IAAY,QAAQ,EAAM,KAAK;aAElE,kBAAC,KAAD,EAAA,UAAA,CACE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACG,KAAe,KACd,kBAAC,OAAD;KACE,OAAO,EAAE,aAAa,QAAQ;KAC9B,WAAU;KACV,KAAK;KACL,KAAK,GAAG,EAAM;KACd,CAAA,EAEH,EACI;OACN,KACC,kBAAC,QAAD;IAAM,WAAU;cACd,kBAAC,GAAD;KAAY,QAAQ;KAAO,OAAO,EAAE,KAAK,GAAU;KAAI,CAAA;IAClD,CAAA,CAEP,EAAA,CAAA;GACA,CAAA,EACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD,EAAA,UAAA;IAAG;IAAE;IAAQ;IAAK,EAAA,CAAA,EAClB,kBAAC,GAAD;IACE,WAAU;IACV,SAAQ;IACR,OAAM;IACN,MAAM;cAEL;IACM,CAAA,CACL;KACF"}
1
+ {"version":3,"file":"Goals.Desktop.js","names":[],"sources":["../../../src/components/Goals/Goals.Desktop.tsx"],"sourcesContent":["import { GoalsDataProps } from './Goals'\nimport QueryCount from '../QueryCount/QueryCount'\nimport { Box, Button } from '@mui/material'\n\nexport default function GoalsDesktop({\n asset,\n link,\n summary,\n countSql,\n title,\n isAssetIcon,\n linkText = 'Explore',\n cardWidth,\n}: GoalsDataProps & { cardWidth?: string }) {\n return (\n <Box\n className=\"Goals__Card\"\n sx={{ cursor: 'pointer', flex: `0 0 ${cardWidth ?? 'auto'}` }}\n onClick={() => window.open(link, '_self')}\n >\n <div\n className=\"Goals__Card__header\"\n style={{ background: isAssetIcon ? undefined : `url('${asset}')` }}\n >\n <p>\n <span className=\"Goals__Card__header__title\">\n {isAssetIcon && asset && (\n <img\n style={{ marginRight: '10px' }}\n className=\"Goals__Card__header__icon\"\n src={asset}\n alt={`${title} icon`}\n />\n )}\n {title}\n </span>\n {countSql && (\n <span className=\"Goals__Card__header__count\">\n <QueryCount parens={false} query={{ sql: countSql }} />\n </span>\n )}\n </p>\n </div>\n <div className=\"Goals__Card__summary\">\n <p> {summary} </p>\n <Button\n className=\"Goals__Card__summary__link\"\n variant=\"outlined\"\n color=\"secondary\"\n href={link}\n >\n {linkText}\n </Button>\n </div>\n </Box>\n )\n}\n"],"mappings":";;;;AAIA,SAAwB,EAAa,EACnC,UACA,SACA,YACA,aACA,UACA,gBACA,cAAW,WACX,gBAC0C;AAC1C,QACE,kBAAC,GAAD;EACE,WAAU;EACV,IAAI;GAAE,QAAQ;GAAW,MAAM,OAAO,KAAa;GAAU;EAC7D,eAAe,OAAO,KAAK,GAAM,QAAQ;YAH3C,CAKE,kBAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,YAAY,IAAc,KAAA,IAAY,QAAQ,EAAM,KAAK;aAElE,kBAAC,KAAD,EAAA,UAAA,CACE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACG,KAAe,KACd,kBAAC,OAAD;KACE,OAAO,EAAE,aAAa,QAAQ;KAC9B,WAAU;KACV,KAAK;KACL,KAAK,GAAG,EAAM;KACd,CAAA,EAEH,EACI;OACN,KACC,kBAAC,QAAD;IAAM,WAAU;cACd,kBAAC,GAAD;KAAY,QAAQ;KAAO,OAAO,EAAE,KAAK,GAAU;KAAI,CAAA;IAClD,CAAA,CAEP,EAAA,CAAA;GACA,CAAA,EACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD,EAAA,UAAA;IAAG;IAAE;IAAQ;IAAK,EAAA,CAAA,EAClB,kBAAC,GAAD;IACE,WAAU;IACV,SAAQ;IACR,OAAM;IACN,MAAM;cAEL;IACM,CAAA,CACL;KACF"}
@@ -2,6 +2,7 @@ export type GoalsProps = {
2
2
  entityId: string;
3
3
  isAssetIcon?: boolean;
4
4
  linkText?: string;
5
+ itemsPerRow?: number;
5
6
  };
6
7
  export type GoalsDataProps = {
7
8
  countSql?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Goals.d.ts","sourceRoot":"","sources":["../../../src/components/Goals/Goals.tsx"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAcD,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,2CAsHtC;AACD,eAAe,KAAK,CAAA"}
1
+ {"version":3,"file":"Goals.d.ts","sourceRoot":"","sources":["../../../src/components/Goals/Goals.tsx"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAcD,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,2CAkItC;AACD,eAAe,KAAK,CAAA"}
@@ -15,19 +15,19 @@ var d = /* @__PURE__ */ function(e) {
15
15
  return e.TABLEID = "TableId", e.COUNT_SQL = "CountSql", e.TITLE = "Title", e.SUMMARY = "Summary", e.LINK = "Link", e.ASSET = "Asset", e;
16
16
  }(d || {}), f = 1200;
17
17
  function p(p) {
18
- let { entityId: m, isAssetIcon: h = !1, linkText: g } = p, _ = t(f), { data: v } = r({
18
+ let { entityId: m, isAssetIcon: h = !1, linkText: g, itemsPerRow: _ = 3 } = p, v = t(f), { data: y } = r({
19
19
  concreteType: "org.sagebionetworks.repo.model.table.QueryBundleRequest",
20
20
  entityId: m,
21
21
  partMask: 5,
22
22
  query: { sql: `select *
23
23
  from ${m}
24
24
  order by ItemOrder` }
25
- }), { assets: y, error: b } = i(m, v), x = n(d.TABLEID, v), S = n(d.COUNT_SQL, v), C = n(d.TITLE, v), w = n(d.SUMMARY, v), T = n(d.LINK, v), E = s(() => v?.queryResult.queryResults.rows.map((e, t) => {
25
+ }), { assets: b, error: x } = i(m, y), S = n(d.TABLEID, y), C = n(d.COUNT_SQL, y), w = n(d.TITLE, y), T = n(d.SUMMARY, y), E = n(d.LINK, y), D = s(() => y?.queryResult.queryResults.rows.map((e, t) => {
26
26
  let n = e.values;
27
27
  n.some((e) => e === null) && console.warn("Row has null value(s) when no nulls expected");
28
- let r = x > -1 ? n[x] : void 0, i;
29
- S > -1 && n[S] ? i = n[S] : r && (i = `SELECT * FROM ${r}`);
30
- let a = n[C], o = n[w], s = n[T], c = y?.[t] ?? "";
28
+ let r = S > -1 ? n[S] : void 0, i;
29
+ C > -1 && n[C] ? i = n[C] : r && (i = `SELECT * FROM ${r}`);
30
+ let a = n[w], o = n[T], s = n[E], c = b?.[t] ?? "";
31
31
  return {
32
32
  countSql: i,
33
33
  title: a,
@@ -37,34 +37,40 @@ function p(p) {
37
37
  isAssetIcon: h
38
38
  };
39
39
  }), [
40
- S,
41
- y,
40
+ C,
41
+ b,
42
+ E,
43
+ y?.queryResult,
42
44
  T,
43
- v?.queryResult,
44
- w,
45
- x,
46
- C
45
+ S,
46
+ w
47
47
  ]);
48
- return b ? /* @__PURE__ */ u(e, { error: b }) : E ? _ ? /* @__PURE__ */ u(c, {
49
- className: "Goals",
50
- sx: {
51
- display: "flex",
52
- flexWrap: "wrap",
53
- gap: "7px",
54
- alignItems: "stretch",
55
- justifyContent: "center"
56
- },
57
- children: E.map((e, t) => /* @__PURE__ */ u(a, {
58
- ...e,
59
- linkText: g
60
- }, t))
61
- }) : /* @__PURE__ */ u("div", {
48
+ if (x) return /* @__PURE__ */ u(e, { error: x });
49
+ if (!D) return /* @__PURE__ */ u(l, {});
50
+ if (v) {
51
+ let e = `calc((100% - ${_ * 20 + (_ - 1) * 7}px) / ${_} - 0.5px)`;
52
+ return /* @__PURE__ */ u(c, {
53
+ className: "Goals",
54
+ sx: {
55
+ display: "flex",
56
+ flexWrap: "wrap",
57
+ gap: "7px",
58
+ justifyContent: "center",
59
+ alignItems: "stretch"
60
+ },
61
+ children: D.map((t, n) => /* @__PURE__ */ u(a, {
62
+ ...t,
63
+ linkText: g,
64
+ cardWidth: e
65
+ }, n))
66
+ });
67
+ } else return /* @__PURE__ */ u("div", {
62
68
  className: "Goals",
63
- children: E.map((e, t) => /* @__PURE__ */ u(o, {
69
+ children: D.map((e, t) => /* @__PURE__ */ u(o, {
64
70
  ...e,
65
71
  linkText: g
66
72
  }, t))
67
- }) : /* @__PURE__ */ u(l, {});
73
+ });
68
74
  }
69
75
  //#endregion
70
76
  export { p as Goals, p as default };