fix: click on field in the list item (#3120)

This commit is contained in:
Yevhen Shevchenko 2023-07-12 16:59:33 +03:00 committed by GitHub
parent 7818f918a8
commit 8e20ca8405
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 115 deletions

View File

@ -2,25 +2,19 @@ import { blue, grey, orange } from '@ant-design/colors';
import { CopyFilled, ExpandAltOutlined } from '@ant-design/icons';
import Convert from 'ansi-to-html';
import { Button, Divider, Row, Typography } from 'antd';
import ROUTES from 'constants/routes';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
import { useNotifications } from 'hooks/useNotifications';
// utils
import { FlatLogData } from 'lib/logs/flatLogData';
import { generateFilterQuery } from 'lib/logs/generateFilterQuery';
import { useCallback, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { useCopyToClipboard } from 'react-use';
import { AppState } from 'store/reducers';
// interfaces
import { IField } from 'types/api/logs/fields';
import { ILog } from 'types/api/logs/log';
import { ILogsReducer } from 'types/reducer/logs';
// components
import AddToQueryHOC from '../AddToQueryHOC';
import AddToQueryHOC, { AddToQueryHOCProps } from '../AddToQueryHOC';
import CopyClipboardHOC from '../CopyClipboardHOC';
// styles
import {
@ -39,6 +33,10 @@ interface LogFieldProps {
fieldKey: string;
fieldValue: string;
}
type LogSelectedFieldProps = LogFieldProps &
Pick<AddToQueryHOCProps, 'onAddToQuery'>;
function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
const html = useMemo(
() => ({
@ -62,37 +60,14 @@ function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
function LogSelectedField({
fieldKey = '',
fieldValue = '',
}: LogFieldProps): JSX.Element {
const history = useHistory();
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],
);
onAddToQuery,
}: LogSelectedFieldProps): JSX.Element {
return (
<SelectedLog>
<AddToQueryHOC
fieldKey={fieldKey}
fieldValue={fieldValue}
onAddToQuery={handleQueryAdd}
onAddToQuery={onAddToQuery}
>
<Typography.Text>
<span style={{ color: blue[4] }}>{fieldKey}</span>
@ -108,15 +83,17 @@ function LogSelectedField({
);
}
interface ListLogViewProps {
type ListLogViewProps = {
logData: ILog;
onOpenDetailedView: (log: ILog) => void;
selectedFields: IField[];
}
} & Pick<AddToQueryHOCProps, 'onAddToQuery'>;
function ListLogView({
logData,
selectedFields,
onOpenDetailedView,
onAddToQuery,
}: ListLogViewProps): JSX.Element {
const flattenLogData = useMemo(() => FlatLogData(logData), [logData]);
@ -166,6 +143,7 @@ function ListLogView({
key={field.name}
fieldKey={field.name}
fieldValue={flattenLogData[field.name] as never}
onAddToQuery={onAddToQuery}
/>
) : null,
)}

View File

@ -1,6 +0,0 @@
import { ILog } from 'types/api/logs/log';
export type LogExplorerDetailedViewProps = {
log: ILog | null;
onClose: () => void;
};

View File

@ -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;

View File

@ -1,3 +1,4 @@
import { AddToQueryHOCProps } from 'components/Logs/AddToQueryHOC';
import { ILog } from 'types/api/logs/log';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
@ -8,4 +9,4 @@ export type LogsExplorerListProps = {
onEndReached: (index: number) => void;
onExpand: (log: ILog) => void;
onOpenDetailedView: (log: ILog) => void;
};
} & Pick<AddToQueryHOCProps, 'onAddToQuery'>;

View File

@ -32,6 +32,7 @@ function LogsExplorerList({
onOpenDetailedView,
onEndReached,
onExpand,
onAddToQuery,
}: LogsExplorerListProps): JSX.Element {
const { initialDataSource } = useQueryBuilder();
@ -79,6 +80,7 @@ function LogsExplorerList({
logData={log}
selectedFields={selectedFields}
onOpenDetailedView={onOpenDetailedView}
onAddToQuery={onAddToQuery}
/>
);
},
@ -87,6 +89,7 @@ function LogsExplorerList({
options.maxLines,
selectedFields,
onOpenDetailedView,
onAddToQuery,
onExpand,
],
);

View File

@ -1,13 +1,17 @@
import { TabsProps } from 'antd';
import axios from 'axios';
import LogDetail from 'components/LogDetail';
import TabLabel from 'components/TabLabel';
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 ROUTES from 'constants/routes';
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
import ExportPanel from 'container/ExportPanel';
import LogExplorerDetailedView from 'container/LogExplorerDetailedView';
import LogsExplorerChart from 'container/LogsExplorerChart';
import LogsExplorerList from 'container/LogsExplorerList';
// TODO: temporary hide table view
@ -20,13 +24,20 @@ import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQuery
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useNotifications } from 'hooks/useNotifications';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
import { getPaginationQueryData } from 'lib/newQueryBuilder/getPaginationQueryData';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useQueryClient } from 'react-query';
import { useSelector } from 'react-redux';
import { generatePath, useHistory } from 'react-router-dom';
import { AppState } from 'store/reducers';
import { SuccessResponse } from 'types/api';
import { Dashboard } from 'types/api/dashboard/getAll';
import { ILog } from 'types/api/logs/log';
import {
BaseAutocompleteData,
IQueryAutocompleteResponse,
} from 'types/api/queryBuilder/queryAutocompleteResponse';
import {
IBuilderQuery,
OrderByPayload,
@ -34,6 +45,7 @@ import {
} from 'types/api/queryBuilder/queryBuilderData';
import { DataSource, StringOperators } from 'types/common/queryBuilder';
import { GlobalReducer } from 'types/reducer/globalTime';
import { v4 as uuid } from 'uuid';
import { ActionsWrapper, TabsStyled } from './LogsExplorerViews.styled';
@ -41,6 +53,8 @@ function LogsExplorerViews(): JSX.Element {
const { notifications } = useNotifications();
const history = useHistory();
const queryClient = useQueryClient();
const { queryData: pageSize } = useUrlQueryData(
queryParamNamesMap.pageSize,
DEFAULT_PER_PAGE_VALUE,
@ -212,6 +226,48 @@ function LogsExplorerViews(): JSX.Element {
[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(
(index: number) => {
if (isLimit) return;
@ -365,6 +421,7 @@ function LogsExplorerViews(): JSX.Element {
onOpenDetailedView={handleSetActiveLog}
onEndReached={handleEndReached}
onExpand={handleSetActiveLog}
onAddToQuery={handleAddQuery}
/>
),
},
@ -395,6 +452,7 @@ function LogsExplorerViews(): JSX.Element {
logs,
handleSetActiveLog,
handleEndReached,
handleAddQuery,
data,
isError,
],
@ -444,7 +502,11 @@ function LogsExplorerViews(): JSX.Element {
onChange={handleChangeView}
destroyInactiveTabPane
/>
<LogExplorerDetailedView log={activeLog} onClose={handleClearActiveLog} />
<LogDetail
log={activeLog}
onClose={handleClearActiveLog}
onAddToQuery={handleAddQuery}
/>
</>
);
}

View File

@ -4,10 +4,13 @@ import ListLogView from 'components/Logs/ListLogView';
import RawLogView from 'components/Logs/RawLogView';
import LogsTableView from 'components/Logs/TableView';
import Spinner from 'components/Spinner';
import ROUTES from 'constants/routes';
import { contentStyle } from 'container/Trace/Search/config';
import useFontFaceObserver from 'hooks/useFontObserver';
import { generateFilterQuery } from 'lib/logs/generateFilterQuery';
import { memo, useCallback, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { Virtuoso } from 'react-virtuoso';
import { AppState } from 'store/reducers';
// interfaces
@ -29,6 +32,8 @@ type LogsTableProps = {
function LogsTable(props: LogsTableProps): JSX.Element {
const { viewMode, onClickExpand, linesPerRow } = props;
const history = useHistory();
const dispatch = useDispatch();
useFontFaceObserver(
@ -47,6 +52,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
const {
logs,
fields: { selected },
searchFilter: { queryString },
isLoading,
liveTail,
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
@ -71,6 +77,25 @@ function LogsTable(props: LogsTableProps): JSX.Element {
[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(
(index: number): JSX.Element => {
const log = logs[index];
@ -92,6 +117,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
logData={log}
selectedFields={selected}
onOpenDetailedView={handleOpenDetailedView}
onAddToQuery={handleQueryAdd}
/>
);
},
@ -99,9 +125,10 @@ function LogsTable(props: LogsTableProps): JSX.Element {
logs,
viewMode,
selected,
handleOpenDetailedView,
linesPerRow,
onClickExpand,
handleOpenDetailedView,
handleQueryAdd,
],
);