Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.
46 changes: 2 additions & 44 deletions src/hooks/useQueryLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ 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 { useCallback, useEffect, useRef } from 'react';
import { useCallback, useRef } from 'react';
import { useLogsStore, logsStoreReducers, LOAD_LIMIT, isJqSearch } from '@/pages/Stream/providers/LogsProvider';
import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider';
import { useQueryResult } from './useQueryResult';
import _ from 'lodash';
import { AxiosError } from 'axios';
import jqSearch from '@/utils/jqSearch';
import { useGetLogStreamSchema } from './useGetLogStreamSchema';

const { setLogData, setTotalCount } = logsStoreReducers;
const { setLogData } = logsStoreReducers;

type QueryLogs = {
streamName: string;
Expand All @@ -32,7 +31,6 @@ export const useQueryLogs = () => {
const _dataRef = useRef<Log[] | null>(null);
const [error, setError] = useMountedState<string | null>(null);
const [loading, setLoading] = useMountedState<boolean>(false);
const [isFetchingCount, setIsFetchingCount] = useMountedState<boolean>(false);
const [pageLogData, setPageLogData] = useMountedState<LogsData | null>(null);
const { getDataSchema } = useGetLogStreamSchema();
const [querySearch, setQuerySearch] = useMountedState<LogsSearch>({
Expand Down Expand Up @@ -111,44 +109,6 @@ export const useQueryLogs = () => {
}
};

// fetchQueryMutation is used only on fetching count
// refactor this hook if you want to use mutation anywhere else
const { fetchQueryMutation } = useQueryResult();

useEffect(() => {
const { fields = [], records = [] } = fetchQueryMutation.data || {};
const firstRecord = _.first(records);
if (_.includes(fields, 'count') && _.includes(_.keys(firstRecord), 'count')) {
const count = _.get(firstRecord, 'count', 0);
setLogsStore((store) => setTotalCount(store, _.toInteger(count)));
}
}, [fetchQueryMutation.data]);

const fetchCount = () => {
try {
setIsFetchingCount(true);
const defaultQuery = `select count(*) as count from ${currentStream}`;
const query = isQuerySearchActive
? custSearchQuery.replace(/SELECT[\s\S]*?FROM/i, 'SELECT COUNT(*) as count FROM')
: defaultQuery;
if (currentStream && query?.length > 0) {
const logsQuery = {
streamName: currentStream,
startTime: timeRange.startTime,
endTime: timeRange.endTime,
access: [],
};
fetchQueryMutation.mutate({
logsQuery,
query,
onSuccess: () => setIsFetchingCount(false),
});
}
} catch (e) {
console.log(e);
}
};

const resetData = () => {
_dataRef.current = null;
setPageLogData(null);
Expand All @@ -164,7 +124,5 @@ export const useQueryLogs = () => {
loading: loading,
getQueryData,
resetData,
fetchCount,
isFetchingCount,
};
};
46 changes: 44 additions & 2 deletions src/hooks/useQueryResult.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { getQueryResultWithHeaders } from '@/api/query';
import { getQueryResultWithHeaders, getQueryResult } from '@/api/query';
import { LogsQuery } from '@/@types/parseable/api/query';
import { notifications } from '@mantine/notifications';
import { isAxiosError, AxiosError } from 'axios';
import { IconCheck, IconFileAlert } from '@tabler/icons-react';
import { useMutation } from 'react-query';
import { useMutation, useQuery } from 'react-query';
import { logsStoreReducers, useLogsStore } from '@/pages/Stream/providers/LogsProvider';
import _ from 'lodash';
import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider';

type QueryData = {
logsQuery: LogsQuery;
Expand Down Expand Up @@ -48,3 +51,42 @@ export const useQueryResult = () => {

return { fetchQueryMutation };
};

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 { isQuerySearchActive, custSearchQuery } = custQuerySearchState;

const defaultQuery = `select count(*) as count from ${currentStream}`;
const query = isQuerySearchActive
? custSearchQuery.replace(/SELECT[\s\S]*?FROM/i, 'SELECT COUNT(*) as count FROM')
: defaultQuery;

const logsQuery = {
streamName: currentStream || '',
startTime: timeRange.startTime,
endTime: timeRange.endTime,
access: [],
};
const {
isLoading: isCountLoading,
isRefetching: isCountRefetching,
refetch: refetchCount,
} = useQuery(['fetchCount', logsQuery], () => getQueryResult(logsQuery, query), {
onSuccess: (resp) => {
const count = _.first(resp.data)?.count;
typeof count === 'number' && setLogsStore((store) => setTotalCount(store, count));
},
refetchOnWindowFocus: false,
retry: false,
enabled: currentStream !== null,
});

return {
isCountLoading,
isCountRefetching,
refetchCount,
};
};
8 changes: 5 additions & 3 deletions src/pages/Stream/Views/Explore/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,16 @@ const LimitControl: FC = () => {
);
};

const Footer = (props: { loaded: boolean; isLoading: boolean; hasNoData: boolean }) => {
const Footer = (props: { loaded: boolean; hasNoData: boolean; isFetchingCount: boolean }) => {
const [currentStream] = useAppStore((store) => store.currentStream);
const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts);
const [filteredData] = useLogsStore((store) => store.data.filteredData);
const { totalPages, currentOffset, currentPage, perPage, headers, totalCount } = tableOpts;

const onPageChange = useCallback((page: number) => {
setLogsStore((store) => setPageAndPageData(store, page));
}, []);
const [currentStream] = useAppStore((store) => store.currentStream);

const pagination = usePagination({ total: totalPages ?? 1, initialPage: 1, onChange: onPageChange });
const onChangeOffset = useCallback(
(key: 'prev' | 'next') => {
Expand Down Expand Up @@ -137,7 +139,7 @@ const Footer = (props: { loaded: boolean; isLoading: boolean; hasNoData: boolean
<Stack w="100%" justify="center" align="flex-start">
<TotalLogsCount
hasTableLoaded={props.loaded}
isFetchingCount={props.isLoading}
isFetchingCount={props.isFetchingCount}
isTableEmpty={props.hasNoData}
/>
</Stack>
Expand Down
6 changes: 3 additions & 3 deletions src/pages/Stream/Views/Explore/JSONView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,14 @@ const TableContainer = (props: { children: ReactNode }) => {
};

const JsonView = (props: {
isFetchingCount: boolean;
errorMessage: string | null;
hasNoData: boolean;
showTable: boolean;
isFetchingCount: boolean;
}) => {
const [maximized] = useAppStore((store) => store.maximized);

const { isFetchingCount, errorMessage, hasNoData, showTable } = props;
const { errorMessage, hasNoData, showTable, isFetchingCount } = props;
const [isSearching, setSearching] = useState(false);
const primaryHeaderHeight = !maximized
? PRIMARY_HEADER_HEIGHT + STREAM_PRIMARY_TOOLBAR_CONTAINER_HEIGHT + STREAM_SECONDARY_TOOLBAR_HRIGHT
Expand Down Expand Up @@ -214,7 +214,7 @@ const JsonView = (props: {
) : (
<ErrorView message={errorMessage} />
)}
<Footer loaded={showTable} isLoading={isFetchingCount} hasNoData={hasNoData} />
<Footer loaded={showTable} hasNoData={hasNoData} isFetchingCount={isFetchingCount} />
</TableContainer>
);
};
Expand Down
7 changes: 4 additions & 3 deletions src/pages/Stream/Views/Explore/LogsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import useLogsFetcher from './useLogsFetcher';

const LogsView = (props: { schemaLoading: boolean }) => {
const { schemaLoading } = props;
const { errorMessage, isFetchingCount, hasNoData, showTable } = useLogsFetcher({ schemaLoading });
const { errorMessage, hasNoData, showTable, isFetchingCount } = useLogsFetcher({
schemaLoading,
});
const [viewMode] = useLogsStore((store) => store.viewMode);

const viewOpts = {
isFetchingCount,
errorMessage,
hasNoData,
showTable,
isFetchingCount,
};
return viewMode === 'table' ? <LogTable {...viewOpts} /> : <JsonView {...viewOpts} />;
};
Expand Down
6 changes: 3 additions & 3 deletions src/pages/Stream/Views/Explore/StaticLogTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ interface SectionRefs {
}

const LogTable = (props: {
isFetchingCount: boolean;
errorMessage: string | null;
hasNoData: boolean;
showTable: boolean;
isFetchingCount: boolean;
}) => {
const { isFetchingCount, errorMessage, hasNoData, showTable } = props;
const { errorMessage, hasNoData, showTable, isFetchingCount } = props;
const [containerRefs, _setContainerRefs] = useState<SectionRefs>({
activeSectionRef: useRef<'left' | 'right'>('left'),
leftSectionRef: useRef<HTMLDivElement>(null),
Expand Down Expand Up @@ -180,7 +180,7 @@ const LogTable = (props: {
) : (
<ErrorView message={errorMessage} />
)}
<Footer loaded={showTable} isLoading={isFetchingCount} hasNoData={hasNoData} />
<Footer loaded={showTable} hasNoData={hasNoData} isFetchingCount={isFetchingCount} />
</TableContainer>
);
};
Expand Down
19 changes: 14 additions & 5 deletions src/pages/Stream/Views/Explore/useLogsFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider';
import { useEffect } from 'react';
import { useLogsStore, logsStoreReducers } from '../../providers/LogsProvider';
import { useQueryLogs } from '@/hooks/useQueryLogs';
import { useFetchCount } from '@/hooks/useQueryResult';

const { setCleanStoreForStreamChange } = logsStoreReducers;

const useLogsFetcher = (props: { schemaLoading: boolean }) => {
const { schemaLoading } = props;
const [currentStream] = useAppStore((store) => store.currentStream);
const [tableOpts, setLogsStore] = useLogsStore((store) => store.tableOpts);
const [{ tableOpts, timeRange }, setLogsStore] = useLogsStore((store) => store);
const { currentOffset, currentPage, pageData } = tableOpts;
const { getQueryData, loading: logsLoading, error: errorMessage, fetchCount, isFetchingCount } = useQueryLogs();
const { getQueryData, loading: logsLoading, error: errorMessage } = useQueryLogs();
const { refetchCount, isCountLoading, isCountRefetching } = useFetchCount();
const hasContentLoaded = schemaLoading === false && logsLoading === false;
const hasNoData = hasContentLoaded && !errorMessage && pageData.length === 0;
const showTable = hasContentLoaded && !hasNoData && !errorMessage;
Expand All @@ -22,17 +24,24 @@ const useLogsFetcher = (props: { schemaLoading: boolean }) => {
useEffect(() => {
if (currentPage === 0 && currentOffset === 0) {
getQueryData();
fetchCount();
refetchCount();
}
}, [currentPage]);
}, [currentPage, currentStream, timeRange]);

useEffect(() => {
if (currentOffset !== 0 && currentPage !== 0) {
getQueryData();
}
}, [currentOffset]);

return { logsLoading, errorMessage, isFetchingCount, hasContentLoaded, hasNoData, showTable };
return {
logsLoading,
errorMessage,
hasContentLoaded,
hasNoData,
showTable,
isFetchingCount: isCountLoading || isCountRefetching,
};
};

export default useLogsFetcher;