diff --git a/src/hooks/useHotTier.ts b/src/hooks/useHotTier.ts index ecd928e1..a38e6204 100644 --- a/src/hooks/useHotTier.ts +++ b/src/hooks/useHotTier.ts @@ -63,6 +63,7 @@ export const useHotTier = (streamName: string, hasSettingsAccess: boolean) => { return { getHotTierInfoError, getHotTierInfoLoading, + refetchHotTierInfo, updateHotTier, deleteHotTier, isDeleting, diff --git a/src/pages/Stream/Views/Explore/JSONView.tsx b/src/pages/Stream/Views/Explore/JSONView.tsx index 2ce15d6c..461df67a 100644 --- a/src/pages/Stream/Views/Explore/JSONView.tsx +++ b/src/pages/Stream/Views/Explore/JSONView.tsx @@ -374,7 +374,7 @@ const JsonView = (props: { - + diff --git a/src/pages/Stream/Views/Explore/useLogsFetcher.ts b/src/pages/Stream/Views/Explore/useLogsFetcher.ts index 58433b6a..30fa0995 100644 --- a/src/pages/Stream/Views/Explore/useLogsFetcher.ts +++ b/src/pages/Stream/Views/Explore/useLogsFetcher.ts @@ -3,7 +3,6 @@ import { useEffect } from 'react'; import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider'; import { useQueryLogs } from '@/hooks/useQueryLogs'; import { useFetchCount } from '@/hooks/useQueryResult'; -import { useStreamStore } from '../../providers/StreamProvider'; import useParamsController from '@/pages/Stream/hooks/useParamsController'; import _ from 'lodash'; @@ -18,8 +17,6 @@ const useLogsFetcher = (props: { schemaLoading: boolean; infoLoading: boolean }) const [{ tableOpts }, setLogsStore] = useLogsStore((store) => store); const { currentOffset, currentPage, pageData } = tableOpts; const { getQueryData, loading: logsLoading, queryLogsError } = useQueryLogs(); - const [{ info }] = useStreamStore((store) => store); - const firstEventAt = 'first-event-at' in info ? info['first-event-at'] : undefined; const { refetchCount, countLoading } = useFetchCount(); const hasContentLoaded = schemaLoading === false && logsLoading === false; @@ -33,21 +30,21 @@ const useLogsFetcher = (props: { schemaLoading: boolean; infoLoading: boolean }) }, [currentStream]); useEffect(() => { - if (infoLoading || !firstEventAt) return; + if (infoLoading) return; if (currentPage === 0) { getQueryData(); refetchCount(); } - }, [currentPage, currentStream, timeRange, infoLoading, firstEventAt]); + }, [currentPage, currentStream, timeRange, infoLoading]); useEffect(() => { - if (infoLoading || !firstEventAt) return; + if (infoLoading) return; if (currentOffset !== 0 && currentPage !== 0) { getQueryData(); } - }, [currentOffset, infoLoading, firstEventAt]); + }, [currentOffset, infoLoading]); return { logsLoading: infoLoading || logsLoading, diff --git a/src/pages/Stream/Views/Manage/Info.tsx b/src/pages/Stream/Views/Manage/Info.tsx index d04aaf5a..64d20f08 100644 --- a/src/pages/Stream/Views/Manage/Info.tsx +++ b/src/pages/Stream/Views/Manage/Info.tsx @@ -1,4 +1,4 @@ -import { Group, Stack, Text } from '@mantine/core'; +import { Group, Loader, Stack, Text } from '@mantine/core'; import classes from '../../styles/Management.module.css'; import { useStreamStore } from '../../providers/StreamProvider'; import _ from 'lodash'; @@ -6,6 +6,7 @@ import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import UpdateTimePartitionLimit from './UpdateTimePartitionLimit'; import UpdateCustomPartitionField from './UpdateCustomPartitionField'; import timeRangeUtils from '@/utils/timeRangeUtils'; +import ErrorView from './ErrorView'; const { formatDateWithTimezone } = timeRangeUtils; @@ -42,7 +43,7 @@ const InfoItem = (props: { title: string; value: string; fullWidth?: boolean }) ); }; -const InfoData = () => { +const InfoData = (props: { isLoading: boolean }) => { const [info] = useStreamStore((store) => store.info); const [currentStream] = useAppStore((store) => store.currentStream); @@ -59,33 +60,44 @@ const InfoData = () => { return ( - - - - - + {props.isLoading ? ( + + + + - - - - + ) : ( + + + + + + + + + + + + + + - - - - + )} ); }; -const Info = () => { +const Info = (props: { isLoading: boolean; isError: boolean }) => { return (
- + {props.isError ? : } ); }; diff --git a/src/pages/Stream/Views/Manage/Management.tsx b/src/pages/Stream/Views/Manage/Management.tsx index 7ac8991b..42b7d871 100644 --- a/src/pages/Stream/Views/Manage/Management.tsx +++ b/src/pages/Stream/Views/Manage/Management.tsx @@ -7,6 +7,7 @@ import Stats from './Stats'; import { useLogStreamStats } from '@/hooks/useLogStreamStats'; import Info from './Info'; import DeleteStreamModal from '../../components/DeleteStreamModal'; +import { useGetStreamInfo } from '@/hooks/useGetStreamInfo'; import { useRetentionQuery } from '@/hooks/useRetentionEditor'; import { useHotTier } from '@/hooks/useHotTier'; @@ -19,6 +20,7 @@ const Management = (props: { schemaLoading: boolean }) => { const getStreamAlertsConfig = useAlertsQuery(currentStream || '', hasAlertsAccess, isStandAloneMode); const getStreamStats = useLogStreamStats(currentStream || ''); const getRetentionConfig = useRetentionQuery(currentStream || '', hasSettingsAccess); + const getStreamInfo = useGetStreamInfo(currentStream || '', currentStream !== null); const hotTierFetch = useHotTier(currentStream || '', hasSettingsAccess); // todo - handle loading and error states separately @@ -34,7 +36,7 @@ const Management = (props: { schemaLoading: boolean }) => { isLoading={getStreamStats.getLogStreamStatsDataIsLoading} isError={getStreamStats.getLogStreamStatsDataIsError} /> - + @@ -42,6 +44,7 @@ const Management = (props: { schemaLoading: boolean }) => { isLoading={isHotTierLoading || isRetentionLoading} updateRetentionConfig={getRetentionConfig.updateLogStreamRetention} updateHotTierInfo={hotTierFetch.updateHotTier} + refetchHotTierInfo={hotTierFetch.refetchHotTierInfo} deleteHotTierInfo={hotTierFetch.deleteHotTier} isDeleting={hotTierFetch.isDeleting} isUpdating={hotTierFetch.isUpdating} diff --git a/src/pages/Stream/Views/Manage/Settings.tsx b/src/pages/Stream/Views/Manage/Settings.tsx index d291851e..f53ba9d0 100644 --- a/src/pages/Stream/Views/Manage/Settings.tsx +++ b/src/pages/Stream/Views/Manage/Settings.tsx @@ -1,4 +1,4 @@ -import { Box, Button, Divider, Loader, Modal, NumberInput, Stack, TextInput } from '@mantine/core'; +import { Box, Button, Divider, Group, Loader, Modal, NumberInput, px, Stack, TextInput } from '@mantine/core'; import classes from '../../styles/Management.module.css'; import { Text } from '@mantine/core'; import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; @@ -6,14 +6,17 @@ import { useForm } from '@mantine/form'; import _ from 'lodash'; import { useCallback, useEffect, useState } from 'react'; import { useStreamStore } from '../../providers/StreamProvider'; -import { IconCheck, IconTrash, IconX } from '@tabler/icons-react'; +import { IconCheck, IconX, IconReload } from '@tabler/icons-react'; import { sanitizeBytes, convertGibToBytes } from '@/utils/formatBytes'; import timeRangeUtils from '@/utils/timeRangeUtils'; import ErrorView from './ErrorView'; import RestrictedView from '@/components/Misc/RestrictedView'; +import IconButton from '@/components/Button/IconButton'; const { formatDateWithTimezone } = timeRangeUtils; +const renderRefreshIcon = () => ; + const Header = () => { return ( @@ -168,6 +171,7 @@ const DeleteHotTierModal = (props: { const HotTierConfig = (props: { updateHotTierInfo: ({ size }: { size: string }) => void; + refetchHotTierInfo: () => void; deleteHotTierInfo: ({ onSuccess }: { onSuccess: () => void }) => void; isDeleting: boolean; isUpdating: boolean; @@ -228,21 +232,23 @@ const HotTierConfig = (props: { /> Hot Tier Storage Size - {!hotTierNotSet && streamType === 'UserDefined' ? ( - + {!hotTierNotSet ? ( + + + ) : null} - - - Oldest Record: - - {_.isEmpty(oldestEntry) ? 'No Entries Stored' : formatDateWithTimezone(oldestEntry)} - - + - + {streamType === 'UserDefined' ? ( {humanizedUsedSize} used | {humanizedAvailableSize} available @@ -265,7 +271,7 @@ const HotTierConfig = (props: { @@ -289,6 +295,18 @@ const HotTierConfig = (props: { {props.isUpdating && } + + {!hotTierNotSet && streamType === 'UserDefined' ? ( + + + + + + ) : null} +