mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 19:55:56 +08:00
fix: click on field in the list item (#3120)
This commit is contained in:
parent
7818f918a8
commit
8e20ca8405
@ -2,25 +2,19 @@ import { blue, grey, orange } from '@ant-design/colors';
|
|||||||
import { CopyFilled, ExpandAltOutlined } from '@ant-design/icons';
|
import { CopyFilled, ExpandAltOutlined } from '@ant-design/icons';
|
||||||
import Convert from 'ansi-to-html';
|
import Convert from 'ansi-to-html';
|
||||||
import { Button, Divider, Row, Typography } from 'antd';
|
import { Button, Divider, Row, Typography } from 'antd';
|
||||||
import ROUTES from 'constants/routes';
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import dompurify from 'dompurify';
|
import dompurify from 'dompurify';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
// utils
|
// utils
|
||||||
import { FlatLogData } from 'lib/logs/flatLogData';
|
import { FlatLogData } from 'lib/logs/flatLogData';
|
||||||
import { generateFilterQuery } from 'lib/logs/generateFilterQuery';
|
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyToClipboard } from 'react-use';
|
||||||
import { AppState } from 'store/reducers';
|
|
||||||
// interfaces
|
// interfaces
|
||||||
import { IField } from 'types/api/logs/fields';
|
import { IField } from 'types/api/logs/fields';
|
||||||
import { ILog } from 'types/api/logs/log';
|
import { ILog } from 'types/api/logs/log';
|
||||||
import { ILogsReducer } from 'types/reducer/logs';
|
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import AddToQueryHOC from '../AddToQueryHOC';
|
import AddToQueryHOC, { AddToQueryHOCProps } from '../AddToQueryHOC';
|
||||||
import CopyClipboardHOC from '../CopyClipboardHOC';
|
import CopyClipboardHOC from '../CopyClipboardHOC';
|
||||||
// styles
|
// styles
|
||||||
import {
|
import {
|
||||||
@ -39,6 +33,10 @@ interface LogFieldProps {
|
|||||||
fieldKey: string;
|
fieldKey: string;
|
||||||
fieldValue: string;
|
fieldValue: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LogSelectedFieldProps = LogFieldProps &
|
||||||
|
Pick<AddToQueryHOCProps, 'onAddToQuery'>;
|
||||||
|
|
||||||
function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
|
function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
|
||||||
const html = useMemo(
|
const html = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@ -62,37 +60,14 @@ function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
|
|||||||
function LogSelectedField({
|
function LogSelectedField({
|
||||||
fieldKey = '',
|
fieldKey = '',
|
||||||
fieldValue = '',
|
fieldValue = '',
|
||||||
}: LogFieldProps): JSX.Element {
|
onAddToQuery,
|
||||||
const history = useHistory();
|
}: LogSelectedFieldProps): JSX.Element {
|
||||||
const {
|
|
||||||
searchFilter: { queryString },
|
|
||||||
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
|
|
||||||
|
|
||||||
const handleQueryAdd = useCallback(
|
|
||||||
(fieldKey: string, fieldValue: string) => {
|
|
||||||
const generatedQuery = generateFilterQuery({
|
|
||||||
fieldKey,
|
|
||||||
fieldValue,
|
|
||||||
type: 'IN',
|
|
||||||
});
|
|
||||||
|
|
||||||
let updatedQueryString = queryString || '';
|
|
||||||
if (updatedQueryString.length === 0) {
|
|
||||||
updatedQueryString += `${generatedQuery}`;
|
|
||||||
} else {
|
|
||||||
updatedQueryString += ` AND ${generatedQuery}`;
|
|
||||||
}
|
|
||||||
history.replace(`${ROUTES.LOGS}?q=${updatedQueryString}`);
|
|
||||||
},
|
|
||||||
[history, queryString],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectedLog>
|
<SelectedLog>
|
||||||
<AddToQueryHOC
|
<AddToQueryHOC
|
||||||
fieldKey={fieldKey}
|
fieldKey={fieldKey}
|
||||||
fieldValue={fieldValue}
|
fieldValue={fieldValue}
|
||||||
onAddToQuery={handleQueryAdd}
|
onAddToQuery={onAddToQuery}
|
||||||
>
|
>
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
<span style={{ color: blue[4] }}>{fieldKey}</span>
|
<span style={{ color: blue[4] }}>{fieldKey}</span>
|
||||||
@ -108,15 +83,17 @@ function LogSelectedField({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListLogViewProps {
|
type ListLogViewProps = {
|
||||||
logData: ILog;
|
logData: ILog;
|
||||||
onOpenDetailedView: (log: ILog) => void;
|
onOpenDetailedView: (log: ILog) => void;
|
||||||
selectedFields: IField[];
|
selectedFields: IField[];
|
||||||
}
|
} & Pick<AddToQueryHOCProps, 'onAddToQuery'>;
|
||||||
|
|
||||||
function ListLogView({
|
function ListLogView({
|
||||||
logData,
|
logData,
|
||||||
selectedFields,
|
selectedFields,
|
||||||
onOpenDetailedView,
|
onOpenDetailedView,
|
||||||
|
onAddToQuery,
|
||||||
}: ListLogViewProps): JSX.Element {
|
}: ListLogViewProps): JSX.Element {
|
||||||
const flattenLogData = useMemo(() => FlatLogData(logData), [logData]);
|
const flattenLogData = useMemo(() => FlatLogData(logData), [logData]);
|
||||||
|
|
||||||
@ -166,6 +143,7 @@ function ListLogView({
|
|||||||
key={field.name}
|
key={field.name}
|
||||||
fieldKey={field.name}
|
fieldKey={field.name}
|
||||||
fieldValue={flattenLogData[field.name] as never}
|
fieldValue={flattenLogData[field.name] as never}
|
||||||
|
onAddToQuery={onAddToQuery}
|
||||||
/>
|
/>
|
||||||
) : null,
|
) : null,
|
||||||
)}
|
)}
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import { ILog } from 'types/api/logs/log';
|
|
||||||
|
|
||||||
export type LogExplorerDetailedViewProps = {
|
|
||||||
log: ILog | null;
|
|
||||||
onClose: () => void;
|
|
||||||
};
|
|
@ -1,69 +0,0 @@
|
|||||||
import LogDetail from 'components/LogDetail';
|
|
||||||
import { QueryBuilderKeys } from 'constants/queryBuilder';
|
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|
||||||
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { useQueryClient } from 'react-query';
|
|
||||||
import { SuccessResponse } from 'types/api';
|
|
||||||
import {
|
|
||||||
BaseAutocompleteData,
|
|
||||||
IQueryAutocompleteResponse,
|
|
||||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
|
||||||
import { v4 as uuid } from 'uuid';
|
|
||||||
|
|
||||||
import { LogExplorerDetailedViewProps } from './LogExplorerDetailedView.interfaces';
|
|
||||||
|
|
||||||
function LogExplorerDetailedView({
|
|
||||||
log,
|
|
||||||
onClose,
|
|
||||||
}: LogExplorerDetailedViewProps): JSX.Element {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
const { redirectWithQueryBuilderData, currentQuery } = useQueryBuilder();
|
|
||||||
|
|
||||||
const handleAddQuery = useCallback(
|
|
||||||
(fieldKey: string, fieldValue: string): void => {
|
|
||||||
const keysAutocomplete: BaseAutocompleteData[] =
|
|
||||||
queryClient.getQueryData<SuccessResponse<IQueryAutocompleteResponse>>(
|
|
||||||
[QueryBuilderKeys.GET_AGGREGATE_KEYS],
|
|
||||||
{ exact: false },
|
|
||||||
)?.payload.attributeKeys || [];
|
|
||||||
|
|
||||||
const existAutocompleteKey = chooseAutocompleteFromCustomValue(
|
|
||||||
keysAutocomplete,
|
|
||||||
fieldKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
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,
|
|
||||||
op: '=',
|
|
||||||
value: fieldValue,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
redirectWithQueryBuilderData(nextQuery);
|
|
||||||
},
|
|
||||||
[currentQuery, queryClient, redirectWithQueryBuilderData],
|
|
||||||
);
|
|
||||||
|
|
||||||
return <LogDetail log={log} onClose={onClose} onAddToQuery={handleAddQuery} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LogExplorerDetailedView;
|
|
@ -1,3 +1,4 @@
|
|||||||
|
import { AddToQueryHOCProps } from 'components/Logs/AddToQueryHOC';
|
||||||
import { ILog } from 'types/api/logs/log';
|
import { ILog } from 'types/api/logs/log';
|
||||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
@ -8,4 +9,4 @@ export type LogsExplorerListProps = {
|
|||||||
onEndReached: (index: number) => void;
|
onEndReached: (index: number) => void;
|
||||||
onExpand: (log: ILog) => void;
|
onExpand: (log: ILog) => void;
|
||||||
onOpenDetailedView: (log: ILog) => void;
|
onOpenDetailedView: (log: ILog) => void;
|
||||||
};
|
} & Pick<AddToQueryHOCProps, 'onAddToQuery'>;
|
||||||
|
@ -32,6 +32,7 @@ function LogsExplorerList({
|
|||||||
onOpenDetailedView,
|
onOpenDetailedView,
|
||||||
onEndReached,
|
onEndReached,
|
||||||
onExpand,
|
onExpand,
|
||||||
|
onAddToQuery,
|
||||||
}: LogsExplorerListProps): JSX.Element {
|
}: LogsExplorerListProps): JSX.Element {
|
||||||
const { initialDataSource } = useQueryBuilder();
|
const { initialDataSource } = useQueryBuilder();
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ function LogsExplorerList({
|
|||||||
logData={log}
|
logData={log}
|
||||||
selectedFields={selectedFields}
|
selectedFields={selectedFields}
|
||||||
onOpenDetailedView={onOpenDetailedView}
|
onOpenDetailedView={onOpenDetailedView}
|
||||||
|
onAddToQuery={onAddToQuery}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -87,6 +89,7 @@ function LogsExplorerList({
|
|||||||
options.maxLines,
|
options.maxLines,
|
||||||
selectedFields,
|
selectedFields,
|
||||||
onOpenDetailedView,
|
onOpenDetailedView,
|
||||||
|
onAddToQuery,
|
||||||
onExpand,
|
onExpand,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
import { TabsProps } from 'antd';
|
import { TabsProps } from 'antd';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import LogDetail from 'components/LogDetail';
|
||||||
import TabLabel from 'components/TabLabel';
|
import TabLabel from 'components/TabLabel';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
import {
|
||||||
|
initialQueriesMap,
|
||||||
|
PANEL_TYPES,
|
||||||
|
QueryBuilderKeys,
|
||||||
|
} from 'constants/queryBuilder';
|
||||||
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
|
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
|
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
|
||||||
import ExportPanel from 'container/ExportPanel';
|
import ExportPanel from 'container/ExportPanel';
|
||||||
import LogExplorerDetailedView from 'container/LogExplorerDetailedView';
|
|
||||||
import LogsExplorerChart from 'container/LogsExplorerChart';
|
import LogsExplorerChart from 'container/LogsExplorerChart';
|
||||||
import LogsExplorerList from 'container/LogsExplorerList';
|
import LogsExplorerList from 'container/LogsExplorerList';
|
||||||
// TODO: temporary hide table view
|
// TODO: temporary hide table view
|
||||||
@ -20,13 +24,20 @@ import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQuery
|
|||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import useUrlQueryData from 'hooks/useUrlQueryData';
|
import useUrlQueryData from 'hooks/useUrlQueryData';
|
||||||
|
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
|
||||||
import { getPaginationQueryData } from 'lib/newQueryBuilder/getPaginationQueryData';
|
import { getPaginationQueryData } from 'lib/newQueryBuilder/getPaginationQueryData';
|
||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
import { useQueryClient } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { generatePath, useHistory } from 'react-router-dom';
|
import { generatePath, useHistory } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
|
import { SuccessResponse } from 'types/api';
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
import { ILog } from 'types/api/logs/log';
|
import { ILog } from 'types/api/logs/log';
|
||||||
|
import {
|
||||||
|
BaseAutocompleteData,
|
||||||
|
IQueryAutocompleteResponse,
|
||||||
|
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import {
|
import {
|
||||||
IBuilderQuery,
|
IBuilderQuery,
|
||||||
OrderByPayload,
|
OrderByPayload,
|
||||||
@ -34,6 +45,7 @@ import {
|
|||||||
} from 'types/api/queryBuilder/queryBuilderData';
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
import { ActionsWrapper, TabsStyled } from './LogsExplorerViews.styled';
|
import { ActionsWrapper, TabsStyled } from './LogsExplorerViews.styled';
|
||||||
|
|
||||||
@ -41,6 +53,8 @@ function LogsExplorerViews(): JSX.Element {
|
|||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const { queryData: pageSize } = useUrlQueryData(
|
const { queryData: pageSize } = useUrlQueryData(
|
||||||
queryParamNamesMap.pageSize,
|
queryParamNamesMap.pageSize,
|
||||||
DEFAULT_PER_PAGE_VALUE,
|
DEFAULT_PER_PAGE_VALUE,
|
||||||
@ -212,6 +226,48 @@ function LogsExplorerViews(): JSX.Element {
|
|||||||
[currentStagedQueryData, orderByTimestamp],
|
[currentStagedQueryData, orderByTimestamp],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleAddQuery = useCallback(
|
||||||
|
(fieldKey: string, fieldValue: string): void => {
|
||||||
|
const keysAutocomplete: BaseAutocompleteData[] =
|
||||||
|
queryClient.getQueryData<SuccessResponse<IQueryAutocompleteResponse>>(
|
||||||
|
[QueryBuilderKeys.GET_AGGREGATE_KEYS],
|
||||||
|
{ exact: false },
|
||||||
|
)?.payload.attributeKeys || [];
|
||||||
|
|
||||||
|
const existAutocompleteKey = chooseAutocompleteFromCustomValue(
|
||||||
|
keysAutocomplete,
|
||||||
|
fieldKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
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,
|
||||||
|
op: '=',
|
||||||
|
value: fieldValue,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
redirectWithQueryBuilderData(nextQuery);
|
||||||
|
},
|
||||||
|
[currentQuery, queryClient, redirectWithQueryBuilderData],
|
||||||
|
);
|
||||||
|
|
||||||
const handleEndReached = useCallback(
|
const handleEndReached = useCallback(
|
||||||
(index: number) => {
|
(index: number) => {
|
||||||
if (isLimit) return;
|
if (isLimit) return;
|
||||||
@ -365,6 +421,7 @@ function LogsExplorerViews(): JSX.Element {
|
|||||||
onOpenDetailedView={handleSetActiveLog}
|
onOpenDetailedView={handleSetActiveLog}
|
||||||
onEndReached={handleEndReached}
|
onEndReached={handleEndReached}
|
||||||
onExpand={handleSetActiveLog}
|
onExpand={handleSetActiveLog}
|
||||||
|
onAddToQuery={handleAddQuery}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -395,6 +452,7 @@ function LogsExplorerViews(): JSX.Element {
|
|||||||
logs,
|
logs,
|
||||||
handleSetActiveLog,
|
handleSetActiveLog,
|
||||||
handleEndReached,
|
handleEndReached,
|
||||||
|
handleAddQuery,
|
||||||
data,
|
data,
|
||||||
isError,
|
isError,
|
||||||
],
|
],
|
||||||
@ -444,7 +502,11 @@ function LogsExplorerViews(): JSX.Element {
|
|||||||
onChange={handleChangeView}
|
onChange={handleChangeView}
|
||||||
destroyInactiveTabPane
|
destroyInactiveTabPane
|
||||||
/>
|
/>
|
||||||
<LogExplorerDetailedView log={activeLog} onClose={handleClearActiveLog} />
|
<LogDetail
|
||||||
|
log={activeLog}
|
||||||
|
onClose={handleClearActiveLog}
|
||||||
|
onAddToQuery={handleAddQuery}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,13 @@ import ListLogView from 'components/Logs/ListLogView';
|
|||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
import LogsTableView from 'components/Logs/TableView';
|
import LogsTableView from 'components/Logs/TableView';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
|
import ROUTES from 'constants/routes';
|
||||||
import { contentStyle } from 'container/Trace/Search/config';
|
import { contentStyle } from 'container/Trace/Search/config';
|
||||||
import useFontFaceObserver from 'hooks/useFontObserver';
|
import useFontFaceObserver from 'hooks/useFontObserver';
|
||||||
|
import { generateFilterQuery } from 'lib/logs/generateFilterQuery';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
// interfaces
|
// interfaces
|
||||||
@ -29,6 +32,8 @@ type LogsTableProps = {
|
|||||||
function LogsTable(props: LogsTableProps): JSX.Element {
|
function LogsTable(props: LogsTableProps): JSX.Element {
|
||||||
const { viewMode, onClickExpand, linesPerRow } = props;
|
const { viewMode, onClickExpand, linesPerRow } = props;
|
||||||
|
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
useFontFaceObserver(
|
useFontFaceObserver(
|
||||||
@ -47,6 +52,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
|
|||||||
const {
|
const {
|
||||||
logs,
|
logs,
|
||||||
fields: { selected },
|
fields: { selected },
|
||||||
|
searchFilter: { queryString },
|
||||||
isLoading,
|
isLoading,
|
||||||
liveTail,
|
liveTail,
|
||||||
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
|
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
|
||||||
@ -71,6 +77,25 @@ function LogsTable(props: LogsTableProps): JSX.Element {
|
|||||||
[dispatch],
|
[dispatch],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleQueryAdd = useCallback(
|
||||||
|
(fieldKey: string, fieldValue: string) => {
|
||||||
|
const generatedQuery = generateFilterQuery({
|
||||||
|
fieldKey,
|
||||||
|
fieldValue,
|
||||||
|
type: 'IN',
|
||||||
|
});
|
||||||
|
|
||||||
|
let updatedQueryString = queryString || '';
|
||||||
|
if (updatedQueryString.length === 0) {
|
||||||
|
updatedQueryString += `${generatedQuery}`;
|
||||||
|
} else {
|
||||||
|
updatedQueryString += ` AND ${generatedQuery}`;
|
||||||
|
}
|
||||||
|
history.replace(`${ROUTES.LOGS}?q=${updatedQueryString}`);
|
||||||
|
},
|
||||||
|
[history, queryString],
|
||||||
|
);
|
||||||
|
|
||||||
const getItemContent = useCallback(
|
const getItemContent = useCallback(
|
||||||
(index: number): JSX.Element => {
|
(index: number): JSX.Element => {
|
||||||
const log = logs[index];
|
const log = logs[index];
|
||||||
@ -92,6 +117,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
|
|||||||
logData={log}
|
logData={log}
|
||||||
selectedFields={selected}
|
selectedFields={selected}
|
||||||
onOpenDetailedView={handleOpenDetailedView}
|
onOpenDetailedView={handleOpenDetailedView}
|
||||||
|
onAddToQuery={handleQueryAdd}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -99,9 +125,10 @@ function LogsTable(props: LogsTableProps): JSX.Element {
|
|||||||
logs,
|
logs,
|
||||||
viewMode,
|
viewMode,
|
||||||
selected,
|
selected,
|
||||||
handleOpenDetailedView,
|
|
||||||
linesPerRow,
|
linesPerRow,
|
||||||
onClickExpand,
|
onClickExpand,
|
||||||
|
handleOpenDetailedView,
|
||||||
|
handleQueryAdd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user