mirror of
https://github.com/datahub-project/datahub.git
synced 2025-06-27 05:03:31 +00:00
Update search results page (#13303)
This commit is contained in:
parent
cb3988a5f3
commit
ca7853c5a4
@ -45,7 +45,7 @@ const getPillVariantStyles = (variant: PillVariantOptions, colorStyles: ColorSty
|
||||
},
|
||||
outline: {
|
||||
backgroundColor: 'transparent',
|
||||
border: `1px solid ${colorStyles.primaryColor}`,
|
||||
border: `1px solid ${colorStyles.bgColor}`,
|
||||
color: colorStyles.primaryColor,
|
||||
'&:hover': {
|
||||
backgroundColor: colorStyles.hoverColor,
|
||||
|
@ -240,17 +240,18 @@ export const SearchPage = () => {
|
||||
onChangeFilters={onChangeFilters}
|
||||
onClearFilters={onClearFilters}
|
||||
onChangeUnionType={onChangeUnionType}
|
||||
/>
|
||||
<SearchResults
|
||||
unionType={unionType}
|
||||
downloadSearchResults={downloadSearchResults}
|
||||
page={page}
|
||||
query={query}
|
||||
viewUrn={viewUrn || undefined}
|
||||
totalResults={total}
|
||||
setShowSelectMode={setIsSelectMode}
|
||||
downloadSearchResults={downloadSearchResults}
|
||||
/>
|
||||
<SearchResults
|
||||
page={page}
|
||||
query={query}
|
||||
error={error}
|
||||
searchResponse={data?.searchAcrossEntities}
|
||||
suggestions={data?.searchAcrossEntities?.suggestions || []}
|
||||
availableFilters={data?.searchAcrossEntities?.facets || []}
|
||||
selectedFilters={filters}
|
||||
loading={loading}
|
||||
onChangeFilters={onChangeFilters}
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Tooltip } from '@components';
|
||||
import ViewDayOutlinedIcon from '@mui/icons-material/ViewDayOutlined';
|
||||
import ViewHeadlineOutlinedIcon from '@mui/icons-material/ViewHeadlineOutlined';
|
||||
import { Pagination, Typography } from 'antd';
|
||||
import { colors } from '@components';
|
||||
import { Pagination } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import styled from 'styled-components/macro';
|
||||
|
||||
@ -10,29 +8,22 @@ import { EntityAndType } from '@app/entity/shared/types';
|
||||
import { isListSubset } from '@app/entity/shared/utils';
|
||||
import { SearchSelectBar } from '@app/entityV2/shared/components/styled/search/SearchSelectBar';
|
||||
import { ANTD_GRAY } from '@app/entityV2/shared/constants';
|
||||
import { useSearchContext } from '@app/search/context/SearchContext';
|
||||
import { SearchEntitySidebarContainer } from '@app/searchV2/SearchEntitySidebarContainer';
|
||||
import { SearchResultList } from '@app/searchV2/SearchResultList';
|
||||
import SearchResultsLoadingSection from '@app/searchV2/SearchResultsLoadingSection';
|
||||
import { RecommendedFilters } from '@app/searchV2/recommendation/RecommendedFilters';
|
||||
import BrowseSidebar from '@app/searchV2/sidebar';
|
||||
import { BrowseProvider } from '@app/searchV2/sidebar/BrowseContext';
|
||||
import { SidebarProvider } from '@app/searchV2/sidebar/SidebarContext';
|
||||
import SearchSortSelect from '@app/searchV2/sorting/SearchSortSelect';
|
||||
import SearchQuerySuggester from '@app/searchV2/suggestions/SearchQuerySugggester';
|
||||
import { useIsBrowseV2, useIsSearchV2 } from '@app/searchV2/useSearchAndBrowseVersion';
|
||||
import { combineSiblingsInSearchResults } from '@app/searchV2/utils/combineSiblingsInSearchResults';
|
||||
import { UnionType } from '@app/searchV2/utils/constants';
|
||||
import { generateOrFilters } from '@app/searchV2/utils/generateOrFilters';
|
||||
import { DownloadSearchResults, DownloadSearchResultsInput } from '@app/searchV2/utils/types';
|
||||
import { ErrorSection } from '@app/shared/error/ErrorSection';
|
||||
import { formatNumberWithoutAbbreviation } from '@app/shared/formatNumber';
|
||||
import SearchMenuItems from '@app/sharedV2/search/SearchMenuItems';
|
||||
import { useIsShowSeparateSiblingsEnabled } from '@app/useAppConfig';
|
||||
import { useShowNavBarRedesign } from '@app/useShowNavBarRedesign';
|
||||
import { SearchCfg } from '@src/conf';
|
||||
|
||||
import { Entity, FacetFilterInput, FacetMetadata, MatchedField, SearchSuggestion } from '@types';
|
||||
import { Entity, FacetFilterInput, MatchedField, SearchSuggestion } from '@types';
|
||||
|
||||
const SearchResultsWrapper = styled.div<{ v2Styles: boolean }>`
|
||||
display: flex;
|
||||
@ -69,15 +60,12 @@ const ResultContainer = styled.div<{ v2Styles: boolean }>`
|
||||
`;
|
||||
|
||||
const PaginationControlContainer = styled.div`
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
text-align: start;
|
||||
`;
|
||||
|
||||
const PaginationInfoContainer = styled.div<{ v2Styles: boolean }>`
|
||||
padding: 12px 24px 14px 24px;
|
||||
min-height: 47px;
|
||||
border-color: ${(props) => props.theme.styles['border-color-base']};
|
||||
padding: 4px 8px 4px 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@ -97,7 +85,8 @@ const SearchResultsScrollContainer = styled.div<{ $isShowNavBarRedesign?: boolea
|
||||
|
||||
const LeftControlsContainer = styled.div`
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
color: ${colors.gray[1700]};
|
||||
gap: 4px;
|
||||
`;
|
||||
|
||||
const StyledTabToolbar = styled.div`
|
||||
@ -111,11 +100,6 @@ const StyledTabToolbar = styled.div`
|
||||
border: 1.5px solid ${ANTD_GRAY[4]};
|
||||
`;
|
||||
|
||||
const SearchMenuContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const SearchResultListContainer = styled.div<{ v2Styles: boolean; $isShowNavBarRedesign?: boolean }>`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -130,41 +114,9 @@ const SearchResultListContainer = styled.div<{ v2Styles: boolean; $isShowNavBarR
|
||||
margin: ${(props) => (props.$isShowNavBarRedesign ? '5px 4px 5px 0px' : '4px 12px 4px 0px')};
|
||||
`;
|
||||
|
||||
const CustomSwitch = styled.div`
|
||||
background: #F6F6F6;
|
||||
border: 1px solid #EBECF0;
|
||||
border-radius: 30px;
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
align-items: center;
|
||||
padding: 2px;
|
||||
width: fit-content;
|
||||
justify-content: space-between;
|
||||
margin-left: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
const IconContainer = styled.div<{ isActive?: boolean }>`
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
transition: left 0.5s ease;
|
||||
|
||||
${(props) =>
|
||||
props.isActive &&
|
||||
`
|
||||
background: ${props.theme.styles['primary-color']};
|
||||
border-radius: 100%;
|
||||
color: white;
|
||||
`}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
loading: boolean;
|
||||
unionType?: UnionType;
|
||||
query: string;
|
||||
viewUrn?: string;
|
||||
page: number;
|
||||
searchResponse?: {
|
||||
start: number;
|
||||
@ -175,12 +127,10 @@ interface Props {
|
||||
matchedFields: MatchedField[];
|
||||
}[];
|
||||
} | null;
|
||||
availableFilters: Array<FacetMetadata> | null;
|
||||
selectedFilters: Array<FacetFilterInput>;
|
||||
error: any;
|
||||
onChangeFilters: (filters: Array<FacetFilterInput>) => void;
|
||||
onChangePage: (page: number) => void;
|
||||
downloadSearchResults: (input: DownloadSearchResultsInput) => Promise<DownloadSearchResults | null | undefined>;
|
||||
numResultsPerPage: number;
|
||||
setNumResultsPerPage: (numResults: number) => void;
|
||||
isSelectMode: boolean;
|
||||
@ -198,26 +148,22 @@ interface Props {
|
||||
|
||||
export const SearchResults = ({
|
||||
loading,
|
||||
unionType = UnionType.AND,
|
||||
query,
|
||||
viewUrn,
|
||||
page,
|
||||
searchResponse,
|
||||
availableFilters,
|
||||
selectedFilters,
|
||||
error,
|
||||
onChangeFilters,
|
||||
onChangePage,
|
||||
downloadSearchResults,
|
||||
numResultsPerPage,
|
||||
setNumResultsPerPage,
|
||||
isSelectMode,
|
||||
selectedEntities,
|
||||
suggestions,
|
||||
setSelectedEntities,
|
||||
areAllEntitiesSelected,
|
||||
setAreAllEntitiesSelected,
|
||||
suggestions,
|
||||
setIsSelectMode,
|
||||
setSelectedEntities,
|
||||
onChangeSelectAll,
|
||||
refetch,
|
||||
previewType,
|
||||
@ -235,10 +181,8 @@ export const SearchResults = ({
|
||||
showSeparateSiblings,
|
||||
searchResponse?.searchResults,
|
||||
);
|
||||
const { selectedSortOption, setSelectedSortOption } = useSearchContext();
|
||||
// For vertical sidebar
|
||||
const [highlightedIndex, setHighlightedIndex] = useState<number | null>(0);
|
||||
const { isFullViewCard, setIsFullViewCard } = useSearchContext();
|
||||
|
||||
const searchResultUrns = combinedSiblingSearchResults.map((result) => result.entity.urn) || [];
|
||||
const selectedEntityUrns = selectedEntities.map((entity) => entity.urn);
|
||||
@ -279,70 +223,8 @@ export const SearchResults = ({
|
||||
v2Styles={showSearchFiltersV2}
|
||||
$isShowNavBarRedesign={isShowNavBarRedesign}
|
||||
>
|
||||
<PaginationInfoContainer v2Styles={showSearchFiltersV2}>
|
||||
<LeftControlsContainer>
|
||||
<Typography.Text>
|
||||
Showing{' '}
|
||||
<b>
|
||||
{lastResultIndex > 0 ? (page - 1) * pageSize + 1 : 0} -{' '}
|
||||
{lastResultIndex}
|
||||
</b>{' '}
|
||||
of{' '}
|
||||
<b>
|
||||
{totalResults >= 10000
|
||||
? `${formatNumberWithoutAbbreviation(10000)}+`
|
||||
: formatNumberWithoutAbbreviation(totalResults)}
|
||||
</b>{' '}
|
||||
results
|
||||
</Typography.Text>
|
||||
</LeftControlsContainer>
|
||||
<SearchMenuContainer>
|
||||
<SearchSortSelect
|
||||
selectedSortOption={selectedSortOption}
|
||||
setSelectedSortOption={setSelectedSortOption}
|
||||
/>
|
||||
<SearchMenuItems
|
||||
downloadSearchResults={downloadSearchResults}
|
||||
filters={generateOrFilters(unionType, selectedFilters)}
|
||||
query={query}
|
||||
viewUrn={viewUrn}
|
||||
setShowSelectMode={setIsSelectMode}
|
||||
totalResults={totalResults}
|
||||
/>
|
||||
<CustomSwitch>
|
||||
<IconContainer
|
||||
isActive={isFullViewCard}
|
||||
onClick={() => setIsFullViewCard(true)}
|
||||
>
|
||||
<Tooltip showArrow={false} title="Full Card View">
|
||||
<ViewDayOutlinedIcon
|
||||
style={{
|
||||
fontSize: '16px',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</IconContainer>
|
||||
<IconContainer
|
||||
isActive={!isFullViewCard}
|
||||
onClick={() => setIsFullViewCard(false)}
|
||||
>
|
||||
<Tooltip showArrow={false} title="Compact Card View">
|
||||
<ViewHeadlineOutlinedIcon
|
||||
style={{
|
||||
fontSize: '16px',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</IconContainer>
|
||||
</CustomSwitch>
|
||||
</SearchMenuContainer>
|
||||
</PaginationInfoContainer>
|
||||
{totalResults > 0 && <SearchQuerySuggester suggestions={suggestions} />}
|
||||
<RecommendedFilters
|
||||
availableFilters={availableFilters || []}
|
||||
selectedFilters={selectedFilters}
|
||||
onChangeFilters={onChangeFilters}
|
||||
/>
|
||||
|
||||
{isSelectMode && (
|
||||
<StyledTabToolbar>
|
||||
<SearchSelectBar
|
||||
@ -361,6 +243,22 @@ export const SearchResults = ({
|
||||
/>
|
||||
</StyledTabToolbar>
|
||||
)}
|
||||
<PaginationInfoContainer v2Styles={showSearchFiltersV2}>
|
||||
<LeftControlsContainer>
|
||||
Showing{' '}
|
||||
<b>
|
||||
{lastResultIndex > 0 ? (page - 1) * pageSize + 1 : 0} -{' '}
|
||||
{lastResultIndex}
|
||||
</b>{' '}
|
||||
of{' '}
|
||||
<b>
|
||||
{totalResults >= 10000
|
||||
? `${formatNumberWithoutAbbreviation(10000)}+`
|
||||
: formatNumberWithoutAbbreviation(totalResults)}
|
||||
</b>{' '}
|
||||
results
|
||||
</LeftControlsContainer>
|
||||
</PaginationInfoContainer>
|
||||
<SearchResultList
|
||||
setHighlightedIndex={setHighlightedIndex}
|
||||
highlightedIndex={highlightedIndex}
|
||||
|
@ -1,10 +1,7 @@
|
||||
import { SlidersOutlined } from '@ant-design/icons';
|
||||
import { Divider } from 'antd';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { useUserContext } from '@app/context/useUserContext';
|
||||
import { ANTD_GRAY } from '@app/entity/shared/constants';
|
||||
import MoreFilters from '@app/searchV2/filters/MoreFilters';
|
||||
import SaveViewButton from '@app/searchV2/filters/SaveViewButton';
|
||||
import SearchFilter from '@app/searchV2/filters/SearchFilter';
|
||||
@ -21,22 +18,6 @@ import { FacetFilterInput, FacetMetadata } from '@types';
|
||||
|
||||
const NUM_VISIBLE_FILTER_DROPDOWNS = 6;
|
||||
|
||||
const FiltersText = styled.div`
|
||||
font-size: 16px;
|
||||
color: ${ANTD_GRAY[8]};
|
||||
`;
|
||||
|
||||
const StyledSlidersOutlined = styled(SlidersOutlined)`
|
||||
margin-right: 8px;
|
||||
`;
|
||||
|
||||
const VerticalDivider = styled(Divider)`
|
||||
&& {
|
||||
padding: 12px 0px;
|
||||
margin: 0px 32px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const FlexWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@ -122,11 +103,6 @@ export default function SearchFilterOptions({
|
||||
return (
|
||||
<FlexSpacer>
|
||||
<FlexWrapper>
|
||||
<FiltersText>
|
||||
<StyledSlidersOutlined />
|
||||
Filters
|
||||
</FiltersText>
|
||||
<VerticalDivider type="vertical" />
|
||||
{loading && !visibleFilters?.length && <SearchFiltersLoadingSection />}
|
||||
{visibleFilters?.map((filter) => {
|
||||
return filterRendererRegistry.hasRenderer(filter.field) ? (
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { Icon, Tooltip, colors } from '@components';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { SEARCH_RESULTS_FILTERS_ID } from '@app/onboarding/config/SearchOnboardingConfig';
|
||||
import { useSearchContext } from '@app/search/context/SearchContext';
|
||||
import SearchFilterOptions from '@app/searchV2/filters/SearchFilterOptions';
|
||||
import SelectedSearchFilters from '@app/searchV2/filters/SelectedSearchFilters';
|
||||
import { RecommendedFilters } from '@app/searchV2/recommendation/RecommendedFilters';
|
||||
import { useGetRecommendedFilters } from '@app/searchV2/recommendation/useGetRecommendedFilters';
|
||||
import SearchSortSelect from '@app/searchV2/sorting/SearchSortSelect';
|
||||
import {
|
||||
BROWSE_PATH_V2_FILTER_NAME,
|
||||
COMPLETED_FORMS_COMPLETED_PROMPT_IDS_FILTER_NAME,
|
||||
@ -20,22 +25,62 @@ import {
|
||||
UnionType,
|
||||
VERIFIED_FORMS_FILTER_NAME,
|
||||
} from '@app/searchV2/utils/constants';
|
||||
import { generateOrFilters } from '@app/searchV2/utils/generateOrFilters';
|
||||
import { DownloadSearchResults, DownloadSearchResultsInput } from '@app/searchV2/utils/types';
|
||||
import SearchMenuItems from '@app/sharedV2/search/SearchMenuItems';
|
||||
import { useShowNavBarRedesign } from '@src/app/useShowNavBarRedesign';
|
||||
|
||||
import { FacetFilterInput, FacetMetadata } from '@types';
|
||||
|
||||
const Container = styled.div<{ $isShowNavBarRedesign?: boolean }>`
|
||||
background-color: #ffffff;
|
||||
background-color: ${colors.white};
|
||||
border-radius: ${(props) =>
|
||||
props.$isShowNavBarRedesign ? props.theme.styles['border-radius-navbar-redesign'] : '8px'};
|
||||
padding: 16px 24px 16px 32px;
|
||||
border: 1px solid #e8e8e8;
|
||||
padding: 16px 0px 8px 0px;
|
||||
border: 1px solid ${colors.gray[100]};
|
||||
box-shadow: ${(props) =>
|
||||
props.$isShowNavBarRedesign ? props.theme.styles['box-shadow-navbar-redesign'] : '0px 4px 10px 0px #a8a8a840'};
|
||||
`;
|
||||
|
||||
const FilterSpacer = styled.div`
|
||||
margin: 16px 0px;
|
||||
const FiltersContainerTop = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-bottom: 8px;
|
||||
`;
|
||||
|
||||
const CustomSwitch = styled.div`
|
||||
border: 1px solid ${colors.gray[100]};
|
||||
border-radius: 30px;
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
align-items: center;
|
||||
padding: 2px;
|
||||
width: fit-content;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
const IconContainer = styled.div<{ isActive?: boolean }>`
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
transition: left 0.5s ease;
|
||||
color: ${colors.gray[1800]};
|
||||
|
||||
${(props) =>
|
||||
props.isActive &&
|
||||
`
|
||||
background: ${colors.gray[100]};
|
||||
border-radius: 100%;
|
||||
color: ${colors.gray[1700]};
|
||||
`}
|
||||
`;
|
||||
|
||||
const SelectedFiltersContainer = styled.div`
|
||||
padding: 4px 16px 8px 16px;
|
||||
`;
|
||||
|
||||
// remove legacy filter options as well as new _index and browsePathV2 filter from dropdowns
|
||||
@ -56,6 +101,18 @@ const FILTERS_TO_REMOVE = [
|
||||
PROPOSED_SCHEMA_TAGS_FILTER_NAME,
|
||||
];
|
||||
|
||||
const ControlsContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
align-self: start;
|
||||
`;
|
||||
|
||||
const RecommendedFiltersContainer = styled.div`
|
||||
border-top: 1px solid ${colors.gray[100]};
|
||||
padding: 16px 16px 8px 16px;
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
loading: boolean;
|
||||
availableFilters: FacetMetadata[];
|
||||
@ -65,6 +122,11 @@ interface Props {
|
||||
onChangeFilters: (newFilters: FacetFilterInput[]) => void;
|
||||
onChangeUnionType: (unionType: UnionType) => void;
|
||||
onClearFilters: () => void;
|
||||
query: string;
|
||||
viewUrn?: string;
|
||||
totalResults?: number;
|
||||
setShowSelectMode?: (showSelectMode: boolean) => any;
|
||||
downloadSearchResults: (input: DownloadSearchResultsInput) => Promise<DownloadSearchResults | null | undefined>;
|
||||
}
|
||||
|
||||
export default function SearchFilters({
|
||||
@ -76,24 +138,58 @@ export default function SearchFilters({
|
||||
onChangeFilters,
|
||||
onChangeUnionType,
|
||||
onClearFilters,
|
||||
query,
|
||||
viewUrn,
|
||||
totalResults,
|
||||
setShowSelectMode,
|
||||
downloadSearchResults,
|
||||
}: Props) {
|
||||
const isShowNavBarRedesign = useShowNavBarRedesign();
|
||||
const { isFullViewCard, setIsFullViewCard, selectedSortOption, setSelectedSortOption } = useSearchContext();
|
||||
// Filter out the available filters if `basicFilters` is true
|
||||
const filteredFilters = (availableFilters || []).filter((f) => !FILTERS_TO_REMOVE.includes(f.field));
|
||||
const filters = basicFilters ? filteredFilters : availableFilters;
|
||||
const recommendedFilters = useGetRecommendedFilters(filters, activeFilters);
|
||||
|
||||
return (
|
||||
<Container id={SEARCH_RESULTS_FILTERS_ID} $isShowNavBarRedesign={isShowNavBarRedesign}>
|
||||
<SearchFilterOptions
|
||||
loading={loading}
|
||||
availableFilters={filters}
|
||||
activeFilters={activeFilters}
|
||||
unionType={unionType}
|
||||
onChangeFilters={onChangeFilters}
|
||||
/>
|
||||
<FiltersContainerTop>
|
||||
<SearchFilterOptions
|
||||
loading={loading}
|
||||
availableFilters={filters}
|
||||
activeFilters={activeFilters}
|
||||
unionType={unionType}
|
||||
onChangeFilters={onChangeFilters}
|
||||
/>
|
||||
<ControlsContainer>
|
||||
<SearchSortSelect
|
||||
selectedSortOption={selectedSortOption}
|
||||
setSelectedSortOption={setSelectedSortOption}
|
||||
/>
|
||||
<SearchMenuItems
|
||||
filters={generateOrFilters(unionType, activeFilters)}
|
||||
query={query}
|
||||
viewUrn={viewUrn}
|
||||
totalResults={totalResults || 0}
|
||||
setShowSelectMode={setShowSelectMode}
|
||||
downloadSearchResults={downloadSearchResults}
|
||||
/>
|
||||
<CustomSwitch>
|
||||
<IconContainer isActive={isFullViewCard} onClick={() => setIsFullViewCard(true)}>
|
||||
<Tooltip showArrow={false} title="Full Card View">
|
||||
<Icon icon="Rows" source="phosphor" size="md" />
|
||||
</Tooltip>
|
||||
</IconContainer>
|
||||
<IconContainer isActive={!isFullViewCard} onClick={() => setIsFullViewCard(false)}>
|
||||
<Tooltip showArrow={false} title="Compact Card View">
|
||||
<Icon icon="List" source="phosphor" size="md" />
|
||||
</Tooltip>
|
||||
</IconContainer>
|
||||
</CustomSwitch>
|
||||
</ControlsContainer>
|
||||
</FiltersContainerTop>
|
||||
{activeFilters.length > 0 && (
|
||||
<>
|
||||
<FilterSpacer />
|
||||
<SelectedFiltersContainer>
|
||||
<SelectedSearchFilters
|
||||
availableFilters={filters}
|
||||
selectedFilters={activeFilters}
|
||||
@ -103,7 +199,16 @@ export default function SearchFilters({
|
||||
onClearFilters={onClearFilters}
|
||||
showUnionType
|
||||
/>
|
||||
</>
|
||||
</SelectedFiltersContainer>
|
||||
)}
|
||||
{(totalResults || 0) > 0 && recommendedFilters.length > 0 && (
|
||||
<RecommendedFiltersContainer>
|
||||
<RecommendedFilters
|
||||
availableFilters={filters}
|
||||
selectedFilters={activeFilters}
|
||||
onChangeFilters={onChangeFilters}
|
||||
/>
|
||||
</RecommendedFiltersContainer>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
|
@ -4,6 +4,7 @@ import styled from 'styled-components';
|
||||
import { SEARCH_RESULTS_FILTERS_V2_INTRO } from '@app/onboarding/config/SearchOnboardingConfig';
|
||||
import SearchFilters from '@app/searchV2/filters/SearchFilters';
|
||||
import { UnionType } from '@app/searchV2/utils/constants';
|
||||
import { DownloadSearchResults, DownloadSearchResultsInput } from '@app/searchV2/utils/types';
|
||||
import { useShowNavBarRedesign } from '@src/app/useShowNavBarRedesign';
|
||||
|
||||
import { FacetFilterInput, FacetMetadata } from '@types';
|
||||
@ -26,6 +27,11 @@ interface Props {
|
||||
onChangeFilters: (newFilters: FacetFilterInput[]) => void;
|
||||
onClearFilters: () => void;
|
||||
onChangeUnionType: (unionType: UnionType) => void;
|
||||
query: string;
|
||||
viewUrn?: string;
|
||||
totalResults: number;
|
||||
setShowSelectMode?: (showSelectMode: boolean) => any;
|
||||
downloadSearchResults: (input: DownloadSearchResultsInput) => Promise<DownloadSearchResults | null | undefined>;
|
||||
}
|
||||
|
||||
export default function SearchFiltersSection({
|
||||
@ -36,6 +42,11 @@ export default function SearchFiltersSection({
|
||||
onChangeFilters,
|
||||
onClearFilters,
|
||||
onChangeUnionType,
|
||||
query,
|
||||
viewUrn,
|
||||
totalResults,
|
||||
setShowSelectMode,
|
||||
downloadSearchResults,
|
||||
}: Props) {
|
||||
const [finalAvailableFilters, setFinalAvailableFilters] = useState(availableFilters);
|
||||
const isShowNavBarRedesign = useShowNavBarRedesign();
|
||||
@ -61,8 +72,13 @@ export default function SearchFiltersSection({
|
||||
activeFilters={activeFilters}
|
||||
unionType={unionType}
|
||||
onChangeFilters={onChangeFilters}
|
||||
onChangeUnionType={onChangeUnionType}
|
||||
onClearFilters={onClearFilters}
|
||||
onChangeUnionType={onChangeUnionType}
|
||||
query={query}
|
||||
viewUrn={viewUrn}
|
||||
totalResults={totalResults}
|
||||
setShowSelectMode={setShowSelectMode}
|
||||
downloadSearchResults={downloadSearchResults}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
|
@ -1,40 +1,7 @@
|
||||
import { Tooltip } from '@components';
|
||||
import { Pill, Tooltip } from '@components';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { RecommendedFilter } from '@app/searchV2/recommendation/types';
|
||||
import { getFilterColor } from '@app/searchV2/recommendation/utils';
|
||||
|
||||
const Pill = styled.div<{ color: string }>`
|
||||
border-radius: 20px;
|
||||
padding: 6px 10px;
|
||||
background-color: white;
|
||||
margin-right: 0px;
|
||||
border: 2px solid white;
|
||||
:hover {
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
border-color: ${(props) => props.color};
|
||||
}
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: ${(props) => props.theme.styles['box-shadow']};
|
||||
`;
|
||||
|
||||
const Icon = styled.div`
|
||||
margin-right: 4px;
|
||||
&&&& {
|
||||
color: #ffffff;
|
||||
}
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const Text = styled.div`
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
filter: RecommendedFilter;
|
||||
@ -42,7 +9,11 @@ type Props = {
|
||||
};
|
||||
|
||||
export const FilterPill = ({ filter, onToggle }: Props) => {
|
||||
const color = getFilterColor(filter.field, filter.value);
|
||||
// Convert the color to a valid ColorValues enum value, defaulting to gray if not found
|
||||
|
||||
// Convert ReactNode label to string
|
||||
const labelString = typeof filter.label === 'string' ? filter.label : filter.label?.toString() || '';
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
showArrow={false}
|
||||
@ -53,10 +24,14 @@ export const FilterPill = ({ filter, onToggle }: Props) => {
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Pill onClick={onToggle} color={color}>
|
||||
{filter.icon && <Icon>{filter.icon}</Icon>}
|
||||
<Text>{filter.label}</Text>
|
||||
</Pill>
|
||||
<Pill
|
||||
label={labelString}
|
||||
customIconRenderer={() => filter.icon}
|
||||
color="gray"
|
||||
variant="outline"
|
||||
clickable
|
||||
onPillClick={onToggle}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
@ -10,9 +10,6 @@ import { FacetFilterInput, FacetMetadata, FilterOperator } from '@types';
|
||||
const FilterPills = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 8px;
|
||||
margin-left: 20px;
|
||||
padding-right: 20px;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
overflow-x: auto;
|
||||
@ -21,8 +18,6 @@ const FilterPills = styled.div`
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
mask-image: linear-gradient(to right, rgba(0, 0, 0, 1) 95%, rgba(255, 0, 0, 0.5) 100%, rgba(255, 0, 0, 0) 100%);
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from '@components';
|
||||
import { Button, Tooltip, colors } from '@components';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledButton = styled(Button)`
|
||||
height: 28px;
|
||||
margin: 0px 4px 0px 4px;
|
||||
border: 1px solid ${colors.gray[100]};
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
@ -17,8 +15,16 @@ type Props = {
|
||||
export default function DownloadButton({ setShowDownloadAsCsvModal, isDownloadingCsv, disabled }: Props) {
|
||||
return (
|
||||
<Tooltip title="Download results..." showArrow={false} placement="top">
|
||||
<StyledButton onClick={() => setShowDownloadAsCsvModal(true)} disabled={isDownloadingCsv || disabled}>
|
||||
<DownloadOutlined />
|
||||
<StyledButton
|
||||
onClick={() => setShowDownloadAsCsvModal(true)}
|
||||
disabled={isDownloadingCsv || disabled}
|
||||
isCircle
|
||||
icon={{ icon: 'DownloadSimple', source: 'phosphor' }}
|
||||
variant="text"
|
||||
color="gray"
|
||||
size="sm"
|
||||
data-testid="download-csv-button"
|
||||
>
|
||||
{isDownloadingCsv ? 'Downloading...' : null}
|
||||
</StyledButton>
|
||||
</Tooltip>
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { EditOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from '@components';
|
||||
import { Button, Tooltip, colors } from '@components';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledButton = styled(Button)`
|
||||
height: 28px;
|
||||
margin: 0px 4px 0px 4px;
|
||||
border: 1px solid ${colors.gray[100]};
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
@ -20,9 +18,12 @@ export default function EditButton({ setShowSelectMode, disabled }: Props) {
|
||||
onClick={() => setShowSelectMode(true)}
|
||||
disabled={disabled}
|
||||
data-testid="search-results-edit-button"
|
||||
>
|
||||
<EditOutlined />
|
||||
</StyledButton>
|
||||
isCircle
|
||||
icon={{ icon: 'PencilSimple', source: 'phosphor' }}
|
||||
variant="text"
|
||||
color="gray"
|
||||
size="sm"
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ const third_degree_plus = [
|
||||
];
|
||||
const downloadCsvFile = (filename) => {
|
||||
cy.get(".ant-list-items").should("be.visible");
|
||||
cy.get(".anticon-download").should("be.visible").click();
|
||||
cy.get('[data-testid="download-csv-button"]').should("be.visible").click();
|
||||
cy.get('[data-testid="download-as-csv-input"]').clear().type(filename);
|
||||
cy.get('[data-testid="csv-modal-download-button"]').click().wait(5000);
|
||||
cy.ensureTextNotPresent("Creating CSV");
|
||||
|
Loading…
x
Reference in New Issue
Block a user