From 074796f4cd5e154faa8a80c3b68f7ad22a07bfe2 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Mon, 9 Sep 2024 16:43:22 +0430 Subject: [PATCH] feat: get labels and all possible values from /timeline API --- .../AlertHistory/Timeline/Table/Table.tsx | 18 +++------- .../Timeline/Table/useTimelineTable.tsx | 34 ++++++++++++------- .../container/QueryBuilder/filters/utils.ts | 2 +- .../AlertHeader/AlertLabels/AlertLabels.tsx | 2 +- frontend/src/providers/Alert.tsx | 12 +------ frontend/src/types/api/alerts/def.ts | 7 +++- 6 files changed, 34 insertions(+), 41 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx index dc46c3eb04..be5c7ae9c3 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx @@ -6,8 +6,7 @@ import { useGetAlertRuleDetailsTimelineTable, useTimelineTable, } from 'pages/AlertDetails/hooks'; -import { useAlertRule } from 'providers/Alert'; -import { useEffect, useMemo, useState } from 'react'; +import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; @@ -25,11 +24,12 @@ function TimelineTable(): JSX.Element { ruleId, } = useGetAlertRuleDetailsTimelineTable({ filters }); - const { timelineData, totalItems } = useMemo(() => { + const { timelineData, totalItems, labels } = useMemo(() => { const response = data?.payload?.data; return { timelineData: response?.items, totalItems: response?.total, + labels: response?.labels, }; }, [data?.payload?.data]); @@ -38,17 +38,6 @@ function TimelineTable(): JSX.Element { }); const { t } = useTranslation('common'); - const { setAlertRuleLabels } = useAlertRule(); - - useEffect(() => { - const labelsFromFirstItem = data?.payload?.data?.items?.[0]?.labels ?? {}; - - if (ruleId && Object.keys(labelsFromFirstItem).length > 0) { - setAlertRuleLabels((prevLabels) => - new Map(prevLabels).set(ruleId, labelsFromFirstItem), - ); - } - }, [data, setAlertRuleLabels, ruleId]); if (isError || !isValidRuleId || !ruleId) { return
{t('something_went_wrong')}
; @@ -60,6 +49,7 @@ function TimelineTable(): JSX.Element { rowKey={(row): string => `${row.fingerprint}-${row.value}-${row.unixMilli}`} columns={timelineTableColumns({ filters, + labels: labels ?? {}, setFilters, })} dataSource={timelineData} diff --git a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx index cd1541dbcf..5c67caa984 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx @@ -6,37 +6,40 @@ import ClientSideQBSearch, { AttributeKey, } from 'components/ClientSideQBSearch/ClientSideQBSearch'; import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/AlertPopover'; +import { transformKeyValuesToAttributeValuesMap } from 'container/QueryBuilder/filters/utils'; import { useIsDarkMode } from 'hooks/useDarkMode'; import { Search } from 'lucide-react'; -import AlertLabels from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels'; +import AlertLabels, { + AlertLabelsProps, +} from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels'; import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState'; -import { useAlertHistoryQueryParams } from 'pages/AlertDetails/hooks'; -import { useAlertRule } from 'providers/Alert'; import { useMemo } from 'react'; import { AlertRuleTimelineTableResponse } from 'types/api/alerts/def'; import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; import { formatEpochTimestamp } from 'utils/timeUtils'; -const transfromLabelsToQbKeys = ( +const transformLabelsToQbKeys = ( labels: AlertRuleTimelineTableResponse['labels'], -): AttributeKey[] => Object.keys(labels).map((key) => ({ key })); +): AttributeKey[] => Object.keys(labels).flatMap((key) => [{ key }]); function LabelFilter({ filters, setFilters, + labels, }: { setFilters: (filters: TagFilter) => void; filters: TagFilter; + labels: AlertLabelsProps['labels']; }): JSX.Element | null { const isDarkMode = useIsDarkMode(); - const { ruleId } = useAlertHistoryQueryParams(); - const { alertRuleLabels } = useAlertRule(); - - const transformedKeys = useMemo(() => { - if (!ruleId) return []; - return transfromLabelsToQbKeys(alertRuleLabels?.get(ruleId) || {}); - }, [alertRuleLabels, ruleId]); + const { transformedKeys, attributesMap } = useMemo( + () => ({ + transformedKeys: transformLabelsToQbKeys(labels || {}), + attributesMap: transformKeyValuesToAttributeValuesMap(labels), + }), + [labels], + ); const handleSearch = (tagFilters: TagFilter): void => { const tagFiltersLength = tagFilters.items.length; @@ -56,6 +59,7 @@ function LabelFilter({ filters={filters} className="alert-history-label-search" attributeKeys={transformedKeys} + attributeValuesMap={attributesMap} suffixIcon={ void; }): ColumnsType => [ { @@ -85,7 +91,9 @@ export const timelineTableColumns = ({ ), }, { - title: , + title: ( + + ), dataIndex: 'labels', render: (labels): JSX.Element => (
diff --git a/frontend/src/container/QueryBuilder/filters/utils.ts b/frontend/src/container/QueryBuilder/filters/utils.ts index 6733cc47ec..ff52e7cb70 100644 --- a/frontend/src/container/QueryBuilder/filters/utils.ts +++ b/frontend/src/container/QueryBuilder/filters/utils.ts @@ -98,7 +98,7 @@ export const transformKeyValuesToAttributeValuesMap = ( attributeValuesMap: Record, ): AttributeValuesMap => Object.fromEntries( - Object.entries(attributeValuesMap).map(([key, values]) => [ + Object.entries(attributeValuesMap || {}).map(([key, values]) => [ key, { stringAttributeValues: diff --git a/frontend/src/pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels.tsx b/frontend/src/pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels.tsx index bdc5eaa019..4386417219 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels.tsx @@ -4,7 +4,7 @@ import KeyValueLabel from 'periscope/components/KeyValueLabel'; import SeeMore from 'periscope/components/SeeMore'; // eslint-disable-next-line @typescript-eslint/no-explicit-any -type AlertLabelsProps = { +export type AlertLabelsProps = { labels: Record; initialCount?: number; }; diff --git a/frontend/src/providers/Alert.tsx b/frontend/src/providers/Alert.tsx index 78bab78803..751129457b 100644 --- a/frontend/src/providers/Alert.tsx +++ b/frontend/src/providers/Alert.tsx @@ -5,10 +5,6 @@ interface AlertRuleContextType { setIsAlertRuleDisabled: React.Dispatch< React.SetStateAction >; - alertRuleLabels: Map>; - setAlertRuleLabels: React.Dispatch< - React.SetStateAction>> - >; } const AlertRuleContext = createContext( @@ -24,18 +20,12 @@ function AlertRuleProvider({ boolean | undefined >(undefined); - const [alertRuleLabels, setAlertRuleLabels] = useState< - Map> - >(new Map()); - const value = React.useMemo( () => ({ isAlertRuleDisabled, setIsAlertRuleDisabled, - alertRuleLabels, - setAlertRuleLabels, }), - [isAlertRuleDisabled, alertRuleLabels], + [isAlertRuleDisabled], ); return ( diff --git a/frontend/src/types/api/alerts/def.ts b/frontend/src/types/api/alerts/def.ts index 9393ccd5a0..db358d448c 100644 --- a/frontend/src/types/api/alerts/def.ts +++ b/frontend/src/types/api/alerts/def.ts @@ -1,3 +1,4 @@ +import { AlertLabelsProps } from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels'; import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery'; // default match type for threshold @@ -94,7 +95,11 @@ export interface AlertRuleTimelineTableResponse { relatedLogsLink: string; } export type AlertRuleTimelineTableResponsePayload = { - data: { items: AlertRuleTimelineTableResponse[]; total: number }; + data: { + items: AlertRuleTimelineTableResponse[]; + total: number; + labels: AlertLabelsProps['labels']; + }; }; type AlertState = 'firing' | 'normal' | 'no-data' | 'muted';