2024-02-12 00:23:19 +05:30
|
|
|
/* eslint-disable sonarjs/cognitive-complexity */
|
|
|
|
|
import './LogsExplorerViews.styles.scss';
|
|
|
|
|
|
2025-08-28 19:03:29 +05:30
|
|
|
import getFromLocalstorage from 'api/browser/localstorage/get';
|
|
|
|
|
import setToLocalstorage from 'api/browser/localstorage/set';
|
2024-08-16 15:07:06 +05:30
|
|
|
import { getQueryStats, WsDataEvent } from 'api/common/getQueryStats';
|
2024-07-16 14:18:59 +05:30
|
|
|
import logEvent from 'api/common/logEvent';
|
2025-07-31 12:16:55 +05:30
|
|
|
import { ENTITY_VERSION_V5 } from 'constants/app';
|
2025-01-27 16:28:54 +04:30
|
|
|
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
2024-02-12 00:23:19 +05:30
|
|
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
2023-08-23 19:44:33 +03:00
|
|
|
import { AVAILABLE_EXPORT_PANEL_TYPES } from 'constants/panelTypes';
|
2023-09-12 11:57:33 +05:30
|
|
|
import { QueryParams } from 'constants/query';
|
2023-07-12 16:59:33 +03:00
|
|
|
import {
|
2023-08-10 12:06:24 +03:00
|
|
|
initialFilters,
|
2023-07-12 16:59:33 +03:00
|
|
|
initialQueriesMap,
|
2023-08-10 12:06:24 +03:00
|
|
|
initialQueryBuilderFormValues,
|
2025-02-13 16:38:02 +05:30
|
|
|
OPERATORS,
|
2023-07-12 16:59:33 +03:00
|
|
|
PANEL_TYPES,
|
|
|
|
|
} from 'constants/queryBuilder';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
|
2024-03-26 17:09:13 +05:30
|
|
|
import ExplorerOptionWrapper from 'container/ExplorerOptions/ExplorerOptionWrapper';
|
2023-07-17 13:42:05 +05:30
|
|
|
import GoToTop from 'container/GoToTop';
|
2025-09-02 11:05:52 +05:30
|
|
|
import {} from 'container/LiveLogs/constants';
|
2023-07-06 14:22:44 +03:00
|
|
|
import LogsExplorerChart from 'container/LogsExplorerChart';
|
2023-06-23 11:19:53 +03:00
|
|
|
import LogsExplorerList from 'container/LogsExplorerList';
|
2023-07-14 12:31:25 +05:30
|
|
|
import LogsExplorerTable from 'container/LogsExplorerTable';
|
2023-06-29 14:22:55 +05:30
|
|
|
import TimeSeriesView from 'container/TimeSeriesView/TimeSeriesView';
|
2024-03-22 13:28:38 +05:30
|
|
|
import dayjs from 'dayjs';
|
2023-07-30 14:02:18 +03:00
|
|
|
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
|
2024-02-12 00:23:19 +05:30
|
|
|
import { useGetPanelTypesQueryParam } from 'hooks/queryBuilder/useGetPanelTypesQueryParam';
|
2023-06-23 11:19:53 +03:00
|
|
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
2023-08-30 20:24:16 +05:30
|
|
|
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
2025-02-14 08:24:49 +04:30
|
|
|
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
2023-07-06 14:22:44 +03:00
|
|
|
import useUrlQueryData from 'hooks/useUrlQueryData';
|
2024-03-22 13:28:38 +05:30
|
|
|
import { FlatLogData } from 'lib/logs/flatLogData';
|
2025-05-22 14:12:51 +04:30
|
|
|
import { getPaginationQueryDataV2 } from 'lib/newQueryBuilder/getPaginationQueryData';
|
2024-07-16 14:18:59 +05:30
|
|
|
import {
|
|
|
|
|
cloneDeep,
|
|
|
|
|
defaultTo,
|
|
|
|
|
isEmpty,
|
|
|
|
|
isUndefined,
|
|
|
|
|
omit,
|
|
|
|
|
set,
|
|
|
|
|
} from 'lodash-es';
|
2025-09-02 11:05:52 +05:30
|
|
|
import LiveLogs from 'pages/LiveLogs';
|
2025-07-31 12:16:55 +05:30
|
|
|
import { ExplorerViews } from 'pages/LogsExplorer/utils';
|
2024-12-16 10:27:20 +04:30
|
|
|
import { useTimezone } from 'providers/Timezone';
|
2024-08-16 13:11:39 +05:30
|
|
|
import {
|
2025-08-05 23:45:39 +05:30
|
|
|
Dispatch,
|
2024-08-16 13:11:39 +05:30
|
|
|
memo,
|
|
|
|
|
MutableRefObject,
|
2025-08-05 23:45:39 +05:30
|
|
|
SetStateAction,
|
2024-08-16 13:11:39 +05:30
|
|
|
useCallback,
|
|
|
|
|
useEffect,
|
|
|
|
|
useMemo,
|
|
|
|
|
useRef,
|
|
|
|
|
useState,
|
|
|
|
|
} from 'react';
|
2025-06-23 13:36:46 +04:30
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
|
import { UpdateTimeInterval } from 'store/actions';
|
2023-07-08 07:27:34 +03:00
|
|
|
import { AppState } from 'store/reducers';
|
2025-08-05 23:45:39 +05:30
|
|
|
import { Warning } from 'types/api';
|
2023-07-07 20:59:35 +05:30
|
|
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
2025-08-05 23:45:39 +05:30
|
|
|
import APIError from 'types/api/error';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { ILog } from 'types/api/logs/log';
|
2024-09-13 13:47:08 +05:30
|
|
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
2023-07-06 14:22:44 +03:00
|
|
|
import {
|
|
|
|
|
IBuilderQuery,
|
|
|
|
|
Query,
|
2023-08-10 12:06:24 +03:00
|
|
|
TagFilter,
|
2023-07-06 14:22:44 +03:00
|
|
|
} from 'types/api/queryBuilder/queryBuilderData';
|
2025-07-31 12:16:55 +05:30
|
|
|
import { QueryDataV3 } from 'types/api/widgets/getQuery';
|
2025-09-02 11:05:52 +05:30
|
|
|
import { DataSource, LogsAggregatorOperator } from 'types/common/queryBuilder';
|
2023-07-08 07:27:34 +03:00
|
|
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
2023-08-23 19:44:33 +03:00
|
|
|
import { generateExportToDashboardLink } from 'utils/dashboard/generateExportToDashboardLink';
|
2023-11-21 00:52:53 +05:30
|
|
|
import { v4 } from 'uuid';
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2025-09-02 11:05:52 +05:30
|
|
|
import LogsActionsContainer from './LogsActionsContainer';
|
2024-08-16 15:07:06 +05:30
|
|
|
|
2025-07-31 12:16:55 +05:30
|
|
|
function LogsExplorerViewsContainer({
|
2024-02-12 00:23:19 +05:30
|
|
|
selectedView,
|
2024-08-16 13:11:39 +05:30
|
|
|
setIsLoadingQueries,
|
|
|
|
|
listQueryKeyRef,
|
|
|
|
|
chartQueryKeyRef,
|
2025-08-05 23:45:39 +05:30
|
|
|
setWarning,
|
2025-09-02 11:05:52 +05:30
|
|
|
showLiveLogs,
|
2024-02-12 00:23:19 +05:30
|
|
|
}: {
|
2025-07-31 12:16:55 +05:30
|
|
|
selectedView: ExplorerViews;
|
2024-08-16 13:11:39 +05:30
|
|
|
setIsLoadingQueries: React.Dispatch<React.SetStateAction<boolean>>;
|
2025-05-22 14:12:51 +04:30
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-08-16 13:11:39 +05:30
|
|
|
listQueryKeyRef: MutableRefObject<any>;
|
2025-05-22 14:12:51 +04:30
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-08-16 13:11:39 +05:30
|
|
|
chartQueryKeyRef: MutableRefObject<any>;
|
2025-08-05 23:45:39 +05:30
|
|
|
setWarning: Dispatch<SetStateAction<Warning | undefined>>;
|
2025-09-02 11:05:52 +05:30
|
|
|
showLiveLogs: boolean;
|
2024-02-12 00:23:19 +05:30
|
|
|
}): JSX.Element {
|
2025-02-14 08:24:49 +04:30
|
|
|
const { safeNavigate } = useSafeNavigate();
|
2025-06-23 13:36:46 +04:30
|
|
|
const dispatch = useDispatch();
|
2025-08-28 19:03:29 +05:30
|
|
|
|
|
|
|
|
const [showFrequencyChart, setShowFrequencyChart] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const frequencyChart = getFromLocalstorage(LOCALSTORAGE.SHOW_FREQUENCY_CHART);
|
|
|
|
|
setShowFrequencyChart(frequencyChart === 'true');
|
|
|
|
|
}, []);
|
2023-07-07 20:59:35 +05:30
|
|
|
|
2024-02-12 00:23:19 +05:30
|
|
|
// this is to respect the panel type present in the URL rather than defaulting it to list always.
|
|
|
|
|
const panelTypes = useGetPanelTypesQueryParam(PANEL_TYPES.LIST);
|
|
|
|
|
|
2025-03-06 10:45:11 +04:30
|
|
|
const { activeLogId } = useCopyLogLink();
|
2024-02-12 00:23:19 +05:30
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const { queryData: pageSize } = useUrlQueryData(
|
2023-09-12 11:57:33 +05:30
|
|
|
QueryParams.pageSize,
|
2023-07-06 14:22:44 +03:00
|
|
|
DEFAULT_PER_PAGE_VALUE,
|
|
|
|
|
);
|
|
|
|
|
|
2025-06-23 13:36:46 +04:30
|
|
|
const { minTime, maxTime, selectedTime } = useSelector<
|
|
|
|
|
AppState,
|
|
|
|
|
GlobalReducer
|
|
|
|
|
>((state) => state.globalTime);
|
2023-07-08 07:27:34 +03:00
|
|
|
|
|
|
|
|
const currentMinTimeRef = useRef<number>(minTime);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
// Context
|
2023-06-23 11:19:53 +03:00
|
|
|
const {
|
|
|
|
|
currentQuery,
|
|
|
|
|
stagedQuery,
|
|
|
|
|
panelType,
|
|
|
|
|
updateAllQueriesOperators,
|
2024-02-12 00:23:19 +05:30
|
|
|
handleSetConfig,
|
2023-06-23 11:19:53 +03:00
|
|
|
} = useQueryBuilder();
|
|
|
|
|
|
2024-02-12 00:23:19 +05:30
|
|
|
const [selectedPanelType, setSelectedPanelType] = useState<PANEL_TYPES>(
|
|
|
|
|
panelType || PANEL_TYPES.LIST,
|
|
|
|
|
);
|
|
|
|
|
|
2023-08-30 20:24:16 +05:30
|
|
|
const { handleExplorerTabChange } = useHandleExplorerTabChange();
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
// State
|
|
|
|
|
const [page, setPage] = useState<number>(1);
|
|
|
|
|
const [logs, setLogs] = useState<ILog[]>([]);
|
|
|
|
|
const [requestData, setRequestData] = useState<Query | null>(null);
|
2024-08-16 15:07:06 +05:30
|
|
|
const [queryId, setQueryId] = useState<string>(v4());
|
|
|
|
|
const [queryStats, setQueryStats] = useState<WsDataEvent>();
|
2025-06-23 13:36:46 +04:30
|
|
|
const [listChartQuery, setListChartQuery] = useState<Query | null>(null);
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2025-07-31 12:16:55 +05:30
|
|
|
const [orderBy, setOrderBy] = useState<string>('timestamp:desc');
|
|
|
|
|
|
2023-08-10 12:06:24 +03:00
|
|
|
const listQuery = useMemo(() => {
|
|
|
|
|
if (!stagedQuery || stagedQuery.builder.queryData.length < 1) return null;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2023-08-10 12:06:24 +03:00
|
|
|
return stagedQuery.builder.queryData.find((item) => !item.disabled) || null;
|
2023-07-06 14:22:44 +03:00
|
|
|
}, [stagedQuery]);
|
|
|
|
|
|
2023-06-23 11:19:53 +03:00
|
|
|
const isMultipleQueries = useMemo(
|
|
|
|
|
() =>
|
2025-07-03 11:03:11 +05:30
|
|
|
currentQuery?.builder?.queryData?.length > 1 ||
|
|
|
|
|
currentQuery?.builder?.queryFormulas?.length > 0,
|
2023-06-23 11:19:53 +03:00
|
|
|
[currentQuery],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const isGroupByExist = useMemo(() => {
|
2025-07-03 11:03:11 +05:30
|
|
|
const groupByCount: number = currentQuery?.builder?.queryData?.reduce<number>(
|
2023-06-23 11:19:53 +03:00
|
|
|
(acc, query) => acc + query.groupBy.length,
|
|
|
|
|
0,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return groupByCount > 0;
|
|
|
|
|
}, [currentQuery]);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const isLimit: boolean = useMemo(() => {
|
2023-08-10 12:06:24 +03:00
|
|
|
if (!listQuery) return false;
|
|
|
|
|
if (!listQuery.limit) return false;
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2023-08-10 12:06:24 +03:00
|
|
|
return logs.length >= listQuery.limit;
|
|
|
|
|
}, [logs.length, listQuery]);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-06-23 13:36:46 +04:30
|
|
|
useEffect(() => {
|
|
|
|
|
if (!stagedQuery || !listQuery) {
|
|
|
|
|
setListChartQuery(null);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-07-06 14:22:44 +03:00
|
|
|
|
|
|
|
|
const modifiedQueryData: IBuilderQuery = {
|
2023-08-10 12:06:24 +03:00
|
|
|
...listQuery,
|
2023-08-29 15:23:22 +03:00
|
|
|
aggregateOperator: LogsAggregatorOperator.COUNT,
|
2024-09-13 13:47:08 +05:30
|
|
|
groupBy: [
|
|
|
|
|
{
|
|
|
|
|
key: 'severity_text',
|
|
|
|
|
dataType: DataTypes.String,
|
|
|
|
|
type: '',
|
|
|
|
|
id: 'severity_text--string----true',
|
|
|
|
|
},
|
|
|
|
|
],
|
2024-11-12 11:24:22 +05:30
|
|
|
legend: '{{severity_text}}',
|
2025-06-03 15:27:39 +05:30
|
|
|
...(activeLogId && {
|
|
|
|
|
filters: {
|
|
|
|
|
...listQuery?.filters,
|
|
|
|
|
items: [
|
|
|
|
|
...(listQuery?.filters?.items || []),
|
|
|
|
|
{
|
|
|
|
|
id: v4(),
|
|
|
|
|
key: {
|
|
|
|
|
key: 'id',
|
|
|
|
|
type: '',
|
|
|
|
|
dataType: DataTypes.String,
|
|
|
|
|
},
|
|
|
|
|
op: OPERATORS['<='],
|
|
|
|
|
value: activeLogId,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
op: 'AND',
|
|
|
|
|
},
|
|
|
|
|
}),
|
2023-07-06 14:22:44 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const modifiedQuery: Query = {
|
|
|
|
|
...stagedQuery,
|
|
|
|
|
builder: {
|
|
|
|
|
...stagedQuery.builder,
|
|
|
|
|
queryData: stagedQuery.builder.queryData.map((item) => ({
|
|
|
|
|
...item,
|
|
|
|
|
...modifiedQueryData,
|
|
|
|
|
})),
|
2023-06-23 11:19:53 +03:00
|
|
|
},
|
2023-07-06 14:22:44 +03:00
|
|
|
};
|
|
|
|
|
|
2025-06-23 13:36:46 +04:30
|
|
|
setListChartQuery(modifiedQuery);
|
2025-06-03 15:27:39 +05:30
|
|
|
}, [stagedQuery, listQuery, activeLogId]);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2023-07-07 20:59:35 +05:30
|
|
|
const exportDefaultQuery = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
updateAllQueriesOperators(
|
|
|
|
|
currentQuery || initialQueriesMap.logs,
|
2024-06-20 17:05:18 +05:30
|
|
|
selectedPanelType,
|
2023-07-07 20:59:35 +05:30
|
|
|
DataSource.LOGS,
|
|
|
|
|
),
|
2024-06-20 17:05:18 +05:30
|
|
|
[currentQuery, selectedPanelType, updateAllQueriesOperators],
|
2023-07-07 20:59:35 +05:30
|
|
|
);
|
|
|
|
|
|
2023-12-20 18:18:27 +05:30
|
|
|
const {
|
|
|
|
|
data: listChartData,
|
|
|
|
|
isFetching: isFetchingListChartData,
|
|
|
|
|
isLoading: isLoadingListChartData,
|
2024-03-01 14:51:50 +05:30
|
|
|
} = useGetExplorerQueryRange(
|
|
|
|
|
listChartQuery,
|
|
|
|
|
PANEL_TYPES.TIME_SERIES,
|
2025-07-31 12:16:55 +05:30
|
|
|
ENTITY_VERSION_V5,
|
2024-03-01 14:51:50 +05:30
|
|
|
{
|
2025-07-31 12:16:55 +05:30
|
|
|
enabled:
|
|
|
|
|
showFrequencyChart && !!listChartQuery && panelType === PANEL_TYPES.LIST,
|
2024-03-01 14:51:50 +05:30
|
|
|
},
|
2024-08-16 13:11:39 +05:30
|
|
|
{},
|
|
|
|
|
undefined,
|
|
|
|
|
chartQueryKeyRef,
|
2025-06-23 13:36:46 +04:30
|
|
|
undefined,
|
|
|
|
|
'custom',
|
2024-03-01 14:51:50 +05:30
|
|
|
);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2024-08-16 15:07:06 +05:30
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isLoading,
|
|
|
|
|
isFetching,
|
|
|
|
|
isError,
|
|
|
|
|
isSuccess,
|
2025-08-05 23:45:39 +05:30
|
|
|
error,
|
2024-08-16 15:07:06 +05:30
|
|
|
} = useGetExplorerQueryRange(
|
2023-07-06 14:22:44 +03:00
|
|
|
requestData,
|
|
|
|
|
panelType,
|
2025-07-31 12:16:55 +05:30
|
|
|
ENTITY_VERSION_V5,
|
2023-07-06 14:22:44 +03:00
|
|
|
{
|
|
|
|
|
keepPreviousData: true,
|
2023-08-04 10:31:54 +03:00
|
|
|
enabled: !isLimit && !!requestData,
|
2023-07-06 14:22:44 +03:00
|
|
|
},
|
2023-07-30 14:02:18 +03:00
|
|
|
{
|
2024-08-26 19:26:34 +05:30
|
|
|
...(activeLogId &&
|
2023-07-30 14:02:18 +03:00
|
|
|
!logs.length && {
|
2024-08-26 19:26:34 +05:30
|
|
|
start: minTime,
|
|
|
|
|
end: maxTime,
|
2023-07-30 14:02:18 +03:00
|
|
|
}),
|
|
|
|
|
},
|
2024-08-16 13:11:39 +05:30
|
|
|
undefined,
|
|
|
|
|
listQueryKeyRef,
|
2024-08-23 17:37:56 +05:30
|
|
|
{
|
|
|
|
|
...(!isEmpty(queryId) &&
|
|
|
|
|
selectedPanelType !== PANEL_TYPES.LIST && { 'X-SIGNOZ-QUERY-ID': queryId }),
|
|
|
|
|
},
|
2025-05-22 14:12:51 +04:30
|
|
|
// custom selected time interval to prevent recalculating the start and end timestamps before fetching next pages
|
|
|
|
|
'custom',
|
2023-06-23 11:19:53 +03:00
|
|
|
);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const getRequestData = useCallback(
|
|
|
|
|
(
|
|
|
|
|
query: Query | null,
|
2023-08-10 12:06:24 +03:00
|
|
|
params: {
|
|
|
|
|
page: number;
|
|
|
|
|
pageSize: number;
|
|
|
|
|
filters: TagFilter;
|
|
|
|
|
},
|
2023-07-06 14:22:44 +03:00
|
|
|
): Query | null => {
|
|
|
|
|
if (!query) return null;
|
|
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
const paginateData = getPaginationQueryDataV2({
|
2023-07-06 14:22:44 +03:00
|
|
|
page: params.page,
|
|
|
|
|
pageSize: params.pageSize,
|
|
|
|
|
});
|
|
|
|
|
|
2025-02-13 16:38:02 +05:30
|
|
|
// Add filter for activeLogId if present
|
2025-06-03 15:27:39 +05:30
|
|
|
let updatedFilters = params.filters;
|
2025-02-13 16:38:02 +05:30
|
|
|
if (activeLogId) {
|
|
|
|
|
updatedFilters = {
|
2025-06-03 15:27:39 +05:30
|
|
|
...params.filters,
|
2025-02-13 16:38:02 +05:30
|
|
|
items: [
|
2025-06-03 15:27:39 +05:30
|
|
|
...(params.filters?.items || []),
|
2025-02-13 16:38:02 +05:30
|
|
|
{
|
|
|
|
|
id: v4(),
|
|
|
|
|
key: {
|
|
|
|
|
key: 'id',
|
|
|
|
|
type: '',
|
|
|
|
|
dataType: DataTypes.String,
|
|
|
|
|
},
|
|
|
|
|
op: OPERATORS['<='],
|
|
|
|
|
value: activeLogId,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
op: 'AND',
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-31 12:16:55 +05:30
|
|
|
// Create orderBy array based on orderDirection
|
|
|
|
|
const [columnName, order] = orderBy.split(':');
|
|
|
|
|
|
|
|
|
|
const newOrderBy = [
|
|
|
|
|
{ columnName: columnName || 'timestamp', order: order || 'desc' },
|
|
|
|
|
{ columnName: 'id', order: order || 'desc' },
|
|
|
|
|
];
|
|
|
|
|
|
2023-08-10 12:06:24 +03:00
|
|
|
const queryData: IBuilderQuery[] =
|
|
|
|
|
query.builder.queryData.length > 1
|
2025-07-31 12:16:55 +05:30
|
|
|
? query.builder.queryData.map((item) => ({
|
|
|
|
|
...item,
|
|
|
|
|
...(selectedView !== ExplorerViews.LIST ? { order: [] } : {}),
|
|
|
|
|
}))
|
2023-08-10 12:06:24 +03:00
|
|
|
: [
|
|
|
|
|
{
|
|
|
|
|
...(listQuery || initialQueryBuilderFormValues),
|
|
|
|
|
...paginateData,
|
2025-02-13 16:38:02 +05:30
|
|
|
...(updatedFilters ? { filters: updatedFilters } : {}),
|
2025-07-31 12:16:55 +05:30
|
|
|
...(selectedView === ExplorerViews.LIST
|
|
|
|
|
? { order: newOrderBy, orderBy: newOrderBy }
|
|
|
|
|
: { order: [] }),
|
2023-08-10 12:06:24 +03:00
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const data: Query = {
|
|
|
|
|
...query,
|
|
|
|
|
builder: {
|
|
|
|
|
...query.builder,
|
2023-08-10 12:06:24 +03:00
|
|
|
queryData,
|
2023-07-06 14:22:44 +03:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
},
|
2025-07-31 12:16:55 +05:30
|
|
|
[activeLogId, orderBy, listQuery, selectedView],
|
2023-07-06 14:22:44 +03:00
|
|
|
);
|
|
|
|
|
|
2025-08-05 23:45:39 +05:30
|
|
|
useEffect(() => {
|
|
|
|
|
if (data?.payload) {
|
|
|
|
|
setWarning(data?.warning);
|
|
|
|
|
}
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
}, [data?.payload, data?.warning]);
|
|
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
const handleEndReached = useCallback(() => {
|
|
|
|
|
if (!listQuery) return;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
if (isLimit) return;
|
|
|
|
|
if (logs.length < pageSize) return;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
const { limit, filters } = listQuery;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
const nextLogsLength = logs.length + pageSize;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
const nextPageSize =
|
|
|
|
|
limit && nextLogsLength >= limit ? limit - logs.length : pageSize;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
if (!stagedQuery) return;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
const newRequestData = getRequestData(stagedQuery, {
|
2025-07-31 12:16:55 +05:30
|
|
|
filters: filters || { items: [], op: 'AND' },
|
2025-05-22 14:12:51 +04:30
|
|
|
page: page + 1,
|
|
|
|
|
pageSize: nextPageSize,
|
|
|
|
|
});
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
setPage((prevPage) => prevPage + 1);
|
2024-09-16 10:06:09 +05:30
|
|
|
|
2025-05-22 14:12:51 +04:30
|
|
|
setRequestData(newRequestData);
|
|
|
|
|
}, [isLimit, logs, listQuery, pageSize, stagedQuery, getRequestData, page]);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2024-08-16 15:07:06 +05:30
|
|
|
useEffect(() => {
|
|
|
|
|
setQueryId(v4());
|
2024-08-23 17:37:56 +05:30
|
|
|
}, [data]);
|
2024-08-16 15:07:06 +05:30
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (
|
|
|
|
|
!isEmpty(queryId) &&
|
|
|
|
|
(isLoading || isFetching) &&
|
|
|
|
|
selectedPanelType !== PANEL_TYPES.LIST
|
|
|
|
|
) {
|
|
|
|
|
setQueryStats(undefined);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
getQueryStats({ queryId, setData: setQueryStats });
|
|
|
|
|
}, 500);
|
|
|
|
|
}
|
|
|
|
|
}, [queryId, isLoading, isFetching, selectedPanelType]);
|
|
|
|
|
|
2024-07-16 14:18:59 +05:30
|
|
|
const logEventCalledRef = useRef(false);
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!logEventCalledRef.current && !isUndefined(data?.payload)) {
|
|
|
|
|
const currentData = data?.payload?.data?.newResult?.data?.result || [];
|
|
|
|
|
logEvent('Logs Explorer: Page visited', {
|
|
|
|
|
panelType,
|
|
|
|
|
isEmpty: !currentData?.[0]?.list,
|
|
|
|
|
});
|
|
|
|
|
logEventCalledRef.current = true;
|
|
|
|
|
}
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
}, [data?.payload]);
|
|
|
|
|
|
2024-06-20 17:05:18 +05:30
|
|
|
const getUpdatedQueryForExport = useCallback((): Query => {
|
|
|
|
|
const updatedQuery = cloneDeep(currentQuery);
|
|
|
|
|
|
|
|
|
|
set(updatedQuery, 'builder.queryData[0].pageSize', 10);
|
|
|
|
|
|
|
|
|
|
return updatedQuery;
|
|
|
|
|
}, [currentQuery]);
|
|
|
|
|
|
2023-07-07 20:59:35 +05:30
|
|
|
const handleExport = useCallback(
|
2024-07-16 14:18:59 +05:30
|
|
|
(dashboard: Dashboard | null, isNewDashboard?: boolean): void => {
|
2023-08-23 19:44:33 +03:00
|
|
|
if (!dashboard || !panelType) return;
|
|
|
|
|
|
|
|
|
|
const panelTypeParam = AVAILABLE_EXPORT_PANEL_TYPES.includes(panelType)
|
|
|
|
|
? panelType
|
|
|
|
|
: PANEL_TYPES.TIME_SERIES;
|
2023-07-07 20:59:35 +05:30
|
|
|
|
2023-11-21 00:52:53 +05:30
|
|
|
const widgetId = v4();
|
|
|
|
|
|
2024-06-20 17:05:18 +05:30
|
|
|
const query =
|
|
|
|
|
panelType === PANEL_TYPES.LIST
|
|
|
|
|
? getUpdatedQueryForExport()
|
|
|
|
|
: exportDefaultQuery;
|
|
|
|
|
|
2024-07-16 14:18:59 +05:30
|
|
|
logEvent('Logs Explorer: Add to dashboard successful', {
|
|
|
|
|
panelType,
|
|
|
|
|
isNewDashboard,
|
|
|
|
|
dashboardName: dashboard?.data?.title,
|
|
|
|
|
});
|
|
|
|
|
|
2025-06-02 13:32:09 +05:30
|
|
|
const dashboardEditView = generateExportToDashboardLink({
|
|
|
|
|
query,
|
|
|
|
|
panelType: panelTypeParam,
|
2025-06-02 22:41:38 +05:30
|
|
|
dashboardId: dashboard.id,
|
2025-06-02 13:32:09 +05:30
|
|
|
widgetId,
|
2023-07-07 20:59:35 +05:30
|
|
|
});
|
2025-06-02 13:32:09 +05:30
|
|
|
|
|
|
|
|
safeNavigate(dashboardEditView);
|
2023-07-07 20:59:35 +05:30
|
|
|
},
|
2025-06-02 13:32:09 +05:30
|
|
|
[getUpdatedQueryForExport, exportDefaultQuery, safeNavigate, panelType],
|
2023-07-07 20:59:35 +05:30
|
|
|
);
|
|
|
|
|
|
2023-06-23 11:19:53 +03:00
|
|
|
useEffect(() => {
|
2025-08-25 17:35:50 +04:30
|
|
|
const shouldChangeView = isMultipleQueries || isGroupByExist;
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2024-02-12 00:23:19 +05:30
|
|
|
if (selectedPanelType === PANEL_TYPES.LIST && shouldChangeView) {
|
2023-08-30 20:24:16 +05:30
|
|
|
handleExplorerTabChange(PANEL_TYPES.TIME_SERIES);
|
2024-02-12 00:23:19 +05:30
|
|
|
setSelectedPanelType(PANEL_TYPES.TIME_SERIES);
|
2023-06-23 11:19:53 +03:00
|
|
|
}
|
2024-02-12 00:23:19 +05:30
|
|
|
|
|
|
|
|
if (panelType) {
|
|
|
|
|
setSelectedPanelType(panelType);
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
isMultipleQueries,
|
|
|
|
|
isGroupByExist,
|
|
|
|
|
selectedPanelType,
|
|
|
|
|
selectedView,
|
|
|
|
|
handleExplorerTabChange,
|
|
|
|
|
panelType,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2025-07-31 12:16:55 +05:30
|
|
|
if (selectedView && selectedView === ExplorerViews.LIST && handleSetConfig) {
|
2024-02-12 00:23:19 +05:30
|
|
|
handleSetConfig(defaultTo(panelTypes, PANEL_TYPES.LIST), DataSource.LOGS);
|
|
|
|
|
}
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2024-02-15 14:13:05 +05:30
|
|
|
}, [handleSetConfig, panelTypes]);
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
useEffect(() => {
|
2024-06-04 00:15:37 +05:30
|
|
|
const currentData = data?.payload?.data?.newResult?.data?.result || [];
|
2023-07-06 14:22:44 +03:00
|
|
|
if (currentData.length > 0 && currentData[0].list) {
|
|
|
|
|
const currentLogs: ILog[] = currentData[0].list.map((item) => ({
|
|
|
|
|
...item.data,
|
|
|
|
|
timestamp: item.timestamp,
|
|
|
|
|
}));
|
2023-07-30 14:02:18 +03:00
|
|
|
const newLogs = [...logs, ...currentLogs];
|
|
|
|
|
|
|
|
|
|
setLogs(newLogs);
|
2023-07-06 14:22:44 +03:00
|
|
|
}
|
2023-07-30 14:02:18 +03:00
|
|
|
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2023-07-06 14:22:44 +03:00
|
|
|
}, [data]);
|
|
|
|
|
|
2025-07-31 12:16:55 +05:30
|
|
|
// Store previous orderDirection to detect changes
|
|
|
|
|
const prevOrderByRef = useRef(orderBy);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
useEffect(() => {
|
2025-07-31 12:16:55 +05:30
|
|
|
const orderByChanged =
|
|
|
|
|
prevOrderByRef.current !== orderBy && selectedPanelType === PANEL_TYPES.LIST;
|
|
|
|
|
prevOrderByRef.current = orderBy;
|
|
|
|
|
|
2023-07-08 07:27:34 +03:00
|
|
|
if (
|
|
|
|
|
requestData?.id !== stagedQuery?.id ||
|
2025-07-31 12:16:55 +05:30
|
|
|
currentMinTimeRef.current !== minTime ||
|
|
|
|
|
orderByChanged
|
2023-07-08 07:27:34 +03:00
|
|
|
) {
|
2025-06-23 13:36:46 +04:30
|
|
|
// Recalculate global time when query changes i.e. stage and run query clicked
|
|
|
|
|
if (
|
|
|
|
|
!!requestData?.id &&
|
|
|
|
|
stagedQuery?.id &&
|
|
|
|
|
requestData?.id !== stagedQuery?.id &&
|
|
|
|
|
selectedTime !== 'custom'
|
|
|
|
|
) {
|
|
|
|
|
dispatch(UpdateTimeInterval(selectedTime));
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const newRequestData = getRequestData(stagedQuery, {
|
2023-08-10 12:06:24 +03:00
|
|
|
filters: listQuery?.filters || initialFilters,
|
2023-07-06 14:22:44 +03:00
|
|
|
page: 1,
|
2024-08-26 19:26:34 +05:30
|
|
|
pageSize,
|
2023-07-06 14:22:44 +03:00
|
|
|
});
|
2023-08-10 12:06:24 +03:00
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
setLogs([]);
|
|
|
|
|
setPage(1);
|
|
|
|
|
setRequestData(newRequestData);
|
2023-07-08 07:27:34 +03:00
|
|
|
currentMinTimeRef.current = minTime;
|
2023-07-06 14:22:44 +03:00
|
|
|
}
|
2023-07-30 14:02:18 +03:00
|
|
|
}, [
|
|
|
|
|
stagedQuery,
|
|
|
|
|
requestData,
|
|
|
|
|
getRequestData,
|
2023-08-10 12:06:24 +03:00
|
|
|
listQuery,
|
2023-07-30 14:02:18 +03:00
|
|
|
pageSize,
|
|
|
|
|
minTime,
|
|
|
|
|
activeLogId,
|
2023-08-10 12:06:24 +03:00
|
|
|
panelType,
|
2024-02-12 00:23:19 +05:30
|
|
|
selectedView,
|
2025-06-23 13:36:46 +04:30
|
|
|
dispatch,
|
|
|
|
|
selectedTime,
|
|
|
|
|
maxTime,
|
2025-07-31 12:16:55 +05:30
|
|
|
orderBy,
|
|
|
|
|
selectedPanelType,
|
2023-07-30 14:02:18 +03:00
|
|
|
]);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
|
|
|
|
const chartData = useMemo(() => {
|
|
|
|
|
if (!stagedQuery) return [];
|
|
|
|
|
|
|
|
|
|
if (panelType === PANEL_TYPES.LIST) {
|
2025-07-02 12:00:17 +04:30
|
|
|
if (listChartData && listChartData.payload.data?.result.length > 0) {
|
2023-12-20 18:18:27 +05:30
|
|
|
return listChartData.payload.data.result;
|
2023-07-06 14:22:44 +03:00
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-02 12:00:17 +04:30
|
|
|
if (!data || data.payload.data?.result.length === 0) return [];
|
2023-07-06 14:22:44 +03:00
|
|
|
|
|
|
|
|
const isGroupByExist = stagedQuery.builder.queryData.some(
|
|
|
|
|
(queryData) => queryData.groupBy.length > 0,
|
|
|
|
|
);
|
|
|
|
|
|
2025-07-02 12:00:17 +04:30
|
|
|
const firstPayloadQuery = data.payload.data?.result.find(
|
2023-08-10 12:06:24 +03:00
|
|
|
(item) => item.queryName === listQuery?.queryName,
|
2023-08-08 12:32:55 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const firstPayloadQueryArray = firstPayloadQuery ? [firstPayloadQuery] : [];
|
|
|
|
|
|
|
|
|
|
return isGroupByExist ? data.payload.data.result : firstPayloadQueryArray;
|
2023-08-10 12:06:24 +03:00
|
|
|
}, [stagedQuery, panelType, data, listChartData, listQuery]);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
2024-08-16 13:11:39 +05:30
|
|
|
useEffect(() => {
|
|
|
|
|
if (
|
|
|
|
|
isLoading ||
|
|
|
|
|
isFetching ||
|
|
|
|
|
isLoadingListChartData ||
|
|
|
|
|
isFetchingListChartData
|
|
|
|
|
) {
|
|
|
|
|
setIsLoadingQueries(true);
|
|
|
|
|
} else {
|
|
|
|
|
setIsLoadingQueries(false);
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
isLoading,
|
|
|
|
|
isFetching,
|
|
|
|
|
isFetchingListChartData,
|
|
|
|
|
isLoadingListChartData,
|
|
|
|
|
setIsLoadingQueries,
|
|
|
|
|
]);
|
|
|
|
|
|
2024-12-16 10:27:20 +04:30
|
|
|
const { timezone } = useTimezone();
|
|
|
|
|
|
2024-03-22 13:28:38 +05:30
|
|
|
const flattenLogData = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
logs.map((log) => {
|
|
|
|
|
const timestamp =
|
|
|
|
|
typeof log.timestamp === 'string'
|
2024-12-16 10:27:20 +04:30
|
|
|
? dayjs(log.timestamp)
|
|
|
|
|
.tz(timezone.value)
|
2025-01-27 16:28:54 +04:30
|
|
|
.format(DATE_TIME_FORMATS.ISO_DATETIME_MS)
|
2024-12-16 10:27:20 +04:30
|
|
|
: dayjs(log.timestamp / 1e6)
|
|
|
|
|
.tz(timezone.value)
|
2025-01-27 16:28:54 +04:30
|
|
|
.format(DATE_TIME_FORMATS.ISO_DATETIME_MS);
|
2024-03-22 13:28:38 +05:30
|
|
|
|
|
|
|
|
return FlatLogData({
|
|
|
|
|
timestamp,
|
|
|
|
|
body: log.body,
|
|
|
|
|
...omit(log, 'timestamp', 'body'),
|
|
|
|
|
});
|
|
|
|
|
}),
|
2024-12-16 10:27:20 +04:30
|
|
|
[logs, timezone.value],
|
2024-03-22 13:28:38 +05:30
|
|
|
);
|
|
|
|
|
|
2025-08-28 19:03:29 +05:30
|
|
|
const handleToggleFrequencyChart = useCallback(() => {
|
|
|
|
|
const newShowFrequencyChart = !showFrequencyChart;
|
|
|
|
|
|
|
|
|
|
// store the value in local storage
|
|
|
|
|
setToLocalstorage(
|
|
|
|
|
LOCALSTORAGE.SHOW_FREQUENCY_CHART,
|
|
|
|
|
newShowFrequencyChart?.toString() || 'false',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
setShowFrequencyChart(newShowFrequencyChart);
|
|
|
|
|
}, [showFrequencyChart]);
|
|
|
|
|
|
2023-06-23 11:19:53 +03:00
|
|
|
return (
|
2024-02-12 00:23:19 +05:30
|
|
|
<div className="logs-explorer-views-container">
|
|
|
|
|
<div className="logs-explorer-views-types">
|
2025-09-02 11:05:52 +05:30
|
|
|
{!showLiveLogs && (
|
|
|
|
|
<LogsActionsContainer
|
|
|
|
|
listQuery={listQuery}
|
|
|
|
|
queryStats={queryStats}
|
|
|
|
|
selectedPanelType={selectedPanelType}
|
|
|
|
|
showFrequencyChart={showFrequencyChart}
|
|
|
|
|
handleToggleFrequencyChart={handleToggleFrequencyChart}
|
|
|
|
|
orderBy={orderBy}
|
|
|
|
|
setOrderBy={setOrderBy}
|
|
|
|
|
flattenLogData={flattenLogData}
|
|
|
|
|
isFetching={isFetching}
|
|
|
|
|
isLoading={isLoading}
|
|
|
|
|
isError={isError}
|
|
|
|
|
isSuccess={isSuccess}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2025-07-31 12:16:55 +05:30
|
|
|
|
2025-09-02 11:05:52 +05:30
|
|
|
{selectedPanelType === PANEL_TYPES.LIST &&
|
|
|
|
|
showFrequencyChart &&
|
|
|
|
|
!showLiveLogs && (
|
|
|
|
|
<div className="logs-frequency-chart-container">
|
|
|
|
|
<LogsExplorerChart
|
|
|
|
|
className="logs-frequency-chart"
|
|
|
|
|
isLoading={isFetchingListChartData || isLoadingListChartData}
|
|
|
|
|
data={chartData}
|
|
|
|
|
isLogsExplorerViews={panelType === PANEL_TYPES.LIST}
|
|
|
|
|
/>
|
2025-07-31 12:16:55 +05:30
|
|
|
</div>
|
2025-09-02 11:05:52 +05:30
|
|
|
)}
|
2025-07-31 12:16:55 +05:30
|
|
|
|
2024-02-12 00:23:19 +05:30
|
|
|
<div className="logs-explorer-views-type-content">
|
2025-09-02 11:05:52 +05:30
|
|
|
{showLiveLogs && <LiveLogs />}
|
|
|
|
|
|
|
|
|
|
{selectedPanelType === PANEL_TYPES.LIST && !showLiveLogs && (
|
2024-02-12 00:23:19 +05:30
|
|
|
<LogsExplorerList
|
|
|
|
|
isLoading={isLoading}
|
|
|
|
|
isFetching={isFetching}
|
|
|
|
|
currentStagedQueryData={listQuery}
|
|
|
|
|
logs={logs}
|
|
|
|
|
onEndReached={handleEndReached}
|
2025-08-28 19:03:29 +05:30
|
|
|
isFrequencyChartVisible={showFrequencyChart}
|
2024-02-12 00:23:19 +05:30
|
|
|
isError={isError}
|
2025-08-05 23:45:39 +05:30
|
|
|
error={error as APIError}
|
2025-07-31 12:16:55 +05:30
|
|
|
isFilterApplied={!isEmpty(listQuery?.filters?.items)}
|
2024-02-12 00:23:19 +05:30
|
|
|
/>
|
|
|
|
|
)}
|
2025-09-02 11:05:52 +05:30
|
|
|
|
|
|
|
|
{selectedPanelType === PANEL_TYPES.TIME_SERIES && !showLiveLogs && (
|
2024-02-12 00:23:19 +05:30
|
|
|
<TimeSeriesView
|
|
|
|
|
isLoading={isLoading || isFetching}
|
|
|
|
|
data={data}
|
|
|
|
|
isError={isError}
|
2025-08-05 23:45:39 +05:30
|
|
|
error={error as APIError}
|
2025-07-31 12:16:55 +05:30
|
|
|
isFilterApplied={!isEmpty(listQuery?.filters?.items)}
|
2024-02-26 12:09:31 +05:30
|
|
|
dataSource={DataSource.LOGS}
|
2025-08-05 23:45:39 +05:30
|
|
|
setWarning={setWarning}
|
2024-02-12 00:23:19 +05:30
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-09-02 11:05:52 +05:30
|
|
|
{selectedPanelType === PANEL_TYPES.TABLE && !showLiveLogs && (
|
2024-02-12 00:23:19 +05:30
|
|
|
<LogsExplorerTable
|
2025-07-31 12:16:55 +05:30
|
|
|
data={
|
|
|
|
|
(data?.payload?.data?.newResult?.data?.result ||
|
|
|
|
|
data?.payload?.data?.result ||
|
|
|
|
|
[]) as QueryDataV3[]
|
|
|
|
|
}
|
2024-02-12 00:23:19 +05:30
|
|
|
isLoading={isLoading || isFetching}
|
|
|
|
|
isError={isError}
|
2025-08-05 23:45:39 +05:30
|
|
|
error={error as APIError}
|
2024-02-12 00:23:19 +05:30
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-07-17 13:42:05 +05:30
|
|
|
|
|
|
|
|
<GoToTop />
|
2024-02-12 00:23:19 +05:30
|
|
|
|
2024-03-26 17:09:13 +05:30
|
|
|
<ExplorerOptionWrapper
|
2024-02-12 00:23:19 +05:30
|
|
|
disabled={!stagedQuery}
|
|
|
|
|
query={exportDefaultQuery}
|
|
|
|
|
onExport={handleExport}
|
|
|
|
|
sourcepage={DataSource.LOGS}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2023-06-23 11:19:53 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-31 12:16:55 +05:30
|
|
|
export default memo(LogsExplorerViewsContainer);
|