From 03c986ba848a9dcea449900cddb866327b5ef776 Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 6 Nov 2024 17:38:06 +0530 Subject: [PATCH 01/16] Pages Params on Log Table --- src/pages/Stream/Views/Explore/LogsView.tsx | 19 +++++++++++-- src/pages/Stream/hooks/useParamsController.ts | 28 ++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index 056370e0..9f3da74c 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -1,17 +1,25 @@ import { Box } from '@mantine/core'; -import { useLogsStore } from '../../providers/LogsProvider'; +import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; import JsonView from './JSONView'; import LogTable from './StaticLogTable'; import useLogsFetcher from './useLogsFetcher'; import LogsViewConfig from './LogsViewConfig'; +import { useEffect, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; +import _ from 'lodash'; + +const { setPageAndPageData, setCurrentPage } = logsStoreReducers; const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { + const [searchParams] = useSearchParams(); + const [targetPage, setTargetPage] = useState(null); const { schemaLoading, infoLoading } = props; const { errorMessage, hasNoData, showTable, isFetchingCount, logsLoading } = useLogsFetcher({ schemaLoading, infoLoading, }); - const [viewMode] = useLogsStore((store) => store.viewMode); + + const [viewMode, setLogsStore] = useLogsStore((store) => store.viewMode); const viewOpts = { errorMessage, hasNoData, @@ -19,6 +27,13 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { isFetchingCount, logsLoading, }; + useEffect(() => { + setTargetPage(searchParams.get('page')); + if (showTable && (targetPage !== null || undefined || '0')) { + setLogsStore((store) => setPageAndPageData(store, _.toNumber(targetPage))); + setLogsStore((store) => setCurrentPage(store, _.toNumber(targetPage))); + } + }, [showTable]); return ( diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index c64811e6..b2cfa2ac 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -3,15 +3,15 @@ import { TimeRange, useLogsStore, logsStoreReducers } from '@/pages/Stream/provi import { useSearchParams } from 'react-router-dom'; import _ from 'lodash'; import { FIXED_DURATIONS } from '@/constants/timeConstants'; +import { LOAD_LIMIT, LOG_QUERY_LIMITS } from '@/pages/Stream/providers/LogsProvider'; import dayjs from 'dayjs'; import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; -const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState } = logsStoreReducers; +const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setCurrentOffset } = logsStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; -const keys = ['view', 'rows', 'interval', 'from', 'to', 'query']; -const FIXED_ROWS = ['50', '100', '150', '200']; +const keys = ['view', 'rows', 'interval', 'from', 'to', 'query', 'offset', 'page', 'fields']; const dateToParamString = (date: Date) => { return formatDateWithTimezone(date, timeRangeFormat); @@ -54,8 +54,9 @@ const storeToParamsObj = (opts: { page: string; rows: string; query: string; + fields: string; }): Record => { - const { timeRange, offset, page, view, rows, query } = opts; + const { timeRange, offset, page, view, rows, query, fields } = opts; const params: Record = { ...deriveTimeRangeParams(timeRange), view, @@ -63,6 +64,7 @@ const storeToParamsObj = (opts: { rows, page, query, + fields, }; return _.pickBy(params, (val, key) => !_.isEmpty(val) && _.includes(keys, key)); }; @@ -85,7 +87,7 @@ const useParamsController = () => { const [custQuerySearchState] = useLogsStore((store) => store.custQuerySearchState); const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); - const { currentOffset, currentPage, perPage } = tableOpts; + const { currentOffset, currentPage, perPage, pageData, headers } = tableOpts; const [searchParams, setSearchParams] = useSearchParams(); @@ -97,15 +99,25 @@ const useParamsController = () => { view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, + fields: `${headers}`, }); const presentParams = paramsStringToParamsObj(searchParams); if (['table', 'json'].includes(presentParams.view) && presentParams.view !== storeAsParams.view) { setLogsStore((store) => onToggleView(store, presentParams.view as 'table' | 'json')); } - if (storeAsParams.rows !== presentParams.rows && FIXED_ROWS.includes(presentParams.rows)) { + if (storeAsParams.rows !== presentParams.rows && LOG_QUERY_LIMITS.includes(_.toNumber(presentParams.rows))) { setLogsStore((store) => setPerPage(store, _.toNumber(presentParams.rows))); } + if (storeAsParams.offset !== presentParams.offset && _.toNumber(presentParams.offset) % LOAD_LIMIT === 0) { + setLogsStore((store) => setCurrentOffset(store, _.toNumber(presentParams.offset))); + } + + if (!_.isEmpty(pageData) && storeAsParams.page !== presentParams.page) { + console.log(presentParams.page); + // setLogsStore((store) => setCurrentPage(store, _.toNumber(presentParams.page))); + } + if (storeAsParams.query !== presentParams.query) { setLogsStore((store) => setCustQuerySearchState(store, presentParams.query)); } @@ -122,6 +134,7 @@ const useParamsController = () => { view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, + fields: `${headers}`, }); const presentParams = paramsStringToParamsObj(searchParams); if (_.isEqual(storeAsParams, presentParams)) return; @@ -139,6 +152,7 @@ const useParamsController = () => { view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, + fields: `${headers}`, }); const presentParams = paramsStringToParamsObj(searchParams); @@ -148,7 +162,7 @@ const useParamsController = () => { if (presentParams.view && presentParams.view !== storeAsParams.view) { setLogsStore((store) => onToggleView(store, presentParams.view as 'table' | 'json')); } - if (storeAsParams.rows !== presentParams.rows && FIXED_ROWS.includes(presentParams.rows)) { + if (storeAsParams.rows !== presentParams.rows && LOG_QUERY_LIMITS.includes(_.toNumber(presentParams.rows))) { setLogsStore((store) => setPerPage(store, _.toNumber(presentParams.rows))); } From 053d4c528da784b5988517edd9a05116861cd10d Mon Sep 17 00:00:00 2001 From: Koustav Date: Thu, 7 Nov 2024 17:04:21 +0530 Subject: [PATCH 02/16] Upgrade Logs Loader Hook to use useQuery --- package.json | 170 +++++++++--------- src/hooks/useQueryLogs.ts | 81 +++++---- src/pages/Stream/Views/Explore/LogsView.tsx | 17 +- src/pages/Stream/hooks/useParamsController.ts | 17 +- 4 files changed, 134 insertions(+), 151 deletions(-) diff --git a/package.json b/package.json index 64997678..161efca0 100644 --- a/package.json +++ b/package.json @@ -1,87 +1,87 @@ { - "name": "parseable-console", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "dev": "vite --host --port 3001", - "build": "tsc && vite build", - "build:test": "tsc && vite build --mode test", - "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "start": "vite preview --host --port 3002", - "tsCheck": "tsc --noEmit", - "pq": "pretty-quick" - }, - "dependencies": { - "@apache-arrow/ts": "^14.0.2", - "@emotion/react": "^11.11.1", - "@mantine/carousel": "^7.8.1", - "@mantine/charts": "^7.8.1", - "@mantine/code-highlight": "^7.8.1", - "@mantine/core": "^7.8.1", - "@mantine/dates": "^7.8.1", - "@mantine/form": "^7.8.1", - "@mantine/hooks": "^7.8.1", - "@mantine/notifications": "^7.8.1", - "@monaco-editor/react": "^4.5.1", - "@tabler/icons-react": "^3.3.0", - "@types/js-cookie": "^3.0.3", - "axios": "^1.4.0", - "dayjs": "^1.11.10", - "embla-carousel-react": "7.1.0", - "html2canvas": "^1.4.1", - "http-status-codes": "^2.2.0", - "immer": "^10.0.2", - "jq-web": "^0.5.1", - "js-cookie": "^3.0.5", - "just-compare": "^2.3.0", - "lodash": "^4.17.21", - "long": "^5.2.3", - "mantine-react-table": "2.0.0-beta.6", - "moment-timezone": "^0.5.45", - "ms": "^2.1.3", - "nice-grpc-common": "^2.0.2", - "nice-grpc-web": "^3.3.2", - "protobufjs": "^7.2.5", - "react": "^18.2.0", - "react-beautiful-dnd": "^13.1.1", - "react-dom": "^18.2.0", - "react-error-boundary": "^4.0.10", - "react-grid-layout": "^1.4.4", - "react-query": "^3.39.3", - "react-querybuilder": "^6.5.5", - "react-resizable": "^3.0.5", - "react-resizable-panels": "^0.0.53", - "react-router-dom": "^6.14.0", - "react-window": "^1.8.9" - }, - "devDependencies": { - "@playwright/test": "^1.48.2", - "@types/lodash": "^4.17.0", - "@types/ms": "^0.7.31", - "@types/node": "^20.3.2", - "@types/react": "^18.2.14", - "@types/react-beautiful-dnd": "^13.1.4", - "@types/react-dom": "^18.2.6", - "@types/react-grid-layout": "^1.3.5", - "@types/react-resizable": "^3.0.8", - "@types/react-window": "^1.8.5", - "@typescript-eslint/eslint-plugin": "^5.60.1", - "@typescript-eslint/parser": "^5.60.1", - "@vitejs/plugin-react-swc": "^3.3.2", - "eslint": "^8.43.0", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-import": "^2.27.5", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.32.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.1", - "postcss": "^8.4.33", - "postcss-preset-mantine": "^1.13.0", - "postcss-simple-vars": "^7.0.1", - "prettier": "^2.8.8", - "pretty-quick": "^3.1.3", - "typescript": "^5.1.6", - "vite": "^4.3.9" - } + "name": "parseable-console", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite --host --port 3001", + "build": "tsc && vite build", + "build:test": "tsc && vite build --mode test", + "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "start": "vite preview --host --port 3002", + "tsCheck": "tsc --noEmit", + "pq": "pretty-quick" + }, + "dependencies": { + "@apache-arrow/ts": "^14.0.2", + "@emotion/react": "^11.11.1", + "@mantine/carousel": "^7.8.1", + "@mantine/charts": "^7.8.1", + "@mantine/code-highlight": "^7.8.1", + "@mantine/core": "^7.8.1", + "@mantine/dates": "^7.8.1", + "@mantine/form": "^7.8.1", + "@mantine/hooks": "^7.8.1", + "@mantine/notifications": "^7.8.1", + "@monaco-editor/react": "^4.5.1", + "@tabler/icons-react": "^3.3.0", + "@types/js-cookie": "^3.0.3", + "axios": "^1.4.0", + "dayjs": "^1.11.10", + "embla-carousel-react": "7.1.0", + "html2canvas": "^1.4.1", + "http-status-codes": "^2.2.0", + "immer": "^10.0.2", + "jq-web": "^0.5.1", + "js-cookie": "^3.0.5", + "just-compare": "^2.3.0", + "lodash": "^4.17.21", + "long": "^5.2.3", + "mantine-react-table": "2.0.0-beta.6", + "moment-timezone": "^0.5.45", + "ms": "^2.1.3", + "nice-grpc-common": "^2.0.2", + "nice-grpc-web": "^3.3.2", + "protobufjs": "^7.2.5", + "react": "^18.2.0", + "react-beautiful-dnd": "^13.1.1", + "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.10", + "react-grid-layout": "^1.4.4", + "react-query": "^3.39.3", + "react-querybuilder": "^6.5.5", + "react-resizable": "^3.0.5", + "react-resizable-panels": "^0.0.53", + "react-router-dom": "^6.14.0", + "react-window": "^1.8.9" + }, + "devDependencies": { + "@playwright/test": "^1.48.2", + "@types/lodash": "^4.17.0", + "@types/ms": "^0.7.31", + "@types/node": "^20.3.2", + "@types/react": "^18.2.14", + "@types/react-beautiful-dnd": "^13.1.4", + "@types/react-dom": "^18.2.6", + "@types/react-grid-layout": "^1.3.5", + "@types/react-resizable": "^3.0.8", + "@types/react-window": "^1.8.5", + "@typescript-eslint/eslint-plugin": "^5.60.1", + "@typescript-eslint/parser": "^5.60.1", + "@vitejs/plugin-react-swc": "^3.3.2", + "eslint": "^8.43.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.1", + "postcss": "^8.4.33", + "postcss-preset-mantine": "^1.13.0", + "postcss-simple-vars": "^7.0.1", + "prettier": "^2.8.8", + "pretty-quick": "^3.1.3", + "typescript": "^5.1.6", + "vite": "^4.3.9" + } } diff --git a/src/hooks/useQueryLogs.ts b/src/hooks/useQueryLogs.ts index 75ccdcfd..a931c84b 100644 --- a/src/hooks/useQueryLogs.ts +++ b/src/hooks/useQueryLogs.ts @@ -2,6 +2,7 @@ import { SortOrder, type Log, type LogsData, type LogsSearch } from '@/@types/pa import { getQueryLogsWithHeaders, getQueryResultWithHeaders } from '@/api/query'; import { StatusCodes } from 'http-status-codes'; import useMountedState from './useMountedState'; +import { useQuery } from 'react-query'; import { useCallback, useRef } from 'react'; import { useLogsStore, logsStoreReducers, LOAD_LIMIT, isJqSearch } from '@/pages/Stream/providers/LogsProvider'; import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; @@ -25,7 +26,6 @@ export const useQueryLogs = () => { // Only mutate it when data is fetched, otherwise read only const _dataRef = useRef(null); const [error, setError] = useMountedState(null); - const [loading, setLoading] = useMountedState(false); const [pageLogData, setPageLogData] = useMountedState(null); const [querySearch, setQuerySearch] = useMountedState({ search: '', @@ -81,45 +81,50 @@ export const useQueryLogs = () => { pageOffset: currentOffset, timePartitionColumn, }; - const getQueryData = async () => { - try { - setLoading(true); - setError(null); - refetchSchema(); // fetch schema parallelly every time we fetch logs - const logsQueryRes = await (async () => { - if (isQuerySearchActive) { - if (activeMode === 'filters') { - const { parsedQuery } = parseQuery(queryEngine, appliedQuery, currentStream || '', { - startTime: timeRange.startTime, - endTime: timeRange.endTime, - timePartitionColumn, - }); - const queryStrWithOffset = appendOffsetToQuery(parsedQuery, defaultQueryOpts.pageOffset); - return await getQueryResultWithHeaders({ ...defaultQueryOpts, access: [] }, queryStrWithOffset); - } else { - const queryStrWithOffset = appendOffsetToQuery(custSearchQuery, defaultQueryOpts.pageOffset); - return await getQueryResultWithHeaders({ ...defaultQueryOpts, access: [] }, queryStrWithOffset); - } + + const { + isLoading: logsLoading, + isRefetching: logsRefetching, + refetch: getQueryData, + } = useQuery( + ['fetch-logs', defaultQueryOpts], + () => { + refetchSchema(); + if (isQuerySearchActive) { + if (activeMode === 'filters') { + const { parsedQuery } = parseQuery(queryEngine, appliedQuery, currentStream || '', { + startTime: timeRange.startTime, + endTime: timeRange.endTime, + timePartitionColumn, + }); + const queryStrWithOffset = appendOffsetToQuery(parsedQuery, defaultQueryOpts.pageOffset); + return getQueryResultWithHeaders({ ...defaultQueryOpts, access: [] }, queryStrWithOffset); } else { - return await getQueryLogsWithHeaders(defaultQueryOpts); + const queryStrWithOffset = appendOffsetToQuery(custSearchQuery, defaultQueryOpts.pageOffset); + return getQueryResultWithHeaders({ ...defaultQueryOpts, access: [] }, queryStrWithOffset); } - })(); - const logs = logsQueryRes.data; - const isInvalidResponse = _.isEmpty(logs) || _.isNil(logs) || logsQueryRes.status !== StatusCodes.OK; - if (isInvalidResponse) return setError('Failed to query log'); + } else { + return getQueryLogsWithHeaders(defaultQueryOpts); + } + }, + { + enabled: false, + refetchOnWindowFocus: false, + onSuccess: async (data) => { + const logs = data.data; + const isInvalidResponse = _.isEmpty(logs) || _.isNil(logs) || data.status !== StatusCodes.OK; + if (isInvalidResponse) return setError('Failed to query logs'); - const { records, fields } = logs; - const jqFilteredData = isJqSearch(instantSearchValue) ? await jqSearch(records, instantSearchValue) : []; - return setLogsStore((store) => setLogData(store, records, fields, jqFilteredData)); - } catch (e) { - const axiosError = e as AxiosError; - const errorMessage = axiosError?.response?.data; - setError(_.isString(errorMessage) && !_.isEmpty(errorMessage) ? errorMessage : 'Failed to query log'); - return setLogsStore((store) => setLogData(store, [], [])); - } finally { - setLoading(false); - } - }; + const { records, fields } = logs; + const jqFilteredData = isJqSearch(instantSearchValue) ? await jqSearch(records, instantSearchValue) : []; + setLogsStore((store) => setLogData(store, records, fields, jqFilteredData)); + }, + onError: (data: AxiosError) => { + const errorMessage = data.response?.data as string; + setError(_.isString(errorMessage) && !_.isEmpty(errorMessage) ? errorMessage : 'Failed to query logs'); + }, + }, + ); const resetData = () => { _dataRef.current = null; @@ -133,7 +138,7 @@ export const useQueryLogs = () => { getColumnFilters, sort: querySearch.sort, error, - loading: loading, + loading: logsLoading || logsRefetching, getQueryData, resetData, }; diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index 9f3da74c..dd765123 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -1,25 +1,19 @@ import { Box } from '@mantine/core'; -import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; +import { useLogsStore } from '../../providers/LogsProvider'; import JsonView from './JSONView'; import LogTable from './StaticLogTable'; import useLogsFetcher from './useLogsFetcher'; import LogsViewConfig from './LogsViewConfig'; -import { useEffect, useState } from 'react'; -import { useSearchParams } from 'react-router-dom'; import _ from 'lodash'; -const { setPageAndPageData, setCurrentPage } = logsStoreReducers; - const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { - const [searchParams] = useSearchParams(); - const [targetPage, setTargetPage] = useState(null); const { schemaLoading, infoLoading } = props; const { errorMessage, hasNoData, showTable, isFetchingCount, logsLoading } = useLogsFetcher({ schemaLoading, infoLoading, }); - const [viewMode, setLogsStore] = useLogsStore((store) => store.viewMode); + const [viewMode] = useLogsStore((store) => store.viewMode); const viewOpts = { errorMessage, hasNoData, @@ -27,13 +21,6 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { isFetchingCount, logsLoading, }; - useEffect(() => { - setTargetPage(searchParams.get('page')); - if (showTable && (targetPage !== null || undefined || '0')) { - setLogsStore((store) => setPageAndPageData(store, _.toNumber(targetPage))); - setLogsStore((store) => setCurrentPage(store, _.toNumber(targetPage))); - } - }, [showTable]); return ( diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index b2cfa2ac..835db5c4 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -3,15 +3,15 @@ import { TimeRange, useLogsStore, logsStoreReducers } from '@/pages/Stream/provi import { useSearchParams } from 'react-router-dom'; import _ from 'lodash'; import { FIXED_DURATIONS } from '@/constants/timeConstants'; -import { LOAD_LIMIT, LOG_QUERY_LIMITS } from '@/pages/Stream/providers/LogsProvider'; +import { LOG_QUERY_LIMITS } from '@/pages/Stream/providers/LogsProvider'; import dayjs from 'dayjs'; import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; -const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setCurrentOffset } = logsStoreReducers; +const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState } = logsStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; -const keys = ['view', 'rows', 'interval', 'from', 'to', 'query', 'offset', 'page', 'fields']; +const keys = ['view', 'rows', 'interval', 'from', 'to', 'query']; const dateToParamString = (date: Date) => { return formatDateWithTimezone(date, timeRangeFormat); @@ -87,7 +87,7 @@ const useParamsController = () => { const [custQuerySearchState] = useLogsStore((store) => store.custQuerySearchState); const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); - const { currentOffset, currentPage, perPage, pageData, headers } = tableOpts; + const { currentOffset, currentPage, perPage, headers } = tableOpts; const [searchParams, setSearchParams] = useSearchParams(); @@ -109,15 +109,6 @@ const useParamsController = () => { setLogsStore((store) => setPerPage(store, _.toNumber(presentParams.rows))); } - if (storeAsParams.offset !== presentParams.offset && _.toNumber(presentParams.offset) % LOAD_LIMIT === 0) { - setLogsStore((store) => setCurrentOffset(store, _.toNumber(presentParams.offset))); - } - - if (!_.isEmpty(pageData) && storeAsParams.page !== presentParams.page) { - console.log(presentParams.page); - // setLogsStore((store) => setCurrentPage(store, _.toNumber(presentParams.page))); - } - if (storeAsParams.query !== presentParams.query) { setLogsStore((store) => setCustQuerySearchState(store, presentParams.query)); } From ef11b0cb2693f5b1097f9d985353936197027cc2 Mon Sep 17 00:00:00 2001 From: Koustav Date: Mon, 11 Nov 2024 10:57:23 +0530 Subject: [PATCH 03/16] Pages params added --- src/pages/Stream/Views/Explore/Footer.tsx | 30 ++++++++----------- src/pages/Stream/Views/Explore/LogsView.tsx | 19 ++++++++++-- src/pages/Stream/hooks/useParamsController.ts | 18 +++++++---- src/pages/Stream/providers/LogsProvider.tsx | 13 ++++++++ 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index 9d03413b..441287c2 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -9,6 +9,7 @@ import { IconSelector } from '@tabler/icons-react'; import useMountedState from '@/hooks/useMountedState'; import classes from '../../styles/Footer.module.css'; import { LOGS_FOOTER_HEIGHT } from '@/constants/theme'; +import { useSearchParams } from 'react-router-dom'; const { setPageAndPageData, setCurrentPage, setCurrentOffset } = logsStoreReducers; @@ -89,6 +90,7 @@ const LimitControl: FC = () => { }; const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: boolean }) => { + const [searchParams] = useSearchParams(); const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts); const { totalPages, currentOffset, currentPage, perPage, totalCount } = tableOpts; @@ -96,7 +98,16 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b setLogsStore((store) => setPageAndPageData(store, page)); }, []); - const pagination = usePagination({ total: totalPages ?? 1, initialPage: 1, onChange: onPageChange }); + console.log(_.toNumber(searchParams.get('page'))); + + const pagination = usePagination({ + total: totalPages ?? 1, + initialPage: + (_.toNumber(searchParams.get('page')) && _.toNumber(searchParams.get('page'))) > 0 + ? _.toNumber(searchParams.get('page')) + : 1, + onChange: onPageChange, + }); const onChangeOffset = useCallback( (key: 'prev' | 'next') => { if (key === 'prev') { @@ -171,23 +182,6 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b ) : null} - {/* {props.loaded && ( - - -
- -
-
- - exportHandler('CSV')} style={{ padding: '0.5rem 2.25rem 0.5rem 0.75rem' }}> - CSV - - exportHandler('JSON')} style={{ padding: '0.5rem 2.25rem 0.5rem 0.75rem' }}> - JSON - - -
- )} */}
diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index dd765123..20b79901 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -1,11 +1,15 @@ import { Box } from '@mantine/core'; -import { useLogsStore } from '../../providers/LogsProvider'; +import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; import JsonView from './JSONView'; import LogTable from './StaticLogTable'; import useLogsFetcher from './useLogsFetcher'; import LogsViewConfig from './LogsViewConfig'; import _ from 'lodash'; +import { useEffect } from 'react'; + +const { setPageAndPageData, setTargetPage } = logsStoreReducers; + const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const { schemaLoading, infoLoading } = props; const { errorMessage, hasNoData, showTable, isFetchingCount, logsLoading } = useLogsFetcher({ @@ -13,7 +17,9 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { infoLoading, }); - const [viewMode] = useLogsStore((store) => store.viewMode); + const [tableOpts] = useLogsStore((store) => store.tableOpts); + const { currentPage, targetPage } = tableOpts; + const [viewMode, setLogsStore] = useLogsStore((store) => store.viewMode); const viewOpts = { errorMessage, hasNoData, @@ -22,6 +28,15 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { logsLoading, }; + useEffect(() => { + if (!showTable) return; + if (targetPage) { + console.log('hello'); + setLogsStore((store) => setPageAndPageData(store, targetPage)); + setLogsStore((store) => setTargetPage(store, undefined)); + } + }, [currentPage]); + return ( {viewMode === 'table' && ( diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 8e36d66d..25d80816 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -11,10 +11,10 @@ import { filterStoreReducers, QueryType, useFilterStore } from '../providers/Fil import { generateQueryBuilderASTFromSQL } from '../utils'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; -const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState } = logsStoreReducers; +const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setTargetPage } = logsStoreReducers; const { applySavedFilters } = filterStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; -const keys = ['view', 'rows', 'interval', 'from', 'to', 'query', 'filterType']; +const keys = ['view', 'rows', 'page', 'interval', 'from', 'to', 'query', 'filterType']; const dateToParamString = (date: Date) => { return formatDateWithTimezone(date, timeRangeFormat); @@ -91,7 +91,7 @@ const useParamsController = () => { const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); const [, setFilterStore] = useFilterStore((store) => store); - const { currentOffset, currentPage, perPage } = tableOpts; + const { currentOffset, currentPage, targetPage, perPage } = tableOpts; const [searchParams, setSearchParams] = useSearchParams(); @@ -99,7 +99,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${currentPage}`, + page: `${targetPage ? targetPage : currentPage}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, @@ -113,6 +113,10 @@ const useParamsController = () => { setLogsStore((store) => setPerPage(store, _.toNumber(presentParams.rows))); } + if (storeAsParams.page !== presentParams.page) { + setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page))); + } + if (storeAsParams.query !== presentParams.query) { setLogsStore((store) => setCustQuerySearchState(store, presentParams.query, presentParams.filterType)); if (presentParams.filterType === 'filters') @@ -120,6 +124,8 @@ const useParamsController = () => { applySavedFilters(store, generateQueryBuilderASTFromSQL(presentParams.query) as QueryType), ); } + + // setLogsStore((store) => setCurrentOffset(store, 1000)); syncTimeRangeToStore(storeAsParams, presentParams); setStoreSynced(true); }, []); @@ -129,7 +135,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${currentPage}`, + page: `${targetPage ? targetPage : currentPage}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, @@ -147,7 +153,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${currentPage}`, + page: `${targetPage ? targetPage : currentPage}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, diff --git a/src/pages/Stream/providers/LogsProvider.tsx b/src/pages/Stream/providers/LogsProvider.tsx index 684e8d42..af1b59fd 100644 --- a/src/pages/Stream/providers/LogsProvider.tsx +++ b/src/pages/Stream/providers/LogsProvider.tsx @@ -209,6 +209,7 @@ type LogsStore = { totalCount: number; displayedCount: number; currentPage: number; + targetPage: number | undefined; perPage: number; currentOffset: number; headers: string[]; @@ -265,6 +266,7 @@ type LogsStoreReducers = { setCurrentOffset: (store: LogsStore, offset: number) => ReducerOutput; setPerPage: (store: LogsStore, perPage: number) => ReducerOutput; setCurrentPage: (store: LogsStore, page: number) => ReducerOutput; + setTargetPage: (store: LogsStore, target: number | undefined) => ReducerOutput; setTotalCount: (store: LogsStore, totalCount: number) => ReducerOutput; setPageAndPageData: (store: LogsStore, pageNo: number, perPage?: number) => ReducerOutput; setAndSortData: (store: LogsStore, sortKey: string, sortOrder: 'asc' | 'desc') => ReducerOutput; @@ -326,6 +328,7 @@ const initialState: LogsStore = { displayedCount: 0, totalPages: 0, currentPage: 0, + targetPage: undefined, currentOffset: 0, headers: [], orderedHeaders: [], @@ -634,6 +637,15 @@ const setPerPage = (store: LogsStore, perPage: number) => { }; }; +const setTargetPage = (store: LogsStore, target: number | undefined) => { + return { + tableOpts: { + ...store.tableOpts, + targetPage: target, + }, + }; +}; + const setCurrentPage = (store: LogsStore, currentPage: number) => { return { tableOpts: { @@ -994,6 +1006,7 @@ const logsStoreReducers: LogsStoreReducers = { setStreamSchema, setPerPage, setCurrentPage, + setTargetPage, setCurrentOffset, setTotalCount, setPageAndPageData, From de04132a894f131d1d1fc7cf8dbfa548de8d0164 Mon Sep 17 00:00:00 2001 From: Koustav Date: Mon, 11 Nov 2024 16:46:54 +0530 Subject: [PATCH 04/16] Fields Params:Clean up --- src/pages/Stream/Views/Explore/Footer.tsx | 2 -- src/pages/Stream/Views/Explore/LogsView.tsx | 18 +++++++++-- src/pages/Stream/hooks/useParamsController.ts | 32 +++++++++++++++---- src/pages/Stream/providers/LogsProvider.tsx | 13 ++++++++ 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index 441287c2..fd02349a 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -98,8 +98,6 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b setLogsStore((store) => setPageAndPageData(store, page)); }, []); - console.log(_.toNumber(searchParams.get('page'))); - const pagination = usePagination({ total: totalPages ?? 1, initialPage: diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index 20b79901..1c172417 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -8,7 +8,7 @@ import _ from 'lodash'; import { useEffect } from 'react'; -const { setPageAndPageData, setTargetPage } = logsStoreReducers; +const { setPageAndPageData, setTargetPage, setTargetColumns, setDisabledColumns } = logsStoreReducers; const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const { schemaLoading, infoLoading } = props; @@ -18,7 +18,7 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { }); const [tableOpts] = useLogsStore((store) => store.tableOpts); - const { currentPage, targetPage } = tableOpts; + const { currentPage, targetPage, headers, targetColumns } = tableOpts; const [viewMode, setLogsStore] = useLogsStore((store) => store.viewMode); const viewOpts = { errorMessage, @@ -31,12 +31,24 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { useEffect(() => { if (!showTable) return; if (targetPage) { - console.log('hello'); setLogsStore((store) => setPageAndPageData(store, targetPage)); setLogsStore((store) => setTargetPage(store, undefined)); } }, [currentPage]); + useEffect(() => { + if (!showTable) return; + if (!_.isEmpty(targetColumns)) { + setLogsStore((store) => + setDisabledColumns( + store, + headers.filter((el) => !targetColumns.includes(el)), + ), + ); + setLogsStore((store) => setTargetColumns(store, [])); + } + }, [headers]); + return ( {viewMode === 'table' && ( diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 25d80816..fae02441 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -3,7 +3,7 @@ import { TimeRange, useLogsStore, logsStoreReducers } from '@/pages/Stream/provi import { useSearchParams } from 'react-router-dom'; import _ from 'lodash'; import { FIXED_DURATIONS } from '@/constants/timeConstants'; -import { LOG_QUERY_LIMITS } from '@/pages/Stream/providers/LogsProvider'; +import { LOG_QUERY_LIMITS, columnsToSkip } from '@/pages/Stream/providers/LogsProvider'; import dayjs from 'dayjs'; import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; @@ -11,10 +11,11 @@ import { filterStoreReducers, QueryType, useFilterStore } from '../providers/Fil import { generateQueryBuilderASTFromSQL } from '../utils'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; -const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setTargetPage } = logsStoreReducers; +const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setTargetPage, setTargetColumns } = + logsStoreReducers; const { applySavedFilters } = filterStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; -const keys = ['view', 'rows', 'page', 'interval', 'from', 'to', 'query', 'filterType']; +const keys = ['view', 'rows', 'page', 'interval', 'from', 'to', 'query', 'filterType', 'fields']; const dateToParamString = (date: Date) => { return formatDateWithTimezone(date, timeRangeFormat); @@ -58,8 +59,9 @@ const storeToParamsObj = (opts: { rows: string; query: string; filterType: string; + fields: string; }): Record => { - const { timeRange, offset, page, view, rows, query, filterType } = opts; + const { timeRange, offset, page, view, rows, query, filterType, fields } = opts; const params: Record = { ...deriveTimeRangeParams(timeRange), view, @@ -68,6 +70,7 @@ const storeToParamsObj = (opts: { page, query, filterType: query ? filterType : '', + fields, }; return _.pickBy(params, (val, key) => !_.isEmpty(val) && _.includes(keys, key)); }; @@ -83,6 +86,15 @@ const paramsStringToParamsObj = (searchParams: URLSearchParams): Record { + const joinOperator = '~'; + if (Array.isArray(value)) { + return value.join(joinOperator); + } else { + return value.split(joinOperator); + } +}; + const useParamsController = () => { const [isStoreSynced, setStoreSynced] = useState(false); const [tableOpts] = useLogsStore((store) => store.tableOpts); @@ -91,8 +103,11 @@ const useParamsController = () => { const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); const [, setFilterStore] = useFilterStore((store) => store); - const { currentOffset, currentPage, targetPage, perPage } = tableOpts; + const { currentOffset, currentPage, targetPage, perPage, headers, disabledColumns, targetColumns } = tableOpts; + + const visibleHeaders = headers.filter((el) => !columnsToSkip.includes(el)); + const activeHeaders = visibleHeaders.filter((el) => !disabledColumns.includes(el)); const [searchParams, setSearchParams] = useSearchParams(); useEffect(() => { @@ -104,6 +119,7 @@ const useParamsController = () => { rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, filterType: custQuerySearchState.viewMode, + fields: `${joinOrSplit(!_.isEmpty(targetColumns) ? targetColumns : activeHeaders)}`, }); const presentParams = paramsStringToParamsObj(searchParams); if (['table', 'json'].includes(presentParams.view) && presentParams.view !== storeAsParams.view) { @@ -125,7 +141,9 @@ const useParamsController = () => { ); } - // setLogsStore((store) => setCurrentOffset(store, 1000)); + if (storeAsParams.fields !== presentParams.fields) { + setLogsStore((store) => setTargetColumns(store, joinOrSplit(presentParams.fields) as string[])); + } syncTimeRangeToStore(storeAsParams, presentParams); setStoreSynced(true); }, []); @@ -140,6 +158,7 @@ const useParamsController = () => { rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, filterType: custQuerySearchState.viewMode, + fields: `${joinOrSplit(!_.isEmpty(targetColumns) ? targetColumns : activeHeaders)}`, }); const presentParams = paramsStringToParamsObj(searchParams); if (_.isEqual(storeAsParams, presentParams)) return; @@ -158,6 +177,7 @@ const useParamsController = () => { rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, filterType: custQuerySearchState.viewMode, + fields: `${joinOrSplit(!_.isEmpty(targetColumns) ? targetColumns : activeHeaders)}`, }); const presentParams = paramsStringToParamsObj(searchParams); diff --git a/src/pages/Stream/providers/LogsProvider.tsx b/src/pages/Stream/providers/LogsProvider.tsx index af1b59fd..ff8eba82 100644 --- a/src/pages/Stream/providers/LogsProvider.tsx +++ b/src/pages/Stream/providers/LogsProvider.tsx @@ -203,6 +203,7 @@ type LogsStore = { tableOpts: { disabledColumns: string[]; wrapDisabledColumns: string[]; + targetColumns: string[]; pinnedColumns: string[]; pageData: Log[]; totalPages: number; @@ -295,6 +296,7 @@ type LogsStoreReducers = { onToggleView: (store: LogsStore, viewMode: 'json' | 'table') => ReducerOutput; toggleConfigViewType: (store: LogsStore) => ReducerOutput; setDisabledColumns: (store: LogsStore, columns: string[]) => ReducerOutput; + setTargetColumns: (store: LogsStore, columms: string[]) => ReducerOutput; setOrderedHeaders: (store: LogsStore, columns: string[]) => ReducerOutput; toggleWordWrap: (store: LogsStore) => ReducerOutput; }; @@ -319,6 +321,7 @@ const initialState: LogsStore = { }, tableOpts: { + targetColumns: [], disabledColumns: [], wrapDisabledColumns: [], pinnedColumns: [], @@ -535,6 +538,15 @@ const setDisabledColumns = (store: LogsStore, columns: string[]) => { }; }; +const setTargetColumns = (store: LogsStore, columns: string[]) => { + return { + tableOpts: { + ...store.tableOpts, + targetColumns: columns, + }, + }; +}; + const togglePinnedColumns = (store: LogsStore, columnName: string) => { const { tableOpts } = store; return { @@ -1028,6 +1040,7 @@ const logsStoreReducers: LogsStoreReducers = { onToggleView, toggleConfigViewType, setDisabledColumns, + setTargetColumns, setOrderedHeaders, toggleWordWrap, toggleWrapDisabledColumns, From fc8179b5057f4c687f3c46da0656e05338e5c1c7 Mon Sep 17 00:00:00 2001 From: Koustav Date: Mon, 11 Nov 2024 18:36:26 +0530 Subject: [PATCH 05/16] offset from page number --- src/pages/Stream/Views/Explore/Footer.tsx | 7 +++---- src/pages/Stream/Views/Explore/LogsView.tsx | 18 ++++++++++++++---- src/utils/index.ts | 5 +++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index fd02349a..f750d282 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -93,6 +93,8 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b const [searchParams] = useSearchParams(); const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts); const { totalPages, currentOffset, currentPage, perPage, totalCount } = tableOpts; + const pageNumberFromURL = _.toNumber(searchParams.get('page')); + console.log(pageNumberFromURL, currentOffset, perPage); const onPageChange = useCallback((page: number) => { setLogsStore((store) => setPageAndPageData(store, page)); @@ -100,10 +102,7 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b const pagination = usePagination({ total: totalPages ?? 1, - initialPage: - (_.toNumber(searchParams.get('page')) && _.toNumber(searchParams.get('page'))) > 0 - ? _.toNumber(searchParams.get('page')) - : 1, + initialPage: pageNumberFromURL && pageNumberFromURL > 0 ? pageNumberFromURL : 1, onChange: onPageChange, }); const onChangeOffset = useCallback( diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index 1c172417..c4a94938 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -5,10 +5,11 @@ import LogTable from './StaticLogTable'; import useLogsFetcher from './useLogsFetcher'; import LogsViewConfig from './LogsViewConfig'; import _ from 'lodash'; +import { getOffset } from '@/utils'; import { useEffect } from 'react'; -const { setPageAndPageData, setTargetPage, setTargetColumns, setDisabledColumns } = logsStoreReducers; +const { setPageAndPageData, setTargetPage, setTargetColumns, setDisabledColumns, setCurrentOffset } = logsStoreReducers; const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const { schemaLoading, infoLoading } = props; @@ -18,7 +19,7 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { }); const [tableOpts] = useLogsStore((store) => store.tableOpts); - const { currentPage, targetPage, headers, targetColumns } = tableOpts; + const { currentPage, targetPage, headers, targetColumns, perPage } = tableOpts; const [viewMode, setLogsStore] = useLogsStore((store) => store.viewMode); const viewOpts = { errorMessage, @@ -29,12 +30,21 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { }; useEffect(() => { + console.log(showTable); if (!showTable) return; if (targetPage) { + const offset = getOffset(targetPage, perPage); + if (offset > 0) { + setLogsStore((store) => setCurrentOffset(store, offset)); + console.log(targetPage - offset / perPage); + setLogsStore((store) => setTargetPage(store, targetPage - offset / perPage)); + } setLogsStore((store) => setPageAndPageData(store, targetPage)); - setLogsStore((store) => setTargetPage(store, undefined)); + if (currentPage === targetPage) { + setLogsStore((store) => setTargetPage(store, undefined)); + } } - }, [currentPage]); + }, [showTable, currentPage]); useEffect(() => { if (!showTable) return; diff --git a/src/utils/index.ts b/src/utils/index.ts index 8b82b17f..edbbc9ed 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -105,3 +105,8 @@ export const copyTextToClipboard = async (value: any) => { return await navigator.clipboard.writeText(JSON.stringify(value, null, 2)); } }; + +export const getOffset = (page: number, rowSize: number) => { + const product = page * rowSize; + return Math.floor(product / 1000) * 1000; +}; From aa7ac922818bdacde47df3845617d9fb383534fa Mon Sep 17 00:00:00 2001 From: Koustav Date: Mon, 11 Nov 2024 19:23:55 +0530 Subject: [PATCH 06/16] Display accurate Page number as shown in UI --- src/pages/Stream/Views/Explore/Footer.tsx | 5 ++++- src/pages/Stream/Views/Explore/LogsView.tsx | 3 +-- src/pages/Stream/hooks/useParamsController.ts | 8 +++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index f750d282..5c5ddfc6 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -94,7 +94,7 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts); const { totalPages, currentOffset, currentPage, perPage, totalCount } = tableOpts; const pageNumberFromURL = _.toNumber(searchParams.get('page')); - console.log(pageNumberFromURL, currentOffset, perPage); + // console.log(pageNumberFromURL - currentOffset / perPage < 0 ? 1 : pageNumberFromURL - currentOffset / perPage); const onPageChange = useCallback((page: number) => { setLogsStore((store) => setPageAndPageData(store, page)); @@ -103,8 +103,11 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b const pagination = usePagination({ total: totalPages ?? 1, initialPage: pageNumberFromURL && pageNumberFromURL > 0 ? pageNumberFromURL : 1, + // initialPage: pageNumberFromURL - currentOffset / perPage < 0 ? 1 : pageNumberFromURL - currentOffset / perPage, onChange: onPageChange, }); + + // console.log(totalPages); const onChangeOffset = useCallback( (key: 'prev' | 'next') => { if (key === 'prev') { diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index c4a94938..2b466018 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -30,13 +30,12 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { }; useEffect(() => { - console.log(showTable); if (!showTable) return; if (targetPage) { const offset = getOffset(targetPage, perPage); if (offset > 0) { setLogsStore((store) => setCurrentOffset(store, offset)); - console.log(targetPage - offset / perPage); + // console.log(targetPage - offset / perPage); setLogsStore((store) => setTargetPage(store, targetPage - offset / perPage)); } setLogsStore((store) => setPageAndPageData(store, targetPage)); diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index fae02441..8ea11433 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -109,12 +109,14 @@ const useParamsController = () => { const activeHeaders = visibleHeaders.filter((el) => !disabledColumns.includes(el)); const [searchParams, setSearchParams] = useSearchParams(); + const pageOffset = currentOffset >= 1000 ? currentOffset / perPage : currentOffset / perPage; + console.log(pageOffset); useEffect(() => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${targetPage ? targetPage : currentPage}`, + page: `${targetPage ? targetPage : currentPage + pageOffset}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, @@ -153,7 +155,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${targetPage ? targetPage : currentPage}`, + page: `${targetPage ? targetPage : currentPage + pageOffset}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, @@ -172,7 +174,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${targetPage ? targetPage : currentPage}`, + page: `${targetPage ? targetPage : currentPage + pageOffset}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, From 50ea54b8978db335b4287cb2f886a960198519e1 Mon Sep 17 00:00:00 2001 From: Koustav Date: Mon, 11 Nov 2024 19:36:42 +0530 Subject: [PATCH 07/16] Clean Up --- src/pages/Stream/Views/Explore/Footer.tsx | 1 - src/pages/Stream/Views/Explore/LogsView.tsx | 1 - src/pages/Stream/hooks/useParamsController.ts | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index 5c5ddfc6..a5d7dbac 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -107,7 +107,6 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b onChange: onPageChange, }); - // console.log(totalPages); const onChangeOffset = useCallback( (key: 'prev' | 'next') => { if (key === 'prev') { diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index 2b466018..be035835 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -35,7 +35,6 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const offset = getOffset(targetPage, perPage); if (offset > 0) { setLogsStore((store) => setCurrentOffset(store, offset)); - // console.log(targetPage - offset / perPage); setLogsStore((store) => setTargetPage(store, targetPage - offset / perPage)); } setLogsStore((store) => setPageAndPageData(store, targetPage)); diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 8ea11433..73266ddc 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -109,8 +109,7 @@ const useParamsController = () => { const activeHeaders = visibleHeaders.filter((el) => !disabledColumns.includes(el)); const [searchParams, setSearchParams] = useSearchParams(); - const pageOffset = currentOffset >= 1000 ? currentOffset / perPage : currentOffset / perPage; - console.log(pageOffset); + const pageOffset = currentOffset / perPage; useEffect(() => { const storeAsParams = storeToParamsObj({ From 1e5bea4c6108d164809c7a4b07cf7cb84ffe9884 Mon Sep 17 00:00:00 2001 From: Koustav Date: Tue, 12 Nov 2024 13:18:10 +0530 Subject: [PATCH 08/16] URL params : Page, fields --- src/pages/Stream/Views/Explore/Footer.tsx | 18 ++++++++++-------- src/pages/Stream/Views/Explore/LogsView.tsx | 2 +- src/pages/Stream/hooks/useParamsController.ts | 11 ++++++----- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index a5d7dbac..9b73cea0 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback } from 'react'; +import { FC, useCallback, useEffect } from 'react'; import { useLogsStore, logsStoreReducers, LOAD_LIMIT, LOG_QUERY_LIMITS } from '../../providers/LogsProvider'; import { usePagination } from '@mantine/hooks'; import { Box, Center, Group, Loader, Menu, Pagination, Stack, Tooltip } from '@mantine/core'; @@ -9,7 +9,6 @@ import { IconSelector } from '@tabler/icons-react'; import useMountedState from '@/hooks/useMountedState'; import classes from '../../styles/Footer.module.css'; import { LOGS_FOOTER_HEIGHT } from '@/constants/theme'; -import { useSearchParams } from 'react-router-dom'; const { setPageAndPageData, setCurrentPage, setCurrentOffset } = logsStoreReducers; @@ -90,20 +89,23 @@ const LimitControl: FC = () => { }; const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: boolean }) => { - const [searchParams] = useSearchParams(); const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts); const { totalPages, currentOffset, currentPage, perPage, totalCount } = tableOpts; - const pageNumberFromURL = _.toNumber(searchParams.get('page')); - // console.log(pageNumberFromURL - currentOffset / perPage < 0 ? 1 : pageNumberFromURL - currentOffset / perPage); const onPageChange = useCallback((page: number) => { setLogsStore((store) => setPageAndPageData(store, page)); }, []); + useEffect(() => { + const initialPageFromUrl = currentPage % Math.ceil(currentOffset / perPage); + if (!initialPageFromUrl) return; + + pagination.setPage(currentPage % Math.ceil(currentOffset / perPage)); + }, [currentOffset, perPage]); + const pagination = usePagination({ total: totalPages ?? 1, - initialPage: pageNumberFromURL && pageNumberFromURL > 0 ? pageNumberFromURL : 1, - // initialPage: pageNumberFromURL - currentOffset / perPage < 0 ? 1 : pageNumberFromURL - currentOffset / perPage, + initialPage: 1, onChange: onPageChange, }); @@ -141,7 +143,7 @@ const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: b total={totalPages} value={currentPage} onChange={(page) => { - pagination.setPage(page); + pagination && pagination.setPage(page); }} size="sm"> diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index be035835..68f0ef92 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -35,7 +35,7 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const offset = getOffset(targetPage, perPage); if (offset > 0) { setLogsStore((store) => setCurrentOffset(store, offset)); - setLogsStore((store) => setTargetPage(store, targetPage - offset / perPage)); + setLogsStore((store) => setTargetPage(store, targetPage - Math.ceil(offset / perPage))); } setLogsStore((store) => setPageAndPageData(store, targetPage)); if (currentPage === targetPage) { diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 73266ddc..23a20e09 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -62,6 +62,7 @@ const storeToParamsObj = (opts: { fields: string; }): Record => { const { timeRange, offset, page, view, rows, query, filterType, fields } = opts; + const params: Record = { ...deriveTimeRangeParams(timeRange), view, @@ -87,7 +88,7 @@ const paramsStringToParamsObj = (searchParams: URLSearchParams): Record { - const joinOperator = '~'; + const joinOperator = ','; if (Array.isArray(value)) { return value.join(joinOperator); } else { @@ -109,13 +110,13 @@ const useParamsController = () => { const activeHeaders = visibleHeaders.filter((el) => !disabledColumns.includes(el)); const [searchParams, setSearchParams] = useSearchParams(); - const pageOffset = currentOffset / perPage; + const pageOffset = Math.ceil(currentOffset / perPage); useEffect(() => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${targetPage ? targetPage : currentPage + pageOffset}`, + page: `${targetPage ? targetPage : Math.ceil(currentPage + pageOffset)}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, @@ -154,7 +155,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${targetPage ? targetPage : currentPage + pageOffset}`, + page: `${targetPage ? targetPage : Math.ceil(currentPage + pageOffset)}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, @@ -173,7 +174,7 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, offset: `${currentOffset}`, - page: `${targetPage ? targetPage : currentPage + pageOffset}`, + page: `${targetPage ? targetPage : Math.ceil(currentPage + pageOffset)}`, view: viewMode, rows: `${perPage}`, query: custQuerySearchState.custSearchQuery, From e0e26fc77d1ac88fee869237c97229480c2b9e72 Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 13 Nov 2024 11:06:37 +0530 Subject: [PATCH 09/16] Handling edge cases --- src/pages/Stream/hooks/useParamsController.ts | 10 +--------- src/pages/Stream/providers/LogsProvider.tsx | 2 +- src/utils/index.ts | 9 +++++++++ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 23a20e09..9a7eb9d7 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -9,6 +9,7 @@ import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; import { filterStoreReducers, QueryType, useFilterStore } from '../providers/FilterProvider'; import { generateQueryBuilderASTFromSQL } from '../utils'; +import { joinOrSplit } from '@/utils'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setTargetPage, setTargetColumns } = @@ -87,15 +88,6 @@ const paramsStringToParamsObj = (searchParams: URLSearchParams): Record { - const joinOperator = ','; - if (Array.isArray(value)) { - return value.join(joinOperator); - } else { - return value.split(joinOperator); - } -}; - const useParamsController = () => { const [isStoreSynced, setStoreSynced] = useState(false); const [tableOpts] = useLogsStore((store) => store.tableOpts); diff --git a/src/pages/Stream/providers/LogsProvider.tsx b/src/pages/Stream/providers/LogsProvider.tsx index ff8eba82..368defd0 100644 --- a/src/pages/Stream/providers/LogsProvider.tsx +++ b/src/pages/Stream/providers/LogsProvider.tsx @@ -653,7 +653,7 @@ const setTargetPage = (store: LogsStore, target: number | undefined) => { return { tableOpts: { ...store.tableOpts, - targetPage: target, + targetPage: target ? target : undefined, }, }; }; diff --git a/src/utils/index.ts b/src/utils/index.ts index edbbc9ed..53a3c221 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -110,3 +110,12 @@ export const getOffset = (page: number, rowSize: number) => { const product = page * rowSize; return Math.floor(product / 1000) * 1000; }; + +export const joinOrSplit = (value: string[] | string): string | string[] => { + const joinOperator = ','; + if (Array.isArray(value)) { + return value.join(joinOperator); + } else { + return value.split(joinOperator); + } +}; From 849c5bb9277e3ee28a3f4327ba25c13d9b1fb3e3 Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 13 Nov 2024 14:09:39 +0530 Subject: [PATCH 10/16] removed extra query call --- package.json | 3 ++- src/pages/Stream/Views/Explore/LogsView.tsx | 10 ++------ .../Stream/Views/Explore/useLogsFetcher.ts | 2 +- src/pages/Stream/hooks/useParamsController.ts | 25 ++++++++++++------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 161efca0..2ccc185a 100644 --- a/package.json +++ b/package.json @@ -83,5 +83,6 @@ "pretty-quick": "^3.1.3", "typescript": "^5.1.6", "vite": "^4.3.9" - } + }, + "packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee" } diff --git a/src/pages/Stream/Views/Explore/LogsView.tsx b/src/pages/Stream/Views/Explore/LogsView.tsx index 68f0ef92..859f4bc3 100644 --- a/src/pages/Stream/Views/Explore/LogsView.tsx +++ b/src/pages/Stream/Views/Explore/LogsView.tsx @@ -5,11 +5,10 @@ import LogTable from './StaticLogTable'; import useLogsFetcher from './useLogsFetcher'; import LogsViewConfig from './LogsViewConfig'; import _ from 'lodash'; -import { getOffset } from '@/utils'; import { useEffect } from 'react'; -const { setPageAndPageData, setTargetPage, setTargetColumns, setDisabledColumns, setCurrentOffset } = logsStoreReducers; +const { setPageAndPageData, setTargetPage, setTargetColumns, setDisabledColumns } = logsStoreReducers; const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const { schemaLoading, infoLoading } = props; @@ -19,7 +18,7 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { }); const [tableOpts] = useLogsStore((store) => store.tableOpts); - const { currentPage, targetPage, headers, targetColumns, perPage } = tableOpts; + const { currentPage, targetPage, headers, targetColumns } = tableOpts; const [viewMode, setLogsStore] = useLogsStore((store) => store.viewMode); const viewOpts = { errorMessage, @@ -32,11 +31,6 @@ const LogsView = (props: { schemaLoading: boolean; infoLoading: boolean }) => { useEffect(() => { if (!showTable) return; if (targetPage) { - const offset = getOffset(targetPage, perPage); - if (offset > 0) { - setLogsStore((store) => setCurrentOffset(store, offset)); - setLogsStore((store) => setTargetPage(store, targetPage - Math.ceil(offset / perPage))); - } setLogsStore((store) => setPageAndPageData(store, targetPage)); if (currentPage === targetPage) { setLogsStore((store) => setTargetPage(store, undefined)); diff --git a/src/pages/Stream/Views/Explore/useLogsFetcher.ts b/src/pages/Stream/Views/Explore/useLogsFetcher.ts index 102bc025..27ac94f0 100644 --- a/src/pages/Stream/Views/Explore/useLogsFetcher.ts +++ b/src/pages/Stream/Views/Explore/useLogsFetcher.ts @@ -24,7 +24,7 @@ const useLogsFetcher = (props: { schemaLoading: boolean; infoLoading: boolean }) useEffect(() => { if (infoLoading) return; - if (currentPage === 0 && currentOffset === 0) { + if (currentPage === 0) { getQueryData(); refetchCount(); } diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 9a7eb9d7..d3ebab17 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -9,11 +9,18 @@ import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; import { filterStoreReducers, QueryType, useFilterStore } from '../providers/FilterProvider'; import { generateQueryBuilderASTFromSQL } from '../utils'; -import { joinOrSplit } from '@/utils'; +import { getOffset, joinOrSplit } from '@/utils'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; -const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState, setTargetPage, setTargetColumns } = - logsStoreReducers; +const { + setTimeRange, + onToggleView, + setPerPage, + setCustQuerySearchState, + setTargetPage, + setCurrentOffset, + setTargetColumns, +} = logsStoreReducers; const { applySavedFilters } = filterStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; const keys = ['view', 'rows', 'page', 'interval', 'from', 'to', 'query', 'filterType', 'fields']; @@ -55,19 +62,17 @@ const deriveTimeRangeParams = (timerange: TimeRange): { interval: string } | { f const storeToParamsObj = (opts: { timeRange: TimeRange; view: string; - offset: string; page: string; rows: string; query: string; filterType: string; fields: string; }): Record => { - const { timeRange, offset, page, view, rows, query, filterType, fields } = opts; + const { timeRange, page, view, rows, query, filterType, fields } = opts; const params: Record = { ...deriveTimeRangeParams(timeRange), view, - offset, rows, page, query, @@ -107,7 +112,6 @@ const useParamsController = () => { useEffect(() => { const storeAsParams = storeToParamsObj({ timeRange, - offset: `${currentOffset}`, page: `${targetPage ? targetPage : Math.ceil(currentPage + pageOffset)}`, view: viewMode, rows: `${perPage}`, @@ -125,6 +129,11 @@ const useParamsController = () => { if (storeAsParams.page !== presentParams.page) { setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page))); + const offset = getOffset(_.toNumber(presentParams.page), perPage); + if (offset > 0) { + setLogsStore((store) => setCurrentOffset(store, offset)); + setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page) - Math.ceil(offset / perPage))); + } } if (storeAsParams.query !== presentParams.query) { @@ -146,7 +155,6 @@ const useParamsController = () => { if (isStoreSynced) { const storeAsParams = storeToParamsObj({ timeRange, - offset: `${currentOffset}`, page: `${targetPage ? targetPage : Math.ceil(currentPage + pageOffset)}`, view: viewMode, rows: `${perPage}`, @@ -165,7 +173,6 @@ const useParamsController = () => { const storeAsParams = storeToParamsObj({ timeRange, - offset: `${currentOffset}`, page: `${targetPage ? targetPage : Math.ceil(currentPage + pageOffset)}`, view: viewMode, rows: `${perPage}`, From 0a74a0ab33e2a72bbd004f04ccc4e71c6e3fdd7f Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 13 Nov 2024 16:20:41 +0530 Subject: [PATCH 11/16] highlight selected page --- src/pages/Stream/Views/Explore/Footer.tsx | 11 ++++++---- src/pages/Stream/hooks/useParamsController.ts | 21 ++++++++++++++++--- src/utils/index.ts | 4 ++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index 9b73cea0..2f5b564e 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -9,6 +9,7 @@ import { IconSelector } from '@tabler/icons-react'; import useMountedState from '@/hooks/useMountedState'; import classes from '../../styles/Footer.module.css'; import { LOGS_FOOTER_HEIGHT } from '@/constants/theme'; +import { useSearchParams } from 'react-router-dom'; const { setPageAndPageData, setCurrentPage, setCurrentOffset } = logsStoreReducers; @@ -91,17 +92,19 @@ const LimitControl: FC = () => { const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: boolean }) => { const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts); const { totalPages, currentOffset, currentPage, perPage, totalCount } = tableOpts; + const [searchParams] = useSearchParams(); + const pageFromURL = _.toNumber(searchParams.get('page')); const onPageChange = useCallback((page: number) => { setLogsStore((store) => setPageAndPageData(store, page)); }, []); useEffect(() => { - const initialPageFromUrl = currentPage % Math.ceil(currentOffset / perPage); - if (!initialPageFromUrl) return; + const initialPageFromUrl = pageFromURL % Math.ceil(currentOffset / perPage); + if (!props.loaded) return; - pagination.setPage(currentPage % Math.ceil(currentOffset / perPage)); - }, [currentOffset, perPage]); + pagination.setPage(pageFromURL > totalPages ? initialPageFromUrl : pageFromURL); + }, [props.loaded]); const pagination = usePagination({ total: totalPages ?? 1, diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index d3ebab17..2d2ff3f6 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -129,10 +129,18 @@ const useParamsController = () => { if (storeAsParams.page !== presentParams.page) { setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page))); - const offset = getOffset(_.toNumber(presentParams.page), perPage); + + const offset = getOffset(_.toNumber(presentParams.page), _.toNumber(presentParams.rows)); + if (offset > 0) { setLogsStore((store) => setCurrentOffset(store, offset)); - setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page) - Math.ceil(offset / perPage))); + + setLogsStore((store) => + setTargetPage( + store, + Math.abs(_.toNumber(presentParams.page) - Math.round(offset / _.toNumber(presentParams.rows))), + ), + ); } } @@ -166,7 +174,14 @@ const useParamsController = () => { if (_.isEqual(storeAsParams, presentParams)) return; setSearchParams(storeAsParams); } - }, [tableOpts, viewMode, timeRange.startTime.toISOString(), timeRange.endTime.toISOString(), custQuerySearchState]); + }, [ + tableOpts, + targetPage, + viewMode, + timeRange.startTime.toISOString(), + timeRange.endTime.toISOString(), + custQuerySearchState, + ]); useEffect(() => { if (!isStoreSynced) return; diff --git a/src/utils/index.ts b/src/utils/index.ts index 53a3c221..4c9bfa38 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -108,6 +108,10 @@ export const copyTextToClipboard = async (value: any) => { export const getOffset = (page: number, rowSize: number) => { const product = page * rowSize; + if (product % 1000 === 0) { + return Math.floor((product - 1) / 1000) * 1000; + } + return Math.floor(product / 1000) * 1000; }; From 1e438d3ab7e03c7918899aab7ad29100c010ea26 Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 13 Nov 2024 16:37:33 +0530 Subject: [PATCH 12/16] clean up --- src/pages/Stream/hooks/useParamsController.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 2d2ff3f6..b14211e4 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -138,7 +138,7 @@ const useParamsController = () => { setLogsStore((store) => setTargetPage( store, - Math.abs(_.toNumber(presentParams.page) - Math.round(offset / _.toNumber(presentParams.rows))), + Math.abs(_.toNumber(presentParams.page) - Math.ceil(offset / _.toNumber(presentParams.rows))), ), ); } @@ -170,6 +170,7 @@ const useParamsController = () => { filterType: custQuerySearchState.viewMode, fields: `${joinOrSplit(!_.isEmpty(targetColumns) ? targetColumns : activeHeaders)}`, }); + const presentParams = paramsStringToParamsObj(searchParams); if (_.isEqual(storeAsParams, presentParams)) return; setSearchParams(storeAsParams); From b792f7423354350c41903818731e65364213186a Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 13 Nov 2024 16:39:00 +0530 Subject: [PATCH 13/16] removed package lock --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 2ccc185a..161efca0 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,5 @@ "pretty-quick": "^3.1.3", "typescript": "^5.1.6", "vite": "^4.3.9" - }, - "packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee" + } } From 82c70e0df4ad01802f6a3ba126ded68daf6fbb5c Mon Sep 17 00:00:00 2001 From: Koustav Date: Wed, 13 Nov 2024 17:47:37 +0530 Subject: [PATCH 14/16] Edge case handled --- src/pages/Stream/hooks/useParamsController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index b14211e4..5be3b94c 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -127,7 +127,7 @@ const useParamsController = () => { setLogsStore((store) => setPerPage(store, _.toNumber(presentParams.rows))); } - if (storeAsParams.page !== presentParams.page) { + if (storeAsParams.page !== presentParams.page && !_.isEmpty(presentParams.page)) { setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page))); const offset = getOffset(_.toNumber(presentParams.page), _.toNumber(presentParams.rows)); From 802e337353cd32cd782ee805aab0413934de97ed Mon Sep 17 00:00:00 2001 From: Koustav Date: Thu, 14 Nov 2024 12:11:57 +0530 Subject: [PATCH 15/16] Handled time range --- src/pages/Stream/hooks/useParamsController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 5be3b94c..26761ef5 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -120,6 +120,7 @@ const useParamsController = () => { fields: `${joinOrSplit(!_.isEmpty(targetColumns) ? targetColumns : activeHeaders)}`, }); const presentParams = paramsStringToParamsObj(searchParams); + syncTimeRangeToStore(storeAsParams, presentParams); if (['table', 'json'].includes(presentParams.view) && presentParams.view !== storeAsParams.view) { setLogsStore((store) => onToggleView(store, presentParams.view as 'table' | 'json')); } @@ -155,7 +156,6 @@ const useParamsController = () => { if (storeAsParams.fields !== presentParams.fields) { setLogsStore((store) => setTargetColumns(store, joinOrSplit(presentParams.fields) as string[])); } - syncTimeRangeToStore(storeAsParams, presentParams); setStoreSynced(true); }, []); From 417189075f0e08c76bb8413888bdb9056454f117 Mon Sep 17 00:00:00 2001 From: Koustav Date: Thu, 14 Nov 2024 15:23:16 +0530 Subject: [PATCH 16/16] Set initial on offset change --- src/pages/Stream/Views/Explore/Footer.tsx | 9 ++------ src/pages/Stream/hooks/useParamsController.ts | 23 ++++++++++--------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/pages/Stream/Views/Explore/Footer.tsx b/src/pages/Stream/Views/Explore/Footer.tsx index 2f5b564e..75467748 100644 --- a/src/pages/Stream/Views/Explore/Footer.tsx +++ b/src/pages/Stream/Views/Explore/Footer.tsx @@ -9,7 +9,6 @@ import { IconSelector } from '@tabler/icons-react'; import useMountedState from '@/hooks/useMountedState'; import classes from '../../styles/Footer.module.css'; import { LOGS_FOOTER_HEIGHT } from '@/constants/theme'; -import { useSearchParams } from 'react-router-dom'; const { setPageAndPageData, setCurrentPage, setCurrentOffset } = logsStoreReducers; @@ -91,19 +90,15 @@ const LimitControl: FC = () => { const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: boolean }) => { const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts); - const { totalPages, currentOffset, currentPage, perPage, totalCount } = tableOpts; - const [searchParams] = useSearchParams(); - const pageFromURL = _.toNumber(searchParams.get('page')); + const { totalPages, currentOffset, currentPage, perPage, totalCount, targetPage } = tableOpts; const onPageChange = useCallback((page: number) => { setLogsStore((store) => setPageAndPageData(store, page)); }, []); useEffect(() => { - const initialPageFromUrl = pageFromURL % Math.ceil(currentOffset / perPage); if (!props.loaded) return; - - pagination.setPage(pageFromURL > totalPages ? initialPageFromUrl : pageFromURL); + pagination.setPage(targetPage ? targetPage : 1); }, [props.loaded]); const pagination = usePagination({ diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 26761ef5..7583533a 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -128,6 +128,18 @@ const useParamsController = () => { setLogsStore((store) => setPerPage(store, _.toNumber(presentParams.rows))); } + if (storeAsParams.query !== presentParams.query) { + setLogsStore((store) => setCustQuerySearchState(store, presentParams.query, presentParams.filterType)); + if (presentParams.filterType === 'filters') + setFilterStore((store) => + applySavedFilters(store, generateQueryBuilderASTFromSQL(presentParams.query) as QueryType), + ); + } + + if (storeAsParams.fields !== presentParams.fields) { + setLogsStore((store) => setTargetColumns(store, joinOrSplit(presentParams.fields) as string[])); + } + if (storeAsParams.page !== presentParams.page && !_.isEmpty(presentParams.page)) { setLogsStore((store) => setTargetPage(store, _.toNumber(presentParams.page))); @@ -145,17 +157,6 @@ const useParamsController = () => { } } - if (storeAsParams.query !== presentParams.query) { - setLogsStore((store) => setCustQuerySearchState(store, presentParams.query, presentParams.filterType)); - if (presentParams.filterType === 'filters') - setFilterStore((store) => - applySavedFilters(store, generateQueryBuilderASTFromSQL(presentParams.query) as QueryType), - ); - } - - if (storeAsParams.fields !== presentParams.fields) { - setLogsStore((store) => setTargetColumns(store, joinOrSplit(presentParams.fields) as string[])); - } setStoreSynced(true); }, []);