From 54298d98e2c248ae3182be02b3bf8810b1e63169 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 09:44:01 +0430 Subject: [PATCH 01/28] fix: don't display severity label --- .../pages/AlertDetails/AlertHeader/AlertHeader.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx index 3c8a9b4a11..4f247c1eaf 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx @@ -1,5 +1,7 @@ import './AlertHeader.styles.scss'; +import { useMemo } from 'react'; + import AlertActionButtons from './ActionButtons/ActionButtons'; import AlertLabels from './AlertLabels/AlertLabels'; import AlertSeverity from './AlertSeverity/AlertSeverity'; @@ -16,6 +18,14 @@ export type AlertHeaderProps = { function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element { const { state, alert, id, labels } = alertDetails; + const labelsWithoutSeverity = useMemo( + () => + Object.fromEntries( + Object.entries(labels).filter(([key]) => key !== 'severity'), + ), + [labels], + ); + return (
@@ -34,7 +44,7 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element { status="firing" timestamp={dayjs().subtract(1, 'd').valueOf()} /> */} - +
From c706386f538795562e497b8451ea9977767e6db8 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 09:49:06 +0430 Subject: [PATCH 02/28] chore: remove id from alert header --- .../pages/AlertDetails/AlertHeader/AlertHeader.styles.scss | 7 ------- .../src/pages/AlertDetails/AlertHeader/AlertHeader.tsx | 3 +-- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.styles.scss b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.styles.scss index fbddf860fc..10a05f2258 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.styles.scss +++ b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.styles.scss @@ -25,13 +25,6 @@ line-height: 24px; letter-spacing: -0.08px; } - .alert-id { - // color: var(--text-slate-50); - color: #62687c; - font-size: 15px; - line-height: 20px; - letter-spacing: -0.075px; - } } } .bottom-section { diff --git a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx index 4f247c1eaf..8f61f73742 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx @@ -16,7 +16,7 @@ export type AlertHeaderProps = { }; }; function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element { - const { state, alert, id, labels } = alertDetails; + const { state, alert, labels } = alertDetails; const labelsWithoutSeverity = useMemo( () => @@ -33,7 +33,6 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
{alert}
-
{id}
From 1b5997faa95785226e2ab8dac42ef7e965014e84 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 09:51:06 +0430 Subject: [PATCH 03/28] chore: add tooltip to enable/disable alert toggle --- .../AlertHeader/ActionButtons/ActionButtons.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx b/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx index bf4ac62446..5fc485f2a0 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx @@ -101,11 +101,13 @@ function AlertActionButtons({ return (
- + + + From bdd224d47baf0f171eb34fdc0bc89072e5f0f52b Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 09:53:16 +0430 Subject: [PATCH 04/28] chore: update enable/disbale toast message --- frontend/src/pages/AlertDetails/hooks.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 78d9bd0038..3df6406838 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -395,7 +395,7 @@ export const useAlertRuleStatusToggle = ({ }, onSuccess: () => { notifications.success({ - message: `Alert has been turned ${!isAlertRuleEnabled ? 'on' : 'off'}.`, + message: `Alert has been ${!isAlertRuleEnabled ? 'enabled' : 'disabled'}.`, }); }, onError: (error) => { From 802be79f9af0c68f2d95a632f99d7c93061c8c21 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 14:26:42 +0430 Subject: [PATCH 05/28] fix: set default relative time to 6h if relative time is not provided --- .../TopNav/DateTimeSelectionV2/index.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx b/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx index 6b6a3bce68..0d08f6529b 100644 --- a/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx +++ b/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx @@ -66,7 +66,7 @@ function DateTimeSelection({ globalTimeLoading, showResetButton = false, showOldExplorerCTA = false, - defaultRelativeTime = RelativeTimeMap['30min'] as Time, + defaultRelativeTime = RelativeTimeMap['6hr'] as Time, }: Props): JSX.Element { const [formSelector] = Form.useForm(); @@ -469,6 +469,20 @@ function DateTimeSelection({ } const currentRoute = location.pathname; + + // set the default relative time for alert history and overview pages if relative time is not specified + if ( + !urlQuery.has(QueryParams.relativeTime) && + (currentRoute === ROUTES.ALERT_OVERVIEW || + currentRoute === ROUTES.ALERT_HISTORY) + ) { + updateTimeInterval(defaultRelativeTime); + urlQuery.set(QueryParams.relativeTime, defaultRelativeTime); + const generatedUrl = `${location.pathname}?${urlQuery.toString()}`; + history.replace(generatedUrl); + return; + } + const time = getDefaultTime(currentRoute); const currentOptions = getOptions(currentRoute); @@ -710,7 +724,7 @@ DateTimeSelection.defaultProps = { hideShareModal: false, showOldExplorerCTA: false, showResetButton: false, - defaultRelativeTime: RelativeTimeMap['30min'] as Time, + defaultRelativeTime: RelativeTimeMap['6hr'] as Time, }; interface DispatchProps { updateTimeInterval: ( From bd9dbe28df476c1b67bfc260bb0d711cceba8a1c Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 14:54:12 +0430 Subject: [PATCH 06/28] chore: update empty top contributors text and remove configure alert --- .../TopContributorsContent.tsx | 31 ++----------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/frontend/src/container/AlertHistory/Statistics/TopContributorsCard/TopContributorsContent.tsx b/frontend/src/container/AlertHistory/Statistics/TopContributorsCard/TopContributorsContent.tsx index 39a2f8f27a..b458871f71 100644 --- a/frontend/src/container/AlertHistory/Statistics/TopContributorsCard/TopContributorsContent.tsx +++ b/frontend/src/container/AlertHistory/Statistics/TopContributorsCard/TopContributorsContent.tsx @@ -1,9 +1,3 @@ -import { Button } from 'antd'; -import { QueryParams } from 'constants/query'; -import ROUTES from 'constants/routes'; -import useUrlQuery from 'hooks/useUrlQuery'; -import history from 'lib/history'; - import TopContributorsRows from './TopContributorsRows'; import { TopContributorsCardProps } from './types'; @@ -13,34 +7,13 @@ function TopContributorsContent({ }: TopContributorsCardProps): JSX.Element { const isEmpty = !topContributorsData.length; - const urlQuery = useUrlQuery(); - const ruleIdKey = QueryParams.ruleId; - const relativeTimeKey = QueryParams.relativeTime; - - const handleRedirectToOverview = (): void => { - const params = `${ruleIdKey}=${urlQuery.get( - ruleIdKey, - )}&${relativeTimeKey}=${urlQuery.get(relativeTimeKey)}`; - - history.push(`${ROUTES.ALERT_OVERVIEW}?${params}`); - }; - if (isEmpty) { return (
ℹ️
- Add Group By Field To view top - contributors, please add at least one group by field to your query. -
-
- + Top contributors highlight the most frequently triggering group-by + attributes in multi-dimensional alerts
); From f6295f87456edba441cd7c2ac26f2e008f8bee8b Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 14:58:07 +0430 Subject: [PATCH 07/28] chore: temporarily hide value column from timeline column --- .../AlertHistory/Timeline/Table/Table.tsx | 35 ++++++++--------- .../Timeline/Table/useTimelineTable.tsx | 38 +++++++++---------- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx index 63d0464eb8..5596ac5ff8 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx @@ -2,15 +2,12 @@ import './Table.styles.scss'; import { Table } from 'antd'; import { initialFilters } from 'constants/queryBuilder'; -import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { useGetAlertRuleDetailsTimelineTable, useTimelineTable, } from 'pages/AlertDetails/hooks'; import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useQueryClient } from 'react-query'; -import { PayloadProps } from 'types/api/alerts/get'; import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; import { timelineTableColumns } from './useTimelineTable'; @@ -39,21 +36,21 @@ function TimelineTable(): JSX.Element { totalItems: totalItems ?? 0, }); - const queryClient = useQueryClient(); + // const queryClient = useQueryClient(); - const { currentUnit, targetUnit } = useMemo(() => { - const alertDetailsQuery = queryClient.getQueryData([ - REACT_QUERY_KEY.ALERT_RULE_DETAILS, - ruleId, - ]) as { - payload: PayloadProps; - }; - const condition = alertDetailsQuery?.payload?.data?.condition; - const { targetUnit } = condition ?? {}; - const { unit: currentUnit } = condition?.compositeQuery ?? {}; + // const { currentUnit, targetUnit } = useMemo(() => { + // const alertDetailsQuery = queryClient.getQueryData([ + // REACT_QUERY_KEY.ALERT_RULE_DETAILS, + // ruleId, + // ]) as { + // payload: PayloadProps; + // }; + // const condition = alertDetailsQuery?.payload?.data?.condition; + // const { targetUnit } = condition ?? {}; + // const { unit: currentUnit } = condition?.compositeQuery ?? {}; - return { currentUnit, targetUnit }; - }, [queryClient, ruleId]); + // return { currentUnit, targetUnit }; + // }, [queryClient, ruleId]); const { t } = useTranslation('common'); @@ -65,7 +62,11 @@ function TimelineTable(): JSX.Element {
`${row.fingerprint}-${row.value}-${row.unixMilli}`} - columns={timelineTableColumns(filters, setFilters, currentUnit, targetUnit)} + columns={timelineTableColumns( + filters, + setFilters, + // , currentUnit, targetUnit + )} dataSource={timelineData} pagination={paginationConfig} size="middle" diff --git a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx index 7dbafb83c6..ed3f693dde 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx @@ -6,7 +6,6 @@ import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/Ale import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; import { useIsDarkMode } from 'hooks/useDarkMode'; import useUrlQuery from 'hooks/useUrlQuery'; -import { convertValue } from 'lib/getConvertedValue'; import { Search } from 'lucide-react'; import AlertLabels from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels'; import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState'; @@ -83,8 +82,8 @@ function LabelFilter({ export const timelineTableColumns = ( filters: TagFilter, setFilters: (text: TagFilter) => void, - currentUnit?: string, - targetUnit?: string, + // currentUnit?: string, + // targetUnit?: string, ): ColumnsType => [ { title: 'STATE', @@ -117,22 +116,23 @@ export const timelineTableColumns = ( ), }, - { - title: 'VALUE', - dataIndex: 'value', - width: '14%', - render: (value, record): JSX.Element => ( - -
- {/* convert the value based on y axis and target unit */} - {convertValue(value.toFixed(2), currentUnit, targetUnit)} -
-
- ), - }, + // temporarily comment value column + // { + // title: 'VALUE', + // dataIndex: 'value', + // width: '14%', + // render: (value, record): JSX.Element => ( + // + //
+ // {/* convert the value based on y axis and target unit */} + // {convertValue(value.toFixed(2), currentUnit, targetUnit)} + //
+ //
+ // ), + // }, { title: 'CREATED AT', dataIndex: 'unixMilli', From db1692b16b29e4e9fe513a6fde609cb991bfd0b9 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 15:00:15 +0430 Subject: [PATCH 08/28] fix: use correct links for logs and traces in alert popover --- .../src/container/AlertHistory/AlertPopover/AlertPopover.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx b/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx index 7c230439b6..4162835fa6 100644 --- a/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx +++ b/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx @@ -27,7 +27,7 @@ function PopoverContent({
{!!relatedTracesLink && (
@@ -38,7 +38,7 @@ function PopoverContent({ )} {!!relatedLogsLink && (
From 3447fa6927829a1cc0049d14a219aff8e18ccef3 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 15:39:43 +0430 Subject: [PATCH 09/28] fix: properly set timeline table offset --- frontend/src/pages/AlertDetails/hooks.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 3df6406838..80ad3fc532 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -257,11 +257,10 @@ export const useGetAlertRuleDetailsTimelineTable = ({ filters: TagFilter; }): GetAlertRuleDetailsTimelineTableProps => { const { ruleId, startTime, endTime, params } = useAlertHistoryQueryParams(); - - const { updatedOrder, getUpdatedOffset } = useMemo( + const { updatedOrder, offset } = useMemo( () => ({ updatedOrder: params.get(urlKey.order) ?? OrderPreferenceItems.ASC, - getUpdatedOffset: params.get(urlKey.offset) ?? '0', + offset: parseInt(params.get(urlKey.offset) ?? '1', 10), }), [params], ); @@ -279,7 +278,7 @@ export const useGetAlertRuleDetailsTimelineTable = ({ endTime, timelineFilter, updatedOrder, - getUpdatedOffset, + offset, JSON.stringify(filters.items), ], { @@ -290,7 +289,7 @@ export const useGetAlertRuleDetailsTimelineTable = ({ end: endTime, limit: TIMELINE_TABLE_PAGE_SIZE, order: updatedOrder, - offset: parseInt(getUpdatedOffset, 10), + offset, filters, ...(timelineFilter && timelineFilter !== TimelineFilter.ALL @@ -327,7 +326,7 @@ export const useTimelineTable = ({ const params = useMemo(() => new URLSearchParams(search), [search]); - const updatedOffset = params.get(urlKey.offset) ?? '0'; + const offset = params.get('offset') ?? '1'; const onChangeHandler: TableProps['onChange'] = useCallback( ( @@ -339,7 +338,7 @@ export const useTimelineTable = ({ ) => { if (!Array.isArray(sorter)) { const { pageSize = 0, current = 0 } = pagination; - const { columnKey = '', order } = sorter; + const { order } = sorter; const updatedOrder = order === 'ascend' ? 'asc' : 'desc'; const params = new URLSearchParams(window.location.search); @@ -347,8 +346,7 @@ export const useTimelineTable = ({ `${pathname}?${createQueryParams({ ...Object.fromEntries(params), order: updatedOrder, - offset: current - 1, - orderParam: columnKey, + offset: current * TIMELINE_TABLE_PAGE_SIZE - TIMELINE_TABLE_PAGE_SIZE, pageSize, })}`, ); @@ -360,7 +358,7 @@ export const useTimelineTable = ({ const paginationConfig: TablePaginationConfig = { pageSize: TIMELINE_TABLE_PAGE_SIZE, showTotal: PaginationInfoText, - current: parseInt(updatedOffset, 10) + 1, + current: parseInt(offset, 10) / TIMELINE_TABLE_PAGE_SIZE + 1, showSizeChanger: false, hideOnSinglePage: true, total: totalItems, From 7567910f15a1bd9863491b30990eaa01d5d03324 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 16:47:43 +0430 Subject: [PATCH 10/28] fix: display all values in graph --- .../AlertHistory/Timeline/Graph/Graph.tsx | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx b/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx index 684ba897f2..c331d93532 100644 --- a/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx @@ -21,19 +21,26 @@ function HorizontalTimelineGraph({ isDarkMode: boolean; data: AlertRuleTimelineGraphResponse[]; }): JSX.Element { - const transformedData: AlignedData = useMemo( - () => - data?.length > 1 - ? [ - data.map((item: AlertRuleTimelineGraphResponse) => item.start / 1000), - data.map( - (item: AlertRuleTimelineGraphResponse) => ALERT_STATUS[item.state], - ), - ] - : [[], []], - - [data], - ); + const transformedData: AlignedData = useMemo(() => { + if (data?.length <= 1) { + return [[], []]; + } + + // add a first and last entry to make sure + const timestamps = [ + data[0].start / 1000 - 300, // 5 minutes before the first entry + ...data.map((item) => item.start / 1000), + data[data.length - 1].end / 1000, // end value of last entry + ]; + + const states = [ + ALERT_STATUS[data[0].state], // Same state as the first entry + ...data.map((item) => ALERT_STATUS[item.state]), + ALERT_STATUS[data[data.length - 1].state], // Same state as the last entry + ]; + + return [timestamps, states]; + }, [data]); const options: uPlot.Options = useMemo( () => ({ From 08e84290046fc5c3c57ed91d363f9d963b806846 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 09:08:55 +0430 Subject: [PATCH 11/28] fix: resolve conflicts --- frontend/src/pages/AlertDetails/hooks.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 80ad3fc532..4a25df818b 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -28,7 +28,7 @@ import EditRules from 'pages/EditRules'; import { OrderPreferenceItems } from 'pages/Logs/config'; import PaginationInfoText from 'periscope/components/PaginationInfoText/PaginationInfoText'; import { useCallback, useMemo, useState } from 'react'; -import { useMutation, useQuery } from 'react-query'; +import { useMutation, useQuery, useQueryClient } from 'react-query'; import { useSelector } from 'react-redux'; import { generatePath, useLocation } from 'react-router-dom'; import { AppState } from 'store/reducers'; @@ -382,6 +382,8 @@ export const useAlertRuleStatusToggle = ({ const [isAlertRuleEnabled, setIsAlertRuleEnabled] = useState( isAlertRuleInitiallyEnabled, ); + + const queryClient = useQueryClient(); const handleError = useAxiosError(); const { mutate: toggleAlertState } = useMutation( @@ -395,6 +397,8 @@ export const useAlertRuleStatusToggle = ({ notifications.success({ message: `Alert has been ${!isAlertRuleEnabled ? 'enabled' : 'disabled'}.`, }); + + queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS]); }, onError: (error) => { setIsAlertRuleEnabled(isAlertRuleInitiallyEnabled); From 992e63ca5bcbbbe2eaee8f68277233c0cb1f951a Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 17:12:47 +0430 Subject: [PATCH 12/28] chore: remove style for value column in timeline table --- .../AlertHistory/Timeline/Table/Table.styles.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss b/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss index 807bbfb4be..fb21173e34 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss @@ -19,8 +19,11 @@ font-size: 12px; font-weight: 500; padding: 12px 16px 8px !important; - &:last-of-type, - &:nth-last-of-type(2) { + &:last-of-type + // TODO(shaheer): uncomment when we display value column + // , + // &:nth-last-of-type(2) + { text-align: right; } } @@ -88,6 +91,9 @@ } } .alert-history-label-search { + // .ant-select-selection-placeholder { + // text-align: left; + // } .ant-select-selector { border: none; } From 20f19ee97a5577ed48348084e28b20115ca242d3 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 20:09:01 +0430 Subject: [PATCH 13/28] chore: temporarily hide labels search --- .../AlertHistory/Timeline/Table/Table.tsx | 23 +-- .../Timeline/Table/useTimelineTable.tsx | 142 +++++++++--------- frontend/src/pages/AlertDetails/hooks.tsx | 11 +- 3 files changed, 87 insertions(+), 89 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx index 5596ac5ff8..5c73107d9d 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx @@ -1,19 +1,22 @@ import './Table.styles.scss'; import { Table } from 'antd'; -import { initialFilters } from 'constants/queryBuilder'; +// import { initialFilters } from 'constants/queryBuilder'; import { useGetAlertRuleDetailsTimelineTable, useTimelineTable, } from 'pages/AlertDetails/hooks'; -import { useMemo, useState } from 'react'; +import { + useMemo, + // , useState +} from 'react'; import { useTranslation } from 'react-i18next'; -import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; +// import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; import { timelineTableColumns } from './useTimelineTable'; function TimelineTable(): JSX.Element { - const [filters, setFilters] = useState(initialFilters); + // const [filters, setFilters] = useState(initialFilters); const { isLoading, @@ -22,7 +25,8 @@ function TimelineTable(): JSX.Element { data, isValidRuleId, ruleId, - } = useGetAlertRuleDetailsTimelineTable({ filters }); + } = useGetAlertRuleDetailsTimelineTable(); + // { filters } const { timelineData, totalItems } = useMemo(() => { const response = data?.payload?.data; @@ -62,11 +66,10 @@ function TimelineTable(): JSX.Element {
`${row.fingerprint}-${row.value}-${row.unixMilli}`} - columns={timelineTableColumns( - filters, - setFilters, - // , currentUnit, targetUnit - )} + columns={ + timelineTableColumns() + // filters, setFilters, , currentUnit, targetUnit + } dataSource={timelineData} pagination={paginationConfig} size="middle" diff --git a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx index ed3f693dde..ca12e5d7a6 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx @@ -1,90 +1,89 @@ -import { Color } from '@signozhq/design-tokens'; +// import { Color } from '@signozhq/design-tokens'; import { ColumnsType } from 'antd/es/table'; -import { QueryParams } from 'constants/query'; -import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; +// import { QueryParams } from 'constants/query'; +// import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/AlertPopover'; -import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; -import { useIsDarkMode } from 'hooks/useDarkMode'; -import useUrlQuery from 'hooks/useUrlQuery'; -import { Search } from 'lucide-react'; +// import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; +// import { useIsDarkMode } from 'hooks/useDarkMode'; +// import useUrlQuery from 'hooks/useUrlQuery'; +// import { Search } from 'lucide-react'; import AlertLabels from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels'; import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState'; -import { useMemo } from 'react'; -import { useQueryClient } from 'react-query'; -import { SuccessResponse } from 'types/api'; +// import { useMemo } from 'react'; +// import { useQueryClient } from 'react-query'; +// import { SuccessResponse } from 'types/api'; import { AlertRuleTimelineTableResponse } from 'types/api/alerts/def'; -import { PayloadProps } from 'types/api/alerts/get'; -import { - IBuilderQuery, - TagFilter, -} from 'types/api/queryBuilder/queryBuilderData'; +// import { PayloadProps } from 'types/api/alerts/get'; +// import { +// IBuilderQuery, +// TagFilter, +// } from 'types/api/queryBuilder/queryBuilderData'; import { formatEpochTimestamp } from 'utils/timeUtils'; -function LabelFilter({ - filters, - setFilters, -}: { - setFilters: (text: TagFilter) => void; - filters: TagFilter; -}): JSX.Element | null { - const isDarkMode = useIsDarkMode(); +// function LabelFilter({ +// filters, +// setFilters, +// }: { +// setFilters: (text: TagFilter) => void; +// filters: TagFilter; +// }): JSX.Element | null { +// const isDarkMode = useIsDarkMode(); - const queryClient = useQueryClient(); - const urlQuery = useUrlQuery(); - const ruleId = urlQuery.get(QueryParams.ruleId); +// const queryClient = useQueryClient(); +// const urlQuery = useUrlQuery(); +// const ruleId = urlQuery.get(QueryParams.ruleId); - const data = queryClient.getQueryData>([ - REACT_QUERY_KEY.ALERT_RULE_DETAILS, - ruleId, - ]); +// const data = queryClient.getQueryData>([ +// REACT_QUERY_KEY.ALERT_RULE_DETAILS, +// ruleId, +// ]); - const query = useMemo(() => { - const compositeQueries = data?.payload?.data?.condition.compositeQuery; - const query = compositeQueries?.builderQueries?.A; +// const query = useMemo(() => { +// const compositeQueries = data?.payload?.data?.condition.compositeQuery; +// const query = compositeQueries?.builderQueries?.A; - return { - ...query, - filters, - } as IBuilderQuery; - }, [data?.payload?.data?.condition.compositeQuery, filters]); +// return { +// ...query, +// filters, +// } as IBuilderQuery; +// }, [data?.payload?.data?.condition.compositeQuery, filters]); - if (!data) { - return null; - } +// if (!data) { +// return null; +// } - const handleSearch = (tagFilters: TagFilter): void => { - const tagFiltersLength = tagFilters.items.length; +// const handleSearch = (tagFilters: TagFilter): void => { +// const tagFiltersLength = tagFilters.items.length; - if ( - (!tagFiltersLength && (!filters || !filters.items.length)) || - tagFiltersLength === filters?.items.length - ) - return; +// if ( +// (!tagFiltersLength && (!filters || !filters.items.length)) || +// tagFiltersLength === filters?.items.length +// ) +// return; - setFilters(tagFilters); - }; +// setFilters(tagFilters); +// }; - return ( - - } - /> - ); -} +// return ( +// +// } +// /> +// ); +// } -export const timelineTableColumns = ( - filters: TagFilter, - setFilters: (text: TagFilter) => void, - // currentUnit?: string, - // targetUnit?: string, -): ColumnsType => [ +export const timelineTableColumns = (): // filters: TagFilter, +// setFilters: (text: TagFilter) => void, +// currentUnit?: string, +// targetUnit?: string, +ColumnsType => [ { title: 'STATE', dataIndex: 'state', @@ -102,7 +101,8 @@ export const timelineTableColumns = ( ), }, { - title: , + title: 'LABELS', + // dataIndex: 'labels', width: '54.5%', render: (labels, record): JSX.Element => ( diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 4a25df818b..a6de48f99d 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -42,7 +42,6 @@ import { AlertRuleTopContributorsPayload, } from 'types/api/alerts/def'; import { PayloadProps } from 'types/api/alerts/get'; -import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; import { GlobalReducer } from 'types/reducer/globalTime'; import { nanoToMilli } from 'utils/timeUtils'; @@ -251,11 +250,7 @@ type GetAlertRuleDetailsTimelineTableProps = GetAlertRuleDetailsApiProps & { | undefined; }; -export const useGetAlertRuleDetailsTimelineTable = ({ - filters, -}: { - filters: TagFilter; -}): GetAlertRuleDetailsTimelineTableProps => { +export const useGetAlertRuleDetailsTimelineTable = (): GetAlertRuleDetailsTimelineTableProps => { const { ruleId, startTime, endTime, params } = useAlertHistoryQueryParams(); const { updatedOrder, offset } = useMemo( () => ({ @@ -279,7 +274,7 @@ export const useGetAlertRuleDetailsTimelineTable = ({ timelineFilter, updatedOrder, offset, - JSON.stringify(filters.items), + // JSON.stringify(filters.items), ], { queryFn: () => @@ -290,7 +285,7 @@ export const useGetAlertRuleDetailsTimelineTable = ({ limit: TIMELINE_TABLE_PAGE_SIZE, order: updatedOrder, offset, - filters, + // filters, ...(timelineFilter && timelineFilter !== TimelineFilter.ALL ? { From 5cbb432c014d9feef66576350b57b793bf7d14bd Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 20:43:15 +0430 Subject: [PATCH 14/28] fix: incorrect current page in pagination info text --- frontend/src/pages/AlertDetails/hooks.tsx | 6 ++++-- frontend/tsconfig.tmp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 frontend/tsconfig.tmp diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index a6de48f99d..3796ddc58e 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -321,7 +321,7 @@ export const useTimelineTable = ({ const params = useMemo(() => new URLSearchParams(search), [search]); - const offset = params.get('offset') ?? '1'; + const offset = params.get('offset') ?? '0'; const onChangeHandler: TableProps['onChange'] = useCallback( ( @@ -350,10 +350,12 @@ export const useTimelineTable = ({ [pathname], ); + const offsetInt = parseInt(offset, 10); + const paginationConfig: TablePaginationConfig = { pageSize: TIMELINE_TABLE_PAGE_SIZE, showTotal: PaginationInfoText, - current: parseInt(offset, 10) / TIMELINE_TABLE_PAGE_SIZE + 1, + current: offsetInt / TIMELINE_TABLE_PAGE_SIZE + 1, showSizeChanger: false, hideOnSinglePage: true, total: totalItems, diff --git a/frontend/tsconfig.tmp b/frontend/tsconfig.tmp new file mode 100644 index 0000000000..5a13de6f69 --- /dev/null +++ b/frontend/tsconfig.tmp @@ -0,0 +1 @@ +{ "extends": "./tsconfig.json", "include": [ "src/typings/**/*.ts","src/**/*.d.ts", "./babel.config.js", "./jest.config.ts", "./.eslintrc.js","./__mocks__","./conf/default.conf","./public","./tests","./playwright.config.ts","./commitlint.config.ts","./webpack.config.js","./webpack.config.prod.js","./jest.setup.ts","./**/*.d.ts", "/home/shaheer-kochai/projects/signoz/frontend/src/pages/AlertDetails/hooks.tsx",] } From ba81af54fcdc1f3473ebb3f6f7167e072c04b9a9 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 20:51:11 +0430 Subject: [PATCH 15/28] chore: remove label QB search --- .../AlertHistory/Timeline/Table/Table.tsx | 11 +-- .../Timeline/Table/useTimelineTable.tsx | 79 +------------------ frontend/tsconfig.tmp | 1 - 3 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 frontend/tsconfig.tmp diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx index 5c73107d9d..979baa6cb8 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx @@ -1,23 +1,16 @@ import './Table.styles.scss'; import { Table } from 'antd'; -// import { initialFilters } from 'constants/queryBuilder'; import { useGetAlertRuleDetailsTimelineTable, useTimelineTable, } from 'pages/AlertDetails/hooks'; -import { - useMemo, - // , useState -} from 'react'; +import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -// import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; import { timelineTableColumns } from './useTimelineTable'; function TimelineTable(): JSX.Element { - // const [filters, setFilters] = useState(initialFilters); - const { isLoading, isRefetching, @@ -68,7 +61,7 @@ function TimelineTable(): JSX.Element { rowKey={(row): string => `${row.fingerprint}-${row.value}-${row.unixMilli}`} columns={ timelineTableColumns() - // filters, setFilters, , currentUnit, targetUnit + // , currentUnit, targetUnit } dataSource={timelineData} pagination={paginationConfig} diff --git a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx index ca12e5d7a6..417d1fe47d 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx @@ -1,87 +1,11 @@ -// import { Color } from '@signozhq/design-tokens'; import { ColumnsType } from 'antd/es/table'; -// import { QueryParams } from 'constants/query'; -// import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/AlertPopover'; -// import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; -// import { useIsDarkMode } from 'hooks/useDarkMode'; -// import useUrlQuery from 'hooks/useUrlQuery'; -// import { Search } from 'lucide-react'; import AlertLabels from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels'; import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState'; -// import { useMemo } from 'react'; -// import { useQueryClient } from 'react-query'; -// import { SuccessResponse } from 'types/api'; import { AlertRuleTimelineTableResponse } from 'types/api/alerts/def'; -// import { PayloadProps } from 'types/api/alerts/get'; -// import { -// IBuilderQuery, -// TagFilter, -// } from 'types/api/queryBuilder/queryBuilderData'; import { formatEpochTimestamp } from 'utils/timeUtils'; -// function LabelFilter({ -// filters, -// setFilters, -// }: { -// setFilters: (text: TagFilter) => void; -// filters: TagFilter; -// }): JSX.Element | null { -// const isDarkMode = useIsDarkMode(); - -// const queryClient = useQueryClient(); -// const urlQuery = useUrlQuery(); -// const ruleId = urlQuery.get(QueryParams.ruleId); - -// const data = queryClient.getQueryData>([ -// REACT_QUERY_KEY.ALERT_RULE_DETAILS, -// ruleId, -// ]); - -// const query = useMemo(() => { -// const compositeQueries = data?.payload?.data?.condition.compositeQuery; -// const query = compositeQueries?.builderQueries?.A; - -// return { -// ...query, -// filters, -// } as IBuilderQuery; -// }, [data?.payload?.data?.condition.compositeQuery, filters]); - -// if (!data) { -// return null; -// } - -// const handleSearch = (tagFilters: TagFilter): void => { -// const tagFiltersLength = tagFilters.items.length; - -// if ( -// (!tagFiltersLength && (!filters || !filters.items.length)) || -// tagFiltersLength === filters?.items.length -// ) -// return; - -// setFilters(tagFilters); -// }; - -// return ( -// -// } -// /> -// ); -// } - -export const timelineTableColumns = (): // filters: TagFilter, -// setFilters: (text: TagFilter) => void, -// currentUnit?: string, +export const timelineTableColumns = (): // currentUnit?: string, // targetUnit?: string, ColumnsType => [ { @@ -102,7 +26,6 @@ ColumnsType => [ }, { title: 'LABELS', - // dataIndex: 'labels', width: '54.5%', render: (labels, record): JSX.Element => ( diff --git a/frontend/tsconfig.tmp b/frontend/tsconfig.tmp deleted file mode 100644 index 5a13de6f69..0000000000 --- a/frontend/tsconfig.tmp +++ /dev/null @@ -1 +0,0 @@ -{ "extends": "./tsconfig.json", "include": [ "src/typings/**/*.ts","src/**/*.d.ts", "./babel.config.js", "./jest.config.ts", "./.eslintrc.js","./__mocks__","./conf/default.conf","./public","./tests","./playwright.config.ts","./commitlint.config.ts","./webpack.config.js","./webpack.config.prod.js","./jest.setup.ts","./**/*.d.ts", "/home/shaheer-kochai/projects/signoz/frontend/src/pages/AlertDetails/hooks.tsx",] } From 43eb8b6fe7f72d4d8894809a9013f33092968915 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 20:55:46 +0430 Subject: [PATCH 16/28] chore: remove value column --- .../AlertHistory/Timeline/Table/Table.tsx | 21 +------------------ .../Timeline/Table/useTimelineTable.tsx | 21 +------------------ frontend/src/pages/AlertDetails/hooks.tsx | 2 -- 3 files changed, 2 insertions(+), 42 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx index 979baa6cb8..48b6144746 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx @@ -33,22 +33,6 @@ function TimelineTable(): JSX.Element { totalItems: totalItems ?? 0, }); - // const queryClient = useQueryClient(); - - // const { currentUnit, targetUnit } = useMemo(() => { - // const alertDetailsQuery = queryClient.getQueryData([ - // REACT_QUERY_KEY.ALERT_RULE_DETAILS, - // ruleId, - // ]) as { - // payload: PayloadProps; - // }; - // const condition = alertDetailsQuery?.payload?.data?.condition; - // const { targetUnit } = condition ?? {}; - // const { unit: currentUnit } = condition?.compositeQuery ?? {}; - - // return { currentUnit, targetUnit }; - // }, [queryClient, ruleId]); - const { t } = useTranslation('common'); if (isError || !isValidRuleId || !ruleId) { @@ -59,10 +43,7 @@ function TimelineTable(): JSX.Element {
`${row.fingerprint}-${row.value}-${row.unixMilli}`} - columns={ - timelineTableColumns() - // , currentUnit, targetUnit - } + columns={timelineTableColumns()} dataSource={timelineData} pagination={paginationConfig} size="middle" diff --git a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx index 417d1fe47d..5a42fcd5bd 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/useTimelineTable.tsx @@ -5,9 +5,7 @@ import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState'; import { AlertRuleTimelineTableResponse } from 'types/api/alerts/def'; import { formatEpochTimestamp } from 'utils/timeUtils'; -export const timelineTableColumns = (): // currentUnit?: string, -// targetUnit?: string, -ColumnsType => [ +export const timelineTableColumns = (): ColumnsType => [ { title: 'STATE', dataIndex: 'state', @@ -39,23 +37,6 @@ ColumnsType => [ ), }, - // temporarily comment value column - // { - // title: 'VALUE', - // dataIndex: 'value', - // width: '14%', - // render: (value, record): JSX.Element => ( - // - //
- // {/* convert the value based on y axis and target unit */} - // {convertValue(value.toFixed(2), currentUnit, targetUnit)} - //
- //
- // ), - // }, { title: 'CREATED AT', dataIndex: 'unixMilli', diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 3796ddc58e..3df9d03a34 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -274,7 +274,6 @@ export const useGetAlertRuleDetailsTimelineTable = (): GetAlertRuleDetailsTimeli timelineFilter, updatedOrder, offset, - // JSON.stringify(filters.items), ], { queryFn: () => @@ -285,7 +284,6 @@ export const useGetAlertRuleDetailsTimelineTable = (): GetAlertRuleDetailsTimeli limit: TIMELINE_TABLE_PAGE_SIZE, order: updatedOrder, offset, - // filters, ...(timelineFilter && timelineFilter !== TimelineFilter.ALL ? { From 72239c8d574fd941e25fdaa070ac4ff22d4c89d1 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 20:58:07 +0430 Subject: [PATCH 17/28] chore: remove commented code --- .../container/AlertHistory/Timeline/Table/Table.styles.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss b/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss index fb21173e34..9d31e0b0ea 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.styles.scss @@ -91,9 +91,6 @@ } } .alert-history-label-search { - // .ant-select-selection-placeholder { - // text-align: left; - // } .ant-select-selector { border: none; } From 8932ffee4fd65fcb26aefad1f12bff7541ded24a Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 21:49:10 +0430 Subject: [PATCH 18/28] fix: show traces button when trace link is available --- .../src/container/AlertHistory/AlertPopover/AlertPopover.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx b/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx index 4162835fa6..83605a61d3 100644 --- a/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx +++ b/frontend/src/container/AlertHistory/AlertPopover/AlertPopover.tsx @@ -25,7 +25,7 @@ function PopoverContent({ const isDarkMode = useIsDarkMode(); return (
- {!!relatedTracesLink && ( + {!!relatedLogsLink && ( View Logs
)} - {!!relatedLogsLink && ( + {!!relatedTracesLink && ( Date: Tue, 3 Sep 2024 21:57:53 +0430 Subject: [PATCH 19/28] fix: display horizontal chart even for a single entry --- frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx b/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx index c331d93532..be4b833cc6 100644 --- a/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx @@ -22,7 +22,7 @@ function HorizontalTimelineGraph({ data: AlertRuleTimelineGraphResponse[]; }): JSX.Element { const transformedData: AlignedData = useMemo(() => { - if (data?.length <= 1) { + if (!data?.length) { return [[], []]; } From bc53f2d1cacaf4f62d2ee1cc32157113874913ab Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 21:58:51 +0430 Subject: [PATCH 20/28] fix: show inactive state in horizontal similar to normal state --- frontend/src/container/AlertHistory/Timeline/Graph/constants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts b/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts index 34a79df486..f8a752e27f 100644 --- a/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts +++ b/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts @@ -2,6 +2,7 @@ import { Color } from '@signozhq/design-tokens'; export const ALERT_STATUS: { [key: string]: number } = { firing: 0, + inactive: 0, normal: 1, 'no-data': 2, disabled: 3, From 938173022d2c8435051972d49bebf0282bd0c423 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 22:54:16 +0430 Subject: [PATCH 21/28] fix: properly render inactive state in horizontal chart --- frontend/src/container/AlertHistory/Timeline/Graph/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts b/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts index f8a752e27f..b56499a0d0 100644 --- a/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts +++ b/frontend/src/container/AlertHistory/Timeline/Graph/constants.ts @@ -2,7 +2,7 @@ import { Color } from '@signozhq/design-tokens'; export const ALERT_STATUS: { [key: string]: number } = { firing: 0, - inactive: 0, + inactive: 1, normal: 1, 'no-data': 2, disabled: 3, From df46918d08eb50d469bea9b8b4693f27e7273605 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 3 Sep 2024 22:56:21 +0430 Subject: [PATCH 22/28] fix: properly handle preserving alert toggle between overview and history tabs --- frontend/src/AppRoutes/index.tsx | 35 ++++++++------- .../ActionButtons/ActionButtons.tsx | 24 +++++------ .../AlertDetails/AlertHeader/AlertHeader.tsx | 20 ++++++--- frontend/src/pages/AlertDetails/hooks.tsx | 28 ++++++------ frontend/src/providers/Alert.tsx | 43 +++++++++++++++++++ 5 files changed, 98 insertions(+), 52 deletions(-) create mode 100644 frontend/src/providers/Alert.tsx diff --git a/frontend/src/AppRoutes/index.tsx b/frontend/src/AppRoutes/index.tsx index 23e7ea9644..b900255172 100644 --- a/frontend/src/AppRoutes/index.tsx +++ b/frontend/src/AppRoutes/index.tsx @@ -19,6 +19,7 @@ import { ResourceProvider } from 'hooks/useResourceAttribute'; import history from 'lib/history'; import { identity, pick, pickBy } from 'lodash-es'; import posthog from 'posthog-js'; +import AlertRuleProvider from 'providers/Alert'; import { DashboardProvider } from 'providers/Dashboard/Dashboard'; import { QueryBuilderProvider } from 'providers/QueryBuilder'; import { Suspense, useEffect, useState } from 'react'; @@ -236,22 +237,24 @@ function App(): JSX.Element { - - }> - - {routes.map(({ path, component, exact }) => ( - - ))} - - - - - + + + }> + + {routes.map(({ path, component, exact }) => ( + + ))} + + + + + + diff --git a/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx b/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx index 5fc485f2a0..982f3a76e7 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx @@ -14,6 +14,7 @@ import { useAlertRuleStatusToggle, } from 'pages/AlertDetails/hooks'; import CopyToClipboard from 'periscope/components/CopyToClipboard'; +import { useAlertRule } from 'providers/Alert'; import React, { useCallback, useState } from 'react'; import { AlertDef } from 'types/api/alerts/def'; @@ -49,19 +50,14 @@ function DropdownMenuRenderer( function AlertActionButtons({ ruleId, - state, alertDetails, }: { ruleId: string; - state: string; alertDetails: AlertHeaderProps['alertDetails']; }): JSX.Element { const [dropdownOpen, setDropdownOpen] = useState(false); - - const { - handleAlertStateToggle, - isAlertRuleEnabled, - } = useAlertRuleStatusToggle({ ruleId, state }); + const { isAlertRuleDisabled } = useAlertRule(); + const { handleAlertStateToggle } = useAlertRuleStatusToggle({ ruleId }); const { handleAlertDuplicate } = useAlertRuleDuplicate({ alertDetails: (alertDetails as unknown) as AlertDef, @@ -101,12 +97,14 @@ function AlertActionButtons({ return (
- - + + {isAlertRuleDisabled !== undefined && ( + + )} diff --git a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx index 8f61f73742..94c7d2532a 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx @@ -1,6 +1,7 @@ import './AlertHeader.styles.scss'; -import { useMemo } from 'react'; +import { useAlertRule } from 'providers/Alert'; +import { useEffect, useMemo } from 'react'; import AlertActionButtons from './ActionButtons/ActionButtons'; import AlertLabels from './AlertLabels/AlertLabels'; @@ -13,10 +14,11 @@ export type AlertHeaderProps = { alert: string; id: string; labels: Record; + disabled: boolean; }; }; function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element { - const { state, alert, labels } = alertDetails; + const { state, alert, labels, disabled } = alertDetails; const labelsWithoutSeverity = useMemo( () => @@ -26,6 +28,14 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element { [labels], ); + const { isAlertRuleDisabled, setIsAlertRuleDisabled } = useAlertRule(); + + useEffect(() => { + if (isAlertRuleDisabled === undefined) { + setIsAlertRuleDisabled(disabled); + } + }, [disabled, setIsAlertRuleDisabled, isAlertRuleDisabled]); + return (
@@ -47,11 +57,7 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
- +
); diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 3df9d03a34..2fde760cf1 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -27,7 +27,8 @@ import { History, Table } from 'lucide-react'; import EditRules from 'pages/EditRules'; import { OrderPreferenceItems } from 'pages/Logs/config'; import PaginationInfoText from 'periscope/components/PaginationInfoText/PaginationInfoText'; -import { useCallback, useMemo, useState } from 'react'; +import { useAlertRule } from 'providers/Alert'; +import { useCallback, useMemo } from 'react'; import { useMutation, useQuery, useQueryClient } from 'react-query'; import { useSelector } from 'react-redux'; import { generatePath, useLocation } from 'react-router-dom'; @@ -363,20 +364,14 @@ export const useTimelineTable = ({ }; export const useAlertRuleStatusToggle = ({ - state, ruleId, }: { - state: string; ruleId: string; }): { handleAlertStateToggle: (state: boolean) => void; - isAlertRuleEnabled: boolean; } => { + const { isAlertRuleDisabled, setIsAlertRuleDisabled } = useAlertRule(); const { notifications } = useNotifications(); - const isAlertRuleInitiallyEnabled = state !== 'disabled'; - const [isAlertRuleEnabled, setIsAlertRuleEnabled] = useState( - isAlertRuleInitiallyEnabled, - ); const queryClient = useQueryClient(); const handleError = useAxiosError(); @@ -386,28 +381,29 @@ export const useAlertRuleStatusToggle = ({ patchAlert, { onMutate: () => { - setIsAlertRuleEnabled((prev) => !prev); + setIsAlertRuleDisabled((prev) => !prev); }, onSuccess: () => { notifications.success({ - message: `Alert has been ${!isAlertRuleEnabled ? 'enabled' : 'disabled'}.`, + message: `Alert has been ${isAlertRuleDisabled ? 'enabled' : 'disabled'}.`, }); - - queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS]); }, onError: (error) => { - setIsAlertRuleEnabled(isAlertRuleInitiallyEnabled); + queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS]); handleError(error); }, }, ); - const handleAlertStateToggle = (state: boolean): void => { - const args = { id: parseInt(ruleId, 10), data: { disabled: !state } }; + const handleAlertStateToggle = (): void => { + const args = { + id: parseInt(ruleId, 10), + data: { disabled: !isAlertRuleDisabled }, + }; toggleAlertState(args); }; - return { handleAlertStateToggle, isAlertRuleEnabled }; + return { handleAlertStateToggle }; }; export const useAlertRuleDuplicate = ({ diff --git a/frontend/src/providers/Alert.tsx b/frontend/src/providers/Alert.tsx new file mode 100644 index 0000000000..337eec9ba5 --- /dev/null +++ b/frontend/src/providers/Alert.tsx @@ -0,0 +1,43 @@ +import React, { createContext, useContext, useState } from 'react'; + +interface AlertRuleContextType { + isAlertRuleDisabled: boolean | undefined; + setIsAlertRuleDisabled: React.Dispatch< + React.SetStateAction + >; +} + +const AlertRuleContext = createContext( + undefined, +); + +function AlertRuleProvider({ + children, +}: { + children: React.ReactNode; +}): JSX.Element { + const [isAlertRuleDisabled, setIsAlertRuleDisabled] = useState< + boolean | undefined + >(undefined); + + const value = React.useMemo( + () => ({ isAlertRuleDisabled, setIsAlertRuleDisabled }), + [isAlertRuleDisabled], + ); + + return ( + + {children} + + ); +} + +export const useAlertRule = (): AlertRuleContextType => { + const context = useContext(AlertRuleContext); + if (context === undefined) { + throw new Error('useAlertRule must be used within an AlertRuleProvider'); + } + return context; +}; + +export default AlertRuleProvider; From d813146dee52d9ccecb4dcd6ec008f62e67b5fc9 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 09:34:58 +0430 Subject: [PATCH 23/28] feat: get page size from query param --- frontend/src/pages/AlertDetails/hooks.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/AlertDetails/hooks.tsx b/frontend/src/pages/AlertDetails/hooks.tsx index 2fde760cf1..fc6219b195 100644 --- a/frontend/src/pages/AlertDetails/hooks.tsx +++ b/frontend/src/pages/AlertDetails/hooks.tsx @@ -350,9 +350,11 @@ export const useTimelineTable = ({ ); const offsetInt = parseInt(offset, 10); + const pageSize = params.get('pageSize') ?? String(TIMELINE_TABLE_PAGE_SIZE); + const pageSizeInt = parseInt(pageSize, 10); const paginationConfig: TablePaginationConfig = { - pageSize: TIMELINE_TABLE_PAGE_SIZE, + pageSize: pageSizeInt, showTotal: PaginationInfoText, current: offsetInt / TIMELINE_TABLE_PAGE_SIZE + 1, showSizeChanger: false, From 3cae368ded6349eb7746ee33f4e72081cfdcfc64 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 13:03:16 +0430 Subject: [PATCH 24/28] chore: remove commented code + minor refactor --- .../src/container/AlertHistory/Timeline/Graph/Graph.tsx | 6 ++++-- .../src/container/AlertHistory/Timeline/Table/Table.tsx | 1 - frontend/tsconfig.tmp | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 frontend/tsconfig.tmp diff --git a/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx b/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx index be4b833cc6..a0534691df 100644 --- a/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Graph/Graph.tsx @@ -26,9 +26,11 @@ function HorizontalTimelineGraph({ return [[], []]; } - // add a first and last entry to make sure + // add a first and last entry to make sure the graph displays all the data + const FIVE_MINUTES_IN_SECONDS = 300; + const timestamps = [ - data[0].start / 1000 - 300, // 5 minutes before the first entry + data[0].start / 1000 - FIVE_MINUTES_IN_SECONDS, // 5 minutes before the first entry ...data.map((item) => item.start / 1000), data[data.length - 1].end / 1000, // end value of last entry ]; diff --git a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx index 48b6144746..f3144b88e6 100644 --- a/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx +++ b/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx @@ -19,7 +19,6 @@ function TimelineTable(): JSX.Element { isValidRuleId, ruleId, } = useGetAlertRuleDetailsTimelineTable(); - // { filters } const { timelineData, totalItems } = useMemo(() => { const response = data?.payload?.data; diff --git a/frontend/tsconfig.tmp b/frontend/tsconfig.tmp new file mode 100644 index 0000000000..e82b80c1a7 --- /dev/null +++ b/frontend/tsconfig.tmp @@ -0,0 +1 @@ +{ "extends": "./tsconfig.json", "include": [ "src/typings/**/*.ts","src/**/*.d.ts", "./babel.config.js", "./jest.config.ts", "./.eslintrc.js","./__mocks__","./conf/default.conf","./public","./tests","./playwright.config.ts","./commitlint.config.ts","./webpack.config.js","./webpack.config.prod.js","./jest.setup.ts","./**/*.d.ts", "/home/shaheer-kochai/projects/signoz/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx",] } From d19e593d55f74f08e47d7a414311056c3f0cb775 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 14:26:26 +0430 Subject: [PATCH 25/28] chore: remove tsconfi.tmp --- frontend/tsconfig.tmp | 1 - 1 file changed, 1 deletion(-) delete mode 100644 frontend/tsconfig.tmp diff --git a/frontend/tsconfig.tmp b/frontend/tsconfig.tmp deleted file mode 100644 index e82b80c1a7..0000000000 --- a/frontend/tsconfig.tmp +++ /dev/null @@ -1 +0,0 @@ -{ "extends": "./tsconfig.json", "include": [ "src/typings/**/*.ts","src/**/*.d.ts", "./babel.config.js", "./jest.config.ts", "./.eslintrc.js","./__mocks__","./conf/default.conf","./public","./tests","./playwright.config.ts","./commitlint.config.ts","./webpack.config.js","./webpack.config.prod.js","./jest.setup.ts","./**/*.d.ts", "/home/shaheer-kochai/projects/signoz/frontend/src/container/AlertHistory/Timeline/Table/Table.tsx",] } From 53dfbd873e598e102a8eeae0f516cbbb575aa769 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 16:42:21 +0430 Subject: [PATCH 26/28] fix: don't add default relative time if start and times exist in the url --- frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx b/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx index 0d08f6529b..cd4fb97d4f 100644 --- a/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx +++ b/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx @@ -472,6 +472,8 @@ function DateTimeSelection({ // set the default relative time for alert history and overview pages if relative time is not specified if ( + (!urlQuery.has(QueryParams.startTime) || + !urlQuery.has(QueryParams.endTime)) && !urlQuery.has(QueryParams.relativeTime) && (currentRoute === ROUTES.ALERT_OVERVIEW || currentRoute === ROUTES.ALERT_HISTORY) From 1b74947ea864b758a82d7a9355a367025773cffd Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 16:58:24 +0430 Subject: [PATCH 27/28] feat: display date range preview for stat cards --- .../Statistics/StatsCard/StatsCard.tsx | 35 ++++++++++++++++++- .../Statistics/StatsCard/utils.ts | 12 +++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 frontend/src/container/AlertHistory/Statistics/StatsCard/utils.ts diff --git a/frontend/src/container/AlertHistory/Statistics/StatsCard/StatsCard.tsx b/frontend/src/container/AlertHistory/Statistics/StatsCard/StatsCard.tsx index 22f1551570..f204579f93 100644 --- a/frontend/src/container/AlertHistory/Statistics/StatsCard/StatsCard.tsx +++ b/frontend/src/container/AlertHistory/Statistics/StatsCard/StatsCard.tsx @@ -1,12 +1,18 @@ import './StatsCard.styles.scss'; import { Color } from '@signozhq/design-tokens'; +import { Tooltip } from 'antd'; +import { QueryParams } from 'constants/query'; import useUrlQuery from 'hooks/useUrlQuery'; import { ArrowDownLeft, ArrowUpRight, Calendar } from 'lucide-react'; import { AlertRuleStats } from 'types/api/alerts/def'; import { calculateChange } from 'utils/calculateChange'; import StatsGraph from './StatsGraph/StatsGraph'; +import { + convertTimestampToLocaleDateString, + extractDayFromTimestamp, +} from './utils'; type ChangePercentageProps = { percentage: number; @@ -78,6 +84,25 @@ function StatsCard({ totalPastCount, ); + const startTime = urlQuery.get(QueryParams.startTime); + const endTime = urlQuery.get(QueryParams.endTime); + + let displayTime = relativeTime; + + if (!displayTime && startTime && endTime) { + const formattedStartDate = extractDayFromTimestamp(startTime); + const formattedEndDate = extractDayFromTimestamp(endTime); + displayTime = `${formattedStartDate} to ${formattedEndDate}`; + } + + if (!displayTime) { + displayTime = ''; + } + const formattedStartTimeForTooltip = convertTimestampToLocaleDateString( + startTime, + ); + const formattedEndTimeForTooltip = convertTimestampToLocaleDateString(endTime); + return (
@@ -86,7 +111,15 @@ function StatsCard({
-
{relativeTime}
+ {relativeTime ? ( +
{displayTime}
+ ) : ( + +
{displayTime}
+
+ )}
diff --git a/frontend/src/container/AlertHistory/Statistics/StatsCard/utils.ts b/frontend/src/container/AlertHistory/Statistics/StatsCard/utils.ts new file mode 100644 index 0000000000..a2584aad37 --- /dev/null +++ b/frontend/src/container/AlertHistory/Statistics/StatsCard/utils.ts @@ -0,0 +1,12 @@ +export const extractDayFromTimestamp = (timestamp: string | null): string => { + if (!timestamp) return ''; + const date = new Date(parseInt(timestamp, 10)); + return date.getDate().toString(); +}; + +export const convertTimestampToLocaleDateString = ( + timestamp: string | null, +): string => { + if (!timestamp) return ''; + return new Date(parseInt(timestamp, 10)).toLocaleString(); +}; From 3b60559146bd948007d28efd73e387acc8af607b Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 4 Sep 2024 17:17:17 +0430 Subject: [PATCH 28/28] chore: remove custom dropdown renderer component --- .../ActionButtons/ActionButtons.tsx | 65 ++++++------------- 1 file changed, 20 insertions(+), 45 deletions(-) diff --git a/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx b/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx index 982f3a76e7..183b4d2aaa 100644 --- a/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx +++ b/frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx @@ -1,7 +1,7 @@ import './ActionButtons.styles.scss'; import { Color } from '@signozhq/design-tokens'; -import { Button, Divider, Dropdown, MenuProps, Switch, Tooltip } from 'antd'; +import { Divider, Dropdown, MenuProps, Switch, Tooltip } from 'antd'; import { QueryParams } from 'constants/query'; import ROUTES from 'constants/routes'; import { useIsDarkMode } from 'hooks/useDarkMode'; @@ -15,39 +15,16 @@ import { } from 'pages/AlertDetails/hooks'; import CopyToClipboard from 'periscope/components/CopyToClipboard'; import { useAlertRule } from 'providers/Alert'; -import React, { useCallback, useState } from 'react'; +import React from 'react'; +import { CSSProperties } from 'styled-components'; import { AlertDef } from 'types/api/alerts/def'; import { AlertHeaderProps } from '../AlertHeader'; -const menuStyle: React.CSSProperties = { - padding: 0, - boxShadow: 'none', - fontSize: 14, +const menuItemStyle: CSSProperties = { + fontSize: '14px', + letterSpacing: '0.14px', }; - -function DropdownMenuRenderer( - menu: React.ReactNode, - handleDelete: () => void, -): React.ReactNode { - return ( -
- {React.cloneElement(menu as React.ReactElement, { - style: menuStyle, - })} - - -
- ); -} - function AlertActionButtons({ ruleId, alertDetails, @@ -55,7 +32,6 @@ function AlertActionButtons({ ruleId: string; alertDetails: AlertHeaderProps['alertDetails']; }): JSX.Element { - const [dropdownOpen, setDropdownOpen] = useState(false); const { isAlertRuleDisabled } = useAlertRule(); const { handleAlertStateToggle } = useAlertRuleStatusToggle({ ruleId }); @@ -64,11 +40,6 @@ function AlertActionButtons({ }); const { handleAlertDelete } = useAlertRuleDelete({ ruleId: Number(ruleId) }); - const handleDeleteWithClose = useCallback(() => { - handleAlertDelete(); - setDropdownOpen(false); - }, [handleAlertDelete]); - const params = useUrlQuery(); const handleRename = React.useCallback(() => { @@ -83,15 +54,27 @@ function AlertActionButtons({ label: 'Rename', icon: , onClick: (): void => handleRename(), + style: menuItemStyle, }, { key: 'duplicate-rule', label: 'Duplicate', icon: , onClick: (): void => handleAlertDuplicate(), + style: menuItemStyle, + }, + { + key: 'delete-rule', + label: 'Delete', + icon: , + onClick: (): void => handleAlertDelete(), + style: { + ...menuItemStyle, + color: Color.BG_CHERRY_400, + }, }, ], - [handleAlertDuplicate, handleRename], + [handleAlertDelete, handleAlertDuplicate, handleRename], ); const isDarkMode = useIsDarkMode(); @@ -110,15 +93,7 @@ function AlertActionButtons({ - - DropdownMenuRenderer(menu, handleDeleteWithClose) - } - > +