diff --git a/src/components/Header/RefreshInterval.tsx b/src/components/Header/RefreshInterval.tsx index 0d1dd504..fbc05103 100644 --- a/src/components/Header/RefreshInterval.tsx +++ b/src/components/Header/RefreshInterval.tsx @@ -7,9 +7,12 @@ import { REFRESH_INTERVALS } from '@/constants/timeConstants'; import classes from './styles/LogQuery.module.css'; import { useLogsStore, logsStoreReducers } from '@/pages/Stream/providers/LogsProvider'; import _ from 'lodash'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; const { setRefreshInterval, getCleanStoreForRefetch } = logsStoreReducers; +const { syncTimeRange } = appStoreReducers; const RefreshInterval: FC = () => { + const [, setAppStore] = useAppStore((_store) => null); const [refreshInterval, setLogsStore] = useLogsStore((store) => store.refreshInterval); const Icon = useMemo(() => (refreshInterval ? IconRefresh : IconRefreshOff), [refreshInterval]); const timerRef = useRef(null); @@ -34,6 +37,7 @@ const RefreshInterval: FC = () => { clearIntervalInstance(); if (refreshInterval !== null) { const intervalId = setInterval(() => { + setAppStore(syncTimeRange); setLogsStore(getCleanStoreForRefetch); }, refreshInterval); timerRef.current = intervalId; diff --git a/src/components/Header/RefreshNow.tsx b/src/components/Header/RefreshNow.tsx index 0e83f3af..0744be61 100644 --- a/src/components/Header/RefreshNow.tsx +++ b/src/components/Header/RefreshNow.tsx @@ -3,15 +3,19 @@ import { IconReload } from '@tabler/icons-react'; import { useCallback, type FC } from 'react'; import { useLogsStore, logsStoreReducers } from '@/pages/Stream/providers/LogsProvider'; import IconButton from '../Button/IconButton'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; const { getCleanStoreForRefetch } = logsStoreReducers; +const { syncTimeRange } = appStoreReducers; const renderRefreshIcon = () => ; const RefreshNow: FC = () => { const [, setLogsStore] = useLogsStore((_store) => null); + const [, setAppStore] = useAppStore((_store) => null); const onRefresh = useCallback(() => { + setAppStore((store) => syncTimeRange(store)); setLogsStore((store) => getCleanStoreForRefetch(store)); }, []); return ; diff --git a/src/components/Header/TimeRange.tsx b/src/components/Header/TimeRange.tsx index e1b99c4c..b92eb34c 100644 --- a/src/components/Header/TimeRange.tsx +++ b/src/components/Header/TimeRange.tsx @@ -8,12 +8,14 @@ import { Fragment, useCallback, useMemo, useRef, useState } from 'react'; import { FIXED_DURATIONS } from '@/constants/timeConstants'; import classes from './styles/LogQuery.module.css'; import { useOuterClick } from '@/hooks/useOuterClick'; -import { logsStoreReducers, useLogsStore } from '@/pages/Stream/providers/LogsProvider'; import _ from 'lodash'; import timeRangeUtils from '@/utils/timeRangeUtils'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { logsStoreReducers, useLogsStore } from '@/pages/Stream/providers/LogsProvider'; -const {getRelativeStartAndEndDate} = timeRangeUtils -const { setTimeRange, setshiftInterval } = logsStoreReducers; +const { getRelativeStartAndEndDate } = timeRangeUtils; +const { setTimeRange, setshiftInterval } = appStoreReducers; +const { getCleanStoreForRefetch } = logsStoreReducers; export type FixedDuration = (typeof FIXED_DURATIONS)[number]; const { timeRangeContainer, fixedRangeBtn, fixedRangeBtnSelected, customRangeContainer, shiftIntervalContainer } = @@ -40,7 +42,8 @@ const RelativeTimeIntervals = (props: { }; const TimeRange: FC = () => { - const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); + const [timeRange, setAppStore] = useAppStore((store) => store.timeRange); + const [, setLogStore] = useLogsStore((_store) => null); const { label, shiftInterval, interval, startTime, endTime, type } = timeRange; const handleOuterClick = useCallback((event: any) => { const targetClassNames: string[] = event.target?.classList || []; @@ -70,8 +73,9 @@ const TimeRange: FC = () => { }, []); const onDurationSelect = (duration: FixedDuration) => { - const {startTime, endTime} = getRelativeStartAndEndDate(duration); - setLogsStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); + const { startTime, endTime } = getRelativeStartAndEndDate(duration); + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); setOpened(false); }; @@ -79,7 +83,8 @@ const TimeRange: FC = () => { const now = dayjs().startOf('minute'); const startTime = now.subtract(FIXED_DURATIONS[0].milliseconds, 'milliseconds'); const endTime = now; - setLogsStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); setOpened(false); }, []); @@ -93,7 +98,7 @@ const TimeRange: FC = () => { const onSetShiftInterval = useCallback((val: number | string) => { if (typeof val === 'number') { - setLogsStore((store) => setshiftInterval(store, val)); + setAppStore((store) => setshiftInterval(store, val)); setShowTick(false); // Hide the tick when editing starts again debouncedShowTick(); // Show the tick after the user stops typing } @@ -104,13 +109,15 @@ const TimeRange: FC = () => { if (direction === 'left') { const newStartTime = new Date(startTime.getTime() - changeInMs); const newEndTime = new Date(endTime.getTime() - changeInMs); - setLogsStore((store) => + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { startTime: dayjs(newStartTime), endTime: dayjs(newEndTime), type: 'custom' }), ); } else { const newStartTime = new Date(startTime.getTime() + changeInMs); const newEndTime = new Date(endTime.getTime() + changeInMs); - setLogsStore((store) => + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { startTime: dayjs(newStartTime), endTime: dayjs(newEndTime), type: 'custom' }), ); } @@ -197,7 +204,8 @@ function isDateInRange(startDate: Date, endDate: Date, currentDate: Date) { } const CustomTimeRange: FC = ({ setOpened, resetToRelative }) => { - const [{ startTime: startTimeFromStore, endTime: endTimeFromStore, type }, setLogsStore] = useLogsStore( + const [, setLogStore] = useLogsStore((_store) => null); + const [{ startTime: startTimeFromStore, endTime: endTimeFromStore, type }, setAppStore] = useAppStore( (store) => store.timeRange, ); @@ -229,7 +237,8 @@ const CustomTimeRange: FC = ({ setOpened, resetToRelative }; const onApply = () => { - setLogsStore((store) => + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { type: 'custom', startTime: dayjs(localSelectedRange.startTime).startOf('minute'), diff --git a/src/hooks/useGetLogStreamSchema.ts b/src/hooks/useGetLogStreamSchema.ts index 483ea1d9..ea921dd9 100644 --- a/src/hooks/useGetLogStreamSchema.ts +++ b/src/hooks/useGetLogStreamSchema.ts @@ -40,6 +40,6 @@ export const useGetStreamSchema = (opts: { streamName: string }) => { isError, isLoading, errorMessage, - isRefetching + isRefetching, }; }; diff --git a/src/hooks/useQueryLogs.ts b/src/hooks/useQueryLogs.ts index 7812f2ae..62ab8997 100644 --- a/src/hooks/useQueryLogs.ts +++ b/src/hooks/useQueryLogs.ts @@ -48,9 +48,9 @@ export const useQueryLogs = () => { const [currentStream] = useAppStore((store) => store.currentStream); const timePartitionColumn = _.get(streamInfo, 'time_partition', 'p_timestamp'); const { refetch: refetchSchema } = useGetStreamSchema({ streamName: currentStream || '' }); + const [timeRange] = useAppStore((store) => store.timeRange); const [ { - timeRange, tableOpts: { currentOffset, instantSearchValue }, custQuerySearchState, }, diff --git a/src/hooks/useQueryResult.tsx b/src/hooks/useQueryResult.tsx index 897b070e..c288305f 100644 --- a/src/hooks/useQueryResult.tsx +++ b/src/hooks/useQueryResult.tsx @@ -59,7 +59,8 @@ export const useFetchCount = () => { const [currentStream] = useAppStore((store) => store.currentStream); const { setTotalCount } = logsStoreReducers; const [custQuerySearchState] = useLogsStore((store) => store.custQuerySearchState); - const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); + const [, setLogsStore] = useLogsStore((_store) => null); const { isQuerySearchActive, custSearchQuery, activeMode } = custQuerySearchState; const [appliedQuery] = useFilterStore((store) => store.appliedQuery); diff --git a/src/layouts/MainLayout/providers/AppProvider.tsx b/src/layouts/MainLayout/providers/AppProvider.tsx index 34c7a9a4..01edea2d 100644 --- a/src/layouts/MainLayout/providers/AppProvider.tsx +++ b/src/layouts/MainLayout/providers/AppProvider.tsx @@ -4,6 +4,13 @@ import { AboutData } from '@/@types/parseable/api/about'; import _ from 'lodash'; import { AxiosResponse } from 'axios'; import { SavedFilterType } from '@/@types/parseable/api/savedFilters'; +import { FIXED_DURATIONS, FixedDuration } from '@/constants/timeConstants'; +import dayjs, { Dayjs } from 'dayjs'; +import timeRangeUtils from '@/utils/timeRangeUtils'; + +const { makeTimeRangeLabel } = timeRangeUtils; + +export const DEFAULT_FIXED_DURATIONS = FIXED_DURATIONS[0]; export type UserRoles = { [roleName: string]: { @@ -17,7 +24,35 @@ export type UserRoles = { type ReducerOutput = Partial; +export type TimeRange = { + startTime: Date; + endTime: Date; + type: 'fixed' | 'custom'; + label: string; + interval: number; + shiftInterval: number; +}; + +const getDefaultTimeRange = (duration: FixedDuration = DEFAULT_FIXED_DURATIONS) => { + const now = dayjs().startOf('minute'); + const { milliseconds } = duration; + + const startTime = now.subtract(milliseconds, 'milliseconds'); + const endTime = now; + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); + + return { + startTime: startTime.toDate(), + endTime: now.toDate(), + type: 'fixed' as const, + label, + interval: milliseconds, + shiftInterval: 1, + }; +}; + type AppStore = { + timeRange: TimeRange; maximized: boolean; helpModalOpen: boolean; createStreamModalOpen: boolean; @@ -34,19 +69,27 @@ type AppStore = { }; type AppStoreReducers = { + setTimeRange: ( + store: AppStore, + payload: { startTime: dayjs.Dayjs; endTime: dayjs.Dayjs; type: 'fixed' | 'custom' }, + ) => ReducerOutput; toggleMaximize: (store: AppStore) => ReducerOutput; toggleHelpModal: (store: AppStore, val?: boolean) => ReducerOutput; changeStream: (store: AppStore, stream: string) => ReducerOutput; setUserRoles: (store: AppStore, roles: UserRoles | null) => ReducerOutput; + setshiftInterval: (store: AppStore, interval: number) => ReducerOutput; + syncTimeRange: (store: AppStore) => ReducerOutput; setUserSpecificStreams: (store: AppStore, userSpecficStreams: LogStreamData | null) => ReducerOutput; setUserAccessMap: (store: AppStore, accessRoles: string[] | null) => ReducerOutput; setStreamSpecificUserAccess: (store: AppStore, streamSpecificUserAccess: string[] | null) => ReducerOutput; setInstanceConfig: (store: AppStore, instanceConfig: AboutData) => ReducerOutput; toggleCreateStreamModal: (store: AppStore, val?: boolean) => ReducerOutput; setSavedFilters: (store: AppStore, savedFilters: AxiosResponse) => ReducerOutput; + applyQueryWithResetTime: (store: AppStore, timeRangePayload: { from: string; to: string } | null) => ReducerOutput; }; const initialState: AppStore = { + timeRange: getDefaultTimeRange(), maximized: false, helpModalOpen: false, currentStream: null, @@ -89,6 +132,65 @@ function getHTTPContext() { return window.isSecureContext; } // reducers +const syncTimeRange = (store: AppStore) => { + const { timeRange } = store; + const duration = _.find(FIXED_DURATIONS, (duration) => duration.milliseconds === timeRange.interval); + const updatedTimeRange = { timeRange: getDefaultTimeRange(duration) }; + return { + ...updatedTimeRange, + }; +}; + +const setTimeRange = ( + store: AppStore, + payload: { startTime: dayjs.Dayjs; endTime: Dayjs; type: 'fixed' | 'custom' }, +) => { + const { startTime, endTime, type } = payload; + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); + const interval = endTime.diff(startTime, 'milliseconds'); + return { + timeRange: { ...store.timeRange, startTime: startTime.toDate(), endTime: endTime.toDate(), label, interval, type }, + }; +}; + +const setshiftInterval = (store: AppStore, interval: number) => { + const { timeRange } = store; + return { + timeRange: { + ...timeRange, + shiftInterval: interval, + }, + }; +}; + +const applyQueryWithResetTime = (store: AppStore, timeRangePayload: { from: string; to: string } | null) => { + const { timeRange } = store; + + const updatedTimeRange = (() => { + if (!timeRangePayload) { + return { timeRange }; + } else { + const startTime = dayjs(timeRangePayload.from); + const endTime = dayjs(timeRangePayload.to); + const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); + const interval = endTime.diff(startTime, 'milliseconds'); + return { + timeRange: { + ...store.timeRange, + startTime: startTime.toDate(), + endTime: endTime.toDate(), + label, + interval, + type: 'custom' as const, // always + }, + }; + } + })(); + + return { + ...updatedTimeRange, + }; +}; const toggleMaximize = (store: AppStore) => { return { maximized: !store.maximized }; @@ -146,6 +248,10 @@ const appStoreReducers: AppStoreReducers = { setInstanceConfig, toggleCreateStreamModal, setSavedFilters, + setTimeRange, + setshiftInterval, + syncTimeRange, + applyQueryWithResetTime, }; export { AppProvider, useAppStore, appStoreReducers }; diff --git a/src/pages/Dashboards/CreateDashboardModal.tsx b/src/pages/Dashboards/CreateDashboardModal.tsx index 180228f5..2283ee4c 100644 --- a/src/pages/Dashboards/CreateDashboardModal.tsx +++ b/src/pages/Dashboards/CreateDashboardModal.tsx @@ -5,9 +5,9 @@ import { useCallback, useEffect } from 'react'; import _ from 'lodash'; import { useDashboardsQuery } from '@/hooks/useDashboards'; import { useForm } from '@mantine/form'; -import { useLogsStore } from '../Stream/providers/LogsProvider'; import timeRangeUtils from '@/utils/timeRangeUtils'; import { Tile } from '@/@types/parseable/api/dashboards'; +import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; const { toggleCreateDashboardModal, toggleEditDashboardModal } = dashboardsStoreReducers; const { makeTimeRangeOptions, getDefaultTimeRangeOption } = timeRangeUtils; @@ -29,7 +29,7 @@ const useDashboardForm = (opts: FormOpts) => { initialValues: opts, validate: { name: (val) => (_.isEmpty(val) ? 'Name cannot be empty' : null), - description: (_val) => (null), + description: (_val) => null, }, validateInputOnChange: true, validateInputOnBlur: true, @@ -53,7 +53,7 @@ const defaultOpts = { const CreateDashboardModal = () => { const [createMode, setDashbaordsStore] = useDashboardsStore((store) => store.createDashboardModalOpen); const [editMode] = useDashboardsStore((store) => store.editDashboardModalOpen); - const [timeRange] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); const [activeDashboard] = useDashboardsStore((store) => store.activeDashboard); const timeRangeOptions = makeTimeRangeOptions({ selected: editMode && activeDashboard ? activeDashboard.time_filter : null, diff --git a/src/pages/Dashboards/CreateTileForm.tsx b/src/pages/Dashboards/CreateTileForm.tsx index e0eab6bd..8b286768 100644 --- a/src/pages/Dashboards/CreateTileForm.tsx +++ b/src/pages/Dashboards/CreateTileForm.tsx @@ -23,7 +23,6 @@ import { } from '@/@types/parseable/api/dashboards'; import { CodeHighlight } from '@mantine/code-highlight'; import { sanitiseSqlString } from '@/utils/sanitiseSqlString'; -import { useLogsStore } from '../Stream/providers/LogsProvider'; import dayjs from 'dayjs'; import TimeRange from '@/components/Header/TimeRange'; import { colors, isCircularChart, isGraph, normalizeGraphColorConfig } from './Charts'; @@ -291,7 +290,7 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value: const [fields, setFields] = useState([]); const [initialHeight, setInitialHeight] = useState(0); const [dashboards] = useDashboardsStore((store) => store.dashboards); - const [timeRange] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); const [appliedFilterQuery, setLogsStore] = useFilterStore((store) => store.appliedFilterQuery); const [aiQuery, setAiQuery] = useState(''); const [userSpecificStreams] = useAppStore((store) => store.userSpecificStreams); diff --git a/src/pages/Dashboards/Tile.tsx b/src/pages/Dashboards/Tile.tsx index 6c4fd90f..dfb5e898 100644 --- a/src/pages/Dashboards/Tile.tsx +++ b/src/pages/Dashboards/Tile.tsx @@ -28,8 +28,9 @@ import { Tile as TileType, TileQueryResponse } from '@/@types/parseable/api/dash import { sanitiseSqlString } from '@/utils/sanitiseSqlString'; import Table from './Table'; import { downloadDataAsCSV, downloadDataAsJson, exportJson } from '@/utils/exportHelpers'; -import { makeExportData, useLogsStore } from '../Stream/providers/LogsProvider'; +import { makeExportData } from '../Stream/providers/LogsProvider'; import { getRandomUnitTypeForChart, getUnitTypeByKey } from './utils'; +import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; const ParseableLogo = () => (
@@ -257,7 +258,7 @@ function TileControls(props: { tile: TileType; data: TileQueryResponse }) { } const Tile = (props: { id: string }) => { - const [timeRange] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); const [tilesData] = useDashboardsStore((store) => store.tilesData); const tileData = _.get(tilesData, props.id, { records: [], fields: [] }); const [activeDashboard] = useDashboardsStore((store) => store.activeDashboard); diff --git a/src/pages/Dashboards/hooks.ts b/src/pages/Dashboards/hooks.ts index 9134eafb..a3848d13 100644 --- a/src/pages/Dashboards/hooks.ts +++ b/src/pages/Dashboards/hooks.ts @@ -1,15 +1,18 @@ -import { useLogsStore, logsStoreReducers } from "../Stream/providers/LogsProvider" -import { useCallback } from "react" -import _ from "lodash" -import dayjs from "dayjs" -import { useDashboardsStore } from "./providers/DashboardsProvider" -import { Dashboard } from "@/@types/parseable/api/dashboards" +import { useCallback } from 'react'; +import _ from 'lodash'; +import dayjs from 'dayjs'; +import { useDashboardsStore } from './providers/DashboardsProvider'; +import { Dashboard } from '@/@types/parseable/api/dashboards'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { logsStoreReducers, useLogsStore } from '../Stream/providers/LogsProvider'; -const { setTimeRange } = logsStoreReducers; +const { setTimeRange } = appStoreReducers; +const { getCleanStoreForRefetch } = logsStoreReducers; export const useSyncTimeRange = () => { - const [dashboards] = useDashboardsStore(store => store.dashboards); - const [, setLogsStore] = useLogsStore((_store) => null); + const [dashboards] = useDashboardsStore((store) => store.dashboards); + const [, setLogStore] = useLogsStore((_store) => null); + const [, setAppStore] = useAppStore((_store) => null); const updateTimeRange = useCallback( (dashboard: Dashboard) => { @@ -17,10 +20,13 @@ export const useSyncTimeRange = () => { const { time_filter } = dashboard; const hasTimeFilter = !_.isEmpty(time_filter); - hasTimeFilter && - setLogsStore((store) => + + if (hasTimeFilter) { + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { startTime: dayjs(time_filter.from), endTime: dayjs(time_filter.to), type: 'custom' }), ); + } }, [dashboards], ); diff --git a/src/pages/Dashboards/hooks/useParamsController.ts b/src/pages/Dashboards/hooks/useParamsController.ts index 3bf038d6..0b68a25c 100644 --- a/src/pages/Dashboards/hooks/useParamsController.ts +++ b/src/pages/Dashboards/hooks/useParamsController.ts @@ -1,16 +1,18 @@ import { useCallback, useEffect, useState } from 'react'; import { useDashboardsStore, dashboardsStoreReducers } from '../providers/DashboardsProvider'; -import { TimeRange, useLogsStore, logsStoreReducers } from '@/pages/Stream/providers/LogsProvider'; import { useSearchParams } from 'react-router-dom'; import _ from 'lodash'; import { FIXED_DURATIONS } from '@/constants/timeConstants'; import dayjs from 'dayjs'; import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; +import { appStoreReducers, TimeRange, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { logsStoreReducers, useLogsStore } from '@/pages/Stream/providers/LogsProvider'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; const { selectDashboard } = dashboardsStoreReducers; -const { setTimeRange } = logsStoreReducers; +const { setTimeRange } = appStoreReducers; +const { getCleanStoreForRefetch } = logsStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; const keys = ['id', 'interval', 'from', 'to']; @@ -71,7 +73,8 @@ const paramsStringToParamsObj = (searchParams: URLSearchParams): Record { const [isStoreSynced, setStoreSynced] = useState(false); const [activeDashboard, setDashboardsStore] = useDashboardsStore((store) => store.activeDashboard); - const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); + const [timeRange, setAppStore] = useAppStore((store) => store.timeRange); + const [, setLogStore] = useLogsStore((_store) => null); const [searchParams, setSearchParams] = useSearchParams(); const dashboardId = activeDashboard?.dashboard_id || ''; @@ -114,14 +117,16 @@ const useParamsController = () => { if (!duration) return; const { startTime, endTime } = getRelativeStartAndEndDate(duration); - return setLogsStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); + setLogStore((store) => getCleanStoreForRefetch(store)); + return setAppStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); } } else if (_.has(presentParams, 'from') && _.has(presentParams, 'to')) { if (storeAsParams.from !== presentParams.from && storeAsParams.to !== presentParams.to) { const startTime = dateParamStrToDateObj(presentParams.from); const endTime = dateParamStrToDateObj(presentParams.to); if (_.isDate(startTime) && _.isDate(endTime)) { - return setLogsStore((store) => + setLogStore((store) => getCleanStoreForRefetch(store)); + return setAppStore((store) => setTimeRange(store, { startTime: dayjs(startTime), endTime: dayjs(endTime), type: 'custom' }), ); } diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index a4b22d33..7631df8d 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -31,7 +31,7 @@ import _ from 'lodash'; import { heights } from '@/components/Mantine/sizing'; import { PRIMARY_HEADER_HEIGHT } from '@/constants/theme'; -const { changeStream, toggleCreateStreamModal } = appStoreReducers; +const { changeStream, toggleCreateStreamModal, syncTimeRange } = appStoreReducers; type NoStreamsViewProps = { hasCreateStreamAccess: boolean; @@ -89,6 +89,7 @@ const Home: FC = () => { useEffect(() => { if (!Array.isArray(userSpecificStreams) || userSpecificStreams.length === 0 || !userRoles) return; + setAppStore((store) => syncTimeRange(store)); getStreamMetadata(userSpecificStreams.map((stream) => stream.name)); }, [userSpecificStreams, userRoles]); diff --git a/src/pages/Stream/Views/Explore/LoadingViews.tsx b/src/pages/Stream/Views/Explore/LoadingViews.tsx index 7bd7d3b6..4505af4c 100644 --- a/src/pages/Stream/Views/Explore/LoadingViews.tsx +++ b/src/pages/Stream/Views/Explore/LoadingViews.tsx @@ -3,13 +3,18 @@ import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; import { Center, Loader, Stack, Text } from '@mantine/core'; import { RetryBtn } from '@/components/Button/Retry'; import classes from '../../styles/Logs.module.css'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; const { getCleanStoreForRefetch } = logsStoreReducers; +const { syncTimeRange } = appStoreReducers; export const ErrorView = (props: { message: string }) => { const [, setLogsStore] = useLogsStore((_store) => null); + const [, setAppStore] = useAppStore((_store) => null); + const { message } = props; const onRetry = useCallback(() => { + setAppStore((store) => syncTimeRange(store)); setLogsStore((store) => getCleanStoreForRefetch(store)); }, []); return ( diff --git a/src/pages/Stream/Views/Explore/useLogsFetcher.ts b/src/pages/Stream/Views/Explore/useLogsFetcher.ts index df31a5ab..96a6435e 100644 --- a/src/pages/Stream/Views/Explore/useLogsFetcher.ts +++ b/src/pages/Stream/Views/Explore/useLogsFetcher.ts @@ -1,4 +1,4 @@ -import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import { useEffect } from 'react'; import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; import { useQueryLogs } from '@/hooks/useQueryLogs'; @@ -6,11 +6,13 @@ import { useFetchCount } from '@/hooks/useQueryResult'; import { useStreamStore } from '../../providers/StreamProvider'; const { setCleanStoreForStreamChange } = logsStoreReducers; +const { syncTimeRange } = appStoreReducers; const useLogsFetcher = (props: { schemaLoading: boolean; infoLoading: boolean }) => { const { schemaLoading, infoLoading } = props; const [currentStream] = useAppStore((store) => store.currentStream); - const [{ tableOpts, timeRange }, setLogsStore] = useLogsStore((store) => store); + const [{ timeRange }, setAppStore] = useAppStore((store) => store); + const [{ tableOpts }, setLogsStore] = useLogsStore((store) => store); const { currentOffset, currentPage, pageData } = tableOpts; const { getQueryData, loading: logsLoading, error: errorMessage } = useQueryLogs(); const [{ info }] = useStreamStore((store) => store); @@ -22,6 +24,7 @@ const useLogsFetcher = (props: { schemaLoading: boolean; infoLoading: boolean }) const showTable = hasContentLoaded && !hasNoData && !errorMessage; useEffect(() => { + setAppStore(syncTimeRange); setLogsStore(setCleanStoreForStreamChange); }, [currentStream]); diff --git a/src/pages/Stream/components/EventTimeLineGraph.tsx b/src/pages/Stream/components/EventTimeLineGraph.tsx index 51d56b0c..030c6837 100644 --- a/src/pages/Stream/components/EventTimeLineGraph.tsx +++ b/src/pages/Stream/components/EventTimeLineGraph.tsx @@ -6,16 +6,17 @@ import dayjs from 'dayjs'; import { ChartTooltipProps, AreaChart } from '@mantine/charts'; import { HumanizeNumber } from '@/utils/formatBytes'; import { logsStoreReducers, useLogsStore } from '../providers/LogsProvider'; -import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import { useFilterStore, filterStoreReducers } from '../providers/FilterProvider'; import { LogsResponseWithHeaders } from '@/@types/parseable/api/query'; import _ from 'lodash'; import timeRangeUtils from '@/utils/timeRangeUtils'; import { useStreamStore } from '../providers/StreamProvider'; -const { setTimeRange } = logsStoreReducers; +const { setTimeRange } = appStoreReducers; const { parseQuery } = filterStoreReducers; const { makeTimeRangeLabel } = timeRangeUtils; +const { getCleanStoreForRefetch } = logsStoreReducers; type CompactInterval = 'minute' | 'day' | 'hour' | 'quarter-hour' | 'half-hour' | 'month'; @@ -266,8 +267,8 @@ const EventTimeLineGraph = () => { const [currentStream] = useAppStore((store) => store.currentStream); const [queryEngine] = useAppStore((store) => store.instanceConfig?.queryEngine); const [appliedQuery] = useFilterStore((store) => store.appliedQuery); - const [{ activeMode, custSearchQuery }] = useLogsStore((store) => store.custQuerySearchState); - const [{ interval, startTime, endTime }] = useLogsStore((store) => store.timeRange); + const [{ activeMode, custSearchQuery }, setLogStore] = useLogsStore((store) => store.custQuerySearchState); + const [{ interval, startTime, endTime }] = useAppStore((store) => store.timeRange); const [localStream, setLocalStream] = useState(''); const [{ info }] = useStreamStore((store) => store); const firstEventAt = 'first-event-at' in info ? info['first-event-at'] : undefined; @@ -306,7 +307,7 @@ const EventTimeLineGraph = () => { return parseGraphData(fetchQueryMutation?.data, avgEventCount, startTime, endTime, interval); }, [fetchQueryMutation?.data, interval, firstEventAt]); const hasData = Array.isArray(graphData) && graphData.length !== 0; - const [, setLogsStore] = useLogsStore((store) => store.timeRange); + const [, setAppStore] = useAppStore((_store) => null); const setTimeRangeFromGraph = useCallback((barValue: any) => { const activePayload = barValue?.activePayload; if (!Array.isArray(activePayload) || activePayload.length === 0) return; @@ -318,7 +319,8 @@ const EventTimeLineGraph = () => { if (!graphTickItem || typeof graphTickItem !== 'object' || _.isEmpty(graphTickItem)) return; const { startTime, endTime } = graphTickItem; - setLogsStore((store) => setTimeRange(store, { type: 'custom', startTime: startTime, endTime: endTime })); + setLogStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { type: 'custom', startTime: startTime, endTime: endTime })); }, []); return ( diff --git a/src/pages/Stream/components/Querier/QueryCodeEditor.tsx b/src/pages/Stream/components/Querier/QueryCodeEditor.tsx index 02a7d0df..ace9de67 100644 --- a/src/pages/Stream/components/Querier/QueryCodeEditor.tsx +++ b/src/pages/Stream/components/Querier/QueryCodeEditor.tsx @@ -80,7 +80,7 @@ const QueryCodeEditor: FC<{ const { data: resAIQuery, postLLMQuery } = usePostLLM(); const isLlmActive = !!llmActive; const isSqlSearchActive = isQuerySearchActive && activeMode === 'sql'; - const [timeRange] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); useEffect(() => { if (props.queryCodeEditorRef.current === '' || currentStream !== localStreamName) { diff --git a/src/pages/Stream/components/Querier/SaveFilterModal.tsx b/src/pages/Stream/components/Querier/SaveFilterModal.tsx index cac31a69..4c0fd8a1 100644 --- a/src/pages/Stream/components/Querier/SaveFilterModal.tsx +++ b/src/pages/Stream/components/Querier/SaveFilterModal.tsx @@ -38,7 +38,7 @@ const SaveFilterModal = () => { const [activeSavedFilters] = useAppStore((store) => store.activeSavedFilters); const [formObject, setFormObject] = useState(null); const [currentStream] = useAppStore((store) => store.currentStream); - const [timeRange] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); const [{ custSearchQuery, savedFilterId, activeMode }] = useLogsStore((store) => store.custQuerySearchState); const [isDirty, setDirty] = useState(false); const { updateSavedFilters, createSavedFilters, isCreating, isUpdating } = useSavedFiltersQuery(); diff --git a/src/pages/Stream/components/Querier/SavedFiltersModal.tsx b/src/pages/Stream/components/Querier/SavedFiltersModal.tsx index edd63abd..d60887a2 100644 --- a/src/pages/Stream/components/Querier/SavedFiltersModal.tsx +++ b/src/pages/Stream/components/Querier/SavedFiltersModal.tsx @@ -10,14 +10,15 @@ import { IconClock, IconEye, IconEyeOff, IconTrash, IconX } from '@tabler/icons- import IconButton from '@/components/Button/IconButton'; import classes from './styles/SavedFiltersModalStyles.module.css'; import { EmptySimple } from '@/components/Empty'; -import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import useSavedFiltersQuery from '@/hooks/useSavedFilters'; import { generateQueryBuilderASTFromSQL } from '../../utils'; import { useLocation } from 'react-router-dom'; const { toggleSavedFiltersModal, resetFilters, parseQuery, applySavedFilters, setAppliedFilterQuery } = filterStoreReducers; -const { applyCustomQuery, updateSavedFilterId, getCleanStoreForRefetch, setTimeRange } = logsStoreReducers; +const { applyCustomQuery, updateSavedFilterId, getCleanStoreForRefetch } = logsStoreReducers; +const { syncTimeRange, setTimeRange, applyQueryWithResetTime } = appStoreReducers; const renderDeleteIcon = () => ; const renderCloseIcon = () => ; @@ -183,7 +184,7 @@ const SavedFilterItem = (props: { const SavedFiltersModal = () => { const [isSavedFiltersModalOpen, setFilterStore] = useFilterStore((store) => store.isSavedFiltersModalOpen); const [savedFilterId, setLogsStore] = useLogsStore((store) => store.custQuerySearchState.savedFilterId); - const [{ startTime, endTime }] = useLogsStore((store) => store.timeRange); + const [{ startTime, endTime }, setAppStore] = useAppStore((store) => store.timeRange); const [savedFilters] = useAppStore((store) => store.savedFilters); const [activeSavedFilters] = useAppStore((store) => store.activeSavedFilters); const [currentStream] = useAppStore((store) => store.currentStream); @@ -192,7 +193,8 @@ const SavedFiltersModal = () => { const onSqlSearchApply = useCallback( (query: string, id: string, time_filter: null | { from: string; to: string }) => { setFilterStore((store) => resetFilters(store)); - setLogsStore((store) => applyCustomQuery(store, query, 'sql', id, time_filter)); + setAppStore((store) => applyQueryWithResetTime(store, time_filter)); + setLogsStore((store) => applyCustomQuery(store, query, 'sql', id)); }, [], ); @@ -227,12 +229,14 @@ const SavedFiltersModal = () => { ); const hardRefresh = useCallback(() => { + setAppStore((store) => syncTimeRange(store)); setLogsStore((store) => getCleanStoreForRefetch(store)); closeModal(); }, []); const changeTimerange = useCallback((from: string, end: string) => { - setLogsStore((store) => setTimeRange(store, { type: 'custom', startTime: dayjs(from), endTime: dayjs(end) })); + setLogsStore((store) => getCleanStoreForRefetch(store)); + setAppStore((store) => setTimeRange(store, { type: 'custom', startTime: dayjs(from), endTime: dayjs(end) })); closeModal(); }, []); diff --git a/src/pages/Stream/components/Querier/index.tsx b/src/pages/Stream/components/Querier/index.tsx index 077ddab8..4ca6dbb8 100644 --- a/src/pages/Stream/components/Querier/index.tsx +++ b/src/pages/Stream/components/Querier/index.tsx @@ -8,7 +8,7 @@ import QueryCodeEditor, { defaultCustSQLQuery } from './QueryCodeEditor'; import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; import { useCallback, useEffect, useRef } from 'react'; import { filterStoreReducers, noValueOperators, useFilterStore } from '../../providers/FilterProvider'; -import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import { useStreamStore } from '../../providers/StreamProvider'; import SaveFilterModal from './SaveFilterModal'; import SavedFiltersModal from './SavedFiltersModal'; @@ -19,6 +19,8 @@ const { setFields, parseQuery, storeAppliedQuery, resetFilters, toggleSubmitBtn, const { toggleQueryBuilder, toggleCustQuerySearchViewMode, applyCustomQuery, resetCustQuerySearchState } = logsStoreReducers; +const { applyQueryWithResetTime, syncTimeRange } = appStoreReducers; + const getLabel = (mode: string | null) => { return mode === 'filters' ? 'Filters' : mode === 'sql' ? 'SQL' : ''; }; @@ -76,7 +78,7 @@ const QuerierModal = (props: { const [queryEngine] = useAppStore((store) => store.instanceConfig?.queryEngine); const [{ showQueryBuilder, viewMode }, setLogsStore] = useLogsStore((store) => store.custQuerySearchState); const [streamInfo] = useStreamStore((store) => store.info); - const [timeRange] = useLogsStore((store) => store.timeRange); + const [timeRange] = useAppStore((store) => store.timeRange); const timePartitionColumn = _.get(streamInfo, 'time_partition', 'p_timestamp'); const onClose = useCallback(() => { setLogsStore((store) => toggleQueryBuilder(store, false)); @@ -121,7 +123,7 @@ const QuerierModal = (props: { const Querier = () => { const [custQuerySearchState, setLogsStore] = useLogsStore((store) => store.custQuerySearchState); - const [{ startTime, endTime }] = useLogsStore((store) => store.timeRange); + const [{ startTime, endTime }, setAppStore] = useAppStore((store) => store.timeRange); const { isQuerySearchActive, viewMode, showQueryBuilder, activeMode, savedFilterId } = custQuerySearchState; const [currentStream] = useAppStore((store) => store.currentStream); const [queryEngine] = useAppStore((store) => store.instanceConfig?.queryEngine); @@ -147,7 +149,8 @@ const Querier = () => { const triggerRefetch = useCallback( (query: string, mode: 'filters' | 'sql', id?: string) => { const time_filter = id ? _.find(activeSavedFilters, (filter) => filter.filter_id === id)?.time_filter : null; - setLogsStore((store) => applyCustomQuery(store, query, mode, id, time_filter)); + setAppStore((store) => applyQueryWithResetTime(store, time_filter || null)); + setLogsStore((store) => applyCustomQuery(store, query, mode, id)); }, [activeSavedFilters], ); @@ -180,6 +183,7 @@ const Querier = () => { const onClear = useCallback(() => { setFilterStore((store) => resetFilters(store)); + setAppStore((store) => syncTimeRange(store)); setLogsStore((store) => resetCustQuerySearchState(store)); }, []); diff --git a/src/pages/Stream/hooks/useParamsController.ts b/src/pages/Stream/hooks/useParamsController.ts index 8e36d66d..b7894003 100644 --- a/src/pages/Stream/hooks/useParamsController.ts +++ b/src/pages/Stream/hooks/useParamsController.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; -import { TimeRange, useLogsStore, logsStoreReducers } from '@/pages/Stream/providers/LogsProvider'; +import { useLogsStore, logsStoreReducers } from '@/pages/Stream/providers/LogsProvider'; import { useSearchParams } from 'react-router-dom'; import _ from 'lodash'; import { FIXED_DURATIONS } from '@/constants/timeConstants'; @@ -9,9 +9,11 @@ import timeRangeUtils from '@/utils/timeRangeUtils'; import moment from 'moment-timezone'; import { filterStoreReducers, QueryType, useFilterStore } from '../providers/FilterProvider'; import { generateQueryBuilderASTFromSQL } from '../utils'; +import { appStoreReducers, TimeRange, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; const { getRelativeStartAndEndDate, formatDateWithTimezone, getLocalTimezone } = timeRangeUtils; -const { setTimeRange, onToggleView, setPerPage, setCustQuerySearchState } = logsStoreReducers; +const { onToggleView, setPerPage, setCustQuerySearchState } = logsStoreReducers; +const { setTimeRange, syncTimeRange } = appStoreReducers; const { applySavedFilters } = filterStoreReducers; const timeRangeFormat = 'DD-MMM-YYYY_HH-mmz'; const keys = ['view', 'rows', 'interval', 'from', 'to', 'query', 'filterType']; @@ -88,7 +90,8 @@ const useParamsController = () => { const [tableOpts] = useLogsStore((store) => store.tableOpts); const [viewMode] = useLogsStore((store) => store.viewMode); const [custQuerySearchState] = useLogsStore((store) => store.custQuerySearchState); - const [timeRange, setLogsStore] = useLogsStore((store) => store.timeRange); + const [timeRange, setAppStore] = useAppStore((store) => store.timeRange); + const [, setLogsStore] = useLogsStore((_store) => null); const [, setFilterStore] = useFilterStore((store) => store); const { currentOffset, currentPage, perPage } = tableOpts; @@ -114,6 +117,7 @@ const useParamsController = () => { } if (storeAsParams.query !== presentParams.query) { + setAppStore((store) => syncTimeRange(store)); setLogsStore((store) => setCustQuerySearchState(store, presentParams.query, presentParams.filterType)); if (presentParams.filterType === 'filters') setFilterStore((store) => @@ -170,6 +174,7 @@ const useParamsController = () => { setFilterStore((store) => applySavedFilters(store, generateQueryBuilderASTFromSQL(presentParams.query) as QueryType), ); + setAppStore((store) => syncTimeRange(store)); setLogsStore((store) => setCustQuerySearchState(store, presentParams.query, presentParams.filterType)); } syncTimeRangeToStore(storeAsParams, presentParams); @@ -183,14 +188,14 @@ const useParamsController = () => { if (!duration) return; const { startTime, endTime } = getRelativeStartAndEndDate(duration); - return setLogsStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); + return setAppStore((store) => setTimeRange(store, { startTime, endTime, type: 'fixed' })); } } else if (_.has(presentParams, 'from') && _.has(presentParams, 'to')) { if (storeAsParams.from !== presentParams.from && storeAsParams.to !== presentParams.to) { const startTime = dateParamStrToDateObj(presentParams.from); const endTime = dateParamStrToDateObj(presentParams.to); if (_.isDate(startTime) && _.isDate(endTime)) { - return setLogsStore((store) => + return setAppStore((store) => setTimeRange(store, { startTime: dayjs(startTime), endTime: dayjs(endTime), type: 'custom' }), ); } diff --git a/src/pages/Stream/providers/LogsProvider.tsx b/src/pages/Stream/providers/LogsProvider.tsx index ddad7682..8af9ed18 100644 --- a/src/pages/Stream/providers/LogsProvider.tsx +++ b/src/pages/Stream/providers/LogsProvider.tsx @@ -1,16 +1,13 @@ import { Log } from '@/@types/parseable/api/query'; import { LogStreamData, LogStreamSchemaData } from '@/@types/parseable/api/stream'; -import { FIXED_DURATIONS, FixedDuration } from '@/constants/timeConstants'; +import { FIXED_DURATIONS } from '@/constants/timeConstants'; import initContext from '@/utils/initContext'; -import dayjs, { Dayjs } from 'dayjs'; import { addOrRemoveElement } from '@/utils'; import { getPageSlice } from '../utils'; import _ from 'lodash'; import { sanitizeCSVData } from '@/utils/exportHelpers'; import timeRangeUtils from '@/utils/timeRangeUtils'; -const { makeTimeRangeLabel } = timeRangeUtils; - export const DEFAULT_FIXED_DURATIONS = FIXED_DURATIONS[0]; export const LOG_QUERY_LIMITS = [50, 100, 150, 200]; export const LOAD_LIMIT = 1000; @@ -83,15 +80,6 @@ export type TransformedAlerts = { alerts: TransformedAlert[]; }; -export type TimeRange = { - startTime: Date; - endTime: Date; - type: 'fixed' | 'custom'; - label: string; - interval: number; - shiftInterval: number; -}; - enum SortOrder { ASCENDING = 1, DESCENDING = -1, @@ -115,7 +103,6 @@ type LiveTailConfig = { liveTailSearchField: string; showLiveTail: boolean; }; - export const formatLogTs = (timestamp: string) => { if (!_.endsWith(timestamp, 'Z')) { return timeRangeUtils.formatDateWithTimezone(`${timestamp}Z`, 'yyyy-MM-DDTHH:mm:ss.SSSZ'); @@ -124,24 +111,6 @@ export const formatLogTs = (timestamp: string) => { } }; -const getDefaultTimeRange = (duration: FixedDuration = DEFAULT_FIXED_DURATIONS) => { - const now = dayjs().startOf('minute'); - const { milliseconds } = duration; - - const startTime = now.subtract(milliseconds, 'milliseconds'); - const endTime = now; - const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); - - return { - startTime: startTime.toDate(), - endTime: now.toDate(), - type: 'fixed' as const, - label, - interval: milliseconds, - shiftInterval: 1, - }; -}; - const defaultQuickFilters = { search: '', filters: {}, @@ -184,7 +153,6 @@ type CustQuerySearchState = { }; type LogsStore = { - timeRange: TimeRange; quickFilters: QuickFilters; liveTailConfig: LiveTailConfig; refreshInterval: number | null; @@ -233,12 +201,6 @@ type LogsStore = { }; type LogsStoreReducers = { - setTimeRange: ( - store: LogsStore, - payload: { startTime: dayjs.Dayjs; endTime: dayjs.Dayjs; type: 'fixed' | 'custom' }, - ) => ReducerOutput; - setshiftInterval: (store: LogsStore, interval: number) => ReducerOutput; - // resetTimeRange: (store: LogsStore) => ReducerOutput; deleteFilterItem: (store: LogsStore, key: string) => ReducerOutput; addFilterItem: (store: LogsStore, key: string, value: string[]) => ReducerOutput; setLiveTailStatus: (store: LogsStore, liveTailStatus: LiveTailStatus) => ReducerOutput; @@ -274,13 +236,7 @@ type LogsStoreReducers = { // data reducers setLogData: (store: LogsStore, data: Log[], headers: string[], jqFilteredData?: Log[]) => ReducerOutput; setStreamSchema: (store: LogsStore, schema: LogStreamSchemaData) => ReducerOutput; - applyCustomQuery: ( - store: LogsStore, - query: string, - mode: 'filters' | 'sql', - savedFilterId?: string, - timeRangePayload?: { from: string; to: string } | null, - ) => ReducerOutput; + applyCustomQuery: (store: LogsStore, query: string, mode: 'filters' | 'sql', savedFilterId?: string) => ReducerOutput; getUniqueValues: (data: Log[], key: string) => string[]; makeExportData: (data: Log[], headers: string[], type: string) => Log[]; setRetention: (store: LogsStore, retention: { description: string; duration: string }) => ReducerOutput; @@ -301,7 +257,6 @@ const defaultSortKey = 'p_timestamp'; const defaultSortOrder = 'desc' as const; const initialState: LogsStore = { - timeRange: getDefaultTimeRange(), quickFilters: defaultQuickFilters, liveTailConfig: defaultLiveTailConfig, refreshInterval: null, @@ -367,39 +322,6 @@ const setSelectedLog = (_store: LogsStore, log: Log | null) => { }; // reducers -const setTimeRange = ( - store: LogsStore, - payload: { startTime: dayjs.Dayjs; endTime: Dayjs; type: 'fixed' | 'custom' }, -) => { - const { startTime, endTime, type } = payload; - const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); - const interval = endTime.diff(startTime, 'milliseconds'); - const cleanStore = getCleanStoreForRefetch(store); - return { - ...cleanStore, - timeRange: { ...store.timeRange, startTime: startTime.toDate(), endTime: endTime.toDate(), label, interval, type }, - viewMode: store.viewMode, - }; -}; - -const setshiftInterval = (store: LogsStore, interval: number) => { - const { timeRange } = store; - return { - timeRange: { - ...timeRange, - shiftInterval: interval, - }, - }; -}; - -// const resetTimeRange = (store: LogsStore) => { -// const now = dayjs(); -// const timeDiff = store.timeRange.endTime.getTime() - store.timeRange.startTime.getTime(); -// const startTime = now.subtract(timeDiff).toDate(); -// const endTime = now.toDate(); -// return store.timeRange.type === 'custom' ? store : { timeRange: { ...store.timeRange, startTime, endTime } }; -// }; - const deleteFilterItem = (store: LogsStore, key: string) => { const filters = store.quickFilters.filters; const updatedFilters = (({ [key]: _, ...filters }) => filters)(filters); @@ -456,7 +378,6 @@ const toggleQueryBuilder = (store: LogsStore, val?: boolean) => { }; const setCustQuerySearchState = (store: LogsStore, query: string, viewMode: string) => { - const { timeRange } = store; return { custQuerySearchState: { showQueryBuilder: false, @@ -467,16 +388,14 @@ const setCustQuerySearchState = (store: LogsStore, query: string, viewMode: stri activeMode: viewMode === 'filters' ? ('filters' as const) : ('sql' as const), }, ...getCleanStoreForRefetch(store), - timeRange, }; }; const resetCustQuerySearchState = (store: LogsStore) => { - const { custQuerySearchState, timeRange } = store; + const { custQuerySearchState } = store; return { custQuerySearchState: { ...defaultCustQuerySearchState, viewMode: custQuerySearchState.viewMode }, ...getCleanStoreForRefetch(store), - timeRange, }; }; @@ -681,12 +600,7 @@ const setPageAndPageData = (store: LogsStore, pageNo: number, perPage?: number) }; const getCleanStoreForRefetch = (store: LogsStore) => { - const { tableOpts, data, timeRange } = store; - const { interval, type } = timeRange; - - const duration = _.find(FIXED_DURATIONS, (duration) => duration.milliseconds === timeRange.interval); - - const updatedTimeRange = interval && type === 'fixed' ? { timeRange: getDefaultTimeRange(duration) } : { timeRange }; + const { tableOpts, data } = store; return { tableOpts: { ...tableOpts, @@ -703,15 +617,11 @@ const getCleanStoreForRefetch = (store: LogsStore) => { filteredData: [], rawData: [], }, - ...updatedTimeRange, }; }; const setCleanStoreForStreamChange = (store: LogsStore) => { - const { tableOpts, timeRange, alerts } = store; - const { interval, type } = timeRange; - const duration = _.find(FIXED_DURATIONS, (duration) => duration.milliseconds === timeRange.interval); - const updatedTimeRange = interval && type === 'fixed' ? { timeRange: getDefaultTimeRange(duration) } : { timeRange }; + const { tableOpts, alerts } = store; return { ...initialState, tableOpts: { @@ -728,40 +638,12 @@ const setCleanStoreForStreamChange = (store: LogsStore) => { pinnedColumns: [], filters: {}, }, - ...updatedTimeRange, alerts, }; }; -const applyCustomQuery = ( - store: LogsStore, - query: string, - mode: 'filters' | 'sql', - savedFilterId?: string, - timeRangePayload?: { from: string; to: string } | null, -) => { - const { custQuerySearchState, timeRange } = store; - - const updatedTimeRange = (() => { - if (!timeRangePayload) { - return { timeRange }; - } else { - const startTime = dayjs(timeRangePayload.from); - const endTime = dayjs(timeRangePayload.to); - const label = makeTimeRangeLabel(startTime.toDate(), endTime.toDate()); - const interval = endTime.diff(startTime, 'milliseconds'); - return { - timeRange: { - ...store.timeRange, - startTime: startTime.toDate(), - endTime: endTime.toDate(), - label, - interval, - type: 'custom' as const, // always - }, - }; - } - })(); +const applyCustomQuery = (store: LogsStore, query: string, mode: 'filters' | 'sql', savedFilterId?: string) => { + const { custQuerySearchState } = store; return { custQuerySearchState: { @@ -774,7 +656,6 @@ const applyCustomQuery = ( viewMode: mode, }, ...getCleanStoreForRefetch(store), - ...updatedTimeRange, }; }; @@ -970,9 +851,6 @@ const toggleWordWrap = (store: LogsStore) => { }; const logsStoreReducers: LogsStoreReducers = { - setTimeRange, - setshiftInterval, - // resetTimeRange, deleteFilterItem, addFilterItem, setLiveTailStatus, diff --git a/src/pages/Stream/providers/StreamProvider.tsx b/src/pages/Stream/providers/StreamProvider.tsx index 4be24140..45bcf1e3 100644 --- a/src/pages/Stream/providers/StreamProvider.tsx +++ b/src/pages/Stream/providers/StreamProvider.tsx @@ -170,29 +170,6 @@ const setStreamSchema = (_store: StreamStore, schema: LogStreamSchemaData) => { }; const getCleanStoreForRefetch = (_store: StreamStore) => { - // const { tableOpts, data, timeRange } = store; - // const { interval, type } = timeRange; - - // const duration = _.find(FIXED_DURATIONS, (duration) => duration.name === timeRange.label); - // const updatedTimeRange = interval && type === 'fixed' ? { timeRange: getDefaultTimeRange(duration) } : {}; - // return { - // tableOpts: { - // ...tableOpts, - // pageData: [], - // totalCount: 0, - // displayedCount: 0, - // currentPage: 0, - // currentOffset: 0, - // headers: [], - // totalPages: 0, - // }, - // data: { - // ...data, - // filteredData: [], - // rawData: [], - // }, - // ...updatedTimeRange, - // }; return initialState; };