mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 03:29:02 +08:00
feat: added global search on table panel (#5893)
* feat: added global search on table panel * feat: added global search on table panel * feat: added global search conditionally and with new design * feat: removed state from datasource * feat: added global search in full view * feat: added lightMode styles * feat: added test cases for querytable and widgetHeader - global search
This commit is contained in:
parent
ced72f86a4
commit
cb1cd3555b
@ -15,6 +15,13 @@
|
||||
box-sizing: border-box;
|
||||
margin: 16px 0;
|
||||
border-radius: 3px;
|
||||
|
||||
.global-search {
|
||||
.ant-input-group-addon {
|
||||
border: none;
|
||||
background-color: var(--bg-ink-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.height-widget {
|
||||
@ -55,3 +62,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.full-view-container {
|
||||
.graph-container {
|
||||
.global-search {
|
||||
.ant-input-group-addon {
|
||||
background-color: var(--bg-vanilla-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
import './WidgetFullView.styles.scss';
|
||||
|
||||
import { LoadingOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
import { Button, Spin } from 'antd';
|
||||
import {
|
||||
LoadingOutlined,
|
||||
SearchOutlined,
|
||||
SyncOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Input, Spin } from 'antd';
|
||||
import cx from 'classnames';
|
||||
import { ToggleGraphProps } from 'components/Graph/types';
|
||||
import Spinner from 'components/Spinner';
|
||||
@ -172,6 +176,10 @@ function FullView({
|
||||
|
||||
const isListView = widget.panelTypes === PANEL_TYPES.LIST;
|
||||
|
||||
const isTablePanel = widget.panelTypes === PANEL_TYPES.TABLE;
|
||||
|
||||
const [searchTerm, setSearchTerm] = useState<string>('');
|
||||
|
||||
if (response.isLoading && widget.panelTypes !== PANEL_TYPES.LIST) {
|
||||
return <Spinner height="100%" size="large" tip="Loading..." />;
|
||||
}
|
||||
@ -216,6 +224,18 @@ function FullView({
|
||||
}}
|
||||
isGraphLegendToggleAvailable={canModifyChart}
|
||||
>
|
||||
{isTablePanel && (
|
||||
<Input
|
||||
addonBefore={<SearchOutlined size={14} />}
|
||||
className="global-search"
|
||||
placeholder="Search..."
|
||||
allowClear
|
||||
key={widget.id}
|
||||
onChange={(e): void => {
|
||||
setSearchTerm(e.target.value || '');
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<PanelWrapper
|
||||
queryResponse={response}
|
||||
widget={widget}
|
||||
@ -226,6 +246,7 @@ function FullView({
|
||||
graphVisibility={graphsVisibilityStates}
|
||||
onDragSelect={onDragSelect}
|
||||
tableProcessedDataRef={tableProcessedDataRef}
|
||||
searchTerm={searchTerm}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</div>
|
||||
|
@ -234,6 +234,8 @@ function WidgetGraphComponent({
|
||||
});
|
||||
};
|
||||
|
||||
const [searchTerm, setSearchTerm] = useState<string>('');
|
||||
|
||||
const loadingState =
|
||||
(queryResponse.isLoading || queryResponse.status === 'idle') &&
|
||||
widget.panelTypes !== PANEL_TYPES.LIST;
|
||||
@ -317,6 +319,7 @@ function WidgetGraphComponent({
|
||||
isWarning={isWarning}
|
||||
isFetchingResponse={isFetchingResponse}
|
||||
tableProcessedDataRef={tableProcessedDataRef}
|
||||
setSearchTerm={setSearchTerm}
|
||||
/>
|
||||
</div>
|
||||
{queryResponse.isLoading && widget.panelTypes !== PANEL_TYPES.LIST && (
|
||||
@ -337,6 +340,7 @@ function WidgetGraphComponent({
|
||||
onDragSelect={onDragSelect}
|
||||
tableProcessedDataRef={tableProcessedDataRef}
|
||||
customTooltipElement={customTooltipElement}
|
||||
searchTerm={searchTerm}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -2,7 +2,7 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
height: 36px;
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
box-sizing: border-box;
|
||||
@ -10,6 +10,14 @@
|
||||
font-weight: 600;
|
||||
|
||||
cursor: move;
|
||||
|
||||
.ant-input-group-addon {
|
||||
border: none;
|
||||
background-color: var(--bg-ink-500);
|
||||
}
|
||||
.search-header-icons {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-header-title {
|
||||
@ -19,6 +27,7 @@
|
||||
.widget-header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.widget-header-more-options {
|
||||
visibility: hidden;
|
||||
@ -30,6 +39,10 @@
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.widget-header-more-options-visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.widget-header-hover {
|
||||
visibility: visible;
|
||||
}
|
||||
@ -37,3 +50,11 @@
|
||||
.widget-api-actions {
|
||||
padding-right: 0.25rem;
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.widget-header-container {
|
||||
.ant-input-group-addon {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,10 @@ import {
|
||||
ExclamationCircleOutlined,
|
||||
FullscreenOutlined,
|
||||
MoreOutlined,
|
||||
SearchOutlined,
|
||||
WarningOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Dropdown, MenuProps, Tooltip, Typography } from 'antd';
|
||||
import { Dropdown, Input, MenuProps, Tooltip, Typography } from 'antd';
|
||||
import Spinner from 'components/Spinner';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
@ -20,8 +21,9 @@ import useComponentPermission from 'hooks/useComponentPermission';
|
||||
import history from 'lib/history';
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { X } from 'lucide-react';
|
||||
import { unparse } from 'papaparse';
|
||||
import { ReactNode, useCallback, useMemo } from 'react';
|
||||
import { ReactNode, useCallback, useMemo, useState } from 'react';
|
||||
import { UseQueryResult } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
@ -51,6 +53,7 @@ interface IWidgetHeaderProps {
|
||||
isWarning: boolean;
|
||||
isFetchingResponse: boolean;
|
||||
tableProcessedDataRef: React.MutableRefObject<RowData[]>;
|
||||
setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
|
||||
}
|
||||
|
||||
function WidgetHeader({
|
||||
@ -67,6 +70,7 @@ function WidgetHeader({
|
||||
isWarning,
|
||||
isFetchingResponse,
|
||||
tableProcessedDataRef,
|
||||
setSearchTerm,
|
||||
}: IWidgetHeaderProps): JSX.Element | null {
|
||||
const onEditHandler = useCallback((): void => {
|
||||
const widgetId = widget.id;
|
||||
@ -187,6 +191,10 @@ function WidgetHeader({
|
||||
|
||||
const updatedMenuList = useMemo(() => generateMenuList(actions), [actions]);
|
||||
|
||||
const [showGlobalSearch, setShowGlobalSearch] = useState(false);
|
||||
|
||||
const globalSearchAvailable = widget.panelTypes === PANEL_TYPES.TABLE;
|
||||
|
||||
const menu = useMemo(
|
||||
() => ({
|
||||
items: updatedMenuList,
|
||||
@ -201,6 +209,31 @@ function WidgetHeader({
|
||||
|
||||
return (
|
||||
<div className="widget-header-container">
|
||||
{showGlobalSearch ? (
|
||||
<Input
|
||||
addonBefore={<SearchOutlined size={14} />}
|
||||
placeholder="Search..."
|
||||
bordered={false}
|
||||
data-testid="widget-header-search-input"
|
||||
autoFocus
|
||||
addonAfter={
|
||||
<X
|
||||
size={14}
|
||||
onClick={(e): void => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
setShowGlobalSearch(false);
|
||||
}}
|
||||
className="search-header-icons"
|
||||
/>
|
||||
}
|
||||
key={widget.id}
|
||||
onChange={(e): void => {
|
||||
setSearchTerm(e.target.value || '');
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<Typography.Text
|
||||
ellipsis
|
||||
data-testid={title}
|
||||
@ -232,15 +265,24 @@ function WidgetHeader({
|
||||
<WarningOutlined />
|
||||
</Tooltip>
|
||||
)}
|
||||
{globalSearchAvailable && (
|
||||
<SearchOutlined
|
||||
className="search-header-icons"
|
||||
onClick={(): void => setShowGlobalSearch(true)}
|
||||
data-testid="widget-header-search"
|
||||
/>
|
||||
)}
|
||||
<Dropdown menu={menu} trigger={['hover']} placement="bottomRight">
|
||||
<MoreOutlined
|
||||
data-testid="widget-header-options"
|
||||
className={`widget-header-more-options ${
|
||||
parentHover ? 'widget-header-hover' : ''
|
||||
}`}
|
||||
} ${globalSearchAvailable ? 'widget-header-more-options-visible' : ''}`}
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ export type GridTableComponentProps = {
|
||||
columnUnits?: ColumnUnit;
|
||||
tableProcessedDataRef?: React.MutableRefObject<RowData[]>;
|
||||
sticky?: TableProps<RowData>['sticky'];
|
||||
searchTerm?: string;
|
||||
} & Pick<LogsExplorerTableProps, 'data'> &
|
||||
Omit<TableProps<RowData>, 'columns' | 'dataSource'>;
|
||||
|
||||
|
@ -16,6 +16,7 @@ function PanelWrapper({
|
||||
selectedGraph,
|
||||
tableProcessedDataRef,
|
||||
customTooltipElement,
|
||||
searchTerm,
|
||||
}: PanelWrapperProps): JSX.Element {
|
||||
const Component = PanelTypeVsPanelWrapper[
|
||||
selectedGraph || widget.panelTypes
|
||||
@ -39,6 +40,7 @@ function PanelWrapper({
|
||||
selectedGraph={selectedGraph}
|
||||
tableProcessedDataRef={tableProcessedDataRef}
|
||||
customTooltipElement={customTooltipElement}
|
||||
searchTerm={searchTerm}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ function TablePanelWrapper({
|
||||
widget,
|
||||
queryResponse,
|
||||
tableProcessedDataRef,
|
||||
searchTerm,
|
||||
}: PanelWrapperProps): JSX.Element {
|
||||
const panelData =
|
||||
(queryResponse.data?.payload?.data?.result?.[0] as any)?.table || [];
|
||||
@ -20,6 +21,7 @@ function TablePanelWrapper({
|
||||
columnUnits={widget.columnUnits}
|
||||
tableProcessedDataRef={tableProcessedDataRef}
|
||||
sticky={widget.panelTypes === PANEL_TYPES.TABLE}
|
||||
searchTerm={searchTerm}
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...GRID_TABLE_CONFIG}
|
||||
/>
|
||||
|
@ -23,6 +23,7 @@ export type PanelWrapperProps = {
|
||||
onDragSelect: (start: number, end: number) => void;
|
||||
selectedGraph?: PANEL_TYPES;
|
||||
tableProcessedDataRef?: React.MutableRefObject<RowData[]>;
|
||||
searchTerm?: string;
|
||||
customTooltipElement?: HTMLDivElement;
|
||||
};
|
||||
|
||||
|
@ -19,4 +19,5 @@ export type QueryTableProps = Omit<
|
||||
columns?: ColumnsType<RowData>;
|
||||
dataSource?: RowData[];
|
||||
sticky?: TableProps<RowData>['sticky'];
|
||||
searchTerm?: string;
|
||||
};
|
||||
|
@ -3,8 +3,11 @@ import './QueryTable.styles.scss';
|
||||
import { ResizeTable } from 'components/ResizeTable';
|
||||
import Download from 'container/Download/Download';
|
||||
import { IServiceName } from 'container/MetricsApplication/Tabs/types';
|
||||
import { createTableColumnsFromQuery } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
createTableColumnsFromQuery,
|
||||
RowData,
|
||||
} from 'lib/query/createTableColumnsFromQuery';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import { QueryTableProps } from './QueryTable.intefaces';
|
||||
@ -20,6 +23,7 @@ export function QueryTable({
|
||||
columns,
|
||||
dataSource,
|
||||
sticky,
|
||||
searchTerm,
|
||||
...props
|
||||
}: QueryTableProps): JSX.Element {
|
||||
const { isDownloadEnabled = false, fileName = '' } = downloadOption || {};
|
||||
@ -55,6 +59,27 @@ export function QueryTable({
|
||||
hideOnSinglePage: true,
|
||||
};
|
||||
|
||||
const [filterTable, setFilterTable] = useState<RowData[] | null>(null);
|
||||
|
||||
const onTableSearch = useCallback(
|
||||
(value?: string): void => {
|
||||
const filterTable = newDataSource.filter((o) =>
|
||||
Object.keys(o).some((k) =>
|
||||
String(o[k])
|
||||
.toLowerCase()
|
||||
.includes(value?.toLowerCase() || ''),
|
||||
),
|
||||
);
|
||||
|
||||
setFilterTable(filterTable);
|
||||
},
|
||||
[newDataSource],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
onTableSearch(searchTerm);
|
||||
}, [newDataSource, onTableSearch, searchTerm]);
|
||||
|
||||
return (
|
||||
<div className="query-table">
|
||||
{isDownloadEnabled && (
|
||||
@ -69,7 +94,7 @@ export function QueryTable({
|
||||
<ResizeTable
|
||||
columns={tableColumns}
|
||||
tableLayout="fixed"
|
||||
dataSource={newDataSource}
|
||||
dataSource={filterTable === null ? newDataSource : filterTable}
|
||||
scroll={{ x: true }}
|
||||
pagination={paginationConfig}
|
||||
sticky={sticky}
|
||||
|
@ -0,0 +1,73 @@
|
||||
/* eslint-disable react/jsx-props-no-spreading */
|
||||
import WidgetHeader from 'container/GridCardLayout/WidgetHeader';
|
||||
import { fireEvent, render } from 'tests/test-utils';
|
||||
|
||||
import { QueryTable } from '../QueryTable';
|
||||
import { QueryTableProps, WidgetHeaderProps } from './mocks';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useLocation: (): { pathname: string } => ({
|
||||
pathname: ``,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock useDashabord hook
|
||||
jest.mock('providers/Dashboard/Dashboard', () => ({
|
||||
useDashboard: (): any => ({
|
||||
selectedDashboard: {
|
||||
data: {
|
||||
variables: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('QueryTable -', () => {
|
||||
it('should render correctly with all the data rows', () => {
|
||||
const { container } = render(<QueryTable {...QueryTableProps} />);
|
||||
const tableRows = container.querySelectorAll('tr.ant-table-row');
|
||||
expect(tableRows.length).toBe(QueryTableProps.queryTableData.rows.length);
|
||||
});
|
||||
|
||||
it('should render correctly with searchTerm', () => {
|
||||
const { container } = render(
|
||||
<QueryTable {...QueryTableProps} searchTerm="frontend" />,
|
||||
);
|
||||
const tableRows = container.querySelectorAll('tr.ant-table-row');
|
||||
expect(tableRows.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
const setSearchTerm = jest.fn();
|
||||
describe('WidgetHeader -', () => {
|
||||
it('global search option should be working', () => {
|
||||
const { getByText, getByTestId } = render(
|
||||
<WidgetHeader {...WidgetHeaderProps} setSearchTerm={setSearchTerm} />,
|
||||
);
|
||||
expect(getByText('Table - Panel')).toBeInTheDocument();
|
||||
const searchWidget = getByTestId('widget-header-search');
|
||||
expect(searchWidget).toBeInTheDocument();
|
||||
// click and open the search input
|
||||
fireEvent.click(searchWidget);
|
||||
// check if input is opened
|
||||
const searchInput = getByTestId('widget-header-search-input');
|
||||
expect(searchInput).toBeInTheDocument();
|
||||
|
||||
// enter search term
|
||||
fireEvent.change(searchInput, { target: { value: 'frontend' } });
|
||||
// check if search term is set
|
||||
expect(setSearchTerm).toHaveBeenCalledWith('frontend');
|
||||
expect(searchInput).toHaveValue('frontend');
|
||||
});
|
||||
|
||||
it('global search should not be present for non-table panel', () => {
|
||||
const { queryByTestId } = render(
|
||||
<WidgetHeader
|
||||
{...WidgetHeaderProps}
|
||||
widget={{ ...WidgetHeaderProps.widget, panelTypes: 'chart' }}
|
||||
/>,
|
||||
);
|
||||
expect(queryByTestId('widget-header-search')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
797
frontend/src/container/QueryTable/__test__/mocks.ts
Normal file
797
frontend/src/container/QueryTable/__test__/mocks.ts
Normal file
@ -0,0 +1,797 @@
|
||||
/* eslint-disable sonarjs/no-duplicate-string */
|
||||
export const QueryTableProps: any = {
|
||||
props: {
|
||||
loading: false,
|
||||
size: 'small',
|
||||
},
|
||||
queryTableData: {
|
||||
columns: [
|
||||
{
|
||||
name: 'resource_host_name',
|
||||
queryName: '',
|
||||
isValueColumn: false,
|
||||
},
|
||||
{
|
||||
name: 'service_name',
|
||||
queryName: '',
|
||||
isValueColumn: false,
|
||||
},
|
||||
{
|
||||
name: 'operation',
|
||||
queryName: '',
|
||||
isValueColumn: false,
|
||||
},
|
||||
{
|
||||
name: 'A',
|
||||
queryName: 'A',
|
||||
isValueColumn: true,
|
||||
},
|
||||
],
|
||||
rows: [
|
||||
{
|
||||
data: {
|
||||
A: 11.5,
|
||||
operation: 'GetDriver',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'redis',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 10.13,
|
||||
operation: 'HTTP GET',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 9.21,
|
||||
operation: 'HTTP GET /route',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'route',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 9.21,
|
||||
operation: 'HTTP GET: /route',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.92,
|
||||
operation: 'HTTP GET: /customer',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.92,
|
||||
operation: 'SQL SELECT',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'mysql',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.92,
|
||||
operation: 'HTTP GET /customer',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'customer',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
query: {
|
||||
builder: {
|
||||
queryData: [
|
||||
{
|
||||
aggregateAttribute: {
|
||||
dataType: 'float64',
|
||||
id: 'signoz_calls_total--float64--Sum--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'signoz_calls_total',
|
||||
type: 'Sum',
|
||||
},
|
||||
aggregateOperator: 'rate',
|
||||
dataSource: 'metrics',
|
||||
disabled: false,
|
||||
expression: 'A',
|
||||
filters: {
|
||||
items: [],
|
||||
op: 'AND',
|
||||
},
|
||||
functions: [],
|
||||
groupBy: [
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'resource_host_name--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'resource_host_name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'service_name--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'service_name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'operation--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'operation',
|
||||
type: 'tag',
|
||||
},
|
||||
],
|
||||
having: [],
|
||||
legend: '',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
reduceTo: 'avg',
|
||||
spaceAggregation: 'sum',
|
||||
stepInterval: 60,
|
||||
timeAggregation: 'rate',
|
||||
},
|
||||
],
|
||||
queryFormulas: [],
|
||||
},
|
||||
clickhouse_sql: [
|
||||
{
|
||||
disabled: false,
|
||||
legend: '',
|
||||
name: 'A',
|
||||
query: '',
|
||||
},
|
||||
],
|
||||
id: '1e08128f-c6a3-42ff-8033-4e38d291cf0a',
|
||||
promql: [
|
||||
{
|
||||
disabled: false,
|
||||
legend: '',
|
||||
name: 'A',
|
||||
query: '',
|
||||
},
|
||||
],
|
||||
queryType: 'builder',
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
dataIndex: 'resource_host_name',
|
||||
title: 'resource_host_name',
|
||||
width: 145,
|
||||
},
|
||||
{
|
||||
dataIndex: 'service_name',
|
||||
title: 'service_name',
|
||||
width: 145,
|
||||
},
|
||||
{
|
||||
dataIndex: 'operation',
|
||||
title: 'operation',
|
||||
width: 145,
|
||||
},
|
||||
{
|
||||
dataIndex: 'A',
|
||||
title: 'A',
|
||||
width: 145,
|
||||
},
|
||||
],
|
||||
dataSource: [
|
||||
{
|
||||
A: 11.5,
|
||||
operation: 'GetDriver',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'redis',
|
||||
},
|
||||
{
|
||||
A: 10.13,
|
||||
operation: 'HTTP GET',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
{
|
||||
A: 9.21,
|
||||
operation: 'HTTP GET /route',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'route',
|
||||
},
|
||||
{
|
||||
A: 9.21,
|
||||
operation: 'HTTP GET: /route',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
{
|
||||
A: 0.92,
|
||||
operation: 'HTTP GET: /customer',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
{
|
||||
A: 0.92,
|
||||
operation: 'SQL SELECT',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'mysql',
|
||||
},
|
||||
{
|
||||
A: 0.92,
|
||||
operation: 'HTTP GET /customer',
|
||||
resource_host_name: 'test-hs-name',
|
||||
service_name: 'customer',
|
||||
},
|
||||
],
|
||||
sticky: true,
|
||||
searchTerm: '',
|
||||
};
|
||||
|
||||
export const WidgetHeaderProps: any = {
|
||||
title: 'Table - Panel',
|
||||
widget: {
|
||||
bucketCount: 30,
|
||||
bucketWidth: 0,
|
||||
columnUnits: {},
|
||||
description: '',
|
||||
fillSpans: false,
|
||||
id: 'add65f0d-7662-4024-af51-da567759235d',
|
||||
isStacked: false,
|
||||
mergeAllActiveQueries: false,
|
||||
nullZeroValues: 'zero',
|
||||
opacity: '1',
|
||||
panelTypes: 'table',
|
||||
query: {
|
||||
builder: {
|
||||
queryData: [
|
||||
{
|
||||
aggregateAttribute: {
|
||||
dataType: 'float64',
|
||||
id: 'signoz_calls_total--float64--Sum--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'signoz_calls_total',
|
||||
type: 'Sum',
|
||||
},
|
||||
aggregateOperator: 'rate',
|
||||
dataSource: 'metrics',
|
||||
disabled: false,
|
||||
expression: 'A',
|
||||
filters: {
|
||||
items: [],
|
||||
op: 'AND',
|
||||
},
|
||||
functions: [],
|
||||
groupBy: [
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'resource_host_name--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'resource_host_name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'service_name--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'service_name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'operation--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'operation',
|
||||
type: 'tag',
|
||||
},
|
||||
],
|
||||
having: [],
|
||||
legend: '',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
reduceTo: 'avg',
|
||||
spaceAggregation: 'sum',
|
||||
stepInterval: 60,
|
||||
timeAggregation: 'rate',
|
||||
},
|
||||
],
|
||||
queryFormulas: [],
|
||||
},
|
||||
clickhouse_sql: [
|
||||
{
|
||||
disabled: false,
|
||||
legend: '',
|
||||
name: 'A',
|
||||
query: '',
|
||||
},
|
||||
],
|
||||
id: '1e08128f-c6a3-42ff-8033-4e38d291cf0a',
|
||||
promql: [
|
||||
{
|
||||
disabled: false,
|
||||
legend: '',
|
||||
name: 'A',
|
||||
query: '',
|
||||
},
|
||||
],
|
||||
queryType: 'builder',
|
||||
},
|
||||
selectedLogFields: [
|
||||
{
|
||||
dataType: 'string',
|
||||
name: 'body',
|
||||
type: '',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
name: 'timestamp',
|
||||
type: '',
|
||||
},
|
||||
],
|
||||
selectedTracesFields: [
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'serviceName--string--tag--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'serviceName',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'name--string--tag--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'float64',
|
||||
id: 'durationNano--float64--tag--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'durationNano',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'httpMethod--string--tag--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'httpMethod',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'responseStatusCode--string--tag--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'responseStatusCode',
|
||||
type: 'tag',
|
||||
},
|
||||
],
|
||||
softMax: 0,
|
||||
softMin: 0,
|
||||
stackedBarChart: false,
|
||||
thresholds: [],
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
title: 'Table - Panel',
|
||||
yAxisUnit: 'none',
|
||||
},
|
||||
parentHover: false,
|
||||
queryResponse: {
|
||||
status: 'success',
|
||||
isLoading: false,
|
||||
isSuccess: true,
|
||||
isError: false,
|
||||
isIdle: false,
|
||||
data: {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: 'success',
|
||||
payload: {
|
||||
status: 'success',
|
||||
data: {
|
||||
resultType: '',
|
||||
result: [
|
||||
{
|
||||
table: {
|
||||
columns: [
|
||||
{
|
||||
name: 'resource_host_name',
|
||||
queryName: '',
|
||||
isValueColumn: false,
|
||||
},
|
||||
{
|
||||
name: 'service_name',
|
||||
queryName: '',
|
||||
isValueColumn: false,
|
||||
},
|
||||
{
|
||||
name: 'operation',
|
||||
queryName: '',
|
||||
isValueColumn: false,
|
||||
},
|
||||
{
|
||||
name: 'A',
|
||||
queryName: 'A',
|
||||
isValueColumn: true,
|
||||
},
|
||||
],
|
||||
rows: [
|
||||
{
|
||||
data: {
|
||||
A: 11.67,
|
||||
operation: 'GetDriver',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'redis',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 10.26,
|
||||
operation: 'HTTP GET',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 9.33,
|
||||
operation: 'HTTP GET: /route',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 9.33,
|
||||
operation: 'HTTP GET /route',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'route',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: 'FindDriverIDs',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'redis',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: 'HTTP GET: /customer',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: '/driver.DriverService/FindNearest',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'driver',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: '/driver.DriverService/FindNearest',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: 'SQL SELECT',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'mysql',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: 'HTTP GET /customer',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'customer',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.93,
|
||||
operation: 'HTTP GET /dispatch',
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.21,
|
||||
operation: 'check_request limit',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.21,
|
||||
operation: 'authenticate_check_cache',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.21,
|
||||
operation: 'authenticate_check_db',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.21,
|
||||
operation: 'authenticate',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.21,
|
||||
operation: 'check cart in cache',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.2,
|
||||
operation: 'get_cart',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.2,
|
||||
operation: 'check cart in db',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
{
|
||||
data: {
|
||||
A: 0.2,
|
||||
operation: 'home',
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
params: {
|
||||
start: 1726669030000,
|
||||
end: 1726670830000,
|
||||
step: 60,
|
||||
variables: {},
|
||||
formatForWeb: true,
|
||||
compositeQuery: {
|
||||
queryType: 'builder',
|
||||
panelType: 'table',
|
||||
fillGaps: false,
|
||||
builderQueries: {
|
||||
A: {
|
||||
aggregateAttribute: {
|
||||
dataType: 'float64',
|
||||
id: 'signoz_calls_total--float64--Sum--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'signoz_calls_total',
|
||||
type: 'Sum',
|
||||
},
|
||||
aggregateOperator: 'rate',
|
||||
dataSource: 'metrics',
|
||||
disabled: false,
|
||||
expression: 'A',
|
||||
filters: {
|
||||
items: [],
|
||||
op: 'AND',
|
||||
},
|
||||
functions: [],
|
||||
groupBy: [
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'resource_host_name--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'resource_host_name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'service_name--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'service_name',
|
||||
type: 'tag',
|
||||
},
|
||||
{
|
||||
dataType: 'string',
|
||||
id: 'operation--string--tag--false',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: 'operation',
|
||||
type: 'tag',
|
||||
},
|
||||
],
|
||||
having: [],
|
||||
legend: '',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
reduceTo: 'avg',
|
||||
spaceAggregation: 'sum',
|
||||
stepInterval: 60,
|
||||
timeAggregation: 'rate',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataUpdatedAt: 1726670830710,
|
||||
error: null,
|
||||
errorUpdatedAt: 0,
|
||||
failureCount: 0,
|
||||
errorUpdateCount: 0,
|
||||
isFetched: true,
|
||||
isFetchedAfterMount: true,
|
||||
isFetching: false,
|
||||
isRefetching: false,
|
||||
isLoadingError: false,
|
||||
isPlaceholderData: false,
|
||||
isPreviousData: false,
|
||||
isRefetchError: false,
|
||||
isStale: true,
|
||||
},
|
||||
headerMenuList: ['view', 'clone', 'delete', 'edit'],
|
||||
isWarning: false,
|
||||
isFetchingResponse: false,
|
||||
tableProcessedDataRef: {
|
||||
current: [
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'redis',
|
||||
operation: 'GetDriver',
|
||||
A: 11.67,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
operation: 'HTTP GET',
|
||||
A: 10.26,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
operation: 'HTTP GET: /route',
|
||||
A: 9.33,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'route',
|
||||
operation: 'HTTP GET /route',
|
||||
A: 9.33,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'redis',
|
||||
operation: 'FindDriverIDs',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
operation: 'HTTP GET: /customer',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'driver',
|
||||
operation: '/driver.DriverService/FindNearest',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
operation: '/driver.DriverService/FindNearest',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'mysql',
|
||||
operation: 'SQL SELECT',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'customer',
|
||||
operation: 'HTTP GET /customer',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '4f6ec470feea',
|
||||
service_name: 'frontend',
|
||||
operation: 'HTTP GET /dispatch',
|
||||
A: 0.93,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'check_request limit',
|
||||
A: 0.21,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'authenticate_check_cache',
|
||||
A: 0.21,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'authenticate_check_db',
|
||||
A: 0.21,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'authenticate',
|
||||
A: 0.21,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'check cart in cache',
|
||||
A: 0.21,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'get_cart',
|
||||
A: 0.2,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'check cart in db',
|
||||
A: 0.2,
|
||||
},
|
||||
{
|
||||
resource_host_name: '',
|
||||
service_name: 'demo-app',
|
||||
operation: 'home',
|
||||
A: 0.2,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user