mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 03:05:55 +08:00
Allow search by service name in services list page (#1520)
* feat: add search by service name * chore: allow clear * chore: table search icon and review comments * chore: fix lint * chore: address review comments * chore: fix types * chore: tweak user experience * chore: antd color enum
This commit is contained in:
parent
5e0eb05a9c
commit
9cd1be6553
@ -1,9 +1,13 @@
|
|||||||
import Table, { ColumnsType } from 'antd/lib/table';
|
import { blue } from '@ant-design/colors';
|
||||||
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Input, Space, Table } from 'antd';
|
||||||
|
import type { ColumnsType, ColumnType } from 'antd/es/table';
|
||||||
|
import type { FilterConfirmProps } from 'antd/es/table/interface';
|
||||||
import localStorageGet from 'api/browser/localstorage/get';
|
import localStorageGet from 'api/browser/localstorage/get';
|
||||||
import localStorageSet from 'api/browser/localstorage/set';
|
import localStorageSet from 'api/browser/localstorage/set';
|
||||||
import { SKIP_ONBOARDING } from 'constants/onboarding';
|
import { SKIP_ONBOARDING } from 'constants/onboarding';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import React, { useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
@ -27,6 +31,57 @@ function Metrics(): JSX.Element {
|
|||||||
localStorageSet(SKIP_ONBOARDING, 'true');
|
localStorageSet(SKIP_ONBOARDING, 'true');
|
||||||
setSkipOnboarding(true);
|
setSkipOnboarding(true);
|
||||||
};
|
};
|
||||||
|
const handleSearch = (confirm: (param?: FilterConfirmProps) => void): void => {
|
||||||
|
confirm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const FilterIcon = useCallback(
|
||||||
|
({ filtered }) => (
|
||||||
|
<SearchOutlined
|
||||||
|
style={{
|
||||||
|
color: filtered ? blue[6] : undefined,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const filterDropdown = useCallback(
|
||||||
|
({ setSelectedKeys, selectedKeys, confirm }) => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Search by service"
|
||||||
|
value={selectedKeys[0]}
|
||||||
|
onChange={(e): void =>
|
||||||
|
setSelectedKeys(e.target.value ? [e.target.value] : [])
|
||||||
|
}
|
||||||
|
allowClear
|
||||||
|
onPressEnter={(): void => handleSearch(confirm)}
|
||||||
|
style={{
|
||||||
|
marginBottom: 8,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Space>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={(): void => handleSearch(confirm)}
|
||||||
|
icon={<SearchOutlined />}
|
||||||
|
size="small"
|
||||||
|
style={{
|
||||||
|
width: 90,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Search
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
services.length === 0 &&
|
services.length === 0 &&
|
||||||
@ -37,21 +92,37 @@ function Metrics(): JSX.Element {
|
|||||||
return <SkipBoardModal onContinueClick={onContinueClick} />;
|
return <SkipBoardModal onContinueClick={onContinueClick} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DataIndex = keyof ServicesList;
|
||||||
|
|
||||||
|
const getColumnSearchProps = (
|
||||||
|
dataIndex: DataIndex,
|
||||||
|
): ColumnType<DataProps> => ({
|
||||||
|
filterDropdown,
|
||||||
|
filterIcon: FilterIcon,
|
||||||
|
onFilter: (value: string | number | boolean, record: DataProps): boolean =>
|
||||||
|
record[dataIndex]
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(value.toString().toLowerCase()),
|
||||||
|
render: (text: string): JSX.Element => (
|
||||||
|
<Link to={`${ROUTES.APPLICATION}/${text}${search}`}>
|
||||||
|
<Name>{text}</Name>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
const columns: ColumnsType<DataProps> = [
|
const columns: ColumnsType<DataProps> = [
|
||||||
{
|
{
|
||||||
title: 'Application',
|
title: 'Application',
|
||||||
dataIndex: 'serviceName',
|
dataIndex: 'serviceName',
|
||||||
key: 'serviceName',
|
key: 'serviceName',
|
||||||
render: (text: string): JSX.Element => (
|
...getColumnSearchProps('serviceName'),
|
||||||
<Link to={`${ROUTES.APPLICATION}/${text}${search}`}>
|
|
||||||
<Name>{text}</Name>
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'P99 latency (in ms)',
|
title: 'P99 latency (in ms)',
|
||||||
dataIndex: 'p99',
|
dataIndex: 'p99',
|
||||||
key: 'p99',
|
key: 'p99',
|
||||||
|
defaultSortOrder: 'descend',
|
||||||
sorter: (a: DataProps, b: DataProps): number => a.p99 - b.p99,
|
sorter: (a: DataProps, b: DataProps): number => a.p99 - b.p99,
|
||||||
render: (value: number): string => (value / 1000000).toFixed(2),
|
render: (value: number): string => (value / 1000000).toFixed(2),
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user