synapse-react-client 4.0.21 → 4.0.23
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.
- package/dist/SWC.index.d.ts +1 -0
- package/dist/SWC.index.d.ts.map +1 -1
- package/dist/SWC.index.js +2 -1
- package/dist/SWC.index.js.map +1 -1
- package/dist/assets/icons/GeneticsIcon.d.ts +3 -0
- package/dist/assets/icons/GeneticsIcon.d.ts.map +1 -0
- package/dist/assets/icons/GeneticsIcon.js +14 -0
- package/dist/assets/icons/GeneticsIcon.js.map +1 -0
- package/dist/components/CardContainer/CardContainer.d.ts.map +1 -1
- package/dist/components/CardContainer/CardContainer.js +43 -49
- package/dist/components/CardContainer/CardContainer.js.map +1 -1
- package/dist/components/CardContainerLogic/CardContainerLogic.d.ts +13 -0
- package/dist/components/CardContainerLogic/CardContainerLogic.d.ts.map +1 -1
- package/dist/components/CardContainerLogic/CardContainerLogic.js +64 -40
- package/dist/components/CardContainerLogic/CardContainerLogic.js.map +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.css +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.js +16 -16
- package/dist/components/DataExplorer/DataExplorer.module.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.scss +0 -1
- package/dist/components/DataGrid/DataGrid.d.ts +1 -0
- package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/DataGrid.js +72 -72
- package/dist/components/DataGrid/DataGrid.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +209 -206
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.d.ts +2 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.d.ts.map +1 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js +51 -42
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.js +68 -67
- package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.d.ts +1 -0
- package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +4 -3
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DataGrid/utils/modelColsToGrid.d.ts +1 -1
- package/dist/components/DataGrid/utils/modelColsToGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/modelColsToGrid.js +15 -14
- package/dist/components/DataGrid/utils/modelColsToGrid.js.map +1 -1
- package/dist/components/DataGrid/utils/normalizeWebsocketError.d.ts +7 -0
- package/dist/components/DataGrid/utils/normalizeWebsocketError.d.ts.map +1 -0
- package/dist/components/DataGrid/utils/normalizeWebsocketError.js +8 -0
- package/dist/components/DataGrid/utils/normalizeWebsocketError.js.map +1 -0
- package/dist/components/EntityCitation/EntityCitation.d.ts.map +1 -1
- package/dist/components/EntityCitation/EntityCitation.js +23 -8
- package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.d.ts +18 -0
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.d.ts.map +1 -0
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js +112 -0
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js.map +1 -0
- package/dist/components/GenericCard/DuoTermTags/duoTerms.d.ts +31 -0
- package/dist/components/GenericCard/DuoTermTags/duoTerms.d.ts.map +1 -0
- package/dist/components/GenericCard/DuoTermTags/duoTerms.js +198 -0
- package/dist/components/GenericCard/DuoTermTags/duoTerms.js.map +1 -0
- package/dist/components/GenericCard/SynapseCardLabel.d.ts.map +1 -1
- package/dist/components/GenericCard/SynapseCardLabel.js +4 -8
- package/dist/components/GenericCard/SynapseCardLabel.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.d.ts +6 -0
- package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +168 -153
- package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
- package/dist/components/Goals/Goals.d.ts +8 -0
- package/dist/components/Goals/Goals.d.ts.map +1 -1
- package/dist/components/Goals/Goals.js +54 -40
- package/dist/components/Goals/Goals.js.map +1 -1
- package/dist/components/IconSvg/IconSvg.d.ts +1 -1
- package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
- package/dist/components/IconSvg/IconSvg.js +19 -18
- package/dist/components/IconSvg/IconSvg.js.map +1 -1
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.d.ts +9 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.d.ts.map +1 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.js +69 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.js.map +1 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.d.ts +13 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.d.ts.map +1 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.js +11 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.js.map +1 -0
- package/dist/components/ProjectVisibilityChip/index.d.ts +5 -0
- package/dist/components/ProjectVisibilityChip/index.d.ts.map +1 -0
- package/dist/components/ProjectVisibilityChip/index.js +7 -0
- package/dist/components/ProjectVisibilityChip/index.js.map +1 -0
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationContext.d.ts +21 -0
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationContext.d.ts.map +1 -1
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationContext.js.map +1 -1
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.d.ts +10 -0
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.d.ts.map +1 -1
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js +66 -60
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +2 -0
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/RowSetView.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/RowSetView.js +9 -12
- package/dist/components/QueryWrapperPlotNav/RowSetView.js.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.d.ts +7 -15
- package/dist/components/RssFeedCards/RssFeedCards.d.ts.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.js +114 -123
- package/dist/components/RssFeedCards/RssFeedCards.js.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +33 -6
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +93 -55
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts +3 -0
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js +39 -37
- package/dist/components/SearchQueryWrapper/SearchQueryWrapper.js.map +1 -1
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts +3 -1
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js +4 -0
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js.map +1 -1
- package/dist/components/UserCardList/UserCardList.d.ts +2 -20
- package/dist/components/UserCardList/UserCardList.d.ts.map +1 -1
- package/dist/components/UserCardList/UserCardList.js +49 -72
- package/dist/components/UserCardList/UserCardList.js.map +1 -1
- package/dist/components/UserCardList/UserCardListRotate.d.ts +13 -0
- package/dist/components/UserCardList/UserCardListRotate.d.ts.map +1 -1
- package/dist/components/UserCardList/UserCardListRotate.js +82 -57
- package/dist/components/UserCardList/UserCardListRotate.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts +5 -2
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +68 -51
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/menu/ComplexMenu.d.ts +8 -1
- package/dist/components/menu/ComplexMenu.d.ts.map +1 -1
- package/dist/components/menu/ComplexMenu.js +50 -20
- package/dist/components/menu/ComplexMenu.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetValueChip.d.ts +25 -0
- package/dist/components/widgets/facet-nav/FacetValueChip.d.ts.map +1 -0
- package/dist/components/widgets/facet-nav/FacetValueChip.js +40 -0
- package/dist/components/widgets/facet-nav/FacetValueChip.js.map +1 -0
- package/dist/components/widgets/facet-nav/SelectionCriteriaPill.d.ts +10 -5
- package/dist/components/widgets/facet-nav/SelectionCriteriaPill.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/SelectionCriteriaPill.js +10 -17
- package/dist/components/widgets/facet-nav/SelectionCriteriaPill.js.map +1 -1
- package/dist/components/widgets/facet-nav/SelectionCriteriaPills.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/SelectionCriteriaPills.js +11 -10
- package/dist/components/widgets/facet-nav/SelectionCriteriaPills.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js +70 -54
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.d.ts +2 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.js +17 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.d.ts +2 -0
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.js +7 -7
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.js.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.d.ts.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.js +99 -45
- package/dist/features/curator/dashboard/components/CurationTaskCard.js.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js +174 -149
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map +1 -1
- package/dist/features/entity/metadata-task/utils/constants.d.ts +6 -0
- package/dist/features/entity/metadata-task/utils/constants.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/utils/constants.js +19 -2
- package/dist/features/entity/metadata-task/utils/constants.js.map +1 -1
- package/dist/style/abstracts/_cssVariables.scss +1 -0
- package/dist/style/components/_total-query-results.scss +10 -34
- package/dist/style/main.css +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +1 -0
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +3 -0
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/curation/task/useCurationTask.d.ts.map +1 -1
- package/dist/synapse-queries/curation/task/useCurationTask.js +1 -1
- package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
- package/dist/synapse-queries/index.js +46 -44
- package/dist/synapse-queries/user/index.js +3 -3
- package/dist/synapse-queries/user/useUserBundle.d.ts +12 -0
- package/dist/synapse-queries/user/useUserBundle.d.ts.map +1 -1
- package/dist/synapse-queries/user/useUserBundle.js +50 -36
- package/dist/synapse-queries/user/useUserBundle.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/AppUtils/session/SessionInitializedGuard.d.ts +10 -5
- package/dist/utils/AppUtils/session/SessionInitializedGuard.d.ts.map +1 -1
- package/dist/utils/AppUtils/session/SessionInitializedGuard.js +13 -9
- package/dist/utils/AppUtils/session/SessionInitializedGuard.js.map +1 -1
- package/dist/utils/functions/SqlFunctions.d.ts +1 -1
- package/dist/utils/functions/SqlFunctions.d.ts.map +1 -1
- package/dist/utils/functions/SqlFunctions.js +1 -1
- package/dist/utils/functions/SqlFunctions.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionCriteriaPills.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/SelectionCriteriaPills.tsx"],"sourcesContent":["import {\n isColumnMultiValueFunctionQueryFilter,\n isColumnSingleValueQueryFilter,\n isFacetColumnRangeRequest,\n isFacetColumnValuesRequest,\n isTextMatchesQueryFilter,\n LockedColumn,\n} from '@/utils'\nimport { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport {\n ColumnModel,\n ColumnMultiValueFunctionQueryFilter,\n ColumnSingleValueQueryFilter,\n FacetColumnRangeRequest,\n FacetColumnRequest,\n QueryFilter,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport pluralize from 'pluralize'\nimport { ReadonlyDeep } from 'type-fest'\nimport { QueryContextType, useQueryContext } from '../../QueryContext'\nimport {\n QueryVisualizationContextType,\n useQueryVisualizationContext,\n} from '../../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport SelectionCriteriaPill, {\n SelectionCriteriaPillProps,\n} from './SelectionCriteriaPill'\nimport { getSearchTextFromBooleanModeSearchExpression } from '@/components/FullTextSearch/FullTextSearchUtils'\n\nconst MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS = 4\n\nfunction getPillPropsFromColumnQueryFilter(\n queryFilter:\n | ColumnSingleValueQueryFilter\n | ColumnMultiValueFunctionQueryFilter,\n queryContext: QueryContextType,\n columnModel: ColumnModel | undefined,\n queryVisualizationContext: QueryVisualizationContextType,\n): SelectionCriteriaPillProps[] {\n const { getColumnDisplayName } = queryVisualizationContext\n // ColumnSingleValueQueryFilter and ColumnMultiValueQueryFilter both allow for a list of values\n // If there are more than _n_ values, consolidate to one pill\n if (\n queryFilter.values.length > MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(queryFilter.columnName),\n )} (${queryFilter.values.length.toLocaleString()})`\n\n return [\n {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n return queryFilter.values.map(value => {\n let filterValue = value\n\n if (value?.startsWith('%') && value?.endsWith('%')) {\n // strip '%' wildcard character when using a LIKE condition\n filterValue = filterValue.substring(1, filterValue.length - 1)\n }\n filterValue = queryVisualizationContext.getDisplayValue(\n filterValue,\n columnModel.columnType,\n )\n const text = `${getColumnDisplayName(\n queryFilter.columnName,\n )}: ${filterValue}`\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}-${value}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeValueFromQueryFilter(queryFilter, value)\n },\n }\n })\n}\n\nexport function getPillPropsFromTextMatchesQueryFilter(\n queryFilter: TextMatchesQueryFilter,\n queryContext: QueryContextType,\n isLocked?: boolean,\n): SelectionCriteriaPillProps {\n let innerText = queryFilter.searchExpression\n if (queryFilter.searchMode == 'BOOLEAN') {\n innerText = getSearchTextFromBooleanModeSearchExpression(\n queryFilter.searchExpression,\n )\n }\n\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.searchExpression}`,\n innerText,\n tooltipText: `Text matches: \"${innerText}\"`,\n ...(isLocked\n ? { isLocked: true }\n : {\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n }),\n }\n}\n\nfunction getPillPropsFromQueryFilters(\n queryFilters: ReadonlyDeep<QueryFilter[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n lockTextMatchesQueryFilterPill?: boolean,\n): SelectionCriteriaPillProps[] {\n return queryFilters.flatMap(queryFilter => {\n if (\n isColumnSingleValueQueryFilter(queryFilter) ||\n isColumnMultiValueFunctionQueryFilter(queryFilter)\n ) {\n const columnModel = columnModels.find(\n cm => cm.name === queryFilter.columnName,\n )\n if (\n queryFilter.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n return getPillPropsFromColumnQueryFilter(\n queryFilter,\n queryContext,\n columnModel,\n queryVisualizationContext,\n )\n } else if (isTextMatchesQueryFilter(queryFilter)) {\n return [\n getPillPropsFromTextMatchesQueryFilter(\n queryFilter,\n queryContext,\n lockTextMatchesQueryFilterPill,\n ),\n ]\n } else {\n console.log('Unknown query filter type', queryFilter)\n return []\n }\n })\n}\n\nfunction getRangeFacetInnerText(min?: string, max?: string) {\n if (min == undefined && max == undefined) {\n return 'Any value'\n } else if (min == undefined) {\n return `Up to ${max}`\n } else if (max == undefined) {\n return `${min} or greater`\n } else if (min === VALUE_NOT_SET && max === VALUE_NOT_SET) {\n return FRIENDLY_VALUE_NOT_SET\n } else {\n return `${min} - ${max}`\n }\n}\n\nfunction getPillPropsFromFacetFilters(\n selectedFacets: ReadonlyDeep<FacetColumnRequest[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n): SelectionCriteriaPillProps[] {\n return selectedFacets.flatMap(selectedFacet => {\n if (\n selectedFacet.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n const columnModel = columnModels.find(\n cm => cm.name === selectedFacet.columnName,\n )\n const { getColumnDisplayName, getDisplayValue } = queryVisualizationContext\n if (isFacetColumnValuesRequest(selectedFacet)) {\n // If there are more than _n_ values, consolidate to one pill\n if (\n selectedFacet.facetValues.length >\n MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n ),\n )} (${selectedFacet.facetValues.length.toLocaleString()})`\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}`,\n innerText: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n\n return selectedFacet.facetValues.map(facetValue => {\n const innerText = getDisplayValue(facetValue, columnModel.columnType)\n return {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${facetValue}`,\n innerText: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeValueFromSelectedFacet(selectedFacet, facetValue)\n },\n }\n })\n } else if (isFacetColumnRangeRequest(selectedFacet)) {\n // Include a single pill for both facet filters if a combined range facet filter config is defined\n const { combineRangeFacetConfig } = queryContext\n if (\n combineRangeFacetConfig &&\n (selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn ||\n selectedFacet.columnName == combineRangeFacetConfig.maxFacetColumn)\n ) {\n if (\n selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn\n ) {\n return []\n } else {\n // find the min facet also\n const maxFacet = selectedFacet\n const minFacet = selectedFacets.find(\n v => v.columnName == combineRangeFacetConfig.minFacetColumn,\n ) as FacetColumnRangeRequest\n const innerText = getRangeFacetInnerText(maxFacet.min, minFacet.max)\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${innerText}`,\n innerText: innerText,\n tooltipText: `${combineRangeFacetConfig.label}: ${innerText}`,\n onRemoveFilter: () => {\n // Remove both facets on pill click\n queryContext.removeSelectedFacet([minFacet, maxFacet])\n },\n },\n ]\n }\n }\n\n const innerText = getRangeFacetInnerText(\n selectedFacet.min,\n selectedFacet.max,\n )\n\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${selectedFacet.min}-${selectedFacet.max}`,\n innerText: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n } else {\n console.log(\n 'Unknown facet type',\n (selectedFacet as unknown as FacetColumnRequest).concreteType,\n )\n return []\n }\n })\n}\n\nfunction SelectionCriteriaPills() {\n const queryContext = useQueryContext()\n const lockedColumn = queryContext.lockedColumn\n const queryVisualizationContext = useQueryVisualizationContext()\n const { lockTextMatchesQueryFilterPill } = queryVisualizationContext\n const { currentQueryRequest } = queryContext\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const queryFilterPillProps = getPillPropsFromQueryFilters(\n currentQueryRequest.query?.additionalFilters ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n lockTextMatchesQueryFilterPill,\n )\n\n const facetPillProps = getPillPropsFromFacetFilters(\n currentQueryRequest.query.selectedFacets ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n )\n\n const allPills = [...queryFilterPillProps, ...facetPillProps]\n\n return (\n <>\n {allPills.map(pillProps => {\n // Encode the key because the facet may include an illegal character\n const key = encodeURIComponent(pillProps.key)\n return <SelectionCriteriaPill {...pillProps} key={key} />\n })}\n </>\n )\n}\n\nexport default SelectionCriteriaPills\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SelectionCriteriaPills.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/SelectionCriteriaPills.tsx"],"sourcesContent":["import {\n isColumnMultiValueFunctionQueryFilter,\n isColumnSingleValueQueryFilter,\n isFacetColumnRangeRequest,\n isFacetColumnValuesRequest,\n isTextMatchesQueryFilter,\n LockedColumn,\n} from '@/utils'\nimport { FRIENDLY_VALUE_NOT_SET, VALUE_NOT_SET } from '@/utils/SynapseConstants'\nimport {\n ColumnModel,\n ColumnMultiValueFunctionQueryFilter,\n ColumnSingleValueQueryFilter,\n FacetColumnRangeRequest,\n FacetColumnRequest,\n QueryFilter,\n TextMatchesQueryFilter,\n} from '@sage-bionetworks/synapse-types'\nimport pluralize from 'pluralize'\nimport { ReadonlyDeep } from 'type-fest'\nimport { QueryContextType, useQueryContext } from '../../QueryContext'\nimport {\n QueryVisualizationContextType,\n useQueryVisualizationContext,\n} from '../../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport SelectionCriteriaPill, {\n SelectionCriteriaPillProps,\n} from './SelectionCriteriaPill'\nimport { getSearchTextFromBooleanModeSearchExpression } from '@/components/FullTextSearch/FullTextSearchUtils'\n\nconst MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS = 4\n\nfunction getPillPropsFromColumnQueryFilter(\n queryFilter:\n | ColumnSingleValueQueryFilter\n | ColumnMultiValueFunctionQueryFilter,\n queryContext: QueryContextType,\n columnModel: ColumnModel | undefined,\n queryVisualizationContext: QueryVisualizationContextType,\n): SelectionCriteriaPillProps[] {\n const { getColumnDisplayName } = queryVisualizationContext\n // ColumnSingleValueQueryFilter and ColumnMultiValueQueryFilter both allow for a list of values\n // If there are more than _n_ values, consolidate to one pill\n if (\n queryFilter.values.length > MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(queryFilter.columnName),\n )} (${queryFilter.values.length.toLocaleString()})`\n\n return [\n {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}`,\n label: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n return queryFilter.values.map(value => {\n let filterValue = value\n\n if (value?.startsWith('%') && value?.endsWith('%')) {\n // strip '%' wildcard character when using a LIKE condition\n filterValue = filterValue.substring(1, filterValue.length - 1)\n }\n filterValue = queryVisualizationContext.getDisplayValue(\n filterValue,\n columnModel.columnType,\n )\n const text = `${getColumnDisplayName(\n queryFilter.columnName,\n )}: ${filterValue}`\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.columnName}-${value}`,\n label: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeValueFromQueryFilter(queryFilter, value)\n },\n }\n })\n}\n\nexport function getPillPropsFromTextMatchesQueryFilter(\n queryFilter: TextMatchesQueryFilter,\n queryContext: QueryContextType,\n isLocked?: boolean,\n): SelectionCriteriaPillProps {\n let innerText = queryFilter.searchExpression\n if (queryFilter.searchMode == 'BOOLEAN') {\n innerText = getSearchTextFromBooleanModeSearchExpression(\n queryFilter.searchExpression,\n )\n }\n\n return {\n key: `queryFilter-${queryFilter.concreteType}-${queryFilter.searchExpression}`,\n label: innerText,\n tooltipText: `Text matches: \"${innerText}\"`,\n ...(isLocked\n ? { isLocked: true }\n : {\n onRemoveFilter: () => {\n queryContext.removeQueryFilter(queryFilter)\n },\n }),\n }\n}\n\nfunction getPillPropsFromQueryFilters(\n queryFilters: ReadonlyDeep<QueryFilter[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n lockTextMatchesQueryFilterPill?: boolean,\n): SelectionCriteriaPillProps[] {\n return queryFilters.flatMap(queryFilter => {\n if (\n isColumnSingleValueQueryFilter(queryFilter) ||\n isColumnMultiValueFunctionQueryFilter(queryFilter)\n ) {\n const columnModel = columnModels.find(\n cm => cm.name === queryFilter.columnName,\n )\n if (\n queryFilter.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n return getPillPropsFromColumnQueryFilter(\n queryFilter,\n queryContext,\n columnModel,\n queryVisualizationContext,\n )\n } else if (isTextMatchesQueryFilter(queryFilter)) {\n return [\n getPillPropsFromTextMatchesQueryFilter(\n queryFilter,\n queryContext,\n lockTextMatchesQueryFilterPill,\n ),\n ]\n } else {\n console.log('Unknown query filter type', queryFilter)\n return []\n }\n })\n}\n\nfunction getRangeFacetInnerText(min?: string, max?: string) {\n if (min == undefined && max == undefined) {\n return 'Any value'\n } else if (min == undefined) {\n return `Up to ${max}`\n } else if (max == undefined) {\n return `${min} or greater`\n } else if (min === VALUE_NOT_SET && max === VALUE_NOT_SET) {\n return FRIENDLY_VALUE_NOT_SET\n } else {\n return `${min} - ${max}`\n }\n}\n\nfunction getPillPropsFromFacetFilters(\n selectedFacets: ReadonlyDeep<FacetColumnRequest[]>,\n queryContext: QueryContextType,\n columnModels: ColumnModel[],\n queryVisualizationContext: QueryVisualizationContextType,\n lockedColumn?: LockedColumn,\n): SelectionCriteriaPillProps[] {\n return selectedFacets.flatMap(\n (selectedFacet): SelectionCriteriaPillProps[] => {\n if (\n selectedFacet.columnName.toLowerCase() ===\n lockedColumn?.columnName?.toLowerCase()\n ) {\n return []\n }\n const columnModel = columnModels.find(\n cm => cm.name === selectedFacet.columnName,\n )\n const { getColumnDisplayName, getDisplayValue, renderFacetValue } =\n queryVisualizationContext\n if (isFacetColumnValuesRequest(selectedFacet)) {\n // If there are more than _n_ values, consolidate to one pill\n if (\n selectedFacet.facetValues.length >\n MAX_VALUES_IN_FILTER_FOR_INDIVIDUAL_PILLS ||\n !columnModel\n ) {\n const text = `${pluralize(\n getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n ),\n )} (${selectedFacet.facetValues.length.toLocaleString()})`\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}`,\n label: text,\n tooltipText: text,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n }\n\n // otherwise render one pill per value\n\n return selectedFacet.facetValues.map(facetValue => {\n const innerText = getDisplayValue(facetValue, columnModel.columnType)\n // A custom renderer (e.g. DUO) supplies structured chip content; the\n // pill renders it through the shared chip and owns the remove button.\n const rendered = renderFacetValue?.(\n selectedFacet.columnName,\n facetValue,\n )\n return {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${facetValue}`,\n label: rendered ? rendered.label : innerText,\n icon: rendered?.icon,\n tooltipText: rendered\n ? rendered.tooltipTitle\n : `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeValueFromSelectedFacet(\n selectedFacet,\n facetValue,\n )\n },\n }\n })\n } else if (isFacetColumnRangeRequest(selectedFacet)) {\n // Include a single pill for both facet filters if a combined range facet filter config is defined\n const { combineRangeFacetConfig } = queryContext\n if (\n combineRangeFacetConfig &&\n (selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn ||\n selectedFacet.columnName == combineRangeFacetConfig.maxFacetColumn)\n ) {\n if (\n selectedFacet.columnName == combineRangeFacetConfig.minFacetColumn\n ) {\n return []\n } else {\n // find the min facet also\n const maxFacet = selectedFacet\n const minFacet = selectedFacets.find(\n v => v.columnName == combineRangeFacetConfig.minFacetColumn,\n ) as FacetColumnRangeRequest\n const innerText = getRangeFacetInnerText(maxFacet.min, minFacet.max)\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${innerText}`,\n label: innerText,\n tooltipText: `${combineRangeFacetConfig.label}: ${innerText}`,\n onRemoveFilter: () => {\n // Remove both facets on pill click\n queryContext.removeSelectedFacet([minFacet, maxFacet])\n },\n },\n ]\n }\n }\n\n const innerText = getRangeFacetInnerText(\n selectedFacet.min,\n selectedFacet.max,\n )\n\n return [\n {\n key: `facet-${selectedFacet.concreteType}-${selectedFacet.columnName}-${selectedFacet.min}-${selectedFacet.max}`,\n label: innerText,\n tooltipText: `${getColumnDisplayName(\n selectedFacet.columnName,\n selectedFacet.jsonPath,\n )}: ${innerText}`,\n onRemoveFilter: () => {\n queryContext.removeSelectedFacet(selectedFacet)\n },\n },\n ]\n } else {\n console.log(\n 'Unknown facet type',\n (selectedFacet as unknown as FacetColumnRequest).concreteType,\n )\n return []\n }\n },\n )\n}\n\nfunction SelectionCriteriaPills() {\n const queryContext = useQueryContext()\n const lockedColumn = queryContext.lockedColumn\n const queryVisualizationContext = useQueryVisualizationContext()\n const { lockTextMatchesQueryFilterPill } = queryVisualizationContext\n const { currentQueryRequest } = queryContext\n const { data: queryMetadata } = useGetQueryMetadata()\n\n const queryFilterPillProps = getPillPropsFromQueryFilters(\n currentQueryRequest.query?.additionalFilters ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n lockTextMatchesQueryFilterPill,\n )\n\n const facetPillProps = getPillPropsFromFacetFilters(\n currentQueryRequest.query.selectedFacets ?? [],\n queryContext,\n queryMetadata?.columnModels || [],\n queryVisualizationContext,\n lockedColumn,\n )\n\n const allPills = [...queryFilterPillProps, ...facetPillProps]\n\n return (\n <>\n {allPills.map(pillProps => {\n // Encode the key because the facet may include an illegal character\n const key = encodeURIComponent(pillProps.key)\n return <SelectionCriteriaPill {...pillProps} key={key} />\n })}\n </>\n )\n}\n\nexport default SelectionCriteriaPills\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumFacetFilter.d.ts","sourceRoot":"","sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx"],"names":[],"mappings":"AAMA,OAAO,EAML,uBAAuB,EAIxB,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"EnumFacetFilter.d.ts","sourceRoot":"","sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx"],"names":[],"mappings":"AAMA,OAAO,EAML,uBAAuB,EAIxB,MAAM,iCAAiC,CAAA;AAWxC,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,uBAAuB,CAAA;IAC9B,WAAW,CAAC,EAAE,aAAa,GAAG,UAAU,CAAA;IACxC,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAA;AA6MD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CAc1D"}
|
|
@@ -6,89 +6,105 @@ import { getCorrespondingColumnForFacet as r, getCorrespondingSelectedFacet as i
|
|
|
6
6
|
import { useQueryContext as a } from "../../../QueryContext/QueryContext.js";
|
|
7
7
|
import "../../../QueryContext/index.js";
|
|
8
8
|
import { useSuspenseGetQueryMetadata as o } from "../../../QueryWrapper/useGetQueryMetadata.js";
|
|
9
|
-
import
|
|
9
|
+
import s from "../../facet-nav/FacetValueChip.js";
|
|
10
|
+
import { useQueryVisualizationContext as c } from "../../../QueryVisualizationWrapper/QueryVisualizationContext.js";
|
|
10
11
|
import "../../../QueryVisualizationWrapper/index.js";
|
|
11
|
-
import
|
|
12
|
-
import { EnumFacetFilterSkeleton as
|
|
13
|
-
import { getAllIsSelected as
|
|
14
|
-
import { Suspense as
|
|
15
|
-
import { cloneDeep as
|
|
16
|
-
import { Fragment as
|
|
17
|
-
import { ColumnTypeEnum as
|
|
12
|
+
import l from "./EnumFacetFilterUI.js";
|
|
13
|
+
import { EnumFacetFilterSkeleton as u } from "./EnumFacetFilterSkeleton.js";
|
|
14
|
+
import { getAllIsSelected as d, valueToLabel as f } from "./EnumFacetFilterUtils.js";
|
|
15
|
+
import { Suspense as p, useMemo as m } from "react";
|
|
16
|
+
import { cloneDeep as h, partition as g, pick as _, sortBy as v } from "lodash-es";
|
|
17
|
+
import { Fragment as y, jsx as b } from "react/jsx-runtime";
|
|
18
|
+
import { ColumnTypeEnum as x } from "@sage-bionetworks/synapse-types";
|
|
18
19
|
//#region src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx
|
|
19
|
-
function
|
|
20
|
-
let { facet:
|
|
21
|
-
let e = i(
|
|
20
|
+
function S(u) {
|
|
21
|
+
let { facet: p, containerAs: S = "Collapsible", dropdownType: C = "Icon", hideCollapsible: w = !1, defaultShowAllValues: T = !1, labelId: E } = u, { nextQueryRequest: D, addValueToSelectedFacet: O, removeSelectedFacet: k, removeValueFromSelectedFacet: A, resetDebounceTimer: j } = a(), { data: M } = o(), { getColumnDisplayName: N, renderFacetValue: P } = c(), F = m(() => {
|
|
22
|
+
let e = i(p, h(D.query.selectedFacets));
|
|
22
23
|
if (e && !t(e)) {
|
|
23
|
-
console.error("The facet rendered in EnumFacetFilter is not a FacetColumnValuesRequest",
|
|
24
|
+
console.error("The facet rendered in EnumFacetFilter is not a FacetColumnValuesRequest", p);
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
return e;
|
|
27
|
-
}, [
|
|
28
|
-
switch (
|
|
29
|
-
case
|
|
30
|
-
case
|
|
31
|
-
case
|
|
28
|
+
}, [p, D.query.selectedFacets]), I = d(h(D), p), L = M.columnModels ? r(p, M.columnModels) : void 0, R = m(() => {
|
|
29
|
+
switch (L?.columnType) {
|
|
30
|
+
case x.DOUBLE:
|
|
31
|
+
case x.DATE:
|
|
32
|
+
case x.INTEGER: return !0;
|
|
32
33
|
default: return !1;
|
|
33
34
|
}
|
|
34
|
-
}, [
|
|
35
|
-
ids:
|
|
35
|
+
}, [L]), z = n({
|
|
36
|
+
ids: L?.columnType === x.USERID || L?.columnType === x.USERID_LIST ? p.facetValues.map((e) => e.value) : [],
|
|
36
37
|
type: "USER_PROFILE"
|
|
37
|
-
}),
|
|
38
|
-
ids:
|
|
38
|
+
}), B = n({
|
|
39
|
+
ids: L?.columnType === x.ENTITYID || L?.columnType === x.ENTITYID_LIST ? p.facetValues.map((e) => e.value) : [],
|
|
39
40
|
type: "ENTITY_HEADER"
|
|
40
|
-
}),
|
|
41
|
-
ids:
|
|
41
|
+
}), V = n({
|
|
42
|
+
ids: L?.columnType === x.EVALUATIONID ? p.facetValues.map((e) => e.value) : [],
|
|
42
43
|
type: "EVALUATION_QUEUE"
|
|
43
|
-
}),
|
|
44
|
-
let t =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
}), H = m(() => {
|
|
45
|
+
let t = g(p.facetValues.map((e) => {
|
|
46
|
+
let t = f(e, z, B, V);
|
|
47
|
+
return {
|
|
48
|
+
...e,
|
|
49
|
+
isSelected: F?.facetValues.includes(e.value) ?? !1,
|
|
50
|
+
displayText: t,
|
|
51
|
+
renderedLabel: (() => {
|
|
52
|
+
let t = P?.(p.columnName, e.value);
|
|
53
|
+
return t ? /* @__PURE__ */ b(s, {
|
|
54
|
+
label: t.label,
|
|
55
|
+
icon: t.icon,
|
|
56
|
+
tooltipTitle: t.tooltipTitle,
|
|
57
|
+
placement: "right",
|
|
58
|
+
truncate: !0
|
|
59
|
+
}) : void 0;
|
|
60
|
+
})()
|
|
61
|
+
};
|
|
62
|
+
}), (t) => t.value === e), n = t[0], r = t[1], i = r;
|
|
63
|
+
return (L == null || L.facetSortConfig == null) && (i = R ? v(r, (e) => Number(e.value)) : v(r, (e) => e.displayText.toLowerCase())), [...i, ...n];
|
|
50
64
|
}, [
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
N?.facetValues,
|
|
65
|
+
p.facetValues,
|
|
66
|
+
p.columnName,
|
|
54
67
|
L,
|
|
55
|
-
|
|
68
|
+
F?.facetValues,
|
|
56
69
|
z,
|
|
57
|
-
|
|
70
|
+
B,
|
|
71
|
+
V,
|
|
72
|
+
R,
|
|
73
|
+
P
|
|
58
74
|
]);
|
|
59
|
-
return
|
|
60
|
-
labelId:
|
|
61
|
-
facetTitle:
|
|
62
|
-
filterIsActive: !
|
|
63
|
-
facetValues:
|
|
64
|
-
containerAs:
|
|
65
|
-
dropdownType:
|
|
66
|
-
hideCollapsible:
|
|
67
|
-
defaultShowAllValues:
|
|
75
|
+
return L ? /* @__PURE__ */ b(l, {
|
|
76
|
+
labelId: E,
|
|
77
|
+
facetTitle: N(p.columnName, p.jsonPath),
|
|
78
|
+
filterIsActive: !I,
|
|
79
|
+
facetValues: H,
|
|
80
|
+
containerAs: S,
|
|
81
|
+
dropdownType: C,
|
|
82
|
+
hideCollapsible: w,
|
|
83
|
+
defaultShowAllValues: T,
|
|
68
84
|
onHoverOverValue: () => {
|
|
69
|
-
|
|
85
|
+
j();
|
|
70
86
|
},
|
|
71
87
|
onAddValueToSelection: (e) => {
|
|
72
|
-
|
|
88
|
+
O(_(p, ["columnName", "jsonPath"]), e, { debounce: !0 });
|
|
73
89
|
},
|
|
74
90
|
onRemoveValueFromSelection: (e) => {
|
|
75
|
-
|
|
91
|
+
A(_(p, ["columnName", "jsonPath"]), e, { debounce: !0 });
|
|
76
92
|
},
|
|
77
|
-
onRemoveAllFacetSelections: () =>
|
|
93
|
+
onRemoveAllFacetSelections: () => k(_(p, ["columnName", "jsonPath"])),
|
|
78
94
|
canMultiSelect: !0
|
|
79
|
-
}) : /* @__PURE__ */ y
|
|
95
|
+
}) : /* @__PURE__ */ b(y, {});
|
|
80
96
|
}
|
|
81
|
-
function
|
|
97
|
+
function C(e) {
|
|
82
98
|
let { containerAs: t = "Collapsible", dropdownType: n = "Icon" } = e;
|
|
83
|
-
return /* @__PURE__ */
|
|
84
|
-
fallback: /* @__PURE__ */
|
|
99
|
+
return /* @__PURE__ */ b(p, {
|
|
100
|
+
fallback: /* @__PURE__ */ b(u, {
|
|
85
101
|
containerAs: t,
|
|
86
102
|
dropdownType: n
|
|
87
103
|
}),
|
|
88
|
-
children: /* @__PURE__ */
|
|
104
|
+
children: /* @__PURE__ */ b(S, { ...e })
|
|
89
105
|
});
|
|
90
106
|
}
|
|
91
107
|
//#endregion
|
|
92
|
-
export {
|
|
108
|
+
export { C as EnumFacetFilter };
|
|
93
109
|
|
|
94
110
|
//# sourceMappingURL=EnumFacetFilter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumFacetFilter.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx"],"sourcesContent":["import { isFacetColumnValuesRequest, SynapseConstants } from '@/utils'\nimport {\n getCorrespondingColumnForFacet,\n getCorrespondingSelectedFacet,\n} from '@/utils/functions/queryUtils'\nimport useGetInfoFromIds from '@/utils/hooks/useGetInfoFromIds'\nimport {\n ColumnTypeEnum,\n EntityHeader,\n Evaluation,\n FacetColumnRequest,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n UserGroupHeader,\n} from '@sage-bionetworks/synapse-types'\nimport { cloneDeep, partition, pick, sortBy } from 'lodash-es'\nimport { Suspense, useMemo } from 'react'\nimport { useQueryContext } from '../../../QueryContext'\nimport { useQueryVisualizationContext } from '../../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../../QueryWrapper/useGetQueryMetadata'\nimport { EnumFacetFilterSkeleton } from './EnumFacetFilterSkeleton'\nimport EnumFacetFilterUI, { RenderedFacetValue } from './EnumFacetFilterUI'\nimport { getAllIsSelected, valueToLabel } from './EnumFacetFilterUtils'\n\nexport type EnumFacetFilterProps = {\n labelId?: string\n facet: FacetColumnResultValues\n containerAs?: 'Collapsible' | 'Dropdown'\n dropdownType?: 'Icon' | 'SelectBox'\n hideCollapsible?: boolean\n defaultShowAllValues?: boolean\n}\n\nfunction EnumFacetFilterInternal(props: EnumFacetFilterProps) {\n const {\n facet,\n containerAs = 'Collapsible',\n dropdownType = 'Icon',\n hideCollapsible = false,\n defaultShowAllValues = false,\n labelId,\n } = props\n const {\n nextQueryRequest,\n addValueToSelectedFacet,\n removeSelectedFacet,\n removeValueFromSelectedFacet,\n resetDebounceTimer,\n } = useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { getColumnDisplayName } = useQueryVisualizationContext()\n\n const currentSelectedFacet: FacetColumnValuesRequest | undefined =\n useMemo(() => {\n const facetColumnRequest = getCorrespondingSelectedFacet(\n facet,\n cloneDeep(nextQueryRequest.query.selectedFacets) as\n | FacetColumnRequest[]\n | undefined,\n )\n\n if (\n facetColumnRequest &&\n !isFacetColumnValuesRequest(facetColumnRequest)\n ) {\n console.error(\n `The facet rendered in EnumFacetFilter is not a FacetColumnValuesRequest`,\n facet,\n )\n return undefined\n }\n return facetColumnRequest\n }, [facet, nextQueryRequest.query.selectedFacets])\n\n // Must compare the known facet values to the \"uncommitted\" current query\n const allIsSelected = getAllIsSelected(\n cloneDeep(nextQueryRequest) as QueryBundleRequest,\n facet,\n )\n\n const columnModel = queryMetadata.columnModels\n ? getCorrespondingColumnForFacet(facet, queryMetadata.columnModels)\n : undefined\n\n const isNumberColumnType = useMemo(() => {\n switch (columnModel?.columnType) {\n case ColumnTypeEnum.DOUBLE:\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.INTEGER:\n return true\n default:\n return false\n }\n }, [columnModel])\n\n const userIds =\n columnModel?.columnType === ColumnTypeEnum.USERID ||\n columnModel?.columnType === ColumnTypeEnum.USERID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const userGroupHeaders = useGetInfoFromIds<UserGroupHeader>({\n ids: userIds,\n type: 'USER_PROFILE',\n })\n\n const entityIds =\n columnModel?.columnType === ColumnTypeEnum.ENTITYID ||\n columnModel?.columnType === ColumnTypeEnum.ENTITYID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const entityHeaders = useGetInfoFromIds<EntityHeader>({\n ids: entityIds,\n type: 'ENTITY_HEADER',\n })\n\n const evaluationIds =\n columnModel?.columnType === ColumnTypeEnum.EVALUATIONID\n ? facet.facetValues.map(facet => facet.value)\n : []\n const evaluations = useGetInfoFromIds<Evaluation>({\n ids: evaluationIds,\n type: 'EVALUATION_QUEUE',\n })\n\n const displayedFacetValues: RenderedFacetValue[] = useMemo(() => {\n const renderedFacetValues = facet.facetValues.map(\n (facetValue: FacetColumnResultValueCount): RenderedFacetValue => {\n return {\n ...facetValue,\n // Selected status should be based on the 'nextQuery', not the result data\n // This ensures the checkboxes respond instantly to user interaction, like while waiting for multiple changes to debounce\n isSelected:\n currentSelectedFacet?.facetValues.includes(facetValue.value) ??\n false,\n displayText: valueToLabel(\n facetValue,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n ),\n }\n },\n )\n //Abby V's suggestion, always show the VALUE_NOT_SET facet value on the bottom of this sorted list\n const partitions = partition(\n renderedFacetValues,\n facet => facet.value === SynapseConstants.VALUE_NOT_SET,\n )\n const valueNotSetFacetArray = partitions[0]\n const restOfFacetValuesArray = partitions[1]\n\n // Apply client-side sorting if no server-side sort is specified\n let sortedValues: RenderedFacetValue[] = restOfFacetValuesArray\n const isClientSideSort =\n columnModel == undefined || columnModel.facetSortConfig == undefined\n if (isClientSideSort) {\n if (isNumberColumnType) {\n sortedValues = sortBy(restOfFacetValuesArray, fv => Number(fv.value))\n } else {\n sortedValues = sortBy(restOfFacetValuesArray, fv =>\n fv.displayText.toLowerCase(),\n )\n }\n }\n\n return [...sortedValues, ...valueNotSetFacetArray]\n }, [\n facet.facetValues,\n columnModel,\n currentSelectedFacet?.facetValues,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n isNumberColumnType,\n ])\n\n if (!columnModel) {\n return <></>\n }\n\n return (\n <EnumFacetFilterUI\n labelId={labelId}\n facetTitle={getColumnDisplayName(facet.columnName, facet.jsonPath)}\n filterIsActive={!allIsSelected}\n facetValues={displayedFacetValues}\n containerAs={containerAs}\n dropdownType={dropdownType}\n hideCollapsible={hideCollapsible}\n defaultShowAllValues={defaultShowAllValues}\n onHoverOverValue={() => {\n // SWC-6698: delay the query execution (via the debounce) when an item is hovered over\n resetDebounceTimer()\n }}\n onAddValueToSelection={value => {\n addValueToSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveValueFromSelection={value => {\n removeValueFromSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveAllFacetSelections={() =>\n removeSelectedFacet(pick(facet, ['columnName', 'jsonPath']))\n }\n canMultiSelect={true}\n />\n )\n}\n\nexport function EnumFacetFilter(props: EnumFacetFilterProps) {\n const { containerAs = 'Collapsible', dropdownType = 'Icon' } = props\n return (\n <Suspense\n fallback={\n <EnumFacetFilterSkeleton\n containerAs={containerAs}\n dropdownType={dropdownType}\n />\n }\n >\n <EnumFacetFilterInternal {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EnumFacetFilter.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.tsx"],"sourcesContent":["import { isFacetColumnValuesRequest, SynapseConstants } from '@/utils'\nimport {\n getCorrespondingColumnForFacet,\n getCorrespondingSelectedFacet,\n} from '@/utils/functions/queryUtils'\nimport useGetInfoFromIds from '@/utils/hooks/useGetInfoFromIds'\nimport {\n ColumnTypeEnum,\n EntityHeader,\n Evaluation,\n FacetColumnRequest,\n FacetColumnResultValueCount,\n FacetColumnResultValues,\n FacetColumnValuesRequest,\n QueryBundleRequest,\n UserGroupHeader,\n} from '@sage-bionetworks/synapse-types'\nimport { cloneDeep, partition, pick, sortBy } from 'lodash-es'\nimport { Suspense, useMemo } from 'react'\nimport { useQueryContext } from '../../../QueryContext'\nimport { useQueryVisualizationContext } from '../../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../../QueryWrapper/useGetQueryMetadata'\nimport { EnumFacetFilterSkeleton } from './EnumFacetFilterSkeleton'\nimport EnumFacetFilterUI, { RenderedFacetValue } from './EnumFacetFilterUI'\nimport { getAllIsSelected, valueToLabel } from './EnumFacetFilterUtils'\nimport FacetValueChip from '../../facet-nav/FacetValueChip'\n\nexport type EnumFacetFilterProps = {\n labelId?: string\n facet: FacetColumnResultValues\n containerAs?: 'Collapsible' | 'Dropdown'\n dropdownType?: 'Icon' | 'SelectBox'\n hideCollapsible?: boolean\n defaultShowAllValues?: boolean\n}\n\nfunction EnumFacetFilterInternal(props: EnumFacetFilterProps) {\n const {\n facet,\n containerAs = 'Collapsible',\n dropdownType = 'Icon',\n hideCollapsible = false,\n defaultShowAllValues = false,\n labelId,\n } = props\n const {\n nextQueryRequest,\n addValueToSelectedFacet,\n removeSelectedFacet,\n removeValueFromSelectedFacet,\n resetDebounceTimer,\n } = useQueryContext()\n\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { getColumnDisplayName, renderFacetValue } =\n useQueryVisualizationContext()\n\n const currentSelectedFacet: FacetColumnValuesRequest | undefined =\n useMemo(() => {\n const facetColumnRequest = getCorrespondingSelectedFacet(\n facet,\n cloneDeep(nextQueryRequest.query.selectedFacets) as\n | FacetColumnRequest[]\n | undefined,\n )\n\n if (\n facetColumnRequest &&\n !isFacetColumnValuesRequest(facetColumnRequest)\n ) {\n console.error(\n `The facet rendered in EnumFacetFilter is not a FacetColumnValuesRequest`,\n facet,\n )\n return undefined\n }\n return facetColumnRequest\n }, [facet, nextQueryRequest.query.selectedFacets])\n\n // Must compare the known facet values to the \"uncommitted\" current query\n const allIsSelected = getAllIsSelected(\n cloneDeep(nextQueryRequest) as QueryBundleRequest,\n facet,\n )\n\n const columnModel = queryMetadata.columnModels\n ? getCorrespondingColumnForFacet(facet, queryMetadata.columnModels)\n : undefined\n\n const isNumberColumnType = useMemo(() => {\n switch (columnModel?.columnType) {\n case ColumnTypeEnum.DOUBLE:\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.INTEGER:\n return true\n default:\n return false\n }\n }, [columnModel])\n\n const userIds =\n columnModel?.columnType === ColumnTypeEnum.USERID ||\n columnModel?.columnType === ColumnTypeEnum.USERID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const userGroupHeaders = useGetInfoFromIds<UserGroupHeader>({\n ids: userIds,\n type: 'USER_PROFILE',\n })\n\n const entityIds =\n columnModel?.columnType === ColumnTypeEnum.ENTITYID ||\n columnModel?.columnType === ColumnTypeEnum.ENTITYID_LIST\n ? facet.facetValues.map(facet => facet.value)\n : []\n const entityHeaders = useGetInfoFromIds<EntityHeader>({\n ids: entityIds,\n type: 'ENTITY_HEADER',\n })\n\n const evaluationIds =\n columnModel?.columnType === ColumnTypeEnum.EVALUATIONID\n ? facet.facetValues.map(facet => facet.value)\n : []\n const evaluations = useGetInfoFromIds<Evaluation>({\n ids: evaluationIds,\n type: 'EVALUATION_QUEUE',\n })\n\n const displayedFacetValues: RenderedFacetValue[] = useMemo(() => {\n const renderedFacetValues = facet.facetValues.map(\n (facetValue: FacetColumnResultValueCount): RenderedFacetValue => {\n const displayText = valueToLabel(\n facetValue,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n )\n return {\n ...facetValue,\n // Selected status should be based on the 'nextQuery', not the result data\n // This ensures the checkboxes respond instantly to user interaction, like while waiting for multiple changes to debounce\n isSelected:\n currentSelectedFacet?.facetValues.includes(facetValue.value) ??\n false,\n displayText,\n renderedLabel: (() => {\n const rendered = renderFacetValue?.(\n facet.columnName,\n facetValue.value,\n )\n return rendered ? (\n <FacetValueChip\n label={rendered.label}\n icon={rendered.icon}\n tooltipTitle={rendered.tooltipTitle}\n placement=\"right\"\n truncate\n />\n ) : undefined\n })(),\n }\n },\n )\n //Abby V's suggestion, always show the VALUE_NOT_SET facet value on the bottom of this sorted list\n const partitions = partition(\n renderedFacetValues,\n facet => facet.value === SynapseConstants.VALUE_NOT_SET,\n )\n const valueNotSetFacetArray = partitions[0]\n const restOfFacetValuesArray = partitions[1]\n\n // Apply client-side sorting if no server-side sort is specified\n let sortedValues: RenderedFacetValue[] = restOfFacetValuesArray\n const isClientSideSort =\n columnModel == undefined || columnModel.facetSortConfig == undefined\n if (isClientSideSort) {\n if (isNumberColumnType) {\n sortedValues = sortBy(restOfFacetValuesArray, fv => Number(fv.value))\n } else {\n sortedValues = sortBy(restOfFacetValuesArray, fv =>\n fv.displayText.toLowerCase(),\n )\n }\n }\n\n return [...sortedValues, ...valueNotSetFacetArray]\n }, [\n facet.facetValues,\n facet.columnName,\n columnModel,\n currentSelectedFacet?.facetValues,\n userGroupHeaders,\n entityHeaders,\n evaluations,\n isNumberColumnType,\n renderFacetValue,\n ])\n\n if (!columnModel) {\n return <></>\n }\n\n return (\n <EnumFacetFilterUI\n labelId={labelId}\n facetTitle={getColumnDisplayName(facet.columnName, facet.jsonPath)}\n filterIsActive={!allIsSelected}\n facetValues={displayedFacetValues}\n containerAs={containerAs}\n dropdownType={dropdownType}\n hideCollapsible={hideCollapsible}\n defaultShowAllValues={defaultShowAllValues}\n onHoverOverValue={() => {\n // SWC-6698: delay the query execution (via the debounce) when an item is hovered over\n resetDebounceTimer()\n }}\n onAddValueToSelection={value => {\n addValueToSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveValueFromSelection={value => {\n removeValueFromSelectedFacet(\n pick(facet, ['columnName', 'jsonPath']),\n value,\n { debounce: true },\n )\n }}\n onRemoveAllFacetSelections={() =>\n removeSelectedFacet(pick(facet, ['columnName', 'jsonPath']))\n }\n canMultiSelect={true}\n />\n )\n}\n\nexport function EnumFacetFilter(props: EnumFacetFilterProps) {\n const { containerAs = 'Collapsible', dropdownType = 'Icon' } = props\n return (\n <Suspense\n fallback={\n <EnumFacetFilterSkeleton\n containerAs={containerAs}\n dropdownType={dropdownType}\n />\n }\n >\n <EnumFacetFilterInternal {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumFacetFilterOption.d.ts","sourceRoot":"","sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EnumFacetFilterOption.d.ts","sourceRoot":"","sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,KAAK,0BAA0B,GAAG;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAA;CACzC,CAAA;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,2CAwEtE"}
|
|
@@ -17,7 +17,15 @@ function s(s) {
|
|
|
17
17
|
children: [/* @__PURE__ */ a(n, {
|
|
18
18
|
control: a(h === "checkbox" ? t : r, {}),
|
|
19
19
|
className: "EnumFacetFilter__checkbox",
|
|
20
|
-
sx: {
|
|
20
|
+
sx: {
|
|
21
|
+
overflowWrap: "anywhere",
|
|
22
|
+
flex: 1,
|
|
23
|
+
minWidth: 0,
|
|
24
|
+
"& .MuiFormControlLabel-label": {
|
|
25
|
+
minWidth: 0,
|
|
26
|
+
overflow: "hidden"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
21
29
|
onClick: (e) => e.stopPropagation(),
|
|
22
30
|
onChange: (e, t) => {
|
|
23
31
|
p(t);
|
|
@@ -26,6 +34,10 @@ function s(s) {
|
|
|
26
34
|
label: l
|
|
27
35
|
}, `${c}`), u != null && /* @__PURE__ */ o(i, { children: [d && /* @__PURE__ */ o("span", {
|
|
28
36
|
className: "EnumFacetFilter__count",
|
|
37
|
+
style: {
|
|
38
|
+
flexShrink: 0,
|
|
39
|
+
marginLeft: 8
|
|
40
|
+
},
|
|
29
41
|
children: [
|
|
30
42
|
"(",
|
|
31
43
|
u.toLocaleString(),
|
|
@@ -33,6 +45,10 @@ function s(s) {
|
|
|
33
45
|
]
|
|
34
46
|
}), !d && /* @__PURE__ */ a("div", {
|
|
35
47
|
className: "EnumFacetFilter__count",
|
|
48
|
+
style: {
|
|
49
|
+
flexShrink: 0,
|
|
50
|
+
marginLeft: 8
|
|
51
|
+
},
|
|
36
52
|
children: u.toLocaleString()
|
|
37
53
|
})] })]
|
|
38
54
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumFacetFilterOption.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.tsx"],"sourcesContent":["import { Box, Checkbox, FormControlLabel, Radio } from '@mui/material'\n\ntype EnumFacetFilterOptionProps = {\n readonly id: string\n readonly label:
|
|
1
|
+
{"version":3,"file":"EnumFacetFilterOption.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.tsx"],"sourcesContent":["import { Box, Checkbox, FormControlLabel, Radio } from '@mui/material'\nimport { ReactNode } from 'react'\n\ntype EnumFacetFilterOptionProps = {\n readonly id: string\n readonly label: ReactNode\n readonly count?: number\n readonly isDropdown: boolean\n readonly checked: boolean\n readonly onChange: (selected: boolean) => void\n readonly onHover: () => void\n readonly inputType: 'checkbox' | 'radio'\n}\n\nexport function EnumFacetFilterOption(props: EnumFacetFilterOptionProps) {\n const {\n id,\n label,\n count,\n isDropdown,\n checked,\n onChange,\n onHover,\n inputType,\n } = props\n\n const control = inputType === 'checkbox' ? <Checkbox /> : <Radio />\n\n return (\n <Box\n className=\"EnumFacetFilter__checkboxContainer\"\n onClick={() => {\n // If this is a dropdown option, clicking anywhere in the field should toggle selection\n if (isDropdown) {\n onChange(!checked)\n }\n }}\n onMouseEnter={onHover}\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <FormControlLabel\n control={control}\n className=\"EnumFacetFilter__checkbox\"\n sx={{\n overflowWrap: 'anywhere',\n // Let the label shrink so the count stays in a consistent column\n // (and custom node labels can truncate rather than overflow the row).\n flex: 1,\n minWidth: 0,\n '& .MuiFormControlLabel-label': { minWidth: 0, overflow: 'hidden' },\n }}\n onClick={event => event.stopPropagation()}\n onChange={(_event, newValue) => {\n onChange(newValue)\n }}\n key={`${id}`}\n checked={checked}\n label={label}\n />\n\n {count != null && (\n <>\n {isDropdown && (\n <span\n className=\"EnumFacetFilter__count\"\n style={{ flexShrink: 0, marginLeft: 8 }}\n >\n ({count.toLocaleString()})\n </span>\n )}\n {!isDropdown && (\n <div\n className=\"EnumFacetFilter__count\"\n style={{ flexShrink: 0, marginLeft: 8 }}\n >\n {count.toLocaleString()}\n </div>\n )}\n </>\n )}\n </Box>\n )\n}\n"],"mappings":";;;AAcA,SAAgB,EAAsB,GAAmC;CACvE,IAAM,EACJ,OACA,UACA,UACA,eACA,YACA,aACA,YACA,iBACE;CAIJ,OACE,kBAAC,GAAD;EACE,WAAU;EACV,eAAe;GAEb,AAAI,KACF,EAAS,CAAC,CAAO;EAErB;EACA,cAAc;EACd,IAAI;GACF,SAAS;GACT,gBAAgB;GAChB,YAAY;EACd;YAbF,CAeE,kBAAC,GAAD;GACW,SAnB4B,EAA3B,MAAc,aAAc,IAAe,GAAhB,CAAW,CAAY;GAoB5D,WAAU;GACV,IAAI;IACF,cAAc;IAGd,MAAM;IACN,UAAU;IACV,gCAAgC;KAAE,UAAU;KAAG,UAAU;IAAS;GACpE;GACA,UAAS,MAAS,EAAM,gBAAgB;GACxC,WAAW,GAAQ,MAAa;IAC9B,EAAS,CAAQ;GACnB;GAES;GACF;EACR,GAHM,GAAG,GAGT,GAEA,KAAS,QACR,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,QAAD;GACE,WAAU;GACV,OAAO;IAAE,YAAY;IAAG,YAAY;GAAE;aAFxC;IAGC;IACG,EAAM,eAAe;IAAE;GACrB;MAEP,CAAC,KACA,kBAAC,OAAD;GACE,WAAU;GACV,OAAO;IAAE,YAAY;IAAG,YAAY;GAAE;aAErC,EAAM,eAAe;EACnB,CAAA,CAEP,EAAA,CAAA,CAED;;AAET"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
1
2
|
import { FacetColumnResultValueCount } from '@sage-bionetworks/synapse-types';
|
|
2
3
|
import { SetOptional } from 'type-fest';
|
|
3
4
|
export type RenderedFacetValue<TValue = string> = Omit<SetOptional<FacetColumnResultValueCount, 'count'>, 'value'> & {
|
|
4
5
|
value: TValue;
|
|
5
6
|
displayText: string;
|
|
7
|
+
renderedLabel?: ReactNode;
|
|
6
8
|
};
|
|
7
9
|
export type EnumFacetFilterUIProps<TValue = string> = {
|
|
8
10
|
labelId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumFacetFilterUI.d.ts","sourceRoot":"","sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EnumFacetFilterUI.d.ts","sourceRoot":"","sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAA6B,MAAM,OAAO,CAAA;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAA;AAK7E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAIvC,MAAM,MAAM,kBAAkB,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,CACpD,WAAW,CAAC,2BAA2B,EAAE,OAAO,CAAC,EACjD,OAAO,CACR,GAAG;IACF,KAAK,EAAE,MAAM,CAAA;IAEb,WAAW,EAAE,MAAM,CAAA;IAEnB,aAAa,CAAC,EAAE,SAAS,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,sBAAsB,CAAC,MAAM,GAAG,MAAM,IAAI;IAEpD,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,UAAU,EAAE,MAAM,CAAA;IAElB,WAAW,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAA;IAEzC,cAAc,EAAE,OAAO,CAAA;IAEvB,WAAW,CAAC,EAAE,aAAa,GAAG,UAAU,CAAA;IAExC,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAEnC,eAAe,CAAC,EAAE,OAAO,CAAA;IAEzB,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAE9C,0BAA0B,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEnD,0BAA0B,EAAE,MAAM,IAAI,CAAA;IAEtC,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEzC,cAAc,EAAE,OAAO,CAAA;IAEvB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAA;AAMD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,MAAM,GAAG,MAAM,EACvD,KAAK,EAAE,sBAAsB,CAAC,MAAM,CAAC,2CAiQtC"}
|
|
@@ -89,25 +89,25 @@ function v(v) {
|
|
|
89
89
|
})]
|
|
90
90
|
}), /* @__PURE__ */ h("div", { children: [
|
|
91
91
|
H.map((e, t) => {
|
|
92
|
-
let { isSelected: r, displayText: i,
|
|
92
|
+
let { isSelected: r, displayText: i, renderedLabel: a, value: o, count: s } = e;
|
|
93
93
|
return /* @__PURE__ */ m(n, {
|
|
94
94
|
id: [
|
|
95
95
|
_(D),
|
|
96
|
-
_(String(
|
|
96
|
+
_(String(o)),
|
|
97
97
|
t
|
|
98
98
|
].join("-"),
|
|
99
|
-
label: i,
|
|
100
|
-
count:
|
|
99
|
+
label: a ?? i,
|
|
100
|
+
count: s,
|
|
101
101
|
isDropdown: W,
|
|
102
102
|
checked: r,
|
|
103
103
|
onHover: () => {
|
|
104
|
-
k(
|
|
104
|
+
k(o);
|
|
105
105
|
},
|
|
106
106
|
onChange: (e) => {
|
|
107
|
-
e ? T(
|
|
107
|
+
e ? T(o) : E(o);
|
|
108
108
|
},
|
|
109
109
|
inputType: A ? "checkbox" : "radio"
|
|
110
|
-
}, String(
|
|
110
|
+
}, String(o));
|
|
111
111
|
}),
|
|
112
112
|
!W && /* @__PURE__ */ h(p, { children: [G && /* @__PURE__ */ m("button", {
|
|
113
113
|
className: "EnumFacetFilter__showMoreFacetsBtn",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnumFacetFilterUI.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.tsx"],"sourcesContent":["import {\n Checkbox,\n Collapse,\n FormControlLabel,\n IconButton,\n TextField,\n Tooltip,\n} from '@mui/material'\nimport { useMemo, useRef, useState } from 'react'\nimport { FacetColumnResultValueCount } from '@sage-bionetworks/synapse-types'\nimport IconSvg from '../../../IconSvg/IconSvg'\nimport { FacetFilterHeader } from '../FacetFilterHeader'\nimport { EnumFacetFilterOption } from './EnumFacetFilterOption'\nimport EnumFacetFilterDropdown from './EnumFacetFilterDropdown'\nimport { SetOptional } from 'type-fest'\n\nconst MAX_ENUMERATION_VALUES_TO_SHOW = 5\n\nexport type RenderedFacetValue<TValue = string> = Omit<\n SetOptional<FacetColumnResultValueCount, 'count'>,\n 'value'\n> & {\n value: TValue\n /* Text displayed for the option, and also used to filter in search */\n displayText: string\n}\n\nexport type EnumFacetFilterUIProps<TValue = string> = {\n /* The ID of the corresponding label, for testing and accessibility */\n labelId?: string\n /* The title of the faceted column to be displayed */\n facetTitle: string\n /* List of all facet values and information associated with each value */\n facetValues: RenderedFacetValue<TValue>[]\n /* Determines how the component is styled and whether the 'All' checkbox should be selected. */\n filterIsActive: boolean // filterIsActive cannot be derived from facetValues[*].isSelected. See PORTALS-2680\n /* The EnumFacetFilter can be rendered as a collapsible panel or a dropdown. Default is `'Collapsible'` */\n containerAs?: 'Collapsible' | 'Dropdown'\n /* If `containerAs` is a dropdown, the dropdown can be either an IconButton or a SelectBox. Default is `'Icon'` */\n dropdownType?: 'Icon' | 'SelectBox'\n /* If true, hides the button to collapse the panel (only shown if `containerAs` is 'Collapsible'). Default is false.*/\n hideCollapsible?: boolean\n /* Called when an unselected value is selected */\n onAddValueToSelection: (value: TValue) => void\n /* Called when a selected value is unselected */\n onRemoveValueFromSelection: (value: TValue) => void\n /* Called when all values should be unselected (e.g. 'All' is clicked) */\n onRemoveAllFacetSelections: () => void\n /* Called when an value is hovered over */\n onHoverOverValue: (value: TValue) => void\n /* Set to true if multiple values can be selected for the filter */\n canMultiSelect: boolean\n /* By default, all values are not shown (defaultShowAllValues = false) */\n defaultShowAllValues?: boolean\n}\n\nfunction removeWhitespace(value: string): string {\n return value.replace(/\\s/g, '').toLowerCase()\n}\n\nexport default function EnumFacetFilterUI<TValue = string>(\n props: EnumFacetFilterUIProps<TValue>,\n) {\n const {\n labelId,\n filterIsActive,\n containerAs = 'Collapsible',\n dropdownType = 'Icon',\n hideCollapsible = false,\n facetValues,\n onAddValueToSelection,\n onRemoveValueFromSelection,\n facetTitle,\n onRemoveAllFacetSelections,\n onHoverOverValue,\n canMultiSelect = true,\n defaultShowAllValues = false,\n } = props\n const [toggleShowAll, setToggleShowAll] =\n useState<boolean>(defaultShowAllValues)\n const [isCollapsed, setIsCollapsed] = useState<boolean>(false)\n const [showSearch, setShowSearch] = useState<boolean>(false)\n const [searchTerm, setSearchText] = useState<string>('')\n\n // e.g. we show a subset of facet values before hiding the rest behind \"Show More\"\n // If the user has selected a value that would normally be hidden, always show all of the values\n const valueIndexedGreaterThanMaxToShowIsSelected =\n facetValues.length > MAX_ENUMERATION_VALUES_TO_SHOW &&\n facetValues\n .slice(MAX_ENUMERATION_VALUES_TO_SHOW)\n .some(({ isSelected }) => isSelected)\n const showAll =\n containerAs === 'Dropdown' ||\n toggleShowAll ||\n showSearch ||\n valueIndexedGreaterThanMaxToShowIsSelected\n\n const facetValuesToShow = useMemo(() => {\n if (showSearch && searchTerm.length > 0) {\n return facetValues.filter(({ displayText }) => {\n return (\n displayText.toLowerCase().indexOf(searchTerm.trim().toLowerCase()) >\n -1\n )\n })\n }\n if (showAll) {\n return facetValues\n }\n return facetValues.slice(0, MAX_ENUMERATION_VALUES_TO_SHOW)\n }, [facetValues, searchTerm, showSearch, showAll])\n\n const textInput = useRef<HTMLInputElement>(null)\n\n const isDropdown = containerAs === 'Dropdown'\n const showMoreButtonIsVisible =\n !showAll && facetValues.length > MAX_ENUMERATION_VALUES_TO_SHOW\n const showLessButtonIsVisible =\n showAll &&\n !searchTerm &&\n !valueIndexedGreaterThanMaxToShowIsSelected &&\n facetValues.length > MAX_ENUMERATION_VALUES_TO_SHOW\n\n const content = (\n <div className={isDropdown ? 'EnumFacetFilter__dropdown_menu' : ''}>\n <div className=\"EnumFacetFilter__checkboxContainer--forAll\">\n <TextField // Search Filter Text\n sx={{\n display: showSearch ? undefined : 'none',\n }}\n size={'small'}\n fullWidth={true}\n slotProps={{\n input: {\n startAdornment: (\n <Tooltip title={'Close search'}>\n <IconButton\n size={'small'}\n onClick={() => {\n setShowSearch(false)\n setToggleShowAll(defaultShowAllValues)\n }}\n >\n <IconSvg\n sx={{ fontSize: 'inherit' }}\n wrap={false}\n icon=\"arrowBack\"\n />\n </IconButton>\n </Tooltip>\n ),\n endAdornment: searchTerm.length > 0 && (\n <Tooltip title={'Clear'}>\n <IconButton\n size={'small'}\n onClick={() => {\n setSearchText('')\n textInput.current?.focus()\n }}\n >\n <IconSvg\n sx={{ fontSize: 'inherit' }}\n wrap={false}\n icon=\"close\"\n />\n </IconButton>\n </Tooltip>\n ),\n },\n }}\n type=\"text\"\n placeholder=\"Find values\"\n value={searchTerm}\n ref={textInput}\n onChange={e => {\n setSearchText(e.target.value)\n }}\n />\n {!showSearch && (\n <div className=\"EnumFacetFilter__checkAll\">\n <FormControlLabel\n control={<Checkbox />}\n className=\"EnumFacetFilter__checkbox\"\n onChange={() => {\n if (filterIsActive) {\n onRemoveAllFacetSelections()\n }\n }}\n key=\"select_all\"\n checked={!filterIsActive}\n label=\"All\"\n />\n <Tooltip title={'Search'}>\n <IconButton\n size={'small'}\n sx={{ aspectRatio: '1 / 1' }}\n onClick={() => {\n setSearchText('')\n setShowSearch(true)\n textInput.current?.focus()\n }}\n >\n <IconSvg\n sx={{ fontSize: 'inherit' }}\n wrap={false}\n icon=\"search\"\n />\n </IconButton>\n </Tooltip>\n </div>\n )}\n </div>\n <div>\n {facetValuesToShow.map((facetValueAndCount, index: number) => {\n const { isSelected, displayText, value, count } = facetValueAndCount\n\n return (\n <EnumFacetFilterOption\n key={String(value)}\n id={[\n removeWhitespace(facetTitle),\n removeWhitespace(String(value)),\n index,\n ].join('-')}\n label={displayText}\n count={count}\n isDropdown={isDropdown}\n checked={isSelected}\n onHover={() => {\n onHoverOverValue(value)\n }}\n onChange={(newIsSelected: boolean) => {\n if (newIsSelected) {\n onAddValueToSelection(value)\n } else {\n onRemoveValueFromSelection(value)\n }\n }}\n inputType={canMultiSelect ? 'checkbox' : 'radio'}\n />\n )\n })}\n {!isDropdown && (\n <>\n {showMoreButtonIsVisible && (\n <button\n className=\"EnumFacetFilter__showMoreFacetsBtn\"\n onClick={() => setToggleShowAll(true)}\n >\n <div className=\"EnumFacetFilter__checkboxContainer\">\n <div className=\"EnumFacetFilter__showMoreFacetsLabel\">\n Show all ({facetValues.length})\n </div>\n </div>\n </button>\n )}\n {showLessButtonIsVisible && (\n <button\n className=\"EnumFacetFilter__showMoreFacetsBtn\"\n onClick={() => setToggleShowAll(false)}\n >\n <div className=\"EnumFacetFilter__checkboxContainer\">\n <div className=\"EnumFacetFilter__showMoreFacetsLabel\">\n Show less\n </div>\n </div>\n </button>\n )}\n </>\n )}\n {facetValuesToShow.length <= 0 && (\n <div className=\"EnumFacetFilter__noMatch\">No match found</div>\n )}\n </div>\n </div>\n )\n\n const menuText = useMemo(() => {\n if (!filterIsActive) {\n return 'All'\n } else if (\n filterIsActive &&\n facetValuesToShow.filter(item => item.isSelected).length === 1\n ) {\n return facetValuesToShow.filter(item => item.isSelected)[0].displayText\n } else {\n return 'Multiple Values Selected'\n }\n }, [filterIsActive, facetValuesToShow])\n\n if (isDropdown) {\n return (\n <EnumFacetFilterDropdown\n facetTitle={facetTitle}\n dropdownType={dropdownType}\n menuText={menuText}\n filterIsActive={filterIsActive}\n labelId={labelId}\n >\n {content}\n </EnumFacetFilterDropdown>\n )\n } else {\n return (\n <>\n <FacetFilterHeader\n hideCollapsible={hideCollapsible}\n isCollapsed={isCollapsed}\n label={facetTitle}\n onClick={(isCollapsed: boolean) => setIsCollapsed(isCollapsed)}\n />\n <Collapse className=\"EnumFacetFilter\" in={!isCollapsed}>\n {content}\n </Collapse>\n </>\n )\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EnumFacetFilterUI.js","names":[],"sources":["../../../../../src/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.tsx"],"sourcesContent":["import {\n Checkbox,\n Collapse,\n FormControlLabel,\n IconButton,\n TextField,\n Tooltip,\n} from '@mui/material'\nimport { ReactNode, useMemo, useRef, useState } from 'react'\nimport { FacetColumnResultValueCount } from '@sage-bionetworks/synapse-types'\nimport IconSvg from '../../../IconSvg/IconSvg'\nimport { FacetFilterHeader } from '../FacetFilterHeader'\nimport { EnumFacetFilterOption } from './EnumFacetFilterOption'\nimport EnumFacetFilterDropdown from './EnumFacetFilterDropdown'\nimport { SetOptional } from 'type-fest'\n\nconst MAX_ENUMERATION_VALUES_TO_SHOW = 5\n\nexport type RenderedFacetValue<TValue = string> = Omit<\n SetOptional<FacetColumnResultValueCount, 'count'>,\n 'value'\n> & {\n value: TValue\n /* Text displayed for the option, and also used to filter in search */\n displayText: string\n /* Optional custom node to render in place of the plain-text label. */\n renderedLabel?: ReactNode\n}\n\nexport type EnumFacetFilterUIProps<TValue = string> = {\n /* The ID of the corresponding label, for testing and accessibility */\n labelId?: string\n /* The title of the faceted column to be displayed */\n facetTitle: string\n /* List of all facet values and information associated with each value */\n facetValues: RenderedFacetValue<TValue>[]\n /* Determines how the component is styled and whether the 'All' checkbox should be selected. */\n filterIsActive: boolean // filterIsActive cannot be derived from facetValues[*].isSelected. See PORTALS-2680\n /* The EnumFacetFilter can be rendered as a collapsible panel or a dropdown. Default is `'Collapsible'` */\n containerAs?: 'Collapsible' | 'Dropdown'\n /* If `containerAs` is a dropdown, the dropdown can be either an IconButton or a SelectBox. Default is `'Icon'` */\n dropdownType?: 'Icon' | 'SelectBox'\n /* If true, hides the button to collapse the panel (only shown if `containerAs` is 'Collapsible'). Default is false.*/\n hideCollapsible?: boolean\n /* Called when an unselected value is selected */\n onAddValueToSelection: (value: TValue) => void\n /* Called when a selected value is unselected */\n onRemoveValueFromSelection: (value: TValue) => void\n /* Called when all values should be unselected (e.g. 'All' is clicked) */\n onRemoveAllFacetSelections: () => void\n /* Called when an value is hovered over */\n onHoverOverValue: (value: TValue) => void\n /* Set to true if multiple values can be selected for the filter */\n canMultiSelect: boolean\n /* By default, all values are not shown (defaultShowAllValues = false) */\n defaultShowAllValues?: boolean\n}\n\nfunction removeWhitespace(value: string): string {\n return value.replace(/\\s/g, '').toLowerCase()\n}\n\nexport default function EnumFacetFilterUI<TValue = string>(\n props: EnumFacetFilterUIProps<TValue>,\n) {\n const {\n labelId,\n filterIsActive,\n containerAs = 'Collapsible',\n dropdownType = 'Icon',\n hideCollapsible = false,\n facetValues,\n onAddValueToSelection,\n onRemoveValueFromSelection,\n facetTitle,\n onRemoveAllFacetSelections,\n onHoverOverValue,\n canMultiSelect = true,\n defaultShowAllValues = false,\n } = props\n const [toggleShowAll, setToggleShowAll] =\n useState<boolean>(defaultShowAllValues)\n const [isCollapsed, setIsCollapsed] = useState<boolean>(false)\n const [showSearch, setShowSearch] = useState<boolean>(false)\n const [searchTerm, setSearchText] = useState<string>('')\n\n // e.g. we show a subset of facet values before hiding the rest behind \"Show More\"\n // If the user has selected a value that would normally be hidden, always show all of the values\n const valueIndexedGreaterThanMaxToShowIsSelected =\n facetValues.length > MAX_ENUMERATION_VALUES_TO_SHOW &&\n facetValues\n .slice(MAX_ENUMERATION_VALUES_TO_SHOW)\n .some(({ isSelected }) => isSelected)\n const showAll =\n containerAs === 'Dropdown' ||\n toggleShowAll ||\n showSearch ||\n valueIndexedGreaterThanMaxToShowIsSelected\n\n const facetValuesToShow = useMemo(() => {\n if (showSearch && searchTerm.length > 0) {\n return facetValues.filter(({ displayText }) => {\n return (\n displayText.toLowerCase().indexOf(searchTerm.trim().toLowerCase()) >\n -1\n )\n })\n }\n if (showAll) {\n return facetValues\n }\n return facetValues.slice(0, MAX_ENUMERATION_VALUES_TO_SHOW)\n }, [facetValues, searchTerm, showSearch, showAll])\n\n const textInput = useRef<HTMLInputElement>(null)\n\n const isDropdown = containerAs === 'Dropdown'\n const showMoreButtonIsVisible =\n !showAll && facetValues.length > MAX_ENUMERATION_VALUES_TO_SHOW\n const showLessButtonIsVisible =\n showAll &&\n !searchTerm &&\n !valueIndexedGreaterThanMaxToShowIsSelected &&\n facetValues.length > MAX_ENUMERATION_VALUES_TO_SHOW\n\n const content = (\n <div className={isDropdown ? 'EnumFacetFilter__dropdown_menu' : ''}>\n <div className=\"EnumFacetFilter__checkboxContainer--forAll\">\n <TextField // Search Filter Text\n sx={{\n display: showSearch ? undefined : 'none',\n }}\n size={'small'}\n fullWidth={true}\n slotProps={{\n input: {\n startAdornment: (\n <Tooltip title={'Close search'}>\n <IconButton\n size={'small'}\n onClick={() => {\n setShowSearch(false)\n setToggleShowAll(defaultShowAllValues)\n }}\n >\n <IconSvg\n sx={{ fontSize: 'inherit' }}\n wrap={false}\n icon=\"arrowBack\"\n />\n </IconButton>\n </Tooltip>\n ),\n endAdornment: searchTerm.length > 0 && (\n <Tooltip title={'Clear'}>\n <IconButton\n size={'small'}\n onClick={() => {\n setSearchText('')\n textInput.current?.focus()\n }}\n >\n <IconSvg\n sx={{ fontSize: 'inherit' }}\n wrap={false}\n icon=\"close\"\n />\n </IconButton>\n </Tooltip>\n ),\n },\n }}\n type=\"text\"\n placeholder=\"Find values\"\n value={searchTerm}\n ref={textInput}\n onChange={e => {\n setSearchText(e.target.value)\n }}\n />\n {!showSearch && (\n <div className=\"EnumFacetFilter__checkAll\">\n <FormControlLabel\n control={<Checkbox />}\n className=\"EnumFacetFilter__checkbox\"\n onChange={() => {\n if (filterIsActive) {\n onRemoveAllFacetSelections()\n }\n }}\n key=\"select_all\"\n checked={!filterIsActive}\n label=\"All\"\n />\n <Tooltip title={'Search'}>\n <IconButton\n size={'small'}\n sx={{ aspectRatio: '1 / 1' }}\n onClick={() => {\n setSearchText('')\n setShowSearch(true)\n textInput.current?.focus()\n }}\n >\n <IconSvg\n sx={{ fontSize: 'inherit' }}\n wrap={false}\n icon=\"search\"\n />\n </IconButton>\n </Tooltip>\n </div>\n )}\n </div>\n <div>\n {facetValuesToShow.map((facetValueAndCount, index: number) => {\n const { isSelected, displayText, renderedLabel, value, count } =\n facetValueAndCount\n\n return (\n <EnumFacetFilterOption\n key={String(value)}\n id={[\n removeWhitespace(facetTitle),\n removeWhitespace(String(value)),\n index,\n ].join('-')}\n label={renderedLabel ?? displayText}\n count={count}\n isDropdown={isDropdown}\n checked={isSelected}\n onHover={() => {\n onHoverOverValue(value)\n }}\n onChange={(newIsSelected: boolean) => {\n if (newIsSelected) {\n onAddValueToSelection(value)\n } else {\n onRemoveValueFromSelection(value)\n }\n }}\n inputType={canMultiSelect ? 'checkbox' : 'radio'}\n />\n )\n })}\n {!isDropdown && (\n <>\n {showMoreButtonIsVisible && (\n <button\n className=\"EnumFacetFilter__showMoreFacetsBtn\"\n onClick={() => setToggleShowAll(true)}\n >\n <div className=\"EnumFacetFilter__checkboxContainer\">\n <div className=\"EnumFacetFilter__showMoreFacetsLabel\">\n Show all ({facetValues.length})\n </div>\n </div>\n </button>\n )}\n {showLessButtonIsVisible && (\n <button\n className=\"EnumFacetFilter__showMoreFacetsBtn\"\n onClick={() => setToggleShowAll(false)}\n >\n <div className=\"EnumFacetFilter__checkboxContainer\">\n <div className=\"EnumFacetFilter__showMoreFacetsLabel\">\n Show less\n </div>\n </div>\n </button>\n )}\n </>\n )}\n {facetValuesToShow.length <= 0 && (\n <div className=\"EnumFacetFilter__noMatch\">No match found</div>\n )}\n </div>\n </div>\n )\n\n const menuText = useMemo(() => {\n if (!filterIsActive) {\n return 'All'\n } else if (\n filterIsActive &&\n facetValuesToShow.filter(item => item.isSelected).length === 1\n ) {\n return facetValuesToShow.filter(item => item.isSelected)[0].displayText\n } else {\n return 'Multiple Values Selected'\n }\n }, [filterIsActive, facetValuesToShow])\n\n if (isDropdown) {\n return (\n <EnumFacetFilterDropdown\n facetTitle={facetTitle}\n dropdownType={dropdownType}\n menuText={menuText}\n filterIsActive={filterIsActive}\n labelId={labelId}\n >\n {content}\n </EnumFacetFilterDropdown>\n )\n } else {\n return (\n <>\n <FacetFilterHeader\n hideCollapsible={hideCollapsible}\n isCollapsed={isCollapsed}\n label={facetTitle}\n onClick={(isCollapsed: boolean) => setIsCollapsed(isCollapsed)}\n />\n <Collapse className=\"EnumFacetFilter\" in={!isCollapsed}>\n {content}\n </Collapse>\n </>\n )\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurationTaskCard.d.ts","sourceRoot":"","sources":["../../../../../src/features/curator/dashboard/components/CurationTaskCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CurationTaskCard.d.ts","sourceRoot":"","sources":["../../../../../src/features/curator/dashboard/components/CurationTaskCard.tsx"],"names":[],"mappings":"AAeA,OAAO,EACL,UAAU,EAEX,MAAM,kCAAkC,CAAA;AASzC,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AA8ED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,2CA+FpE"}
|