From f487f088bd899ae6940653964c5858705ab3b1ab Mon Sep 17 00:00:00 2001 From: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com> Date: Wed, 28 May 2025 21:24:26 +0530 Subject: [PATCH 1/4] Revert "feat: improved the alert rules list search functionality" (#8085) * Revert "feat: improved the alert rules list search functionality (#8075)" This reverts commit bec52c3d3e3b95dc8ca72bda5c237b3e7b2d02dc. * feat: added search capability for labels * feat: added test cases --- .../container/ListAlertRules/ListAlert.tsx | 60 +------ .../ListAlertRules/__test__/utils.test.ts | 131 ++++++++++++++ .../src/container/ListAlertRules/styles.ts | 18 -- .../container/ListAlertRules/utils.test.ts | 162 ------------------ .../src/container/ListAlertRules/utils.ts | 111 ++---------- 5 files changed, 154 insertions(+), 328 deletions(-) create mode 100644 frontend/src/container/ListAlertRules/__test__/utils.test.ts delete mode 100644 frontend/src/container/ListAlertRules/utils.test.ts diff --git a/frontend/src/container/ListAlertRules/ListAlert.tsx b/frontend/src/container/ListAlertRules/ListAlert.tsx index 07db958916..0ad805ede8 100644 --- a/frontend/src/container/ListAlertRules/ListAlert.tsx +++ b/frontend/src/container/ListAlertRules/ListAlert.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/display-name */ -import { InfoCircleOutlined, PlusOutlined } from '@ant-design/icons'; -import { Flex, Input, Tooltip, Typography } from 'antd'; +import { PlusOutlined } from '@ant-design/icons'; +import { Flex, Input, Typography } from 'antd'; import type { ColumnsType } from 'antd/es/table/interface'; import saveAlertApi from 'api/alerts/save'; import logEvent from 'api/common/logEvent'; @@ -175,41 +175,6 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element { setData(filteredData); }); - const searchTooltipContent = ( -
-
Search Options:
-
- • Plain text: Search across all fields -
-
- • Key:value pairs: Specific field matching -
-
- • Multiple terms: All terms must match (AND logic) -
-
- • Status mapping: Use "ok" for inactive alerts -
-
Examples:
-
- • cpu warning - Find alerts with both "cpu" and - "warning" -
-
- • status:ok - Find alerts with OK status -
-
- • severity:critical - Find critical alerts -
-
- • cluster:prod - Find alerts with cluster=prod label -
-
- • status:ok cpu - Find OK alerts containing "cpu" -
-
- ); - const dynamicColumns: ColumnsType = [ { title: 'Created At', @@ -379,22 +344,11 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element { return ( <> -
- - - - -
- - } - /> -
- + {addNewAlert && (
({ + const initialFilters = useMemo(() => { + const urlView = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.VIEW); + const queryKey = + urlView === VIEW_TYPES.LOGS + ? INFRA_MONITORING_K8S_PARAMS_KEYS.LOG_FILTERS + : INFRA_MONITORING_K8S_PARAMS_KEYS.TRACES_FILTERS; + const filters = getFiltersFromParams(searchParams, queryKey); + if (filters) { + return filters; + } + + return { op: 'AND', items: [ { @@ -111,9 +123,8 @@ function HostMetricsDetails({ value: host?.hostName || '', }, ], - }), - [host?.hostName], - ); + }; + }, [host?.hostName, searchParams]); const [logFilters, setLogFilters] = useState( initialFilters, @@ -154,7 +165,13 @@ function HostMetricsDetails({ const handleTabChange = (e: RadioChangeEvent): void => { setSelectedView(e.target.value); if (host?.hostName) { - setSearchParams({ hostName: host?.hostName, view: e.target.value }); + setSelectedView(e.target.value); + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.VIEW]: e.target.value, + [INFRA_MONITORING_K8S_PARAMS_KEYS.LOG_FILTERS]: JSON.stringify(null), + [INFRA_MONITORING_K8S_PARAMS_KEYS.TRACES_FILTERS]: JSON.stringify(null), + }); } logEvent(InfraMonitoringEvents.TabChanged, { entity: InfraMonitoringEvents.HostEntity, @@ -191,7 +208,7 @@ function HostMetricsDetails({ ); const handleChangeLogFilters = useCallback( - (value: IBuilderQuery['filters']) => { + (value: IBuilderQuery['filters'], view: VIEWS) => { setLogFilters((prevFilters) => { const hostNameFilter = prevFilters.items.find( (item) => item.key?.key === 'host.name', @@ -209,7 +226,7 @@ function HostMetricsDetails({ }); } - return { + const updatedFilters = { op: 'AND', items: [ hostNameFilter, @@ -217,6 +234,15 @@ function HostMetricsDetails({ ...(paginationFilter ? [paginationFilter] : []), ].filter((item): item is TagFilterItem => item !== undefined), }; + + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.LOG_FILTERS]: JSON.stringify( + updatedFilters, + ), + [INFRA_MONITORING_K8S_PARAMS_KEYS.VIEW]: view, + }); + return updatedFilters; }); }, // eslint-disable-next-line react-hooks/exhaustive-deps @@ -224,7 +250,7 @@ function HostMetricsDetails({ ); const handleChangeTracesFilters = useCallback( - (value: IBuilderQuery['filters']) => { + (value: IBuilderQuery['filters'], view: VIEWS) => { setTracesFilters((prevFilters) => { const hostNameFilter = prevFilters.items.find( (item) => item.key?.key === 'host.name', @@ -238,13 +264,23 @@ function HostMetricsDetails({ }); } - return { + const updatedFilters = { op: 'AND', items: [ hostNameFilter, ...value.items.filter((item) => item.key?.key !== 'host.name'), ].filter((item): item is TagFilterItem => item !== undefined), }; + + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.TRACES_FILTERS]: JSON.stringify( + updatedFilters, + ), + [INFRA_MONITORING_K8S_PARAMS_KEYS.VIEW]: view, + }); + + return updatedFilters; }); }, // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/frontend/src/components/HostMetricsDetail/HostMetricsLogs/HostMetricLogsDetailedView.tsx b/frontend/src/components/HostMetricsDetail/HostMetricsLogs/HostMetricLogsDetailedView.tsx index 611295f8f3..7fe06a641e 100644 --- a/frontend/src/components/HostMetricsDetail/HostMetricsLogs/HostMetricLogsDetailedView.tsx +++ b/frontend/src/components/HostMetricsDetail/HostMetricsLogs/HostMetricLogsDetailedView.tsx @@ -11,6 +11,7 @@ import { useMemo } from 'react'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { DataSource } from 'types/common/queryBuilder'; +import { VIEWS } from '../constants'; import HostMetricsLogs from './HostMetricsLogs'; interface Props { @@ -23,7 +24,7 @@ interface Props { interval: Time | CustomTimeType, dateTimeRange?: [number, number], ) => void; - handleChangeLogFilters: (value: IBuilderQuery['filters']) => void; + handleChangeLogFilters: (value: IBuilderQuery['filters'], view: VIEWS) => void; logFilters: IBuilderQuery['filters']; selectedInterval: Time; } @@ -51,14 +52,14 @@ function HostMetricLogsDetailedView({ ...currentQuery.builder.queryData[0].aggregateAttribute, }, filters: { - items: [], + items: logFilters.items.filter((item) => item.key?.key !== 'host.name'), op: 'AND', }, }, ], }, }), - [currentQuery], + [currentQuery, logFilters.items], ); const query = updatedCurrentQuery?.builder?.queryData[0] || null; @@ -70,14 +71,14 @@ function HostMetricLogsDetailedView({ {query && ( handleChangeLogFilters(value, VIEWS.LOGS)} disableNavigationShortcuts /> )}
( + new Array(queries.length).fill({ + start: timeRange.startTime, + end: timeRange.endTime, + }), + ); + + useEffect(() => { + setGraphTimeIntervals( + new Array(queries.length).fill({ + start: timeRange.startTime, + end: timeRange.endTime, + }), + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [timeRange]); + + const onDragSelect = useCallback( + (start: number, end: number, graphIndex: number) => { + const startTimestamp = Math.trunc(start); + const endTimestamp = Math.trunc(end); + + setGraphTimeIntervals((prev) => { + const newIntervals = [...prev]; + newIntervals[graphIndex] = { + start: Math.floor(startTimestamp / 1000), + end: Math.floor(endTimestamp / 1000), + }; + return newIntervals; + }); + }, + [], + ); + const options = useMemo( () => queries.map(({ data }, idx) => @@ -78,12 +117,12 @@ function Metrics({ yAxisUnit: hostWidgetInfo[idx].yAxisUnit, softMax: null, softMin: null, - minTimeScale: timeRange.startTime, - maxTimeScale: timeRange.endTime, - enableZoom: true, + minTimeScale: graphTimeIntervals[idx].start, + maxTimeScale: graphTimeIntervals[idx].end, + onDragSelect: (start, end) => onDragSelect(start, end, idx), }), ), - [queries, isDarkMode, dimensions, timeRange.startTime, timeRange.endTime], + [queries, isDarkMode, dimensions, graphTimeIntervals, onDragSelect], ); const renderCardContent = ( diff --git a/frontend/src/container/InfraMonitoringHosts/HostsListControls.tsx b/frontend/src/container/InfraMonitoringHosts/HostsListControls.tsx index ca0e85e752..8b4f7b1a3b 100644 --- a/frontend/src/container/InfraMonitoringHosts/HostsListControls.tsx +++ b/frontend/src/container/InfraMonitoringHosts/HostsListControls.tsx @@ -58,7 +58,7 @@ function HostsListControls({
diff --git a/frontend/src/container/InfraMonitoringK8s/Clusters/K8sClustersList.tsx b/frontend/src/container/InfraMonitoringK8s/Clusters/K8sClustersList.tsx index 6732d018dc..aef7bb491a 100644 --- a/frontend/src/container/InfraMonitoringK8s/Clusters/K8sClustersList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/Clusters/K8sClustersList.tsx @@ -59,11 +59,26 @@ function K8sClustersList({ (state) => state.globalTime, ); - const [currentPage, setCurrentPage] = useState(1); - - const [expandedRowKeys, setExpandedRowKeys] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + const [expandedRowKeys, setExpandedRowKeys] = useState([]); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); + const [orderBy, setOrderBy] = useState<{ columnName: string; order: 'asc' | 'desc'; @@ -115,7 +130,9 @@ function K8sClustersList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -309,7 +326,11 @@ function K8sClustersList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -319,7 +340,8 @@ function K8sClustersList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/DaemonSets/K8sDaemonSetsList.tsx b/frontend/src/container/InfraMonitoringK8s/DaemonSets/K8sDaemonSetsList.tsx index a104144e52..767b175347 100644 --- a/frontend/src/container/InfraMonitoringK8s/DaemonSets/K8sDaemonSetsList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/DaemonSets/K8sDaemonSetsList.tsx @@ -61,11 +61,26 @@ function K8sDaemonSetsList({ (state) => state.globalTime, ); - const [currentPage, setCurrentPage] = useState(1); const [searchParams, setSearchParams] = useSearchParams(); + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); const [expandedRowKeys, setExpandedRowKeys] = useState([]); + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); + const [orderBy, setOrderBy] = useState<{ columnName: string; order: 'asc' | 'desc'; @@ -117,7 +132,9 @@ function K8sDaemonSetsList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -313,7 +330,11 @@ function K8sDaemonSetsList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -323,7 +344,8 @@ function K8sDaemonSetsList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/Deployments/K8sDeploymentsList.tsx b/frontend/src/container/InfraMonitoringK8s/Deployments/K8sDeploymentsList.tsx index b4294226bc..1bbb58bb1a 100644 --- a/frontend/src/container/InfraMonitoringK8s/Deployments/K8sDeploymentsList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/Deployments/K8sDeploymentsList.tsx @@ -61,10 +61,26 @@ function K8sDeploymentsList({ (state) => state.globalTime, ); - const [currentPage, setCurrentPage] = useState(1); + const [searchParams, setSearchParams] = useSearchParams(); + + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); const [expandedRowKeys, setExpandedRowKeys] = useState([]); - const [searchParams, setSearchParams] = useSearchParams(); const [orderBy, setOrderBy] = useState<{ columnName: string; @@ -117,7 +133,9 @@ function K8sDeploymentsList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -315,7 +333,11 @@ function K8sDeploymentsList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -325,7 +347,8 @@ function K8sDeploymentsList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents/EntityEvents.tsx b/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents/EntityEvents.tsx index 97808f2d29..20037b8956 100644 --- a/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents/EntityEvents.tsx +++ b/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents/EntityEvents.tsx @@ -259,7 +259,7 @@ export default function Events({
({ [queries], ); + const [graphTimeIntervals, setGraphTimeIntervals] = useState< + { + start: number; + end: number; + }[] + >( + new Array(queries.length).fill({ + start: timeRange.startTime, + end: timeRange.endTime, + }), + ); + + useEffect(() => { + setGraphTimeIntervals( + new Array(queries.length).fill({ + start: timeRange.startTime, + end: timeRange.endTime, + }), + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [timeRange]); + + const onDragSelect = useCallback( + (start: number, end: number, graphIndex: number) => { + const startTimestamp = Math.trunc(start); + const endTimestamp = Math.trunc(end); + + setGraphTimeIntervals((prev) => { + const newIntervals = [...prev]; + newIntervals[graphIndex] = { + start: Math.floor(startTimestamp / 1000), + end: Math.floor(endTimestamp / 1000), + }; + return newIntervals; + }); + }, + [], + ); + const options = useMemo( () => queries.map(({ data }, idx) => { @@ -108,9 +147,9 @@ function EntityMetrics({ yAxisUnit: entityWidgetInfo[idx].yAxisUnit, softMax: null, softMin: null, - minTimeScale: timeRange.startTime, - maxTimeScale: timeRange.endTime, - enableZoom: true, + minTimeScale: graphTimeIntervals[idx].start, + maxTimeScale: graphTimeIntervals[idx].end, + onDragSelect: (start, end) => onDragSelect(start, end, idx), }); }), [ @@ -118,8 +157,8 @@ function EntityMetrics({ isDarkMode, dimensions, entityWidgetInfo, - timeRange.startTime, - timeRange.endTime, + graphTimeIntervals, + onDragSelect, ], ); diff --git a/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces/EntityTraces.tsx b/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces/EntityTraces.tsx index 925fa0e545..e0c367bf0c 100644 --- a/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces/EntityTraces.tsx +++ b/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces/EntityTraces.tsx @@ -177,7 +177,7 @@ function EntityTraces({
( (state) => state.globalTime, ); + const [searchParams, setSearchParams] = useSearchParams(); - const [currentPage, setCurrentPage] = useState(1); + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); const [expandedRowKeys, setExpandedRowKeys] = useState([]); - const [searchParams, setSearchParams] = useSearchParams(); const [orderBy, setOrderBy] = useState<{ columnName: string; @@ -112,7 +127,9 @@ function K8sJobsList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -300,7 +317,11 @@ function K8sJobsList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -310,7 +331,8 @@ function K8sJobsList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/K8sHeader.tsx b/frontend/src/container/InfraMonitoringK8s/K8sHeader.tsx index fa9eaf2d6f..f22519285f 100644 --- a/frontend/src/container/InfraMonitoringK8s/K8sHeader.tsx +++ b/frontend/src/container/InfraMonitoringK8s/K8sHeader.tsx @@ -136,7 +136,7 @@ function K8sHeader({
diff --git a/frontend/src/container/InfraMonitoringK8s/Namespaces/K8sNamespacesList.tsx b/frontend/src/container/InfraMonitoringK8s/Namespaces/K8sNamespacesList.tsx index 6f076132cf..4d2cc2a847 100644 --- a/frontend/src/container/InfraMonitoringK8s/Namespaces/K8sNamespacesList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/Namespaces/K8sNamespacesList.tsx @@ -60,11 +60,26 @@ function K8sNamespacesList({ (state) => state.globalTime, ); - const [currentPage, setCurrentPage] = useState(1); - const [expandedRowKeys, setExpandedRowKeys] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); + const [orderBy, setOrderBy] = useState<{ columnName: string; order: 'asc' | 'desc'; @@ -116,7 +131,9 @@ function K8sNamespacesList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -312,7 +329,11 @@ function K8sNamespacesList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -322,7 +343,8 @@ function K8sNamespacesList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/Nodes/K8sNodesList.tsx b/frontend/src/container/InfraMonitoringK8s/Nodes/K8sNodesList.tsx index 441346980f..107a13454a 100644 --- a/frontend/src/container/InfraMonitoringK8s/Nodes/K8sNodesList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/Nodes/K8sNodesList.tsx @@ -59,12 +59,26 @@ function K8sNodesList({ const { maxTime, minTime } = useSelector( (state) => state.globalTime, ); - - const [currentPage, setCurrentPage] = useState(1); - - const [expandedRowKeys, setExpandedRowKeys] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); + + const [expandedRowKeys, setExpandedRowKeys] = useState([]); const [orderBy, setOrderBy] = useState<{ columnName: string; order: 'asc' | 'desc'; @@ -111,7 +125,9 @@ function K8sNodesList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -299,7 +315,11 @@ function K8sNodesList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -309,7 +329,8 @@ function K8sNodesList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/Pods/K8sPodLists.tsx b/frontend/src/container/InfraMonitoringK8s/Pods/K8sPodLists.tsx index f6bc79171e..acbb003925 100644 --- a/frontend/src/container/InfraMonitoringK8s/Pods/K8sPodLists.tsx +++ b/frontend/src/container/InfraMonitoringK8s/Pods/K8sPodLists.tsx @@ -64,7 +64,22 @@ function K8sPodsList({ ); const [searchParams, setSearchParams] = useSearchParams(); - const [currentPage, setCurrentPage] = useState(1); + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); const [addedColumns, setAddedColumns] = useState([]); @@ -123,7 +138,9 @@ function K8sPodsList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); useEffect(() => { @@ -314,7 +331,11 @@ function K8sPodsList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -324,7 +345,8 @@ function K8sPodsList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); const handleGroupByChange = useCallback( diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/K8sStatefulSetsList.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/K8sStatefulSetsList.tsx index ba2b14f8de..e2dae778f6 100644 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/K8sStatefulSetsList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/StatefulSets/K8sStatefulSetsList.tsx @@ -60,10 +60,26 @@ function K8sStatefulSetsList({ (state) => state.globalTime, ); - const [currentPage, setCurrentPage] = useState(1); + const [searchParams, setSearchParams] = useSearchParams(); + + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); const [expandedRowKeys, setExpandedRowKeys] = useState([]); - const [searchParams, setSearchParams] = useSearchParams(); const [orderBy, setOrderBy] = useState<{ columnName: string; @@ -116,7 +132,9 @@ function K8sStatefulSetsList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -314,7 +332,11 @@ function K8sStatefulSetsList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -324,7 +346,8 @@ function K8sStatefulSetsList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/Volumes/K8sVolumesList.tsx b/frontend/src/container/InfraMonitoringK8s/Volumes/K8sVolumesList.tsx index 9ba4a75448..aa9a1c69dd 100644 --- a/frontend/src/container/InfraMonitoringK8s/Volumes/K8sVolumesList.tsx +++ b/frontend/src/container/InfraMonitoringK8s/Volumes/K8sVolumesList.tsx @@ -60,10 +60,26 @@ function K8sVolumesList({ (state) => state.globalTime, ); - const [currentPage, setCurrentPage] = useState(1); + const [searchParams, setSearchParams] = useSearchParams(); + + const [currentPage, setCurrentPage] = useState(() => { + const page = searchParams.get(INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE); + if (page) { + return parseInt(page, 10); + } + return 1; + }); + const [filtersInitialised, setFiltersInitialised] = useState(false); + + useEffect(() => { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + [INFRA_MONITORING_K8S_PARAMS_KEYS.CURRENT_PAGE]: currentPage.toString(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage]); const [expandedRowKeys, setExpandedRowKeys] = useState([]); - const [searchParams, setSearchParams] = useSearchParams(); const [orderBy, setOrderBy] = useState<{ columnName: string; @@ -116,7 +132,9 @@ function K8sVolumesList({ // Reset pagination every time quick filters are changed useEffect(() => { - setCurrentPage(1); + if (quickFiltersLastUpdated !== -1) { + setCurrentPage(1); + } }, [quickFiltersLastUpdated]); const createFiltersForSelectedRowData = ( @@ -304,7 +322,11 @@ function K8sVolumesList({ const handleFiltersChange = useCallback( (value: IBuilderQuery['filters']): void => { handleChangeQueryData('filters', value); - setCurrentPage(1); + if (filtersInitialised) { + setCurrentPage(1); + } else { + setFiltersInitialised(true); + } if (value.items.length > 0) { logEvent(InfraMonitoringEvents.FilterApplied, { @@ -314,7 +336,8 @@ function K8sVolumesList({ }); } }, - [handleChangeQueryData], + // eslint-disable-next-line react-hooks/exhaustive-deps + [], ); useEffect(() => { diff --git a/frontend/src/container/InfraMonitoringK8s/constants.ts b/frontend/src/container/InfraMonitoringK8s/constants.ts index a8bc29351f..d182922421 100644 --- a/frontend/src/container/InfraMonitoringK8s/constants.ts +++ b/frontend/src/container/InfraMonitoringK8s/constants.ts @@ -538,4 +538,5 @@ export const INFRA_MONITORING_K8S_PARAMS_KEYS = { TRACES_FILTERS: 'tracesFilters', EVENTS_FILTERS: 'eventsFilters', HOSTS_FILTERS: 'hostsFilters', + CURRENT_PAGE: 'currentPage', }; diff --git a/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx b/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx index e4c764ea3e..b390798bab 100644 --- a/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx +++ b/frontend/src/container/TopNav/DateTimeSelectionV2/index.tsx @@ -835,6 +835,7 @@ function DateTimeSelection({ onCustomDateHandler={onCustomDateHandler} customDateTimeVisible={customDateTimeVisible} setCustomDTPickerVisible={setCustomDTPickerVisible} + onTimeChange={onTimeChange} /> {showAutoRefresh && selectedTime !== 'custom' && (