mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat: Show pinned filter values while filters are loading (#1308)
Closes HDX-2641 # Summary With this change, HyperDX will now display pinned filter values as soon as the search page loads, without waiting for the filter values to be queried from ClickHouse. This enables users to quickly apply relevant filters, before the (sometimes very slow) filter values query completes. ## Demo For this demo, I added an artificial delay to the filter query to simulate an environment where filter queries are slow https://github.com/user-attachments/assets/6345cb91-7aba-4acc-a832-05efb3bf17d0
This commit is contained in:
parent
d5a38c3e05
commit
3ee93ae918
3 changed files with 37 additions and 5 deletions
5
.changeset/lucky-taxis-leave.md
Normal file
5
.changeset/lucky-taxis-leave.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
feat: Show pinned filter values while filters are loading
|
||||
|
|
@ -677,8 +677,13 @@ const DBSearchPageFiltersComponent = ({
|
|||
) => {
|
||||
return _setFilterValue(property, value, action);
|
||||
};
|
||||
const { toggleFilterPin, toggleFieldPin, isFilterPinned, isFieldPinned } =
|
||||
usePinnedFilters(sourceId ?? null);
|
||||
const {
|
||||
toggleFilterPin,
|
||||
toggleFieldPin,
|
||||
isFilterPinned,
|
||||
isFieldPinned,
|
||||
pinnedFilters,
|
||||
} = usePinnedFilters(sourceId ?? null);
|
||||
const { width, startResize } = useResizable(16, 'left');
|
||||
|
||||
const { data: jsonColumns } = useJsonColumns({
|
||||
|
|
@ -740,7 +745,7 @@ const DBSearchPageFiltersComponent = ({
|
|||
!['body', 'timestamp', '_hdx_body'].includes(path.toLowerCase()),
|
||||
);
|
||||
return strings;
|
||||
}, [data, jsonColumns, filterState, showMoreFields]);
|
||||
}, [data, jsonColumns, filterState, showMoreFields, isFieldPinned]);
|
||||
|
||||
// Special case for live tail
|
||||
const [dateRange, setDateRange] = useState<[Date, Date]>(
|
||||
|
|
@ -767,6 +772,26 @@ const DBSearchPageFiltersComponent = ({
|
|||
keys: keysToFetch,
|
||||
});
|
||||
|
||||
// Merge pinned filter values into the queried facets, so that pinned values are always available
|
||||
const facetsWithPinnedValues = useMemo(() => {
|
||||
const facetsMap = new Map((facets ?? []).map(f => [f.key, f.value]));
|
||||
const mergedKeys = new Set<string>([
|
||||
...facetsMap.keys(),
|
||||
...Object.keys(pinnedFilters),
|
||||
]);
|
||||
|
||||
return Array.from(mergedKeys).map(key => {
|
||||
const queriedValues = facetsMap.get(key);
|
||||
const pinnedValues = pinnedFilters[key];
|
||||
const mergedValues = new Set<string>([
|
||||
...(queriedValues ?? []),
|
||||
...(pinnedValues ?? []),
|
||||
]);
|
||||
|
||||
return { key, value: Array.from(mergedValues) };
|
||||
});
|
||||
}, [facets, pinnedFilters]);
|
||||
|
||||
const metadata = useMetadataWithSettings();
|
||||
const [extraFacets, setExtraFacets] = useState<Record<string, string[]>>({});
|
||||
const [loadMoreLoadingKeys, setLoadMoreLoadingKeys] = useState<Set<string>>(
|
||||
|
|
@ -807,7 +832,7 @@ const DBSearchPageFiltersComponent = ({
|
|||
|
||||
const shownFacets = useMemo(() => {
|
||||
const _facets: { key: string; value: string[] }[] = [];
|
||||
for (const _facet of facets ?? []) {
|
||||
for (const _facet of facetsWithPinnedValues ?? []) {
|
||||
const facet = structuredClone(_facet);
|
||||
if (jsonColumns?.some(col => facet.key.startsWith(col))) {
|
||||
facet.key = `toString(${facet.key})`;
|
||||
|
|
@ -866,7 +891,7 @@ const DBSearchPageFiltersComponent = ({
|
|||
|
||||
return _facets;
|
||||
}, [
|
||||
facets,
|
||||
facetsWithPinnedValues,
|
||||
filterState,
|
||||
tableMetadata,
|
||||
extraFacets,
|
||||
|
|
@ -982,6 +1007,7 @@ const DBSearchPageFiltersComponent = ({
|
|||
</Text>
|
||||
)
|
||||
)}
|
||||
{/* Show facets even when loading to ensure pinned filters are visible while loading */}
|
||||
{shownFacets.map(facet => (
|
||||
<FilterGroup
|
||||
key={facet.key}
|
||||
|
|
|
|||
|
|
@ -353,5 +353,6 @@ export function usePinnedFilters(sourceId: string | null) {
|
|||
isFilterPinned,
|
||||
isFieldPinned,
|
||||
getPinnedFields,
|
||||
pinnedFilters,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue