mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-07 06:46:35 +00:00
persist filters in url and selection
This commit is contained in:
parent
7c71be1d07
commit
fe11aa22d1
@ -50,6 +50,7 @@ const DataProductListPage = () => {
|
|||||||
// Use the simplified data product filters configuration
|
// Use the simplified data product filters configuration
|
||||||
const { quickFilters, defaultFilters } = useDataProductFilters({
|
const { quickFilters, defaultFilters } = useDataProductFilters({
|
||||||
aggregations: dataProductListing.aggregations || undefined,
|
aggregations: dataProductListing.aggregations || undefined,
|
||||||
|
parsedFilters: dataProductListing.parsedFilters,
|
||||||
onFilterChange: dataProductListing.handleFilterChange,
|
onFilterChange: dataProductListing.handleFilterChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ const DataProductListPage = () => {
|
|||||||
const { filterSelectionDisplay } = useFilterSelection({
|
const { filterSelectionDisplay } = useFilterSelection({
|
||||||
urlState: dataProductListing.urlState,
|
urlState: dataProductListing.urlState,
|
||||||
filterConfigs: defaultFilters,
|
filterConfigs: defaultFilters,
|
||||||
|
parsedFilters: dataProductListing.parsedFilters,
|
||||||
onFilterChange: dataProductListing.handleFilterChange,
|
onFilterChange: dataProductListing.handleFilterChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -13,7 +13,10 @@
|
|||||||
|
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { TABLE_CARD_PAGE_SIZE } from '../../../constants/constants';
|
import { TABLE_CARD_PAGE_SIZE } from '../../../constants/constants';
|
||||||
import { DATAPRODUCT_DEFAULT_QUICK_FILTERS } from '../../../constants/DataProduct.constants';
|
import {
|
||||||
|
DATAPRODUCT_DEFAULT_QUICK_FILTERS,
|
||||||
|
DATAPRODUCT_FILTERS,
|
||||||
|
} from '../../../constants/DataProduct.constants';
|
||||||
import { SearchIndex } from '../../../enums/search.enum';
|
import { SearchIndex } from '../../../enums/search.enum';
|
||||||
import { DataProduct } from '../../../generated/entity/domains/dataProduct';
|
import { DataProduct } from '../../../generated/entity/domains/dataProduct';
|
||||||
import { TagSource } from '../../../generated/type/tagLabel';
|
import { TagSource } from '../../../generated/type/tagLabel';
|
||||||
@ -26,6 +29,7 @@ import {
|
|||||||
|
|
||||||
export const useDataProductListingData = (): ListingData<DataProduct> => {
|
export const useDataProductListingData = (): ListingData<DataProduct> => {
|
||||||
const filterKeys = useMemo(() => DATAPRODUCT_DEFAULT_QUICK_FILTERS, []);
|
const filterKeys = useMemo(() => DATAPRODUCT_DEFAULT_QUICK_FILTERS, []);
|
||||||
|
const filterConfigs = useMemo(() => DATAPRODUCT_FILTERS, []);
|
||||||
|
|
||||||
const getGlossaryTags = useCallback(
|
const getGlossaryTags = useCallback(
|
||||||
(dataProduct: DataProduct) =>
|
(dataProduct: DataProduct) =>
|
||||||
@ -70,6 +74,7 @@ export const useDataProductListingData = (): ListingData<DataProduct> => {
|
|||||||
baseFilter: '', // No parent filter for data products
|
baseFilter: '', // No parent filter for data products
|
||||||
pageSize: TABLE_CARD_PAGE_SIZE,
|
pageSize: TABLE_CARD_PAGE_SIZE,
|
||||||
filterKeys,
|
filterKeys,
|
||||||
|
filterConfigs,
|
||||||
columns,
|
columns,
|
||||||
renderers,
|
renderers,
|
||||||
basePath: '/dataProduct',
|
basePath: '/dataProduct',
|
||||||
|
@ -88,7 +88,6 @@ import {
|
|||||||
getDomainDetailsPath,
|
getDomainDetailsPath,
|
||||||
getDomainPath,
|
getDomainPath,
|
||||||
getDomainVersionsPath,
|
getDomainVersionsPath,
|
||||||
getEntityDetailsPath,
|
|
||||||
} from '../../../utils/RouterUtils';
|
} from '../../../utils/RouterUtils';
|
||||||
import {
|
import {
|
||||||
escapeESReservedCharacters,
|
escapeESReservedCharacters,
|
||||||
@ -139,69 +138,71 @@ const DomainDetailsPage = ({
|
|||||||
const [subDomainForm] = Form.useForm();
|
const [subDomainForm] = Form.useForm();
|
||||||
const [isSubDomainLoading, setIsSubDomainLoading] = useState(false);
|
const [isSubDomainLoading, setIsSubDomainLoading] = useState(false);
|
||||||
|
|
||||||
const {
|
|
||||||
formDrawer: subDomainDrawer,
|
|
||||||
openDrawer: openSubDomainDrawer,
|
|
||||||
closeDrawer: closeSubDomainDrawer,
|
|
||||||
} = useFormDrawerWithRef({
|
|
||||||
title: t('label.add-entity', { entity: t('label.sub-domain') }),
|
|
||||||
anchor: 'right',
|
|
||||||
width: 670,
|
|
||||||
closeOnEscape: false,
|
|
||||||
form: (
|
|
||||||
<AddDomainForm
|
|
||||||
isFormInDialog
|
|
||||||
formRef={subDomainForm}
|
|
||||||
loading={isSubDomainLoading}
|
|
||||||
type={DomainFormType.SUBDOMAIN}
|
|
||||||
onCancel={() => {
|
|
||||||
// No-op: Drawer close is handled by useFormDrawerWithRef
|
|
||||||
}}
|
|
||||||
onSubmit={async (formData: any) => {
|
|
||||||
setIsSubDomainLoading(true);
|
|
||||||
try {
|
|
||||||
formData.parent = domain.fullyQualifiedName;
|
|
||||||
await addDomains(formData);
|
|
||||||
showSuccessToast(
|
|
||||||
t('server.create-entity-success', {
|
|
||||||
entity: t('label.sub-domain'),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
fetchSubDomainsCount();
|
|
||||||
// Navigate to the subdomains tab
|
|
||||||
handleTabChange(EntityTabs.SUBDOMAINS);
|
|
||||||
closeSubDomainDrawer();
|
|
||||||
} catch (error) {
|
|
||||||
showErrorToast(
|
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
|
||||||
? t('server.entity-already-exist', {
|
|
||||||
entity: t('label.sub-domain'),
|
|
||||||
entityPlural: 'sub-domains',
|
|
||||||
name: formData.name,
|
|
||||||
})
|
|
||||||
: (error as AxiosError),
|
|
||||||
t('server.add-entity-error', {
|
|
||||||
entity: t('label.sub-domain').toLowerCase(),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
setIsSubDomainLoading(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
formRef: subDomainForm,
|
|
||||||
onSubmit: () => {
|
|
||||||
// This is called by the drawer button, but actual submission
|
|
||||||
// happens via formRef.submit() which triggers form.onFinish
|
|
||||||
},
|
|
||||||
loading: isSubDomainLoading,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Data product drawer implementation
|
// Data product drawer implementation
|
||||||
const [dataProductForm] = Form.useForm();
|
const [dataProductForm] = Form.useForm();
|
||||||
const [isDataProductLoading, setIsDataProductLoading] = useState(false);
|
const [isDataProductLoading, setIsDataProductLoading] = useState(false);
|
||||||
|
|
||||||
|
const [showActions, setShowActions] = useState(false);
|
||||||
|
const [isDelete, setIsDelete] = useState<boolean>(false);
|
||||||
|
const [isNameEditing, setIsNameEditing] = useState<boolean>(false);
|
||||||
|
const [isStyleEditing, setIsStyleEditing] = useState(false);
|
||||||
|
const [previewAsset, setPreviewAsset] =
|
||||||
|
useState<EntityDetailsObjectInterface>();
|
||||||
|
const [assetCount, setAssetCount] = useState<number>(0);
|
||||||
|
const [dataProductsCount, setDataProductsCount] = useState<number>(0);
|
||||||
|
const [subDomainsCount, setSubDomainsCount] = useState<number>(0);
|
||||||
|
const encodedFqn = getEncodedFqn(
|
||||||
|
escapeESReservedCharacters(domain.fullyQualifiedName)
|
||||||
|
);
|
||||||
|
const { customizedPage, isLoading } = useCustomPages(PageType.Domain);
|
||||||
|
const [isTabExpanded, setIsTabExpanded] = useState(false);
|
||||||
|
const isSubDomain = useMemo(() => !isEmpty(domain.parent), [domain]);
|
||||||
|
|
||||||
|
const queryFilter = useMemo(() => {
|
||||||
|
return getQueryFilterForDomain(domainFqn);
|
||||||
|
}, [domainFqn]);
|
||||||
|
|
||||||
|
const isOwner = useMemo(
|
||||||
|
() => domain.owners?.some((owner) => isEqual(owner.id, currentUser?.id)),
|
||||||
|
[domain, currentUser]
|
||||||
|
);
|
||||||
|
|
||||||
|
const fetchDomainAssets = async () => {
|
||||||
|
if (domainFqn && !isVersionsView) {
|
||||||
|
try {
|
||||||
|
const res = await searchQuery({
|
||||||
|
query: '',
|
||||||
|
pageNumber: 0,
|
||||||
|
pageSize: 0,
|
||||||
|
queryFilter,
|
||||||
|
searchIndex: SearchIndex.ALL,
|
||||||
|
filters: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalCount = res?.hits?.total.value ?? 0;
|
||||||
|
setAssetCount(totalCount);
|
||||||
|
} catch (error) {
|
||||||
|
setAssetCount(0);
|
||||||
|
showErrorToast(
|
||||||
|
error as AxiosError,
|
||||||
|
t('server.entity-fetch-error', {
|
||||||
|
entity: t('label.asset-plural-lowercase'),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTabChange = (activeKey: string) => {
|
||||||
|
if (activeKey === 'assets') {
|
||||||
|
// refresh domain count when assets tab is selected
|
||||||
|
fetchDomainAssets();
|
||||||
|
}
|
||||||
|
if (activeKey !== activeTab) {
|
||||||
|
navigate(getDomainDetailsPath(domainFqn, activeKey));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
formDrawer: dataProductDrawer,
|
formDrawer: dataProductDrawer,
|
||||||
openDrawer: openDataProductDrawer,
|
openDrawer: openDataProductDrawer,
|
||||||
@ -221,11 +222,13 @@ const DomainDetailsPage = ({
|
|||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
// No-op: Drawer close is handled by useFormDrawerWithRef
|
// No-op: Drawer close is handled by useFormDrawerWithRef
|
||||||
}}
|
}}
|
||||||
onSubmit={async (formData: any) => {
|
onSubmit={async (formData: CreateDomain | CreateDataProduct) => {
|
||||||
setIsDataProductLoading(true);
|
setIsDataProductLoading(true);
|
||||||
try {
|
try {
|
||||||
formData.domains = [domain.fullyQualifiedName];
|
(formData as CreateDataProduct).domains = [
|
||||||
await addDataProducts(formData);
|
domain.fullyQualifiedName ?? '',
|
||||||
|
];
|
||||||
|
await addDataProducts(formData as CreateDataProduct);
|
||||||
showSuccessToast(
|
showSuccessToast(
|
||||||
t('server.create-entity-success', {
|
t('server.create-entity-success', {
|
||||||
entity: t('label.data-product'),
|
entity: t('label.data-product'),
|
||||||
@ -262,26 +265,6 @@ const DomainDetailsPage = ({
|
|||||||
},
|
},
|
||||||
loading: isDataProductLoading,
|
loading: isDataProductLoading,
|
||||||
});
|
});
|
||||||
const [showActions, setShowActions] = useState(false);
|
|
||||||
const [isDelete, setIsDelete] = useState<boolean>(false);
|
|
||||||
const [isNameEditing, setIsNameEditing] = useState<boolean>(false);
|
|
||||||
const [isStyleEditing, setIsStyleEditing] = useState(false);
|
|
||||||
const [previewAsset, setPreviewAsset] =
|
|
||||||
useState<EntityDetailsObjectInterface>();
|
|
||||||
const [assetCount, setAssetCount] = useState<number>(0);
|
|
||||||
const [dataProductsCount, setDataProductsCount] = useState<number>(0);
|
|
||||||
const [subDomainsCount, setSubDomainsCount] = useState<number>(0);
|
|
||||||
const encodedFqn = getEncodedFqn(
|
|
||||||
escapeESReservedCharacters(domain.fullyQualifiedName)
|
|
||||||
);
|
|
||||||
const { customizedPage, isLoading } = useCustomPages(PageType.Domain);
|
|
||||||
const [isTabExpanded, setIsTabExpanded] = useState(false);
|
|
||||||
const isSubDomain = useMemo(() => !isEmpty(domain.parent), [domain]);
|
|
||||||
|
|
||||||
const isOwner = useMemo(
|
|
||||||
() => domain.owners?.some((owner) => isEqual(owner.id, currentUser?.id)),
|
|
||||||
[domain, currentUser]
|
|
||||||
);
|
|
||||||
|
|
||||||
const breadcrumbs = useMemo(() => {
|
const breadcrumbs = useMemo(() => {
|
||||||
if (!domainFqn) {
|
if (!domainFqn) {
|
||||||
@ -328,6 +311,65 @@ const DomainDetailsPage = ({
|
|||||||
}
|
}
|
||||||
}, [domain, isVersionsView]);
|
}, [domain, isVersionsView]);
|
||||||
|
|
||||||
|
const {
|
||||||
|
formDrawer: subDomainDrawer,
|
||||||
|
openDrawer: openSubDomainDrawer,
|
||||||
|
closeDrawer: closeSubDomainDrawer,
|
||||||
|
} = useFormDrawerWithRef({
|
||||||
|
title: t('label.add-entity', { entity: t('label.sub-domain') }),
|
||||||
|
anchor: 'right',
|
||||||
|
width: 670,
|
||||||
|
closeOnEscape: false,
|
||||||
|
form: (
|
||||||
|
<AddDomainForm
|
||||||
|
isFormInDialog
|
||||||
|
formRef={subDomainForm}
|
||||||
|
loading={isSubDomainLoading}
|
||||||
|
type={DomainFormType.SUBDOMAIN}
|
||||||
|
onCancel={() => {
|
||||||
|
// No-op: Drawer close is handled by useFormDrawerWithRef
|
||||||
|
}}
|
||||||
|
onSubmit={async (formData: CreateDomain | CreateDataProduct) => {
|
||||||
|
setIsSubDomainLoading(true);
|
||||||
|
try {
|
||||||
|
(formData as CreateDomain).parent = domain.fullyQualifiedName;
|
||||||
|
await addDomains(formData as CreateDomain);
|
||||||
|
showSuccessToast(
|
||||||
|
t('server.create-entity-success', {
|
||||||
|
entity: t('label.sub-domain'),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
fetchSubDomainsCount();
|
||||||
|
// Navigate to the subdomains tab
|
||||||
|
handleTabChange(EntityTabs.SUBDOMAINS);
|
||||||
|
closeSubDomainDrawer();
|
||||||
|
} catch (error) {
|
||||||
|
showErrorToast(
|
||||||
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
|
? t('server.entity-already-exist', {
|
||||||
|
entity: t('label.sub-domain'),
|
||||||
|
entityPlural: 'sub-domains',
|
||||||
|
name: formData.name,
|
||||||
|
})
|
||||||
|
: (error as AxiosError),
|
||||||
|
t('server.add-entity-error', {
|
||||||
|
entity: t('label.sub-domain').toLowerCase(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsSubDomainLoading(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
formRef: subDomainForm,
|
||||||
|
onSubmit: () => {
|
||||||
|
// This is called by the drawer button, but actual submission
|
||||||
|
// happens via formRef.submit() which triggers form.onFinish
|
||||||
|
},
|
||||||
|
loading: isSubDomainLoading,
|
||||||
|
});
|
||||||
|
|
||||||
const editDisplayNamePermission = useMemo(() => {
|
const editDisplayNamePermission = useMemo(() => {
|
||||||
return getPrioritizedEditPermission(
|
return getPrioritizedEditPermission(
|
||||||
domainPermission,
|
domainPermission,
|
||||||
@ -420,45 +462,6 @@ const DomainDetailsPage = ({
|
|||||||
[domain, fetchSubDomainsCount]
|
[domain, fetchSubDomainsCount]
|
||||||
);
|
);
|
||||||
|
|
||||||
const addDataProduct = useCallback(
|
|
||||||
async (formData: CreateDataProduct | CreateDomain) => {
|
|
||||||
if (!domain.fullyQualifiedName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
...formData,
|
|
||||||
domains: [domain.fullyQualifiedName],
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await addDataProducts(data);
|
|
||||||
navigate(
|
|
||||||
getEntityDetailsPath(
|
|
||||||
EntityType.DATA_PRODUCT,
|
|
||||||
res.fullyQualifiedName ?? ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
showErrorToast(
|
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
|
||||||
? t('server.entity-already-exist', {
|
|
||||||
entity: t('label.sub-domain'),
|
|
||||||
entityPlural: t('label.sub-domain-lowercase-plural'),
|
|
||||||
name: data.name,
|
|
||||||
})
|
|
||||||
: (error as AxiosError),
|
|
||||||
t('server.add-entity-error', {
|
|
||||||
entity: t('label.sub-domain-lowercase'),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
closeDataProductDrawer();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[domain]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleVersionClick = async () => {
|
const handleVersionClick = async () => {
|
||||||
const path = isVersionsView
|
const path = isVersionsView
|
||||||
? getDomainPath(domainFqn)
|
? getDomainPath(domainFqn)
|
||||||
@ -493,32 +496,6 @@ const DomainDetailsPage = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchDomainAssets = async () => {
|
|
||||||
if (domainFqn && !isVersionsView) {
|
|
||||||
try {
|
|
||||||
const res = await searchQuery({
|
|
||||||
query: '',
|
|
||||||
pageNumber: 0,
|
|
||||||
pageSize: 0,
|
|
||||||
queryFilter,
|
|
||||||
searchIndex: SearchIndex.ALL,
|
|
||||||
filters: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const totalCount = res?.hits?.total.value ?? 0;
|
|
||||||
setAssetCount(totalCount);
|
|
||||||
} catch (error) {
|
|
||||||
setAssetCount(0);
|
|
||||||
showErrorToast(
|
|
||||||
error as AxiosError,
|
|
||||||
t('server.entity-fetch-error', {
|
|
||||||
entity: t('label.asset-plural-lowercase'),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchDomainPermission = async () => {
|
const fetchDomainPermission = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await getEntityPermission(
|
const response = await getEntityPermission(
|
||||||
@ -531,16 +508,6 @@ const DomainDetailsPage = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTabChange = (activeKey: string) => {
|
|
||||||
if (activeKey === 'assets') {
|
|
||||||
// refresh domain count when assets tab is selected
|
|
||||||
fetchDomainAssets();
|
|
||||||
}
|
|
||||||
if (activeKey !== activeTab) {
|
|
||||||
navigate(getDomainDetailsPath(domainFqn, activeKey));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onAddDataProduct = useCallback(() => {
|
const onAddDataProduct = useCallback(() => {
|
||||||
openDataProductDrawer();
|
openDataProductDrawer();
|
||||||
}, [openDataProductDrawer]);
|
}, [openDataProductDrawer]);
|
||||||
@ -658,10 +625,6 @@ const DomainDetailsPage = ({
|
|||||||
: []),
|
: []),
|
||||||
];
|
];
|
||||||
|
|
||||||
const queryFilter = useMemo(() => {
|
|
||||||
return getQueryFilterForDomain(domainFqn);
|
|
||||||
}, [domainFqn]);
|
|
||||||
|
|
||||||
const tabs = useMemo(() => {
|
const tabs = useMemo(() => {
|
||||||
const tabLabelMap = getTabLabelMapFromTabs(customizedPage?.tabs);
|
const tabLabelMap = getTabLabelMapFromTabs(customizedPage?.tabs);
|
||||||
|
|
||||||
|
@ -27,11 +27,7 @@ import { useDataTable } from '../../common/atoms/table/useDataTable';
|
|||||||
import { useSubdomainListingData } from './hooks/useSubdomainListingData';
|
import { useSubdomainListingData } from './hooks/useSubdomainListingData';
|
||||||
import { SubDomainsTableProps } from './SubDomainsTable.interface';
|
import { SubDomainsTableProps } from './SubDomainsTable.interface';
|
||||||
|
|
||||||
const SubDomainsTable = ({
|
const SubDomainsTable = ({ domainFqn }: SubDomainsTableProps) => {
|
||||||
domainFqn,
|
|
||||||
permissions,
|
|
||||||
onAddSubDomain,
|
|
||||||
}: SubDomainsTableProps) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const subdomainListing = useSubdomainListingData({
|
const subdomainListing = useSubdomainListingData({
|
||||||
@ -42,6 +38,7 @@ const SubDomainsTable = ({
|
|||||||
const { quickFilters, defaultFilters } = useDomainFilters({
|
const { quickFilters, defaultFilters } = useDomainFilters({
|
||||||
isSubDomain: true,
|
isSubDomain: true,
|
||||||
aggregations: subdomainListing.aggregations || undefined,
|
aggregations: subdomainListing.aggregations || undefined,
|
||||||
|
parsedFilters: subdomainListing.parsedFilters,
|
||||||
onFilterChange: subdomainListing.handleFilterChange,
|
onFilterChange: subdomainListing.handleFilterChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -49,6 +46,7 @@ const SubDomainsTable = ({
|
|||||||
const { filterSelectionDisplay } = useFilterSelection({
|
const { filterSelectionDisplay } = useFilterSelection({
|
||||||
urlState: subdomainListing.urlState,
|
urlState: subdomainListing.urlState,
|
||||||
filterConfigs: defaultFilters,
|
filterConfigs: defaultFilters,
|
||||||
|
parsedFilters: subdomainListing.parsedFilters,
|
||||||
onFilterChange: subdomainListing.handleFilterChange,
|
onFilterChange: subdomainListing.handleFilterChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -39,5 +39,6 @@ export const useSubdomainListingData = ({
|
|||||||
return useDomainListing({
|
return useDomainListing({
|
||||||
baseFilter: JSON.stringify(baseFilter),
|
baseFilter: JSON.stringify(baseFilter),
|
||||||
nameLabelKey: 'label.sub-domain',
|
nameLabelKey: 'label.sub-domain',
|
||||||
|
isSubDomain: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -50,6 +50,7 @@ const DomainListPage = () => {
|
|||||||
// Use the simplified domain filters configuration
|
// Use the simplified domain filters configuration
|
||||||
const { quickFilters, defaultFilters } = useDomainFilters({
|
const { quickFilters, defaultFilters } = useDomainFilters({
|
||||||
aggregations: domainListing.aggregations || undefined,
|
aggregations: domainListing.aggregations || undefined,
|
||||||
|
parsedFilters: domainListing.parsedFilters,
|
||||||
onFilterChange: domainListing.handleFilterChange,
|
onFilterChange: domainListing.handleFilterChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ const DomainListPage = () => {
|
|||||||
const { filterSelectionDisplay } = useFilterSelection({
|
const { filterSelectionDisplay } = useFilterSelection({
|
||||||
urlState: domainListing.urlState,
|
urlState: domainListing.urlState,
|
||||||
filterConfigs: defaultFilters,
|
filterConfigs: defaultFilters,
|
||||||
|
parsedFilters: domainListing.parsedFilters,
|
||||||
onFilterChange: domainListing.handleFilterChange,
|
onFilterChange: domainListing.handleFilterChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ interface UseListingDataProps<T> {
|
|||||||
baseFilter?: string;
|
baseFilter?: string;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
filterKeys: string[];
|
filterKeys: string[];
|
||||||
|
filterConfigs?: ExploreQuickFilterField[];
|
||||||
columns: ColumnConfig<T>[];
|
columns: ColumnConfig<T>[];
|
||||||
renderers?: CellRenderer<T>;
|
renderers?: CellRenderer<T>;
|
||||||
basePath?: string;
|
basePath?: string;
|
||||||
@ -46,6 +47,7 @@ export const useListingData = <
|
|||||||
baseFilter = '',
|
baseFilter = '',
|
||||||
pageSize = 10,
|
pageSize = 10,
|
||||||
filterKeys,
|
filterKeys,
|
||||||
|
filterConfigs,
|
||||||
columns,
|
columns,
|
||||||
renderers = {},
|
renderers = {},
|
||||||
basePath,
|
basePath,
|
||||||
@ -55,8 +57,14 @@ export const useListingData = <
|
|||||||
onCustomAddClick,
|
onCustomAddClick,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const urlStateHook = useUrlState({ filterKeys });
|
const urlStateHook = useUrlState({ filterKeys, filterConfigs });
|
||||||
const { urlState, setSearchQuery, setFilters, setCurrentPage } = urlStateHook;
|
const {
|
||||||
|
urlState,
|
||||||
|
parsedFilters,
|
||||||
|
setSearchQuery,
|
||||||
|
setFilters,
|
||||||
|
setCurrentPage,
|
||||||
|
} = urlStateHook;
|
||||||
|
|
||||||
const dataFetching = useDataFetching<T>({
|
const dataFetching = useDataFetching<T>({
|
||||||
searchIndex,
|
searchIndex,
|
||||||
@ -159,6 +167,7 @@ export const useListingData = <
|
|||||||
isSelected: selectionState.isSelected,
|
isSelected: selectionState.isSelected,
|
||||||
clearSelection: selectionState.clearSelection,
|
clearSelection: selectionState.clearSelection,
|
||||||
urlState,
|
urlState,
|
||||||
|
parsedFilters,
|
||||||
actionHandlers,
|
actionHandlers,
|
||||||
filterOptions: {},
|
filterOptions: {},
|
||||||
aggregations: getAggregations(dataFetching.aggregations || {}),
|
aggregations: getAggregations(dataFetching.aggregations || {}),
|
||||||
|
@ -16,10 +16,17 @@ import { useSearchParams } from 'react-router-dom';
|
|||||||
import { ExploreQuickFilterField } from '../../../Explore/ExplorePage.interface';
|
import { ExploreQuickFilterField } from '../../../Explore/ExplorePage.interface';
|
||||||
import { UrlState, UrlStateConfig, UrlStateHook } from '../shared/types';
|
import { UrlState, UrlStateConfig, UrlStateHook } from '../shared/types';
|
||||||
|
|
||||||
export const useUrlState = (config: UrlStateConfig): UrlStateHook => {
|
export const useUrlState = (
|
||||||
|
config: UrlStateConfig & { filterConfigs?: ExploreQuickFilterField[] }
|
||||||
|
): UrlStateHook => {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
const { searchKey = 'q', filterKeys, pageKey = 'page' } = config;
|
const {
|
||||||
|
searchKey = 'q',
|
||||||
|
filterKeys,
|
||||||
|
pageKey = 'page',
|
||||||
|
filterConfigs,
|
||||||
|
} = config;
|
||||||
|
|
||||||
const urlState: UrlState = useMemo(() => {
|
const urlState: UrlState = useMemo(() => {
|
||||||
const searchQuery = searchParams.get(searchKey) || '';
|
const searchQuery = searchParams.get(searchKey) || '';
|
||||||
@ -38,6 +45,21 @@ export const useUrlState = (config: UrlStateConfig): UrlStateHook => {
|
|||||||
};
|
};
|
||||||
}, [searchParams, searchKey, pageKey, filterKeys]);
|
}, [searchParams, searchKey, pageKey, filterKeys]);
|
||||||
|
|
||||||
|
const parsedFilters: ExploreQuickFilterField[] = useMemo(() => {
|
||||||
|
if (!filterConfigs) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterConfigs.map((filterConfig) => {
|
||||||
|
const values = urlState.filters[filterConfig.key] || [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...filterConfig,
|
||||||
|
value: values.map((v) => ({ key: v, label: v })),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [urlState.filters, filterConfigs]);
|
||||||
|
|
||||||
const updateUrlParams = useCallback(
|
const updateUrlParams = useCallback(
|
||||||
(updates: Record<string, string | null>) => {
|
(updates: Record<string, string | null>) => {
|
||||||
setSearchParams((current) => {
|
setSearchParams((current) => {
|
||||||
@ -125,6 +147,7 @@ export const useUrlState = (config: UrlStateConfig): UrlStateHook => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
urlState,
|
urlState,
|
||||||
|
parsedFilters,
|
||||||
setSearchQuery,
|
setSearchQuery,
|
||||||
setFilters,
|
setFilters,
|
||||||
setCurrentPage,
|
setCurrentPage,
|
||||||
|
@ -13,7 +13,12 @@
|
|||||||
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { TABLE_CARD_PAGE_SIZE } from '../../../../../constants/constants';
|
import { TABLE_CARD_PAGE_SIZE } from '../../../../../constants/constants';
|
||||||
import { DOMAIN_DEFAULT_QUICK_FILTERS } from '../../../../../constants/Domain.constants';
|
import {
|
||||||
|
DOMAIN_DEFAULT_QUICK_FILTERS,
|
||||||
|
DOMAIN_FILTERS,
|
||||||
|
SUBDOMAIN_DEFAULT_QUICK_FILTERS,
|
||||||
|
SUB_DOMAIN_FILTERS,
|
||||||
|
} from '../../../../../constants/Domain.constants';
|
||||||
import { SearchIndex } from '../../../../../enums/search.enum';
|
import { SearchIndex } from '../../../../../enums/search.enum';
|
||||||
import { Domain } from '../../../../../generated/entity/domains/domain';
|
import { Domain } from '../../../../../generated/entity/domains/domain';
|
||||||
import { useListingData } from '../../compositions/useListingData';
|
import { useListingData } from '../../compositions/useListingData';
|
||||||
@ -32,6 +37,7 @@ interface UseDomainListingConfig {
|
|||||||
includeClassificationTags?: boolean;
|
includeClassificationTags?: boolean;
|
||||||
customColumns?: ColumnConfig<Domain>[];
|
customColumns?: ColumnConfig<Domain>[];
|
||||||
customRenderers?: CellRenderer<Domain>;
|
customRenderers?: CellRenderer<Domain>;
|
||||||
|
isSubDomain?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDomainListing = (
|
export const useDomainListing = (
|
||||||
@ -48,6 +54,7 @@ export const useDomainListing = (
|
|||||||
includeClassificationTags = true,
|
includeClassificationTags = true,
|
||||||
customColumns = [],
|
customColumns = [],
|
||||||
customRenderers = {},
|
customRenderers = {},
|
||||||
|
isSubDomain = false,
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
// Memoize domain atom configurations to ensure stability (like DataProduct pattern)
|
// Memoize domain atom configurations to ensure stability (like DataProduct pattern)
|
||||||
@ -82,7 +89,17 @@ export const useDomainListing = (
|
|||||||
const { columns } = useDomainColumns(domainColumnsConfig);
|
const { columns } = useDomainColumns(domainColumnsConfig);
|
||||||
const { renderers } = useDomainRenderers(domainRenderersConfig);
|
const { renderers } = useDomainRenderers(domainRenderersConfig);
|
||||||
// Define filterKeys for domain filters
|
// Define filterKeys for domain filters
|
||||||
const filterKeys = useMemo(() => DOMAIN_DEFAULT_QUICK_FILTERS, []);
|
const filterKeys = useMemo(
|
||||||
|
() =>
|
||||||
|
isSubDomain
|
||||||
|
? SUBDOMAIN_DEFAULT_QUICK_FILTERS
|
||||||
|
: DOMAIN_DEFAULT_QUICK_FILTERS,
|
||||||
|
[isSubDomain]
|
||||||
|
);
|
||||||
|
const filterConfigs = useMemo(
|
||||||
|
() => (isSubDomain ? SUB_DOMAIN_FILTERS : DOMAIN_FILTERS),
|
||||||
|
[isSubDomain]
|
||||||
|
);
|
||||||
|
|
||||||
// Use generic listing composition with domain-specific configuration
|
// Use generic listing composition with domain-specific configuration
|
||||||
const listingData = useListingData<Domain>({
|
const listingData = useListingData<Domain>({
|
||||||
@ -90,6 +107,7 @@ export const useDomainListing = (
|
|||||||
baseFilter,
|
baseFilter,
|
||||||
pageSize,
|
pageSize,
|
||||||
filterKeys,
|
filterKeys,
|
||||||
|
filterConfigs,
|
||||||
columns,
|
columns,
|
||||||
renderers,
|
renderers,
|
||||||
basePath,
|
basePath,
|
||||||
|
@ -20,6 +20,7 @@ import { useQuickFiltersWithComponent } from '../../filters/useQuickFiltersWithC
|
|||||||
|
|
||||||
interface UseDataProductFiltersConfig {
|
interface UseDataProductFiltersConfig {
|
||||||
aggregations?: Aggregations;
|
aggregations?: Aggregations;
|
||||||
|
parsedFilters?: ExploreQuickFilterField[];
|
||||||
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ export const useDataProductFilters = (config: UseDataProductFiltersConfig) => {
|
|||||||
const { quickFilters, selectedFilters } = useQuickFiltersWithComponent({
|
const { quickFilters, selectedFilters } = useQuickFiltersWithComponent({
|
||||||
defaultFilters: DATAPRODUCT_FILTERS,
|
defaultFilters: DATAPRODUCT_FILTERS,
|
||||||
aggregations: config.aggregations,
|
aggregations: config.aggregations,
|
||||||
|
parsedFilters: config.parsedFilters,
|
||||||
searchIndex: SearchIndex.DATA_PRODUCT,
|
searchIndex: SearchIndex.DATA_PRODUCT,
|
||||||
assetType: AssetsOfEntity.DATA_PRODUCT,
|
assetType: AssetsOfEntity.DATA_PRODUCT,
|
||||||
onFilterChange: config.onFilterChange,
|
onFilterChange: config.onFilterChange,
|
||||||
|
@ -25,11 +25,12 @@ import { useQuickFiltersWithComponent } from '../../filters/useQuickFiltersWithC
|
|||||||
interface UseDomainFiltersConfig {
|
interface UseDomainFiltersConfig {
|
||||||
isSubDomain?: boolean;
|
isSubDomain?: boolean;
|
||||||
aggregations?: Aggregations;
|
aggregations?: Aggregations;
|
||||||
|
parsedFilters?: ExploreQuickFilterField[];
|
||||||
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDomainFilters = (config: UseDomainFiltersConfig) => {
|
export const useDomainFilters = (config: UseDomainFiltersConfig) => {
|
||||||
const { isSubDomain = false } = config;
|
const { isSubDomain = false, parsedFilters } = config;
|
||||||
|
|
||||||
const defaultFilters = useMemo(
|
const defaultFilters = useMemo(
|
||||||
() => (isSubDomain ? SUB_DOMAIN_FILTERS : DOMAIN_FILTERS),
|
() => (isSubDomain ? SUB_DOMAIN_FILTERS : DOMAIN_FILTERS),
|
||||||
@ -39,6 +40,7 @@ export const useDomainFilters = (config: UseDomainFiltersConfig) => {
|
|||||||
const { quickFilters, selectedFilters } = useQuickFiltersWithComponent({
|
const { quickFilters, selectedFilters } = useQuickFiltersWithComponent({
|
||||||
defaultFilters,
|
defaultFilters,
|
||||||
aggregations: config.aggregations,
|
aggregations: config.aggregations,
|
||||||
|
parsedFilters,
|
||||||
searchIndex: SearchIndex.DOMAIN,
|
searchIndex: SearchIndex.DOMAIN,
|
||||||
assetType: AssetsOfEntity.DOMAIN,
|
assetType: AssetsOfEntity.DOMAIN,
|
||||||
onFilterChange: config.onFilterChange,
|
onFilterChange: config.onFilterChange,
|
||||||
|
@ -27,6 +27,7 @@ interface FilterConfig {
|
|||||||
interface FilterSelectionConfig {
|
interface FilterSelectionConfig {
|
||||||
urlState: UrlState;
|
urlState: UrlState;
|
||||||
filterConfigs: FilterConfig[];
|
filterConfigs: FilterConfig[];
|
||||||
|
parsedFilters?: ExploreQuickFilterField[];
|
||||||
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,11 +39,24 @@ interface FilterSelectionItem {
|
|||||||
|
|
||||||
export const useFilterSelection = (config: FilterSelectionConfig) => {
|
export const useFilterSelection = (config: FilterSelectionConfig) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { urlState, filterConfigs, onFilterChange } = config;
|
const { urlState, filterConfigs, parsedFilters, onFilterChange } = config;
|
||||||
|
|
||||||
const selectedFilters = useMemo<FilterSelectionItem[]>(() => {
|
const selectedFilters = useMemo<FilterSelectionItem[]>(() => {
|
||||||
const filters: FilterSelectionItem[] = [];
|
const filters: FilterSelectionItem[] = [];
|
||||||
|
|
||||||
|
// Use parsedFilters if available for consistent values
|
||||||
|
if (parsedFilters) {
|
||||||
|
parsedFilters.forEach((filter) => {
|
||||||
|
if (filter.value && filter.value.length > 0) {
|
||||||
|
filters.push({
|
||||||
|
key: filter.key,
|
||||||
|
label: filter.label,
|
||||||
|
values: filter.value.map((v) => v.label || v.key),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback to urlState.filters
|
||||||
Object.entries(urlState.filters).forEach(([filterKey, values]) => {
|
Object.entries(urlState.filters).forEach(([filterKey, values]) => {
|
||||||
if (values && values.length > 0) {
|
if (values && values.length > 0) {
|
||||||
const filterConfig = filterConfigs.find((fc) => fc.key === filterKey);
|
const filterConfig = filterConfigs.find((fc) => fc.key === filterKey);
|
||||||
@ -55,9 +69,10 @@ export const useFilterSelection = (config: FilterSelectionConfig) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return filters;
|
return filters;
|
||||||
}, [urlState.filters, filterConfigs]);
|
}, [urlState.filters, filterConfigs, parsedFilters]);
|
||||||
|
|
||||||
const handleRemoveFilter = useCallback(
|
const handleRemoveFilter = useCallback(
|
||||||
(filterKey: string) => {
|
(filterKey: string) => {
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 Collate.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { SearchIndex } from '../../../../enums/search.enum';
|
|
||||||
import { Aggregations } from '../../../../interface/search.interface';
|
|
||||||
import { ExploreQuickFilterField } from '../../../Explore/ExplorePage.interface';
|
|
||||||
import ExploreQuickFilters from '../../../Explore/ExploreQuickFilters';
|
|
||||||
import { FilterConfig, FilterField } from '../shared/types';
|
|
||||||
|
|
||||||
interface QuickFiltersConfig {
|
|
||||||
filterFields: FilterField[];
|
|
||||||
filterConfigs: FilterConfig[];
|
|
||||||
queryConfig: Record<string, string>;
|
|
||||||
onFilterChange: (filterKey: string, values: string[]) => void;
|
|
||||||
aggregations: Aggregations;
|
|
||||||
searchIndex: SearchIndex;
|
|
||||||
independent?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useQuickFilters = (config: QuickFiltersConfig) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const initialFilters = useMemo(
|
|
||||||
() =>
|
|
||||||
config.filterFields.map((field) => {
|
|
||||||
const filterConfig = config.filterConfigs.find(
|
|
||||||
(fc) => fc.key === field.key
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
key: field.aggregationField,
|
|
||||||
label: filterConfig ? t(filterConfig.labelKey) : field.key,
|
|
||||||
value: [],
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
[config.filterFields, config.filterConfigs, t]
|
|
||||||
);
|
|
||||||
|
|
||||||
const [selectedQuickFilters, setSelectedQuickFilters] =
|
|
||||||
useState<ExploreQuickFilterField[]>(initialFilters);
|
|
||||||
|
|
||||||
const getFilterKeyFromField = useCallback(
|
|
||||||
(fieldKey: string): string => {
|
|
||||||
// Reverse lookup from aggregationField to filter key
|
|
||||||
const entry = Object.entries(config.queryConfig).find(
|
|
||||||
([, value]) => value === fieldKey
|
|
||||||
);
|
|
||||||
|
|
||||||
return entry ? entry[0] : fieldKey;
|
|
||||||
},
|
|
||||||
[config.queryConfig]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleQuickFiltersValueSelect = useCallback(
|
|
||||||
(field: ExploreQuickFilterField) => {
|
|
||||||
setSelectedQuickFilters((prev) => {
|
|
||||||
const data = prev.map((prevField) => {
|
|
||||||
if (prevField.key === field.key) {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prevField;
|
|
||||||
});
|
|
||||||
|
|
||||||
const filterKey = getFilterKeyFromField(field.key);
|
|
||||||
config.onFilterChange(filterKey, field.value?.map((v) => v.key) || []);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[config.onFilterChange, getFilterKeyFromField]
|
|
||||||
);
|
|
||||||
|
|
||||||
const quickFilters = useMemo(
|
|
||||||
() => (
|
|
||||||
<ExploreQuickFilters
|
|
||||||
aggregations={config.aggregations}
|
|
||||||
fields={selectedQuickFilters}
|
|
||||||
independent={config.independent}
|
|
||||||
index={config.searchIndex}
|
|
||||||
onFieldValueSelect={handleQuickFiltersValueSelect}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
[
|
|
||||||
config.independent,
|
|
||||||
config.aggregations,
|
|
||||||
config.searchIndex,
|
|
||||||
selectedQuickFilters,
|
|
||||||
handleQuickFiltersValueSelect,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
quickFilters,
|
|
||||||
selectedQuickFilters,
|
|
||||||
handleQuickFiltersValueSelect,
|
|
||||||
};
|
|
||||||
};
|
|
@ -21,6 +21,7 @@ import { AssetsOfEntity } from '../../../Glossary/GlossaryTerms/tabs/AssetsTabs.
|
|||||||
interface QuickFiltersWithComponentConfig {
|
interface QuickFiltersWithComponentConfig {
|
||||||
defaultFilters: ExploreQuickFilterField[];
|
defaultFilters: ExploreQuickFilterField[];
|
||||||
aggregations?: Aggregations;
|
aggregations?: Aggregations;
|
||||||
|
parsedFilters?: ExploreQuickFilterField[];
|
||||||
searchIndex: SearchIndex;
|
searchIndex: SearchIndex;
|
||||||
assetType: AssetsOfEntity;
|
assetType: AssetsOfEntity;
|
||||||
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
onFilterChange: (filters: ExploreQuickFilterField[]) => void;
|
||||||
@ -34,23 +35,25 @@ export const useQuickFiltersWithComponent = (
|
|||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Use parsedFilters if available (from URL), otherwise use defaultFilters
|
||||||
|
if (config.parsedFilters && config.parsedFilters.length > 0) {
|
||||||
|
// Merge parsedFilters with defaultFilters to maintain structure
|
||||||
|
const mergedFilters = config.defaultFilters.map((defaultFilter) => {
|
||||||
|
const parsedFilter = config.parsedFilters?.find(
|
||||||
|
(pf) => pf.key === defaultFilter.key
|
||||||
|
);
|
||||||
|
|
||||||
|
return parsedFilter || defaultFilter;
|
||||||
|
});
|
||||||
|
setSelectedQuickFilters(mergedFilters);
|
||||||
|
} else {
|
||||||
setSelectedQuickFilters(config.defaultFilters);
|
setSelectedQuickFilters(config.defaultFilters);
|
||||||
}, [config.defaultFilters]);
|
}
|
||||||
|
}, [config.defaultFilters, config.parsedFilters]);
|
||||||
|
|
||||||
const handleQuickFiltersChange = useCallback(
|
const handleQuickFiltersChange = useCallback(
|
||||||
(data: ExploreQuickFilterField[]) => {
|
(data: ExploreQuickFilterField[]) => {
|
||||||
config.onFilterChange(data);
|
config.onFilterChange(data);
|
||||||
|
|
||||||
// data.forEach((filter) => {
|
|
||||||
// if (filter.value && filter.value.length > 0) {
|
|
||||||
// config.onFilterChange(
|
|
||||||
// filter.key,
|
|
||||||
// filter.value as unknown as string[]
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// config.onFilterChange(filter.key, []);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
[config.onFilterChange]
|
[config.onFilterChange]
|
||||||
);
|
);
|
||||||
@ -77,7 +80,6 @@ export const useQuickFiltersWithComponent = (
|
|||||||
const quickFilters = useMemo(
|
const quickFilters = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<ExploreQuickFilters
|
<ExploreQuickFilters
|
||||||
independent
|
|
||||||
showSelectedCounts
|
showSelectedCounts
|
||||||
aggregations={config.aggregations || {}}
|
aggregations={config.aggregations || {}}
|
||||||
fields={selectedQuickFilters}
|
fields={selectedQuickFilters}
|
||||||
|
@ -29,6 +29,7 @@ export interface UrlState {
|
|||||||
|
|
||||||
export interface UrlStateHook {
|
export interface UrlStateHook {
|
||||||
urlState: UrlState;
|
urlState: UrlState;
|
||||||
|
parsedFilters: ExploreQuickFilterField[];
|
||||||
setSearchQuery: (query: string) => void;
|
setSearchQuery: (query: string) => void;
|
||||||
setFilters: (filters: ExploreQuickFilterField[]) => void;
|
setFilters: (filters: ExploreQuickFilterField[]) => void;
|
||||||
setCurrentPage: (page: number) => void;
|
setCurrentPage: (page: number) => void;
|
||||||
@ -123,6 +124,7 @@ export interface ListingData<T> {
|
|||||||
isSelected: (id: string) => boolean;
|
isSelected: (id: string) => boolean;
|
||||||
clearSelection: () => void;
|
clearSelection: () => void;
|
||||||
urlState: UrlState;
|
urlState: UrlState;
|
||||||
|
parsedFilters: ExploreQuickFilterField[];
|
||||||
actionHandlers: ActionHandlers<T>;
|
actionHandlers: ActionHandlers<T>;
|
||||||
filterOptions?: FilterOptions;
|
filterOptions?: FilterOptions;
|
||||||
aggregations?: Aggregations | null;
|
aggregations?: Aggregations | null;
|
||||||
|
@ -85,6 +85,7 @@ export const SUBDOMAIN_DEFAULT_QUICK_FILTERS = [
|
|||||||
EntityFields.OWNERS,
|
EntityFields.OWNERS,
|
||||||
EntityFields.CLASSIFICATION_TAGS,
|
EntityFields.CLASSIFICATION_TAGS,
|
||||||
EntityFields.GLOSSARY_TERMS,
|
EntityFields.GLOSSARY_TERMS,
|
||||||
|
EntityFields.DOMAIN_TYPE,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DOMAIN_FILTERS = [
|
export const DOMAIN_FILTERS = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user