Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ui): Refactor the Glossary Related Entities, Tag Profiles to use search filters instead of query API. #6352

@@ -1,6 +1,7 @@
import React from 'react';
import { useEntityData } from '../shared/EntityContext';
import { EmbeddedListSearchSection } from '../shared/components/styled/search/EmbeddedListSearchSection';
import { UnionType } from '../../search/utils/constants';

export const ContainerEntitiesTab = () => {
const { urn } = useEntityData();
Expand All @@ -12,7 +13,10 @@ export const ContainerEntitiesTab = () => {

return (
<EmbeddedListSearchSection
fixedFilter={fixedFilter}
fixedFilters={{
unionType: UnionType.AND,
filters: [fixedFilter],
}}
emptySearchQuery="*"
placeholderText="Filter container entities..."
/>
Expand Down
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { useEntityData } from '../shared/EntityContext';
import { EntityType } from '../../../types.generated';
import { EmbeddedListSearchSection } from '../shared/components/styled/search/EmbeddedListSearchSection';
import { UnionType } from '../../search/utils/constants';

export const DomainEntitiesTab = () => {
const { urn, entityType } = useEntityData();
Expand All @@ -17,7 +18,10 @@ export const DomainEntitiesTab = () => {

return (
<EmbeddedListSearchSection
fixedFilter={fixedFilter}
fixedFilters={{
unionType: UnionType.AND,
filters: [fixedFilter],
}}
emptySearchQuery="*"
placeholderText="Filter domain entities..."
/>
Expand Down
@@ -1,20 +1,49 @@
import * as React from 'react';
import { UnionType } from '../../../search/utils/constants';
import { EmbeddedListSearchSection } from '../../shared/components/styled/search/EmbeddedListSearchSection';

import { useEntityData } from '../../shared/EntityContext';

export default function GlossaryRelatedEntity() {
const { entityData }: any = useEntityData();
const glossaryTermHierarchicalName = entityData?.hierarchicalName;
let fixedQueryString = `glossaryTerms:"${glossaryTermHierarchicalName}" OR fieldGlossaryTerms:"${glossaryTermHierarchicalName}" OR editedFieldGlossaryTerms:"${glossaryTermHierarchicalName}"`;

const entityUrn = entityData?.urn;

const fixedOrFilters =
(entityUrn && [
{
field: 'glossaryTerms',
values: [entityUrn],
},
{
field: 'fieldGlossaryTerms',
values: [entityUrn],
},
]) ||
[];

entityData?.isAChildren?.relationships.forEach((term) => {
const name = term.entity?.hierarchicalName;
fixedQueryString += `OR glossaryTerms:"${name}" OR fieldGlossaryTerms:"${name}" OR editedFieldGlossaryTerms:"${name}"`;
const childUrn = term.entity?.urn;

if (childUrn) {
fixedOrFilters.push({
field: 'glossaryTerms',
values: [childUrn],
});

fixedOrFilters.push({
field: 'fieldGlossaryTerms',
values: [childUrn],
});
}
});

return (
<EmbeddedListSearchSection
fixedQuery={fixedQueryString}
fixedFilters={{
unionType: UnionType.OR,
filters: fixedOrFilters,
}}
emptySearchQuery="*"
placeholderText="Filter entities..."
/>
Expand Down
6 changes: 5 additions & 1 deletion datahub-web-react/src/app/entity/group/GroupAssets.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import styled from 'styled-components';
import { UnionType } from '../../search/utils/constants';
import { EmbeddedListSearchSection } from '../shared/components/styled/search/EmbeddedListSearchSection';

const GroupAssetsWrapper = styled.div`
Expand All @@ -14,7 +15,10 @@ export const GroupAssets = ({ urn }: Props) => {
return (
<GroupAssetsWrapper>
<EmbeddedListSearchSection
fixedFilter={{ field: 'owners', values: [urn] }}
fixedFilters={{
unionType: UnionType.AND,
filters: [{ field: 'owners', values: [urn] }],
}}
emptySearchQuery="*"
placeholderText="Filter entities..."
/>
Expand Down
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { Button, Input, Modal } from 'antd';
import { useLocation } from 'react-router';

import { EntityType, FacetFilterInput, SearchAcrossEntitiesInput } from '../../../../../../types.generated';
import { EntityType, OrFilter, SearchAcrossEntitiesInput } from '../../../../../../types.generated';
import { SearchResultsInterface } from './types';
import { getSearchCsvDownloadHeader, transformResultsToCsvRow } from './downloadAsCsvUtil';
import { downloadRowsAsCsv } from '../../../../../search/utils/csvUtils';
Expand All @@ -15,7 +15,7 @@ type Props = {
input: SearchAcrossEntitiesInput;
}) => Promise<SearchResultsInterface | null | undefined>;
entityFilters: EntityType[];
filters: FacetFilterInput[];
filters: OrFilter[];
query: string;
setIsDownloadingCsv: (isDownloadingCsv: boolean) => any;
showDownloadAsCsvModal: boolean;
Expand Down Expand Up @@ -63,7 +63,7 @@ export default function DownloadAsCsvModal({
query,
start: SEARCH_PAGE_SIZE_FOR_DOWNLOAD * downloadPage,
count: SEARCH_PAGE_SIZE_FOR_DOWNLOAD,
filters,
orFilters: filters,
},
}).then((refetchData) => {
console.log('fetched data for page number ', downloadPage);
Expand Down
@@ -1,17 +1,18 @@
import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import { ApolloError } from '@apollo/client';
import { EntityType, FacetFilterInput } from '../../../../../../types.generated';
import { EntityType, FacetFilterInput, FacetMetadata } from '../../../../../../types.generated';
import { ENTITY_FILTER_NAME, UnionType } from '../../../../../search/utils/constants';
import { SearchCfg } from '../../../../../../conf';
import { EmbeddedListSearchResults } from './EmbeddedListSearchResults';
import EmbeddedListSearchHeader from './EmbeddedListSearchHeader';
import { useGetSearchResultsForMultipleQuery } from '../../../../../../graphql/search.generated';
import { GetSearchResultsParams, SearchResultsInterface } from './types';
import { FilterSet, GetSearchResultsParams, SearchResultsInterface } from './types';
import { isListSubset } from '../../../utils';
import { EntityAndType } from '../../../types';
import { Message } from '../../../../../shared/Message';
import { generateOrFilters } from '../../../../../search/utils/generateOrFilters';
import { mergeFilterSets } from '../../../../../search/utils/filterUtils';

const Container = styled.div`
display: flex;
Expand All @@ -31,6 +32,7 @@ function useWrappedSearchResults(params: GetSearchResultsParams) {
refetch(refetchParams).then((res) => res.data.searchAcrossEntities),
};
}

// the addFixedQuery checks and generate the query as per params pass to embeddedListSearch
export const addFixedQuery = (baseQuery: string, fixedQuery: string, emptyQuery: string) => {
let finalQuery = ``;
Expand All @@ -46,6 +48,13 @@ export const addFixedQuery = (baseQuery: string, fixedQuery: string, emptyQuery:
return finalQuery;
};

// Simply remove the fields that were marked as fixed from the facets that the server
// responds.
export const removeFixedFiltersFromFacets = (fixedFilters: FilterSet, facets: FacetMetadata[]) => {
const fixedFields = fixedFilters.filters.map((filter) => filter.field);
return facets.filter((facet) => !fixedFields.includes(facet.field));
};

type Props = {
query: string;
page: number;
Expand All @@ -56,7 +65,7 @@ type Props = {
onChangePage: (page) => void;
onChangeUnionType: (unionType: UnionType) => void;
emptySearchQuery?: string | null;
fixedFilter?: FacetFilterInput | null;
fixedFilters?: FilterSet;
fixedQuery?: string | null;
placeholderText?: string | null;
defaultShowFilters?: boolean;
Expand All @@ -81,7 +90,7 @@ export const EmbeddedListSearch = ({
onChangePage,
onChangeUnionType,
emptySearchQuery,
fixedFilter,
fixedFilters,
fixedQuery,
placeholderText,
defaultShowFilters,
Expand All @@ -97,7 +106,16 @@ export const EmbeddedListSearch = ({
const filtersWithoutEntities: Array<FacetFilterInput> = filters.filter(
(filter) => filter.field !== ENTITY_FILTER_NAME,
);
const finalFilters = (fixedFilter && [...filtersWithoutEntities, fixedFilter]) || filtersWithoutEntities;

const baseFilters = {
unionType,
filters: filtersWithoutEntities,
};

const finalFilters =
(fixedFilters && mergeFilterSets(fixedFilters, baseFilters)) ||
generateOrFilters(unionType, filtersWithoutEntities);

const entityFilters: Array<EntityType> = filters
.filter((filter) => filter.field === ENTITY_FILTER_NAME)
.flatMap((filter) => filter.values?.map((value) => value?.toUpperCase() as EntityType) || []);
Expand All @@ -114,8 +132,7 @@ export const EmbeddedListSearch = ({
query: finalQuery,
start: (page - 1) * SearchCfg.RESULTS_PER_PAGE,
count: SearchCfg.RESULTS_PER_PAGE,
filters: [],
orFilters: generateOrFilters(unionType, finalFilters),
orFilters: finalFilters,
},
},
skip: true,
Expand All @@ -132,8 +149,7 @@ export const EmbeddedListSearch = ({
query: finalQuery,
start: (page - 1) * numResultsPerPage,
count: numResultsPerPage,
filters: [],
orFilters: generateOrFilters(unionType, finalFilters),
orFilters: finalFilters,
},
},
});
Expand Down Expand Up @@ -183,8 +199,13 @@ export const EmbeddedListSearch = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// Filter out the persistent filter values
const filteredFilters = data?.facets?.filter((facet) => facet.field !== fixedFilter?.field) || [];
/**
* Compute the final Facet fields that we show in the left hand search Filters (aggregation).
*
* Do this by filtering out any fields that are included in the fixed filters.
*/
const finalFacets =
(fixedFilters && removeFixedFiltersFromFacets(fixedFilters, data?.facets || [])) || data?.facets;

return (
<Container>
Expand All @@ -210,7 +231,7 @@ export const EmbeddedListSearch = ({
unionType={unionType}
loading={loading}
searchResponse={data}
filters={filteredFilters}
filters={finalFacets}
selectedFilters={filters}
onChangeFilters={onChangeFilters}
onChangePage={onChangePage}
Expand Down
Expand Up @@ -5,7 +5,7 @@ import styled from 'styled-components';
import TabToolbar from '../TabToolbar';
import { SearchBar } from '../../../../../search/SearchBar';
import { useEntityRegistry } from '../../../../../useEntityRegistry';
import { EntityType, FacetFilterInput, SearchAcrossEntitiesInput } from '../../../../../../types.generated';
import { EntityType, OrFilter, SearchAcrossEntitiesInput } from '../../../../../../types.generated';
import { SearchResultsInterface } from './types';
import SearchExtendedMenu from './SearchExtendedMenu';
import { SearchSelectBar } from './SearchSelectBar';
Expand Down Expand Up @@ -36,7 +36,7 @@ type Props = {
input: SearchAcrossEntitiesInput;
}) => Promise<SearchResultsInterface | null | undefined>;
entityFilters: EntityType[];
filters: FacetFilterInput[];
filters: OrFilter[];
query: string;
isSelectMode: boolean;
isSelectAll: boolean;
Expand Down Expand Up @@ -77,6 +77,7 @@ export default function EmbeddedListSearchHeader({
</Button>
<SearchAndDownloadContainer>
<SearchBar
data-testid="embedded-search-bar"
initialQuery=""
placeholderText={placeholderText || 'Search entities...'}
suggestions={[]}
Expand Down
Expand Up @@ -4,6 +4,7 @@ import styled from 'styled-components';
import { FacetFilterInput } from '../../../../../../types.generated';
import { EmbeddedListSearch } from './EmbeddedListSearch';
import { UnionType } from '../../../../../search/utils/constants';
import { FilterSet } from './types';

const SearchContainer = styled.div`
height: 500px;
Expand All @@ -18,7 +19,7 @@ const modalBodyStyle = {

type Props = {
emptySearchQuery?: string | null;
fixedFilter?: FacetFilterInput | null;
fixedFilters?: FilterSet;
fixedQuery?: string | null;
placeholderText?: string | null;
defaultShowFilters?: boolean;
Expand All @@ -30,7 +31,7 @@ type Props = {

export const EmbeddedListSearchModal = ({
emptySearchQuery,
fixedFilter,
fixedFilters,
fixedQuery,
placeholderText,
defaultShowFilters,
Expand Down Expand Up @@ -79,7 +80,7 @@ export const EmbeddedListSearchModal = ({
onChangePage={onChangePage}
onChangeUnionType={setUnionType}
emptySearchQuery={emptySearchQuery}
fixedFilter={fixedFilter}
fixedFilters={fixedFilters}
fixedQuery={fixedQuery}
placeholderText={placeholderText}
defaultShowFilters={defaultShowFilters}
Expand Down
Expand Up @@ -5,7 +5,7 @@ import { ApolloError } from '@apollo/client';
import { FacetFilterInput } from '../../../../../../types.generated';
import useFilters from '../../../../../search/utils/useFilters';
import { navigateToEntitySearchUrl } from './navigateToEntitySearchUrl';
import { GetSearchResultsParams, SearchResultsInterface } from './types';
import { FilterSet, GetSearchResultsParams, SearchResultsInterface } from './types';
import { useEntityQueryParams } from '../../../containers/profile/utils';
import { EmbeddedListSearch } from './EmbeddedListSearch';
import { UnionType } from '../../../../../search/utils/constants';
Expand All @@ -24,7 +24,7 @@ function getParamsWithoutFilters(params: QueryString.ParsedQuery<string>) {

type Props = {
emptySearchQuery?: string | null;
fixedFilter?: FacetFilterInput | null;
fixedFilters?: FilterSet;
fixedQuery?: string | null;
placeholderText?: string | null;
defaultShowFilters?: boolean;
Expand All @@ -41,7 +41,7 @@ type Props = {

export const EmbeddedListSearchSection = ({
emptySearchQuery,
fixedFilter,
fixedFilters,
fixedQuery,
placeholderText,
defaultShowFilters,
Expand Down Expand Up @@ -82,8 +82,8 @@ export const EmbeddedListSearchSection = ({
query,
page: 1,
filters: newFilters,
history,
unionType,
history,
});
};

Expand Down Expand Up @@ -122,7 +122,7 @@ export const EmbeddedListSearchSection = ({
onChangePage={onChangePage}
onChangeUnionType={onChangeUnionType}
emptySearchQuery={emptySearchQuery}
fixedFilter={fixedFilter}
fixedFilters={fixedFilters}
fixedQuery={fixedQuery}
placeholderText={placeholderText}
defaultShowFilters={defaultShowFilters}
Expand Down
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { Button, Dropdown, Menu } from 'antd';
import { FormOutlined, MoreOutlined } from '@ant-design/icons';
import styled from 'styled-components';
import { EntityType, FacetFilterInput, SearchAcrossEntitiesInput } from '../../../../../../types.generated';
import { EntityType, OrFilter, SearchAcrossEntitiesInput } from '../../../../../../types.generated';
import { SearchResultsInterface } from './types';
import DownloadAsCsvButton from './DownloadAsCsvButton';
import DownloadAsCsvModal from './DownloadAsCsvModal';
Expand All @@ -27,7 +27,7 @@ type Props = {
input: SearchAcrossEntitiesInput;
}) => Promise<SearchResultsInterface | null | undefined>;
entityFilters: EntityType[];
filters: FacetFilterInput[];
filters: OrFilter[];
query: string;
setShowSelectMode?: (showSelectMode: boolean) => any;
};
Expand Down