mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 21:45:59 +08:00
feat: add hostname and os type quick filter to hosts list (#6926)
This commit is contained in:
parent
cc9eb32c50
commit
d0eefa0cf2
@ -1,34 +1,25 @@
|
|||||||
import './InfraMonitoring.styles.scss';
|
import './InfraMonitoring.styles.scss';
|
||||||
|
|
||||||
import { LoadingOutlined } from '@ant-design/icons';
|
import { VerticalAlignTopOutlined } from '@ant-design/icons';
|
||||||
import {
|
import { Tooltip, Typography } from 'antd';
|
||||||
Skeleton,
|
|
||||||
Spin,
|
|
||||||
Table,
|
|
||||||
TablePaginationConfig,
|
|
||||||
TableProps,
|
|
||||||
Typography,
|
|
||||||
} from 'antd';
|
|
||||||
import { SorterResult } from 'antd/es/table/interface';
|
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { HostListPayload } from 'api/infraMonitoring/getHostLists';
|
import { HostListPayload } from 'api/infraMonitoring/getHostLists';
|
||||||
import HostMetricDetail from 'components/HostMetricsDetail';
|
import HostMetricDetail from 'components/HostMetricsDetail';
|
||||||
|
import QuickFilters from 'components/QuickFilters/QuickFilters';
|
||||||
|
import { QuickFiltersSource } from 'components/QuickFilters/types';
|
||||||
import { usePageSize } from 'container/InfraMonitoringK8s/utils';
|
import { usePageSize } from 'container/InfraMonitoringK8s/utils';
|
||||||
import { useGetHostList } from 'hooks/infraMonitoring/useGetHostList';
|
import { useGetHostList } from 'hooks/infraMonitoring/useGetHostList';
|
||||||
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery, Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
|
||||||
import HostsEmptyOrIncorrectMetrics from './HostsEmptyOrIncorrectMetrics';
|
|
||||||
import HostsListControls from './HostsListControls';
|
import HostsListControls from './HostsListControls';
|
||||||
import {
|
import HostsListTable from './HostsListTable';
|
||||||
formatDataForTable,
|
import { getHostListsQuery, HostsQuickFiltersConfig } from './utils';
|
||||||
getHostListsQuery,
|
|
||||||
getHostsListColumns,
|
|
||||||
HostRowData,
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
function HostsList(): JSX.Element {
|
function HostsList(): JSX.Element {
|
||||||
@ -41,6 +32,7 @@ function HostsList(): JSX.Element {
|
|||||||
items: [],
|
items: [],
|
||||||
op: 'and',
|
op: 'and',
|
||||||
});
|
});
|
||||||
|
const [showFilters, setShowFilters] = useState<boolean>(true);
|
||||||
|
|
||||||
const [orderBy, setOrderBy] = useState<{
|
const [orderBy, setOrderBy] = useState<{
|
||||||
columnName: string;
|
columnName: string;
|
||||||
@ -72,55 +64,24 @@ function HostsList(): JSX.Element {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const sentAnyHostMetricsData = useMemo(
|
|
||||||
() => data?.payload?.data?.sentAnyHostMetricsData || false,
|
|
||||||
[data],
|
|
||||||
);
|
|
||||||
|
|
||||||
const isSendingIncorrectK8SAgentMetrics = useMemo(
|
|
||||||
() => data?.payload?.data?.isSendingK8SAgentMetrics || false,
|
|
||||||
[data],
|
|
||||||
);
|
|
||||||
|
|
||||||
const hostMetricsData = useMemo(() => data?.payload?.data?.records || [], [
|
const hostMetricsData = useMemo(() => data?.payload?.data?.records || [], [
|
||||||
data,
|
data,
|
||||||
]);
|
]);
|
||||||
const totalCount = data?.payload?.data?.total || 0;
|
|
||||||
|
|
||||||
const formattedHostMetricsData = useMemo(
|
const { currentQuery } = useQueryBuilder();
|
||||||
() => formatDataForTable(hostMetricsData),
|
|
||||||
[hostMetricsData],
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns = useMemo(() => getHostsListColumns(), []);
|
const { handleChangeQueryData } = useQueryOperations({
|
||||||
|
index: 0,
|
||||||
const handleTableChange: TableProps<HostRowData>['onChange'] = useCallback(
|
query: currentQuery.builder.queryData[0],
|
||||||
(
|
entityVersion: '',
|
||||||
pagination: TablePaginationConfig,
|
|
||||||
_filters: Record<string, (string | number | boolean)[] | null>,
|
|
||||||
sorter: SorterResult<HostRowData> | SorterResult<HostRowData>[],
|
|
||||||
): void => {
|
|
||||||
if (pagination.current) {
|
|
||||||
setCurrentPage(pagination.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('field' in sorter && sorter.order) {
|
|
||||||
setOrderBy({
|
|
||||||
columnName: sorter.field as string,
|
|
||||||
order: sorter.order === 'ascend' ? 'asc' : 'desc',
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
setOrderBy(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleFiltersChange = useCallback(
|
const handleFiltersChange = useCallback(
|
||||||
(value: IBuilderQuery['filters']): void => {
|
(value: IBuilderQuery['filters']): void => {
|
||||||
const isNewFilterAdded = value.items.length !== filters.items.length;
|
const isNewFilterAdded = value.items.length !== filters.items.length;
|
||||||
if (isNewFilterAdded) {
|
|
||||||
setFilters(value);
|
setFilters(value);
|
||||||
|
handleChangeQueryData('filters', value);
|
||||||
|
if (isNewFilterAdded) {
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
|
|
||||||
logEvent('Infra Monitoring: Hosts list filters applied', {
|
logEvent('Infra Monitoring: Hosts list filters applied', {
|
||||||
@ -128,6 +89,7 @@ function HostsList(): JSX.Element {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
[filters],
|
[filters],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -142,118 +104,59 @@ function HostsList(): JSX.Element {
|
|||||||
);
|
);
|
||||||
}, [selectedHostName, hostMetricsData]);
|
}, [selectedHostName, hostMetricsData]);
|
||||||
|
|
||||||
const handleRowClick = (record: HostRowData): void => {
|
|
||||||
setSelectedHostName(record.hostName);
|
|
||||||
|
|
||||||
logEvent('Infra Monitoring: Hosts list item clicked', {
|
|
||||||
host: record.hostName,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCloseHostDetail = (): void => {
|
const handleCloseHostDetail = (): void => {
|
||||||
setSelectedHostName(null);
|
setSelectedHostName(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showHostsTable =
|
const handleFilterVisibilityChange = (): void => {
|
||||||
!isError &&
|
setShowFilters(!showFilters);
|
||||||
sentAnyHostMetricsData &&
|
};
|
||||||
!isSendingIncorrectK8SAgentMetrics &&
|
|
||||||
!(formattedHostMetricsData.length === 0 && filters.items.length > 0);
|
|
||||||
|
|
||||||
const showNoFilteredHostsMessage =
|
const handleQuickFiltersChange = (query: Query): void => {
|
||||||
!isFetching &&
|
handleChangeQueryData('filters', query.builder.queryData[0].filters);
|
||||||
!isLoading &&
|
handleFiltersChange(query.builder.queryData[0].filters);
|
||||||
formattedHostMetricsData.length === 0 &&
|
};
|
||||||
filters.items.length > 0;
|
|
||||||
|
|
||||||
const showHostsEmptyState =
|
|
||||||
!isFetching &&
|
|
||||||
!isLoading &&
|
|
||||||
(!sentAnyHostMetricsData || isSendingIncorrectK8SAgentMetrics) &&
|
|
||||||
!filters.items.length;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hosts-list">
|
<div className="hosts-list">
|
||||||
|
<div className="hosts-list-content">
|
||||||
|
{showFilters && (
|
||||||
|
<div className="hosts-quick-filters-container">
|
||||||
|
<div className="hosts-quick-filters-container-header">
|
||||||
|
<Typography.Text>Filters</Typography.Text>
|
||||||
|
<Tooltip title="Collapse Filters">
|
||||||
|
<VerticalAlignTopOutlined
|
||||||
|
rotate={270}
|
||||||
|
onClick={handleFilterVisibilityChange}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<QuickFilters
|
||||||
|
source={QuickFiltersSource.INFRA_MONITORING}
|
||||||
|
config={HostsQuickFiltersConfig}
|
||||||
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
|
onFilterChange={handleQuickFiltersChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="hosts-list-table-container">
|
||||||
<HostsListControls handleFiltersChange={handleFiltersChange} />
|
<HostsListControls handleFiltersChange={handleFiltersChange} />
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
<HostsListTable
|
||||||
|
isLoading={isLoading}
|
||||||
{showHostsEmptyState && (
|
isFetching={isFetching}
|
||||||
<HostsEmptyOrIncorrectMetrics
|
isError={isError}
|
||||||
noData={!sentAnyHostMetricsData}
|
tableData={data}
|
||||||
incorrectData={isSendingIncorrectK8SAgentMetrics}
|
hostMetricsData={hostMetricsData}
|
||||||
/>
|
filters={filters}
|
||||||
)}
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
{showNoFilteredHostsMessage && (
|
setSelectedHostName={setSelectedHostName}
|
||||||
<div className="no-filtered-hosts-message-container">
|
pageSize={pageSize}
|
||||||
<div className="no-filtered-hosts-message-content">
|
setPageSize={setPageSize}
|
||||||
<img
|
setOrderBy={setOrderBy}
|
||||||
src="/Icons/emptyState.svg"
|
|
||||||
alt="thinking-emoji"
|
|
||||||
className="empty-state-svg"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Typography.Text className="no-filtered-hosts-message">
|
|
||||||
This query had no results. Edit your query and try again!
|
|
||||||
</Typography.Text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(isFetching || isLoading) && (
|
|
||||||
<div className="hosts-list-loading-state">
|
|
||||||
<Skeleton.Input
|
|
||||||
className="hosts-list-loading-state-item"
|
|
||||||
size="large"
|
|
||||||
block
|
|
||||||
active
|
|
||||||
/>
|
|
||||||
<Skeleton.Input
|
|
||||||
className="hosts-list-loading-state-item"
|
|
||||||
size="large"
|
|
||||||
block
|
|
||||||
active
|
|
||||||
/>
|
|
||||||
<Skeleton.Input
|
|
||||||
className="hosts-list-loading-state-item"
|
|
||||||
size="large"
|
|
||||||
block
|
|
||||||
active
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
|
||||||
{showHostsTable && (
|
|
||||||
<Table
|
|
||||||
className="hosts-list-table"
|
|
||||||
dataSource={isFetching || isLoading ? [] : formattedHostMetricsData}
|
|
||||||
columns={columns}
|
|
||||||
pagination={{
|
|
||||||
current: currentPage,
|
|
||||||
pageSize,
|
|
||||||
total: totalCount,
|
|
||||||
showSizeChanger: true,
|
|
||||||
hideOnSinglePage: false,
|
|
||||||
onChange: (page, pageSize): void => {
|
|
||||||
setCurrentPage(page);
|
|
||||||
setPageSize(pageSize);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
scroll={{ x: true }}
|
|
||||||
loading={{
|
|
||||||
spinning: isFetching || isLoading,
|
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
|
||||||
}}
|
|
||||||
tableLayout="fixed"
|
|
||||||
rowKey={(record): string => record.hostName}
|
|
||||||
onChange={handleTableChange}
|
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
|
||||||
onClick: (): void => handleRowClick(record),
|
|
||||||
className: 'clickable-row',
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<HostMetricDetail
|
<HostMetricDetail
|
||||||
host={selectedHostData}
|
host={selectedHostData}
|
||||||
isModalTimeSelection
|
isModalTimeSelection
|
||||||
|
183
frontend/src/container/InfraMonitoringHosts/HostsListTable.tsx
Normal file
183
frontend/src/container/InfraMonitoringHosts/HostsListTable.tsx
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
Skeleton,
|
||||||
|
Spin,
|
||||||
|
Table,
|
||||||
|
TablePaginationConfig,
|
||||||
|
TableProps,
|
||||||
|
Typography,
|
||||||
|
} from 'antd';
|
||||||
|
import { SorterResult } from 'antd/es/table/interface';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
|
import HostsEmptyOrIncorrectMetrics from './HostsEmptyOrIncorrectMetrics';
|
||||||
|
import {
|
||||||
|
formatDataForTable,
|
||||||
|
getHostsListColumns,
|
||||||
|
HostRowData,
|
||||||
|
HostsListTableProps,
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
|
export default function HostsListTable({
|
||||||
|
isLoading,
|
||||||
|
isFetching,
|
||||||
|
isError,
|
||||||
|
tableData: data,
|
||||||
|
hostMetricsData,
|
||||||
|
filters,
|
||||||
|
setSelectedHostName,
|
||||||
|
currentPage,
|
||||||
|
setCurrentPage,
|
||||||
|
pageSize,
|
||||||
|
setOrderBy,
|
||||||
|
setPageSize,
|
||||||
|
}: HostsListTableProps): JSX.Element {
|
||||||
|
const columns = useMemo(() => getHostsListColumns(), []);
|
||||||
|
|
||||||
|
const sentAnyHostMetricsData = useMemo(
|
||||||
|
() => data?.payload?.data?.sentAnyHostMetricsData || false,
|
||||||
|
[data],
|
||||||
|
);
|
||||||
|
|
||||||
|
const isSendingIncorrectK8SAgentMetrics = useMemo(
|
||||||
|
() => data?.payload?.data?.isSendingK8SAgentMetrics || false,
|
||||||
|
[data],
|
||||||
|
);
|
||||||
|
|
||||||
|
const formattedHostMetricsData = useMemo(
|
||||||
|
() => formatDataForTable(hostMetricsData),
|
||||||
|
[hostMetricsData],
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalCount = data?.payload?.data?.total || 0;
|
||||||
|
|
||||||
|
const handleTableChange: TableProps<HostRowData>['onChange'] = useCallback(
|
||||||
|
(
|
||||||
|
pagination: TablePaginationConfig,
|
||||||
|
_filters: Record<string, (string | number | boolean)[] | null>,
|
||||||
|
sorter: SorterResult<HostRowData> | SorterResult<HostRowData>[],
|
||||||
|
): void => {
|
||||||
|
if (pagination.current) {
|
||||||
|
setCurrentPage(pagination.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('field' in sorter && sorter.order) {
|
||||||
|
setOrderBy({
|
||||||
|
columnName: sorter.field as string,
|
||||||
|
order: sorter.order === 'ascend' ? 'asc' : 'desc',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setOrderBy(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleRowClick = (record: HostRowData): void => {
|
||||||
|
setSelectedHostName(record.hostName);
|
||||||
|
logEvent('Infra Monitoring: Hosts list item clicked', {
|
||||||
|
host: record.hostName,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const showNoFilteredHostsMessage =
|
||||||
|
!isFetching &&
|
||||||
|
!isLoading &&
|
||||||
|
formattedHostMetricsData.length === 0 &&
|
||||||
|
filters.items.length > 0;
|
||||||
|
|
||||||
|
const showHostsEmptyState =
|
||||||
|
!isFetching &&
|
||||||
|
!isLoading &&
|
||||||
|
(!sentAnyHostMetricsData || isSendingIncorrectK8SAgentMetrics) &&
|
||||||
|
!filters.items.length;
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
return <Typography>{data?.error || 'Something went wrong'}</Typography>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showHostsEmptyState) {
|
||||||
|
return (
|
||||||
|
<HostsEmptyOrIncorrectMetrics
|
||||||
|
noData={!sentAnyHostMetricsData}
|
||||||
|
incorrectData={isSendingIncorrectK8SAgentMetrics}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showNoFilteredHostsMessage) {
|
||||||
|
return (
|
||||||
|
<div className="no-filtered-hosts-message-container">
|
||||||
|
<div className="no-filtered-hosts-message-content">
|
||||||
|
<img
|
||||||
|
src="/Icons/emptyState.svg"
|
||||||
|
alt="thinking-emoji"
|
||||||
|
className="empty-state-svg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Typography.Text className="no-filtered-hosts-message">
|
||||||
|
This query had no results. Edit your query and try again!
|
||||||
|
</Typography.Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoading || isFetching) {
|
||||||
|
return (
|
||||||
|
<div className="hosts-list-loading-state">
|
||||||
|
<Skeleton.Input
|
||||||
|
className="hosts-list-loading-state-item"
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
active
|
||||||
|
/>
|
||||||
|
<Skeleton.Input
|
||||||
|
className="hosts-list-loading-state-item"
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
active
|
||||||
|
/>
|
||||||
|
<Skeleton.Input
|
||||||
|
className="hosts-list-loading-state-item"
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
active
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
className="hosts-list-table"
|
||||||
|
dataSource={isLoading || isFetching ? [] : formattedHostMetricsData}
|
||||||
|
columns={columns}
|
||||||
|
pagination={{
|
||||||
|
current: currentPage,
|
||||||
|
pageSize,
|
||||||
|
total: totalCount,
|
||||||
|
showSizeChanger: true,
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
onChange: (page, pageSize): void => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
setPageSize(pageSize);
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
scroll={{ x: true }}
|
||||||
|
loading={{
|
||||||
|
spinning: isFetching || isLoading,
|
||||||
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
|
}}
|
||||||
|
tableLayout="fixed"
|
||||||
|
rowKey={(record): string => record.hostName}
|
||||||
|
onChange={handleTableChange}
|
||||||
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
|
onClick: (): void => handleRowClick(record),
|
||||||
|
className: 'clickable-row',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -51,6 +51,30 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hosts-list-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.hosts-quick-filters-container {
|
||||||
|
width: 280px;
|
||||||
|
min-width: 280px;
|
||||||
|
border-right: 1px solid var(--bg-slate-400);
|
||||||
|
|
||||||
|
.hosts-quick-filters-container-header {
|
||||||
|
padding: 8px;
|
||||||
|
border-bottom: 1px solid var(--bg-slate-400);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hosts-list-table-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.hosts-list-table {
|
.hosts-list-table {
|
||||||
.ant-table {
|
.ant-table {
|
||||||
.ant-table-thead > tr > th {
|
.ant-table-thead > tr > th {
|
||||||
@ -164,7 +188,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
// this is to offset intercom icon till we improve the design
|
// this is to offset intercom icon till we improve the design
|
||||||
padding-right: 72px;
|
right: 20px;
|
||||||
|
|
||||||
.ant-pagination-item {
|
.ant-pagination-item {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -214,6 +238,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
.hosts-list-loading-state-item {
|
.hosts-list-loading-state-item {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
@ -222,6 +247,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.no-filtered-hosts-message-container {
|
.no-filtered-hosts-message-container {
|
||||||
|
flex: 1;
|
||||||
height: 30vh;
|
height: 30vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -246,6 +272,7 @@
|
|||||||
.hosts-empty-state-container {
|
.hosts-empty-state-container {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
height: 40vh;
|
height: 40vh;
|
||||||
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -3,9 +3,22 @@ import './InfraMonitoring.styles.scss';
|
|||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Progress, TabsProps, Tag } from 'antd';
|
import { Progress, TabsProps, Tag } from 'antd';
|
||||||
import { ColumnType } from 'antd/es/table';
|
import { ColumnType } from 'antd/es/table';
|
||||||
import { HostData, HostListPayload } from 'api/infraMonitoring/getHostLists';
|
import {
|
||||||
|
HostData,
|
||||||
|
HostListPayload,
|
||||||
|
HostListResponse,
|
||||||
|
} from 'api/infraMonitoring/getHostLists';
|
||||||
|
import {
|
||||||
|
FiltersType,
|
||||||
|
IQuickFiltersConfig,
|
||||||
|
} from 'components/QuickFilters/types';
|
||||||
import TabLabel from 'components/TabLabel';
|
import TabLabel from 'components/TabLabel';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
|
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
import HostsList from './HostsList';
|
import HostsList from './HostsList';
|
||||||
|
|
||||||
@ -18,6 +31,29 @@ export interface HostRowData {
|
|||||||
active: React.ReactNode;
|
active: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HostsListTableProps {
|
||||||
|
isLoading: boolean;
|
||||||
|
isError: boolean;
|
||||||
|
isFetching: boolean;
|
||||||
|
tableData:
|
||||||
|
| SuccessResponse<HostListResponse, unknown>
|
||||||
|
| ErrorResponse
|
||||||
|
| undefined;
|
||||||
|
hostMetricsData: HostData[];
|
||||||
|
filters: TagFilter;
|
||||||
|
setSelectedHostName: Dispatch<SetStateAction<string | null>>;
|
||||||
|
currentPage: number;
|
||||||
|
setCurrentPage: Dispatch<SetStateAction<number>>;
|
||||||
|
pageSize: number;
|
||||||
|
setOrderBy: Dispatch<
|
||||||
|
SetStateAction<{
|
||||||
|
columnName: string;
|
||||||
|
order: 'asc' | 'desc';
|
||||||
|
} | null>
|
||||||
|
>;
|
||||||
|
setPageSize: (pageSize: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const getHostListsQuery = (): HostListPayload => ({
|
export const getHostListsQuery = (): HostListPayload => ({
|
||||||
filters: {
|
filters: {
|
||||||
items: [],
|
items: [],
|
||||||
@ -132,3 +168,36 @@ export const formatDataForTable = (data: HostData[]): HostRowData[] =>
|
|||||||
wait: `${Number((host.wait * 100).toFixed(1))}%`,
|
wait: `${Number((host.wait * 100).toFixed(1))}%`,
|
||||||
load15: host.load15,
|
load15: host.load15,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const HostsQuickFiltersConfig: IQuickFiltersConfig[] = [
|
||||||
|
{
|
||||||
|
type: FiltersType.CHECKBOX,
|
||||||
|
title: 'Host Name',
|
||||||
|
attributeKey: {
|
||||||
|
key: 'host_name',
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
type: 'resource',
|
||||||
|
isColumn: false,
|
||||||
|
isJSON: false,
|
||||||
|
},
|
||||||
|
aggregateOperator: 'noop',
|
||||||
|
aggregateAttribute: 'system_cpu_load_average_15m',
|
||||||
|
dataSource: DataSource.METRICS,
|
||||||
|
defaultOpen: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: FiltersType.CHECKBOX,
|
||||||
|
title: 'OS Type',
|
||||||
|
attributeKey: {
|
||||||
|
key: 'os_type',
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
type: 'resource',
|
||||||
|
isColumn: false,
|
||||||
|
isJSON: false,
|
||||||
|
},
|
||||||
|
aggregateOperator: 'noop',
|
||||||
|
aggregateAttribute: 'system_cpu_load_average_15m',
|
||||||
|
dataSource: DataSource.METRICS,
|
||||||
|
defaultOpen: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user