2023-06-23 11:19:53 +03:00
|
|
|
import { TabsProps } from 'antd';
|
2023-07-07 20:59:35 +05:30
|
|
|
import axios from 'axios';
|
2023-07-12 16:59:33 +03:00
|
|
|
import LogDetail from 'components/LogDetail';
|
2023-07-07 15:35:42 +03:00
|
|
|
import TabLabel from 'components/TabLabel';
|
2023-07-07 20:59:35 +05:30
|
|
|
import { QueryParams } from 'constants/query';
|
2023-07-12 16:59:33 +03:00
|
|
|
import {
|
|
|
|
|
initialQueriesMap,
|
2023-07-13 15:55:43 +03:00
|
|
|
OPERATORS,
|
2023-07-12 16:59:33 +03:00
|
|
|
PANEL_TYPES,
|
|
|
|
|
QueryBuilderKeys,
|
|
|
|
|
} from 'constants/queryBuilder';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
|
2023-07-07 20:59:35 +05:30
|
|
|
import ROUTES from 'constants/routes';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
|
2023-07-07 20:59:35 +05:30
|
|
|
import ExportPanel from 'container/ExportPanel';
|
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-23 11:19:53 +03:00
|
|
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
2023-06-29 14:22:55 +05:30
|
|
|
import TimeSeriesView from 'container/TimeSeriesView/TimeSeriesView';
|
2023-07-07 20:59:35 +05:30
|
|
|
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
|
|
|
|
|
import { addEmptyWidgetInDashboardJSONWithQuery } from 'hooks/dashboard/utils';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
|
2023-06-23 11:19:53 +03:00
|
|
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
2023-07-07 20:59:35 +05:30
|
|
|
import { useNotifications } from 'hooks/useNotifications';
|
2023-07-06 14:22:44 +03:00
|
|
|
import useUrlQueryData from 'hooks/useUrlQueryData';
|
2023-07-12 16:59:33 +03:00
|
|
|
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { getPaginationQueryData } from 'lib/newQueryBuilder/getPaginationQueryData';
|
2023-07-08 07:27:34 +03:00
|
|
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
2023-07-12 16:59:33 +03:00
|
|
|
import { useQueryClient } from 'react-query';
|
2023-07-08 07:27:34 +03:00
|
|
|
import { useSelector } from 'react-redux';
|
2023-07-07 20:59:35 +05:30
|
|
|
import { generatePath, useHistory } from 'react-router-dom';
|
2023-07-08 07:27:34 +03:00
|
|
|
import { AppState } from 'store/reducers';
|
2023-07-12 16:59:33 +03:00
|
|
|
import { SuccessResponse } from 'types/api';
|
2023-07-07 20:59:35 +05:30
|
|
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
2023-07-06 14:22:44 +03:00
|
|
|
import { ILog } from 'types/api/logs/log';
|
2023-07-12 16:59:33 +03:00
|
|
|
import {
|
|
|
|
|
BaseAutocompleteData,
|
|
|
|
|
IQueryAutocompleteResponse,
|
|
|
|
|
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
2023-07-06 14:22:44 +03:00
|
|
|
import {
|
|
|
|
|
IBuilderQuery,
|
|
|
|
|
OrderByPayload,
|
|
|
|
|
Query,
|
|
|
|
|
} from 'types/api/queryBuilder/queryBuilderData';
|
|
|
|
|
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
2023-07-08 07:27:34 +03:00
|
|
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
2023-07-12 16:59:33 +03:00
|
|
|
import { v4 as uuid } from 'uuid';
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2023-07-07 20:59:35 +05:30
|
|
|
import { ActionsWrapper, TabsStyled } from './LogsExplorerViews.styled';
|
2023-06-23 11:19:53 +03:00
|
|
|
|
|
|
|
|
function LogsExplorerViews(): JSX.Element {
|
2023-07-07 20:59:35 +05:30
|
|
|
const { notifications } = useNotifications();
|
|
|
|
|
const history = useHistory();
|
|
|
|
|
|
2023-07-12 16:59:33 +03:00
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const { queryData: pageSize } = useUrlQueryData(
|
|
|
|
|
queryParamNamesMap.pageSize,
|
|
|
|
|
DEFAULT_PER_PAGE_VALUE,
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-08 07:27:34 +03:00
|
|
|
const { minTime } = useSelector<AppState, GlobalReducer>(
|
|
|
|
|
(state) => state.globalTime,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
redirectWithQueryBuilderData,
|
|
|
|
|
} = useQueryBuilder();
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
// State
|
|
|
|
|
const [activeLog, setActiveLog] = useState<ILog | null>(null);
|
|
|
|
|
const [page, setPage] = useState<number>(1);
|
|
|
|
|
const [logs, setLogs] = useState<ILog[]>([]);
|
|
|
|
|
const [requestData, setRequestData] = useState<Query | null>(null);
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const currentStagedQueryData = useMemo(() => {
|
|
|
|
|
if (!stagedQuery || stagedQuery.builder.queryData.length !== 1) return null;
|
|
|
|
|
|
|
|
|
|
return stagedQuery.builder.queryData[0];
|
|
|
|
|
}, [stagedQuery]);
|
|
|
|
|
|
|
|
|
|
const orderByTimestamp: OrderByPayload | null = useMemo(() => {
|
|
|
|
|
const timestampOrderBy = currentStagedQueryData?.orderBy.find(
|
|
|
|
|
(item) => item.columnName === 'timestamp',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return timestampOrderBy || null;
|
|
|
|
|
}, [currentStagedQueryData]);
|
2023-06-23 11:19:53 +03:00
|
|
|
|
|
|
|
|
const isMultipleQueries = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
currentQuery.builder.queryData.length > 1 ||
|
|
|
|
|
currentQuery.builder.queryFormulas.length > 0,
|
|
|
|
|
[currentQuery],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const isGroupByExist = useMemo(() => {
|
|
|
|
|
const groupByCount: number = currentQuery.builder.queryData.reduce<number>(
|
|
|
|
|
(acc, query) => acc + query.groupBy.length,
|
|
|
|
|
0,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return groupByCount > 0;
|
|
|
|
|
}, [currentQuery]);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const isLimit: boolean = useMemo(() => {
|
|
|
|
|
if (!currentStagedQueryData) return false;
|
|
|
|
|
if (!currentStagedQueryData.limit) return false;
|
2023-06-23 11:19:53 +03:00
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
return logs.length >= currentStagedQueryData.limit;
|
|
|
|
|
}, [logs.length, currentStagedQueryData]);
|
|
|
|
|
|
|
|
|
|
const listChartQuery = useMemo(() => {
|
|
|
|
|
if (!stagedQuery || !currentStagedQueryData) return null;
|
|
|
|
|
|
|
|
|
|
const modifiedQueryData: IBuilderQuery = {
|
|
|
|
|
...currentStagedQueryData,
|
|
|
|
|
aggregateOperator: StringOperators.COUNT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return modifiedQuery;
|
|
|
|
|
}, [stagedQuery, currentStagedQueryData]);
|
|
|
|
|
|
2023-07-07 20:59:35 +05:30
|
|
|
const exportDefaultQuery = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
updateAllQueriesOperators(
|
|
|
|
|
currentQuery || initialQueriesMap.logs,
|
|
|
|
|
PANEL_TYPES.TIME_SERIES,
|
|
|
|
|
DataSource.LOGS,
|
|
|
|
|
),
|
|
|
|
|
[currentQuery, updateAllQueriesOperators],
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const listChartData = useGetExplorerQueryRange(
|
|
|
|
|
listChartQuery,
|
|
|
|
|
PANEL_TYPES.TIME_SERIES,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const { data, isFetching, isError } = useGetExplorerQueryRange(
|
|
|
|
|
requestData,
|
|
|
|
|
panelType,
|
|
|
|
|
{
|
|
|
|
|
keepPreviousData: true,
|
|
|
|
|
enabled: !isLimit,
|
|
|
|
|
},
|
2023-06-23 11:19:53 +03:00
|
|
|
);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const handleSetActiveLog = useCallback((nextActiveLog: ILog) => {
|
|
|
|
|
setActiveLog(nextActiveLog);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const handleClearActiveLog = useCallback(() => {
|
|
|
|
|
setActiveLog(null);
|
|
|
|
|
}, []);
|
|
|
|
|
|
2023-06-23 11:19:53 +03:00
|
|
|
const handleChangeView = useCallback(
|
|
|
|
|
(newPanelType: string) => {
|
|
|
|
|
if (newPanelType === panelType) return;
|
|
|
|
|
|
|
|
|
|
const query = updateAllQueriesOperators(
|
|
|
|
|
currentQuery,
|
|
|
|
|
newPanelType as GRAPH_TYPES,
|
|
|
|
|
DataSource.LOGS,
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
redirectWithQueryBuilderData(query, {
|
|
|
|
|
[queryParamNamesMap.panelTypes]: newPanelType,
|
|
|
|
|
});
|
2023-06-23 11:19:53 +03:00
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
currentQuery,
|
|
|
|
|
panelType,
|
|
|
|
|
updateAllQueriesOperators,
|
|
|
|
|
redirectWithQueryBuilderData,
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const getRequestData = useCallback(
|
|
|
|
|
(
|
|
|
|
|
query: Query | null,
|
|
|
|
|
params: { page: number; log: ILog | null; pageSize: number },
|
|
|
|
|
): Query | null => {
|
|
|
|
|
if (!query) return null;
|
|
|
|
|
|
|
|
|
|
const paginateData = getPaginationQueryData({
|
|
|
|
|
currentStagedQueryData,
|
|
|
|
|
listItemId: params.log ? params.log.id : null,
|
|
|
|
|
orderByTimestamp,
|
|
|
|
|
page: params.page,
|
|
|
|
|
pageSize: params.pageSize,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const data: Query = {
|
|
|
|
|
...query,
|
|
|
|
|
builder: {
|
|
|
|
|
...query.builder,
|
|
|
|
|
queryData: query.builder.queryData.map((item) => ({
|
|
|
|
|
...item,
|
|
|
|
|
...paginateData,
|
|
|
|
|
pageSize: params.pageSize,
|
|
|
|
|
})),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
},
|
|
|
|
|
[currentStagedQueryData, orderByTimestamp],
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-13 15:55:43 +03:00
|
|
|
const handleAddToQuery = useCallback(
|
|
|
|
|
(fieldKey: string, fieldValue: string, operator: string): void => {
|
2023-07-12 16:59:33 +03:00
|
|
|
const keysAutocomplete: BaseAutocompleteData[] =
|
|
|
|
|
queryClient.getQueryData<SuccessResponse<IQueryAutocompleteResponse>>(
|
|
|
|
|
[QueryBuilderKeys.GET_AGGREGATE_KEYS],
|
|
|
|
|
{ exact: false },
|
|
|
|
|
)?.payload.attributeKeys || [];
|
|
|
|
|
|
|
|
|
|
const existAutocompleteKey = chooseAutocompleteFromCustomValue(
|
|
|
|
|
keysAutocomplete,
|
|
|
|
|
fieldKey,
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-13 15:55:43 +03:00
|
|
|
const currentOperator =
|
|
|
|
|
Object.keys(OPERATORS).find((op) => op === operator) || '';
|
|
|
|
|
|
2023-07-12 16:59:33 +03:00
|
|
|
const nextQuery: Query = {
|
|
|
|
|
...currentQuery,
|
|
|
|
|
builder: {
|
|
|
|
|
...currentQuery.builder,
|
|
|
|
|
queryData: currentQuery.builder.queryData.map((item) => ({
|
|
|
|
|
...item,
|
|
|
|
|
filters: {
|
|
|
|
|
...item.filters,
|
|
|
|
|
items: [
|
|
|
|
|
...item.filters.items.filter(
|
|
|
|
|
(item) => item.key?.id !== existAutocompleteKey.id,
|
|
|
|
|
),
|
|
|
|
|
{
|
|
|
|
|
id: uuid(),
|
|
|
|
|
key: existAutocompleteKey,
|
2023-07-13 15:55:43 +03:00
|
|
|
op: currentOperator,
|
2023-07-12 16:59:33 +03:00
|
|
|
value: fieldValue,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
})),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
redirectWithQueryBuilderData(nextQuery);
|
|
|
|
|
},
|
|
|
|
|
[currentQuery, queryClient, redirectWithQueryBuilderData],
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
const handleEndReached = useCallback(
|
|
|
|
|
(index: number) => {
|
|
|
|
|
if (isLimit) return;
|
2023-07-12 18:20:17 +03:00
|
|
|
if (logs.length < pageSize) return;
|
2023-07-06 14:22:44 +03:00
|
|
|
|
|
|
|
|
const lastLog = logs[index];
|
|
|
|
|
|
|
|
|
|
const limit = currentStagedQueryData?.limit;
|
|
|
|
|
|
|
|
|
|
const nextLogsLenth = logs.length + pageSize;
|
|
|
|
|
|
|
|
|
|
const nextPageSize =
|
|
|
|
|
limit && nextLogsLenth >= limit ? limit - logs.length : pageSize;
|
|
|
|
|
|
|
|
|
|
if (!stagedQuery) return;
|
|
|
|
|
|
|
|
|
|
const newRequestData = getRequestData(stagedQuery, {
|
|
|
|
|
page: page + 1,
|
|
|
|
|
log: orderByTimestamp ? lastLog : null,
|
|
|
|
|
pageSize: nextPageSize,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
setPage((prevPage) => prevPage + 1);
|
|
|
|
|
|
|
|
|
|
setRequestData(newRequestData);
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
isLimit,
|
|
|
|
|
logs,
|
|
|
|
|
currentStagedQueryData?.limit,
|
|
|
|
|
pageSize,
|
|
|
|
|
stagedQuery,
|
|
|
|
|
getRequestData,
|
|
|
|
|
page,
|
|
|
|
|
orderByTimestamp,
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-07 20:59:35 +05:30
|
|
|
const {
|
|
|
|
|
mutate: updateDashboard,
|
|
|
|
|
isLoading: isUpdateDashboardLoading,
|
|
|
|
|
} = useUpdateDashboard();
|
|
|
|
|
|
|
|
|
|
const handleExport = useCallback(
|
|
|
|
|
(dashboard: Dashboard | null): void => {
|
|
|
|
|
if (!dashboard) return;
|
|
|
|
|
|
|
|
|
|
const updatedDashboard = addEmptyWidgetInDashboardJSONWithQuery(
|
|
|
|
|
dashboard,
|
|
|
|
|
exportDefaultQuery,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
updateDashboard(updatedDashboard, {
|
|
|
|
|
onSuccess: (data) => {
|
|
|
|
|
if (data.error) {
|
|
|
|
|
const message =
|
|
|
|
|
data.error === 'feature usage exceeded' ? (
|
|
|
|
|
<span>
|
|
|
|
|
Panel limit exceeded for {DataSource.LOGS} in community edition. Please
|
|
|
|
|
checkout our paid plans{' '}
|
|
|
|
|
<a
|
2023-07-11 19:38:09 +05:30
|
|
|
href="https://signoz.io/pricing/?utm_source=product&utm_medium=dashboard-limit"
|
2023-07-07 20:59:35 +05:30
|
|
|
rel="noreferrer noopener"
|
|
|
|
|
target="_blank"
|
|
|
|
|
>
|
|
|
|
|
here
|
|
|
|
|
</a>
|
|
|
|
|
</span>
|
|
|
|
|
) : (
|
|
|
|
|
data.error
|
|
|
|
|
);
|
|
|
|
|
notifications.error({
|
|
|
|
|
message,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const dashboardEditView = `${generatePath(ROUTES.DASHBOARD, {
|
|
|
|
|
dashboardId: data?.payload?.uuid,
|
|
|
|
|
})}/new?${QueryParams.graphType}=graph&${QueryParams.widgetId}=empty&${
|
|
|
|
|
queryParamNamesMap.compositeQuery
|
|
|
|
|
}=${encodeURIComponent(JSON.stringify(exportDefaultQuery))}`;
|
|
|
|
|
|
|
|
|
|
history.push(dashboardEditView);
|
|
|
|
|
},
|
|
|
|
|
onError: (error) => {
|
|
|
|
|
if (axios.isAxiosError(error)) {
|
|
|
|
|
notifications.error({
|
|
|
|
|
message: error.message,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
[exportDefaultQuery, history, notifications, updateDashboard],
|
|
|
|
|
);
|
|
|
|
|
|
2023-06-23 11:19:53 +03:00
|
|
|
useEffect(() => {
|
|
|
|
|
const shouldChangeView = isMultipleQueries || isGroupByExist;
|
|
|
|
|
|
2023-07-12 18:20:17 +03:00
|
|
|
if (panelType === PANEL_TYPES.LIST && shouldChangeView) {
|
2023-06-23 11:19:53 +03:00
|
|
|
handleChangeView(PANEL_TYPES.TIME_SERIES);
|
|
|
|
|
}
|
|
|
|
|
}, [panelType, isMultipleQueries, isGroupByExist, handleChangeView]);
|
|
|
|
|
|
2023-07-06 14:22:44 +03:00
|
|
|
useEffect(() => {
|
|
|
|
|
const currentData = data?.payload.data.newResult.data.result || [];
|
|
|
|
|
if (currentData.length > 0 && currentData[0].list) {
|
|
|
|
|
const currentLogs: ILog[] = currentData[0].list.map((item) => ({
|
|
|
|
|
...item.data,
|
|
|
|
|
timestamp: item.timestamp,
|
|
|
|
|
}));
|
|
|
|
|
setLogs((prevLogs) => [...prevLogs, ...currentLogs]);
|
|
|
|
|
}
|
|
|
|
|
}, [data]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2023-07-08 07:27:34 +03:00
|
|
|
if (
|
|
|
|
|
requestData?.id !== stagedQuery?.id ||
|
|
|
|
|
currentMinTimeRef.current !== minTime
|
|
|
|
|
) {
|
2023-07-06 14:22:44 +03:00
|
|
|
const newRequestData = getRequestData(stagedQuery, {
|
|
|
|
|
page: 1,
|
|
|
|
|
log: null,
|
|
|
|
|
pageSize,
|
|
|
|
|
});
|
|
|
|
|
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-08 07:27:34 +03:00
|
|
|
}, [stagedQuery, requestData, getRequestData, pageSize, minTime]);
|
2023-07-06 14:22:44 +03:00
|
|
|
|
|
|
|
|
const tabsItems: TabsProps['items'] = useMemo(
|
|
|
|
|
() => [
|
|
|
|
|
{
|
2023-07-07 15:35:42 +03:00
|
|
|
label: (
|
|
|
|
|
<TabLabel
|
|
|
|
|
label="List View"
|
|
|
|
|
tooltipText="Please remove attributes from Group By filter to switch to List View tab"
|
|
|
|
|
isDisabled={isMultipleQueries || isGroupByExist}
|
|
|
|
|
/>
|
|
|
|
|
),
|
2023-07-06 14:22:44 +03:00
|
|
|
key: PANEL_TYPES.LIST,
|
|
|
|
|
disabled: isMultipleQueries || isGroupByExist,
|
|
|
|
|
children: (
|
|
|
|
|
<LogsExplorerList
|
|
|
|
|
isLoading={isFetching}
|
|
|
|
|
currentStagedQueryData={currentStagedQueryData}
|
|
|
|
|
logs={logs}
|
|
|
|
|
onOpenDetailedView={handleSetActiveLog}
|
|
|
|
|
onEndReached={handleEndReached}
|
|
|
|
|
onExpand={handleSetActiveLog}
|
2023-07-13 15:55:43 +03:00
|
|
|
onAddToQuery={handleAddToQuery}
|
2023-07-06 14:22:44 +03:00
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-07 15:35:42 +03:00
|
|
|
label: <TabLabel label="Time Series" isDisabled={false} />,
|
2023-07-06 14:22:44 +03:00
|
|
|
key: PANEL_TYPES.TIME_SERIES,
|
|
|
|
|
children: (
|
|
|
|
|
<TimeSeriesView isLoading={isFetching} data={data} isError={isError} />
|
|
|
|
|
),
|
|
|
|
|
},
|
2023-07-14 12:31:25 +05:30
|
|
|
{
|
|
|
|
|
label: 'Table',
|
|
|
|
|
key: PANEL_TYPES.TABLE,
|
|
|
|
|
children: (
|
|
|
|
|
<LogsExplorerTable
|
|
|
|
|
data={data?.payload.data.newResult.data.result || []}
|
|
|
|
|
isLoading={isFetching}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
},
|
2023-07-06 14:22:44 +03:00
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
isMultipleQueries,
|
|
|
|
|
isGroupByExist,
|
|
|
|
|
isFetching,
|
|
|
|
|
currentStagedQueryData,
|
|
|
|
|
logs,
|
|
|
|
|
handleSetActiveLog,
|
|
|
|
|
handleEndReached,
|
2023-07-13 15:55:43 +03:00
|
|
|
handleAddToQuery,
|
2023-07-06 14:22:44 +03:00
|
|
|
data,
|
|
|
|
|
isError,
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const chartData = useMemo(() => {
|
|
|
|
|
if (!stagedQuery) return [];
|
|
|
|
|
|
|
|
|
|
if (panelType === PANEL_TYPES.LIST) {
|
|
|
|
|
if (
|
|
|
|
|
listChartData &&
|
|
|
|
|
listChartData.data &&
|
|
|
|
|
listChartData.data.payload.data.result.length > 0
|
|
|
|
|
) {
|
|
|
|
|
return listChartData.data.payload.data.result;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!data || data.payload.data.result.length === 0) return [];
|
|
|
|
|
|
|
|
|
|
const isGroupByExist = stagedQuery.builder.queryData.some(
|
|
|
|
|
(queryData) => queryData.groupBy.length > 0,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return isGroupByExist
|
|
|
|
|
? data.payload.data.result
|
|
|
|
|
: [data.payload.data.result[0]];
|
|
|
|
|
}, [stagedQuery, data, panelType, listChartData]);
|
|
|
|
|
|
2023-06-23 11:19:53 +03:00
|
|
|
return (
|
2023-07-06 14:22:44 +03:00
|
|
|
<>
|
|
|
|
|
<LogsExplorerChart isLoading={isFetching} data={chartData} />
|
2023-07-07 20:59:35 +05:30
|
|
|
{stagedQuery && (
|
|
|
|
|
<ActionsWrapper>
|
|
|
|
|
<ExportPanel
|
|
|
|
|
query={exportDefaultQuery}
|
|
|
|
|
isLoading={isUpdateDashboardLoading}
|
|
|
|
|
onExport={handleExport}
|
|
|
|
|
/>
|
|
|
|
|
</ActionsWrapper>
|
|
|
|
|
)}
|
2023-06-23 11:19:53 +03:00
|
|
|
<TabsStyled
|
|
|
|
|
items={tabsItems}
|
|
|
|
|
defaultActiveKey={panelType || PANEL_TYPES.LIST}
|
|
|
|
|
activeKey={panelType || PANEL_TYPES.LIST}
|
|
|
|
|
onChange={handleChangeView}
|
2023-07-06 14:22:44 +03:00
|
|
|
destroyInactiveTabPane
|
2023-06-23 11:19:53 +03:00
|
|
|
/>
|
2023-07-12 16:59:33 +03:00
|
|
|
<LogDetail
|
|
|
|
|
log={activeLog}
|
|
|
|
|
onClose={handleClearActiveLog}
|
2023-07-13 15:55:43 +03:00
|
|
|
onAddToQuery={handleAddToQuery}
|
|
|
|
|
onClickActionItem={handleAddToQuery}
|
2023-07-12 16:59:33 +03:00
|
|
|
/>
|
2023-07-06 14:22:44 +03:00
|
|
|
</>
|
2023-06-23 11:19:53 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default memo(LogsExplorerViews);
|