mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 18:39:04 +08:00
chore: infra monitoring bug fixes (#6795)
This commit is contained in:
parent
16e61b45ac
commit
5c45e1f7b3
@ -1,4 +1,4 @@
|
|||||||
import { ApiBaseInstance } from 'api';
|
import axios from 'api';
|
||||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
@ -47,7 +47,7 @@ export const getK8sNodesList = async (
|
|||||||
headers?: Record<string, string>,
|
headers?: Record<string, string>,
|
||||||
): Promise<SuccessResponse<K8sNodesListResponse> | ErrorResponse> => {
|
): Promise<SuccessResponse<K8sNodesListResponse> | ErrorResponse> => {
|
||||||
try {
|
try {
|
||||||
const response = await ApiBaseInstance.post('/nodes/list', props, {
|
const response = await axios.post('/nodes/list', props, {
|
||||||
signal,
|
signal,
|
||||||
headers,
|
headers,
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ApiBaseInstance } from 'api';
|
import axios from 'api';
|
||||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
@ -75,7 +75,7 @@ export const getK8sPodsList = async (
|
|||||||
headers?: Record<string, string>,
|
headers?: Record<string, string>,
|
||||||
): Promise<SuccessResponse<K8sPodsListResponse> | ErrorResponse> => {
|
): Promise<SuccessResponse<K8sPodsListResponse> | ErrorResponse> => {
|
||||||
try {
|
try {
|
||||||
const response = await ApiBaseInstance.post('/pods/list', props, {
|
const response = await axios.post('/pods/list', props, {
|
||||||
signal,
|
signal,
|
||||||
headers,
|
headers,
|
||||||
});
|
});
|
||||||
|
@ -39,10 +39,6 @@
|
|||||||
.ant-collapse-header {
|
.ant-collapse-header {
|
||||||
border-bottom: 1px solid var(--bg-slate-400);
|
border-bottom: 1px solid var(--bg-slate-400);
|
||||||
padding: 12px 8px;
|
padding: 12px 8px;
|
||||||
|
|
||||||
&[aria-expanded='true'] {
|
|
||||||
background: var(--bg-ink-400);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-collapse-content-box {
|
.ant-collapse-content-box {
|
||||||
@ -271,8 +267,6 @@
|
|||||||
|
|
||||||
.group-by-label {
|
.group-by-label {
|
||||||
min-width: max-content;
|
min-width: max-content;
|
||||||
|
|
||||||
color: var(--bg-vanilla-100, #c0c1c3);
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@ -282,7 +276,6 @@
|
|||||||
border-radius: 2px 0px 0px 2px;
|
border-radius: 2px 0px 0px 2px;
|
||||||
border: 1px solid var(--bg-slate-400, #1d212d);
|
border: 1px solid var(--bg-slate-400, #1d212d);
|
||||||
border-right: none;
|
border-right: none;
|
||||||
background: var(--bg-ink-100, #16181d);
|
|
||||||
border-top-right-radius: 0px;
|
border-top-right-radius: 0px;
|
||||||
border-bottom-right-radius: 0px;
|
border-bottom-right-radius: 0px;
|
||||||
|
|
||||||
@ -488,7 +481,7 @@
|
|||||||
.expanded-table-container {
|
.expanded-table-container {
|
||||||
border: 1px solid var(--bg-ink-400);
|
border: 1px solid var(--bg-ink-400);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding-left: 16px;
|
padding-left: 48px;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 0.1rem;
|
width: 0.1rem;
|
||||||
@ -710,8 +703,34 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ant-table-cell {
|
.ant-table-cell {
|
||||||
min-width: 170px !important;
|
min-width: 140px !important;
|
||||||
max-width: 170px !important;
|
max-width: 140px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-cell {
|
||||||
|
&:has(.pod-name-header) {
|
||||||
|
min-width: 250px !important;
|
||||||
|
max-width: 250px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-cell {
|
||||||
|
&:has(.med-col) {
|
||||||
|
min-width: 180px !important;
|
||||||
|
max-width: 180px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.expanded-k8s-list-table {
|
||||||
|
.ant-table-cell {
|
||||||
|
min-width: 180px !important;
|
||||||
|
max-width: 180px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-row-expand-icon-cell {
|
||||||
|
min-width: 30px !important;
|
||||||
|
max-width: 30px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-table-row-expand-icon-cell {
|
.ant-table-row-expand-icon-cell {
|
||||||
@ -808,6 +827,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lightMode {
|
.lightMode {
|
||||||
|
.infra-monitoring-container {
|
||||||
|
.k8s-list-table {
|
||||||
|
.ant-table-expanded-row {
|
||||||
|
&:hover {
|
||||||
|
background: var(--bg-vanilla-100) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-cell {
|
||||||
|
background: var(--bg-vanilla-100) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table .ant-table-thead > tr > th {
|
||||||
|
padding: 4px 16px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.event-content-container {
|
.event-content-container {
|
||||||
.ant-table {
|
.ant-table {
|
||||||
background: var(--bg-vanilla-100);
|
background: var(--bg-vanilla-100);
|
||||||
@ -831,4 +868,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entity-group-header {
|
||||||
|
.ant-tag {
|
||||||
|
background-color: var(--bg-vanilla-300) !important;
|
||||||
|
color: var(--bg-slate-400) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|||||||
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||||
import { Container, Workflow } from 'lucide-react';
|
import { Container, Workflow } from 'lucide-react';
|
||||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||||
import { useCallback, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -24,6 +24,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
const [showFilters, setShowFilters] = useState(true);
|
const [showFilters, setShowFilters] = useState(true);
|
||||||
|
|
||||||
const [selectedCategory, setSelectedCategory] = useState(K8sCategories.PODS);
|
const [selectedCategory, setSelectedCategory] = useState(K8sCategories.PODS);
|
||||||
|
const [quickFiltersLastUpdated, setQuickFiltersLastUpdated] = useState(-1);
|
||||||
|
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
@ -37,14 +38,12 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
entityVersion: '',
|
entityVersion: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleFilterChange = useCallback(
|
const handleFilterChange = (query: Query): void => {
|
||||||
(query: Query): void => {
|
// update the current query with the new filters
|
||||||
// update the current query with the new filters
|
// in infra monitoring k8s, we are using only one query, hence updating the 0th index of queryData
|
||||||
// in infra monitoring k8s, we are using only one query, hence updating the 0th index of queryData
|
handleChangeQueryData('filters', query.builder.queryData[0].filters);
|
||||||
handleChangeQueryData('filters', query.builder.queryData[0].filters);
|
setQuickFiltersLastUpdated(Date.now());
|
||||||
},
|
};
|
||||||
[handleChangeQueryData],
|
|
||||||
);
|
|
||||||
|
|
||||||
const items: CollapseProps['items'] = [
|
const items: CollapseProps['items'] = [
|
||||||
{
|
{
|
||||||
@ -262,6 +261,8 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
const handleCategoryChange = (key: string | string[]): void => {
|
const handleCategoryChange = (key: string | string[]): void => {
|
||||||
if (Array.isArray(key) && key.length > 0) {
|
if (Array.isArray(key) && key.length > 0) {
|
||||||
setSelectedCategory(key[0] as string);
|
setSelectedCategory(key[0] as string);
|
||||||
|
// Reset filters
|
||||||
|
handleChangeQueryData('filters', { items: [], op: 'and' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,6 +303,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
<K8sPodLists
|
<K8sPodLists
|
||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -309,6 +311,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
<K8sNodesList
|
<K8sNodesList
|
||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,7 +7,7 @@ import { Button, Input } from 'antd';
|
|||||||
import { GripVertical, TableColumnsSplit, X } from 'lucide-react';
|
import { GripVertical, TableColumnsSplit, X } from 'lucide-react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { IPodColumn } from '../utils';
|
import { IEntityColumn } from '../utils';
|
||||||
|
|
||||||
function K8sFiltersSidePanel({
|
function K8sFiltersSidePanel({
|
||||||
defaultAddedColumns,
|
defaultAddedColumns,
|
||||||
@ -17,12 +17,12 @@ function K8sFiltersSidePanel({
|
|||||||
onAddColumn = () => {},
|
onAddColumn = () => {},
|
||||||
onRemoveColumn = () => {},
|
onRemoveColumn = () => {},
|
||||||
}: {
|
}: {
|
||||||
defaultAddedColumns: IPodColumn[];
|
defaultAddedColumns: IEntityColumn[];
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
addedColumns?: IPodColumn[];
|
addedColumns?: IEntityColumn[];
|
||||||
availableColumns?: IPodColumn[];
|
availableColumns?: IEntityColumn[];
|
||||||
onAddColumn?: (column: IPodColumn) => void;
|
onAddColumn?: (column: IEntityColumn) => void;
|
||||||
onRemoveColumn?: (column: IPodColumn) => void;
|
onRemoveColumn?: (column: IEntityColumn) => void;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [searchValue, setSearchValue] = useState('');
|
const [searchValue, setSearchValue] = useState('');
|
||||||
const sidePanelRef = useRef<HTMLDivElement>(null);
|
const sidePanelRef = useRef<HTMLDivElement>(null);
|
||||||
|
@ -12,7 +12,7 @@ import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
|||||||
|
|
||||||
import { K8sCategory } from './constants';
|
import { K8sCategory } from './constants';
|
||||||
import K8sFiltersSidePanel from './K8sFiltersSidePanel/K8sFiltersSidePanel';
|
import K8sFiltersSidePanel from './K8sFiltersSidePanel/K8sFiltersSidePanel';
|
||||||
import { IPodColumn } from './utils';
|
import { IEntityColumn } from './utils';
|
||||||
|
|
||||||
interface K8sHeaderProps {
|
interface K8sHeaderProps {
|
||||||
selectedGroupBy: BaseAutocompleteData[];
|
selectedGroupBy: BaseAutocompleteData[];
|
||||||
@ -20,11 +20,11 @@ interface K8sHeaderProps {
|
|||||||
isLoadingGroupByFilters: boolean;
|
isLoadingGroupByFilters: boolean;
|
||||||
handleFiltersChange: (value: IBuilderQuery['filters']) => void;
|
handleFiltersChange: (value: IBuilderQuery['filters']) => void;
|
||||||
handleGroupByChange: (value: IBuilderQuery['groupBy']) => void;
|
handleGroupByChange: (value: IBuilderQuery['groupBy']) => void;
|
||||||
defaultAddedColumns: IPodColumn[];
|
defaultAddedColumns: IEntityColumn[];
|
||||||
addedColumns?: IPodColumn[];
|
addedColumns?: IEntityColumn[];
|
||||||
availableColumns?: IPodColumn[];
|
availableColumns?: IEntityColumn[];
|
||||||
onAddColumn?: (column: IPodColumn) => void;
|
onAddColumn?: (column: IEntityColumn) => void;
|
||||||
onRemoveColumn?: (column: IPodColumn) => void;
|
onRemoveColumn?: (column: IEntityColumn) => void;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
entity: K8sCategory;
|
entity: K8sCategory;
|
||||||
|
@ -45,9 +45,11 @@ import {
|
|||||||
function K8sNodesList({
|
function K8sNodesList({
|
||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
|
quickFiltersLastUpdated,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
|
quickFiltersLastUpdated: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@ -60,7 +62,7 @@ function K8sNodesList({
|
|||||||
const [orderBy, setOrderBy] = useState<{
|
const [orderBy, setOrderBy] = useState<{
|
||||||
columnName: string;
|
columnName: string;
|
||||||
order: 'asc' | 'desc';
|
order: 'asc' | 'desc';
|
||||||
} | null>(null);
|
} | null>({ columnName: 'cpu', order: 'desc' });
|
||||||
|
|
||||||
const [selectedNodeUID, setselectedNodeUID] = useState<string | null>(null);
|
const [selectedNodeUID, setselectedNodeUID] = useState<string | null>(null);
|
||||||
|
|
||||||
@ -76,12 +78,28 @@ function K8sNodesList({
|
|||||||
{ value: string; label: string }[]
|
{ value: string; label: string }[]
|
||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
|
const queryFilters = useMemo(
|
||||||
|
() =>
|
||||||
|
currentQuery?.builder?.queryData[0]?.filters || {
|
||||||
|
items: [],
|
||||||
|
op: 'and',
|
||||||
|
},
|
||||||
|
[currentQuery?.builder?.queryData],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reset pagination every time quick filters are changed
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentPage(1);
|
||||||
|
}, [quickFiltersLastUpdated]);
|
||||||
|
|
||||||
const createFiltersForSelectedRowData = (
|
const createFiltersForSelectedRowData = (
|
||||||
selectedRowData: K8sNodesRowData,
|
selectedRowData: K8sNodesRowData,
|
||||||
groupBy: IBuilderQuery['groupBy'],
|
groupBy: IBuilderQuery['groupBy'],
|
||||||
): IBuilderQuery['filters'] => {
|
): IBuilderQuery['filters'] => {
|
||||||
const baseFilters: IBuilderQuery['filters'] = {
|
const baseFilters: IBuilderQuery['filters'] = {
|
||||||
items: [],
|
items: [...queryFilters.items],
|
||||||
op: 'and',
|
op: 'and',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,6 +138,7 @@ function K8sNodesList({
|
|||||||
end: Math.floor(maxTime / 1000000),
|
end: Math.floor(maxTime / 1000000),
|
||||||
orderBy,
|
orderBy,
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [minTime, maxTime, orderBy, selectedRowData, groupBy]);
|
}, [minTime, maxTime, orderBy, selectedRowData, groupBy]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -133,8 +152,6 @@ function K8sNodesList({
|
|||||||
enabled: !!fetchGroupedByRowDataQuery && !!selectedRowData,
|
enabled: !!fetchGroupedByRowDataQuery && !!selectedRowData,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { currentQuery } = useQueryBuilder();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: groupByFiltersData,
|
data: groupByFiltersData,
|
||||||
isLoading: isLoadingGroupByFilters,
|
isLoading: isLoadingGroupByFilters,
|
||||||
@ -153,15 +170,6 @@ function K8sNodesList({
|
|||||||
K8sCategory.NODES,
|
K8sCategory.NODES,
|
||||||
);
|
);
|
||||||
|
|
||||||
const queryFilters = useMemo(
|
|
||||||
() =>
|
|
||||||
currentQuery?.builder?.queryData[0]?.filters || {
|
|
||||||
items: [],
|
|
||||||
op: 'and',
|
|
||||||
},
|
|
||||||
[currentQuery?.builder?.queryData],
|
|
||||||
);
|
|
||||||
|
|
||||||
const query = useMemo(() => {
|
const query = useMemo(() => {
|
||||||
const baseQuery = getK8sNodesListQuery();
|
const baseQuery = getK8sNodesListQuery();
|
||||||
const queryPayload = {
|
const queryPayload = {
|
||||||
@ -308,6 +316,7 @@ function K8sNodesList({
|
|||||||
) : (
|
) : (
|
||||||
<div className="expanded-table">
|
<div className="expanded-table">
|
||||||
<Table
|
<Table
|
||||||
|
className="expanded-table-view"
|
||||||
columns={nestedColumns as ColumnType<K8sNodesRowData>[]}
|
columns={nestedColumns as ColumnType<K8sNodesRowData>[]}
|
||||||
dataSource={formattedGroupedByNodesData}
|
dataSource={formattedGroupedByNodesData}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
@ -382,18 +391,6 @@ function K8sNodesList({
|
|||||||
setselectedNodeUID(null);
|
setselectedNodeUID(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showsNodesTable =
|
|
||||||
!isError &&
|
|
||||||
!isLoading &&
|
|
||||||
!isFetching &&
|
|
||||||
!(formattedNodesData.length === 0 && queryFilters.items.length > 0);
|
|
||||||
|
|
||||||
const showNoFilteredNodesMessage =
|
|
||||||
!isFetching &&
|
|
||||||
!isLoading &&
|
|
||||||
formattedNodesData.length === 0 &&
|
|
||||||
queryFilters.items.length > 0;
|
|
||||||
|
|
||||||
const handleGroupByChange = useCallback(
|
const handleGroupByChange = useCallback(
|
||||||
(value: IBuilderQuery['groupBy']) => {
|
(value: IBuilderQuery['groupBy']) => {
|
||||||
const groupBy = [];
|
const groupBy = [];
|
||||||
@ -442,54 +439,53 @@ function K8sNodesList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
{showNoFilteredNodesMessage && (
|
<Table
|
||||||
<div className="no-filtered-hosts-message-container">
|
className="k8s-list-table nodes-list-table"
|
||||||
<div className="no-filtered-hosts-message-content">
|
dataSource={isFetching || isLoading ? [] : formattedNodesData}
|
||||||
<img
|
columns={columns}
|
||||||
src="/Icons/emptyState.svg"
|
pagination={{
|
||||||
alt="thinking-emoji"
|
current: currentPage,
|
||||||
className="empty-state-svg"
|
pageSize,
|
||||||
/>
|
total: totalCount,
|
||||||
|
showSizeChanger: false,
|
||||||
|
hideOnSinglePage: true,
|
||||||
|
}}
|
||||||
|
scroll={{ x: true }}
|
||||||
|
loading={{
|
||||||
|
spinning: isFetching || isLoading,
|
||||||
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
|
}}
|
||||||
|
locale={{
|
||||||
|
emptyText:
|
||||||
|
isFetching || isLoading ? null : (
|
||||||
|
<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">
|
<Typography.Text className="no-filtered-hosts-message">
|
||||||
This query had no results. Edit your query and try again!
|
This query had no results. Edit your query and try again!
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
),
|
||||||
|
}}
|
||||||
|
tableLayout="fixed"
|
||||||
|
onChange={handleTableChange}
|
||||||
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
|
onClick: (): void => handleRowClick(record),
|
||||||
|
className: 'clickable-row',
|
||||||
|
})}
|
||||||
|
expandable={{
|
||||||
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
|
expandIcon: expandRowIconRenderer,
|
||||||
|
expandedRowKeys,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{(isFetching || isLoading) && <LoadingContainer />}
|
|
||||||
|
|
||||||
{showsNodesTable && (
|
|
||||||
<Table
|
|
||||||
className="k8s-list-table nodes-list-table"
|
|
||||||
dataSource={isFetching || isLoading ? [] : formattedNodesData}
|
|
||||||
columns={columns}
|
|
||||||
pagination={{
|
|
||||||
current: currentPage,
|
|
||||||
pageSize,
|
|
||||||
total: totalCount,
|
|
||||||
showSizeChanger: false,
|
|
||||||
hideOnSinglePage: true,
|
|
||||||
}}
|
|
||||||
scroll={{ x: true }}
|
|
||||||
loading={{
|
|
||||||
spinning: isFetching || isLoading,
|
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
|
||||||
}}
|
|
||||||
tableLayout="fixed"
|
|
||||||
onChange={handleTableChange}
|
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
|
||||||
onClick: (): void => handleRowClick(record),
|
|
||||||
className: 'clickable-row',
|
|
||||||
})}
|
|
||||||
expandable={{
|
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
|
||||||
expandIcon: expandRowIconRenderer,
|
|
||||||
expandedRowKeys,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<NodeDetails
|
<NodeDetails
|
||||||
node={selectedNodeData}
|
node={selectedNodeData}
|
||||||
isModalTimeSelection
|
isModalTimeSelection
|
||||||
|
@ -155,6 +155,7 @@ export default function Events({
|
|||||||
id: event.data.id,
|
id: event.data.id,
|
||||||
key: event.data.id,
|
key: event.data.id,
|
||||||
resources_string: event.data.resources_string,
|
resources_string: event.data.resources_string,
|
||||||
|
attributes_string: event.data.attributes_string,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -174,7 +175,9 @@ export default function Events({
|
|||||||
}, [eventsData]);
|
}, [eventsData]);
|
||||||
|
|
||||||
const handleExpandRow = (record: EventDataType): JSX.Element => (
|
const handleExpandRow = (record: EventDataType): JSX.Element => (
|
||||||
<EventContents data={record.resources_string} />
|
<EventContents
|
||||||
|
data={{ ...record.attributes_string, ...record.resources_string }}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePrev = (): void => {
|
const handlePrev = (): void => {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
initialQueryState,
|
initialQueryState,
|
||||||
} from 'constants/queryBuilder';
|
} from 'constants/queryBuilder';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
|
import { filterDuplicateFilters } from 'container/InfraMonitoringK8s/entityDetailUtils';
|
||||||
import {
|
import {
|
||||||
CustomTimeType,
|
CustomTimeType,
|
||||||
Time,
|
Time,
|
||||||
@ -97,22 +98,9 @@ function NodeDetails({
|
|||||||
op: '=',
|
op: '=',
|
||||||
value: node?.meta.k8s_node_name || '',
|
value: node?.meta.k8s_node_name || '',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: uuidv4(),
|
|
||||||
key: {
|
|
||||||
key: QUERY_KEYS.K8S_CLUSTER_NAME,
|
|
||||||
dataType: DataTypes.String,
|
|
||||||
type: 'resource',
|
|
||||||
isColumn: false,
|
|
||||||
isJSON: false,
|
|
||||||
id: 'k8s_node_name--string--resource--false',
|
|
||||||
},
|
|
||||||
op: '=',
|
|
||||||
value: node?.meta.k8s_cluster_name || '',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
[node?.meta.k8s_node_name, node?.meta.k8s_cluster_name],
|
[node?.meta.k8s_node_name],
|
||||||
);
|
);
|
||||||
|
|
||||||
const initialEventsFilters = useMemo(
|
const initialEventsFilters = useMemo(
|
||||||
@ -239,11 +227,13 @@ function NodeDetails({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
op: 'AND',
|
op: 'AND',
|
||||||
items: [
|
items: filterDuplicateFilters(
|
||||||
...primaryFilters,
|
[
|
||||||
...newFilters,
|
...primaryFilters,
|
||||||
...(paginationFilter ? [paginationFilter] : []),
|
...newFilters,
|
||||||
].filter((item): item is TagFilterItem => item !== undefined),
|
...(paginationFilter ? [paginationFilter] : []),
|
||||||
|
].filter((item): item is TagFilterItem => item !== undefined),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -266,12 +256,14 @@ function NodeDetails({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
op: 'AND',
|
op: 'AND',
|
||||||
items: [
|
items: filterDuplicateFilters(
|
||||||
...primaryFilters,
|
[
|
||||||
...value.items.filter(
|
...primaryFilters,
|
||||||
(item) => item.key?.key !== QUERY_KEYS.K8S_NODE_NAME,
|
...value.items.filter(
|
||||||
),
|
(item) => item.key?.key !== QUERY_KEYS.K8S_NODE_NAME,
|
||||||
].filter((item): item is TagFilterItem => item !== undefined),
|
),
|
||||||
|
].filter((item): item is TagFilterItem => item !== undefined),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -64,7 +64,7 @@ export interface K8sNodesRowData {
|
|||||||
|
|
||||||
const nodeGroupColumnConfig = {
|
const nodeGroupColumnConfig = {
|
||||||
title: (
|
title: (
|
||||||
<div className="column-header node-group-header">
|
<div className="column-header entity-group-header">
|
||||||
<Group size={14} /> NODE GROUP
|
<Group size={14} /> NODE GROUP
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
@ -74,6 +74,7 @@ const nodeGroupColumnConfig = {
|
|||||||
width: 150,
|
width: 150,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
sorter: false,
|
sorter: false,
|
||||||
|
className: 'column entity-group-header',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getK8sNodesListQuery = (): K8sNodesListPayload => ({
|
export const getK8sNodesListQuery = (): K8sNodesListPayload => ({
|
||||||
@ -86,7 +87,7 @@ export const getK8sNodesListQuery = (): K8sNodesListPayload => ({
|
|||||||
|
|
||||||
const columnsConfig = [
|
const columnsConfig = [
|
||||||
{
|
{
|
||||||
title: <div className="column-header-left">Node Name</div>,
|
title: <div className="column-header-left name-header">Node Name</div>,
|
||||||
dataIndex: 'nodeName',
|
dataIndex: 'nodeName',
|
||||||
key: 'nodeName',
|
key: 'nodeName',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
@ -95,7 +96,7 @@ const columnsConfig = [
|
|||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <div className="column-header-left">Cluster Name</div>,
|
title: <div className="column-header-left name-header">Cluster Name</div>,
|
||||||
dataIndex: 'clusterName',
|
dataIndex: 'clusterName',
|
||||||
key: 'clusterName',
|
key: 'clusterName',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
@ -15,6 +15,7 @@ import get from 'api/browser/localstorage/get';
|
|||||||
import set from 'api/browser/localstorage/set';
|
import set from 'api/browser/localstorage/set';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { K8sPodsListPayload } from 'api/infraMonitoring/getK8sPodsList';
|
import { K8sPodsListPayload } from 'api/infraMonitoring/getK8sPodsList';
|
||||||
|
import classNames from 'classnames';
|
||||||
import { useGetK8sPodsList } from 'hooks/infraMonitoring/useGetK8sPodsList';
|
import { useGetK8sPodsList } from 'hooks/infraMonitoring/useGetK8sPodsList';
|
||||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
@ -38,7 +39,7 @@ import {
|
|||||||
formatDataForTable,
|
formatDataForTable,
|
||||||
getK8sPodsListColumns,
|
getK8sPodsListColumns,
|
||||||
getK8sPodsListQuery,
|
getK8sPodsListQuery,
|
||||||
IPodColumn,
|
IEntityColumn,
|
||||||
K8sPodsRowData,
|
K8sPodsRowData,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import PodDetails from './PodDetails/PodDetails';
|
import PodDetails from './PodDetails/PodDetails';
|
||||||
@ -47,9 +48,11 @@ import PodDetails from './PodDetails/PodDetails';
|
|||||||
function K8sPodsList({
|
function K8sPodsList({
|
||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
|
quickFiltersLastUpdated,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
|
quickFiltersLastUpdated: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@ -57,9 +60,9 @@ function K8sPodsList({
|
|||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
|
||||||
const [addedColumns, setAddedColumns] = useState<IPodColumn[]>([]);
|
const [addedColumns, setAddedColumns] = useState<IEntityColumn[]>([]);
|
||||||
|
|
||||||
const [availableColumns, setAvailableColumns] = useState<IPodColumn[]>(
|
const [availableColumns, setAvailableColumns] = useState<IEntityColumn[]>(
|
||||||
defaultAvailableColumns,
|
defaultAvailableColumns,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -104,6 +107,11 @@ function K8sPodsList({
|
|||||||
K8sCategory.PODS, // infraMonitoringEntity
|
K8sCategory.PODS, // infraMonitoringEntity
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Reset pagination every time quick filters are changed
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentPage(1);
|
||||||
|
}, [quickFiltersLastUpdated]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const addedColumns = JSON.parse(get('k8sPodsAddedColumns') ?? '[]');
|
const addedColumns = JSON.parse(get('k8sPodsAddedColumns') ?? '[]');
|
||||||
|
|
||||||
@ -124,7 +132,7 @@ function K8sPodsList({
|
|||||||
const [orderBy, setOrderBy] = useState<{
|
const [orderBy, setOrderBy] = useState<{
|
||||||
columnName: string;
|
columnName: string;
|
||||||
order: 'asc' | 'desc';
|
order: 'asc' | 'desc';
|
||||||
} | null>(null);
|
} | null>({ columnName: 'cpu', order: 'desc' });
|
||||||
|
|
||||||
const [selectedPodUID, setSelectedPodUID] = useState<string | null>(null);
|
const [selectedPodUID, setSelectedPodUID] = useState<string | null>(null);
|
||||||
|
|
||||||
@ -162,7 +170,7 @@ function K8sPodsList({
|
|||||||
selectedRowData: K8sPodsRowData,
|
selectedRowData: K8sPodsRowData,
|
||||||
): IBuilderQuery['filters'] => {
|
): IBuilderQuery['filters'] => {
|
||||||
const baseFilters: IBuilderQuery['filters'] = {
|
const baseFilters: IBuilderQuery['filters'] = {
|
||||||
items: [],
|
items: [...query.filters.items],
|
||||||
op: 'and',
|
op: 'and',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -201,6 +209,7 @@ function K8sPodsList({
|
|||||||
end: Math.floor(maxTime / 1000000),
|
end: Math.floor(maxTime / 1000000),
|
||||||
orderBy,
|
orderBy,
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [minTime, maxTime, orderBy, selectedRowData]);
|
}, [minTime, maxTime, orderBy, selectedRowData]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -338,20 +347,8 @@ function K8sPodsList({
|
|||||||
setSelectedPodUID(null);
|
setSelectedPodUID(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showPodsTable =
|
|
||||||
!isError &&
|
|
||||||
!isLoading &&
|
|
||||||
!isFetching &&
|
|
||||||
!(formattedPodsData.length === 0 && queryFilters.items.length > 0);
|
|
||||||
|
|
||||||
const showNoFilteredPodsMessage =
|
|
||||||
!isFetching &&
|
|
||||||
!isLoading &&
|
|
||||||
formattedPodsData.length === 0 &&
|
|
||||||
queryFilters.items.length > 0;
|
|
||||||
|
|
||||||
const handleAddColumn = useCallback(
|
const handleAddColumn = useCallback(
|
||||||
(column: IPodColumn): void => {
|
(column: IEntityColumn): void => {
|
||||||
setAddedColumns((prev) => [...prev, column]);
|
setAddedColumns((prev) => [...prev, column]);
|
||||||
|
|
||||||
setAvailableColumns((prev) => prev.filter((c) => c.value !== column.value));
|
setAvailableColumns((prev) => prev.filter((c) => c.value !== column.value));
|
||||||
@ -378,7 +375,7 @@ function K8sPodsList({
|
|||||||
}, [groupByFiltersData]);
|
}, [groupByFiltersData]);
|
||||||
|
|
||||||
const handleRemoveColumn = useCallback(
|
const handleRemoveColumn = useCallback(
|
||||||
(column: IPodColumn): void => {
|
(column: IEntityColumn): void => {
|
||||||
setAddedColumns((prev) => prev.filter((c) => c.value !== column.value));
|
setAddedColumns((prev) => prev.filter((c) => c.value !== column.value));
|
||||||
|
|
||||||
setAvailableColumns((prev) => [...prev, column]);
|
setAvailableColumns((prev) => [...prev, column]);
|
||||||
@ -505,54 +502,54 @@ function K8sPodsList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
{showNoFilteredPodsMessage && (
|
<Table
|
||||||
<div className="no-filtered-hosts-message-container">
|
className={classNames('k8s-list-table', {
|
||||||
<div className="no-filtered-hosts-message-content">
|
'expanded-k8s-list-table': isGroupedByAttribute,
|
||||||
<img
|
})}
|
||||||
src="/Icons/emptyState.svg"
|
dataSource={isFetching || isLoading ? [] : formattedPodsData}
|
||||||
alt="thinking-emoji"
|
columns={columns}
|
||||||
className="empty-state-svg"
|
pagination={{
|
||||||
/>
|
current: currentPage,
|
||||||
|
pageSize,
|
||||||
|
total: totalCount,
|
||||||
|
showSizeChanger: false,
|
||||||
|
hideOnSinglePage: true,
|
||||||
|
}}
|
||||||
|
loading={{
|
||||||
|
spinning: isFetching || isLoading,
|
||||||
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
|
}}
|
||||||
|
locale={{
|
||||||
|
emptyText:
|
||||||
|
isFetching || isLoading ? null : (
|
||||||
|
<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">
|
<Typography.Text className="no-filtered-hosts-message">
|
||||||
This query had no results. Edit your query and try again!
|
This query had no results. Edit your query and try again!
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
),
|
||||||
|
}}
|
||||||
{(isFetching || isLoading) && <LoadingContainer />}
|
scroll={{ x: true }}
|
||||||
|
tableLayout="fixed"
|
||||||
{showPodsTable && (
|
onChange={handleTableChange}
|
||||||
<Table
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
className="k8s-list-table"
|
onClick: (): void => handleRowClick(record),
|
||||||
dataSource={isFetching || isLoading ? [] : formattedPodsData}
|
className: 'clickable-row',
|
||||||
columns={columns}
|
})}
|
||||||
pagination={{
|
expandable={{
|
||||||
current: currentPage,
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
pageSize,
|
expandIcon: expandRowIconRenderer,
|
||||||
total: totalCount,
|
expandedRowKeys,
|
||||||
showSizeChanger: false,
|
}}
|
||||||
hideOnSinglePage: true,
|
/>
|
||||||
}}
|
|
||||||
loading={{
|
|
||||||
spinning: isFetching || isLoading,
|
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
|
||||||
}}
|
|
||||||
scroll={{ x: true }}
|
|
||||||
tableLayout="fixed"
|
|
||||||
onChange={handleTableChange}
|
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
|
||||||
onClick: (): void => handleRowClick(record),
|
|
||||||
className: 'clickable-row',
|
|
||||||
})}
|
|
||||||
expandable={{
|
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
|
||||||
expandIcon: expandRowIconRenderer,
|
|
||||||
expandedRowKeys,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{selectedPodData && (
|
{selectedPodData && (
|
||||||
<PodDetails
|
<PodDetails
|
||||||
|
@ -155,6 +155,7 @@ export default function Events({
|
|||||||
id: event.data.id,
|
id: event.data.id,
|
||||||
key: event.data.id,
|
key: event.data.id,
|
||||||
resources_string: event.data.resources_string,
|
resources_string: event.data.resources_string,
|
||||||
|
attributes_string: event.data.attributes_string,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -174,7 +175,9 @@ export default function Events({
|
|||||||
}, [eventsData]);
|
}, [eventsData]);
|
||||||
|
|
||||||
const handleExpandRow = (record: EventDataType): JSX.Element => (
|
const handleExpandRow = (record: EventDataType): JSX.Element => (
|
||||||
<EventContents data={record.resources_string} />
|
<EventContents
|
||||||
|
data={{ ...record.attributes_string, ...record.resources_string }}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePrev = (): void => {
|
const handlePrev = (): void => {
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
initialQueryState,
|
initialQueryState,
|
||||||
} from 'constants/queryBuilder';
|
} from 'constants/queryBuilder';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
|
import { filterDuplicateFilters } from 'container/InfraMonitoringK8s/entityDetailUtils';
|
||||||
import {
|
import {
|
||||||
CustomTimeType,
|
CustomTimeType,
|
||||||
Time,
|
Time,
|
||||||
@ -50,7 +51,7 @@ import { PodDetailProps } from './PodDetail.interfaces';
|
|||||||
import PodLogsDetailedView from './PodLogs/PodLogsDetailedView';
|
import PodLogsDetailedView from './PodLogs/PodLogsDetailedView';
|
||||||
import PodTraces from './PodTraces/PodTraces';
|
import PodTraces from './PodTraces/PodTraces';
|
||||||
|
|
||||||
const TimeRangeOffset = 1000000;
|
const TimeRangeOffset = 1000000000;
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
function PodDetails({
|
function PodDetails({
|
||||||
@ -101,19 +102,6 @@ function PodDetails({
|
|||||||
op: '=',
|
op: '=',
|
||||||
value: pod?.meta.k8s_pod_name || '',
|
value: pod?.meta.k8s_pod_name || '',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: uuidv4(),
|
|
||||||
key: {
|
|
||||||
key: QUERY_KEYS.K8S_CLUSTER_NAME,
|
|
||||||
dataType: DataTypes.String,
|
|
||||||
type: 'resource',
|
|
||||||
isColumn: false,
|
|
||||||
isJSON: false,
|
|
||||||
id: 'k8s_pod_name--string--resource--false',
|
|
||||||
},
|
|
||||||
op: '=',
|
|
||||||
value: pod?.meta.k8s_cluster_name || '',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
key: {
|
key: {
|
||||||
@ -129,11 +117,7 @@ function PodDetails({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
[
|
[pod?.meta.k8s_namespace_name, pod?.meta.k8s_pod_name],
|
||||||
pod?.meta.k8s_cluster_name,
|
|
||||||
pod?.meta.k8s_namespace_name,
|
|
||||||
pod?.meta.k8s_pod_name,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const initialEventsFilters = useMemo(
|
const initialEventsFilters = useMemo(
|
||||||
@ -262,11 +246,13 @@ function PodDetails({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
op: 'AND',
|
op: 'AND',
|
||||||
items: [
|
items: filterDuplicateFilters(
|
||||||
...primaryFilters,
|
[
|
||||||
...newFilters,
|
...primaryFilters,
|
||||||
...(paginationFilter ? [paginationFilter] : []),
|
...newFilters,
|
||||||
].filter((item): item is TagFilterItem => item !== undefined),
|
...(paginationFilter ? [paginationFilter] : []),
|
||||||
|
].filter((item): item is TagFilterItem => item !== undefined),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -291,12 +277,14 @@ function PodDetails({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
op: 'AND',
|
op: 'AND',
|
||||||
items: [
|
items: filterDuplicateFilters(
|
||||||
...primaryFilters,
|
[
|
||||||
...value.items.filter(
|
...primaryFilters,
|
||||||
(item) => item.key?.key !== QUERY_KEYS.K8S_POD_NAME,
|
...value.items.filter(
|
||||||
),
|
(item) => item.key?.key !== QUERY_KEYS.K8S_POD_NAME,
|
||||||
].filter((item): item is TagFilterItem => item !== undefined),
|
),
|
||||||
|
].filter((item): item is TagFilterItem => item !== undefined),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -78,8 +78,6 @@ function PodTraces({
|
|||||||
[currentQuery],
|
[currentQuery],
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log({ updatedCurrentQuery });
|
|
||||||
|
|
||||||
const query = updatedCurrentQuery?.builder?.queryData[0] || null;
|
const query = updatedCurrentQuery?.builder?.queryData[0] || null;
|
||||||
|
|
||||||
const { queryData: paginationQueryData } = useUrlQueryData<Pagination>(
|
const { queryData: paginationQueryData } = useUrlQueryData<Pagination>(
|
||||||
|
@ -100,7 +100,13 @@ export function getStrokeColorForLimitUtilization(value: number): string {
|
|||||||
export const getProgressBarText = (percent: number): React.ReactNode =>
|
export const getProgressBarText = (percent: number): React.ReactNode =>
|
||||||
`${percent}%`;
|
`${percent}%`;
|
||||||
|
|
||||||
export function EntityProgressBar({ value }: { value: number }): JSX.Element {
|
export function EntityProgressBar({
|
||||||
|
value,
|
||||||
|
type,
|
||||||
|
}: {
|
||||||
|
value: number;
|
||||||
|
type: 'request' | 'limit';
|
||||||
|
}): JSX.Element {
|
||||||
const percentage = Number((value * 100).toFixed(1));
|
const percentage = Number((value * 100).toFixed(1));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -110,7 +116,11 @@ export function EntityProgressBar({ value }: { value: number }): JSX.Element {
|
|||||||
strokeLinecap="butt"
|
strokeLinecap="butt"
|
||||||
size="small"
|
size="small"
|
||||||
status="normal"
|
status="normal"
|
||||||
strokeColor={getStrokeColorForLimitUtilization(value)}
|
strokeColor={
|
||||||
|
type === 'limit'
|
||||||
|
? getStrokeColorForLimitUtilization(value)
|
||||||
|
: getStrokeColorForRequestUtilization(value)
|
||||||
|
}
|
||||||
className="progress-bar"
|
className="progress-bar"
|
||||||
showInfo={false}
|
showInfo={false}
|
||||||
/>
|
/>
|
||||||
|
@ -150,6 +150,8 @@ export const PodsQuickFiltersConfig: IQuickFiltersConfig[] = [
|
|||||||
isColumn: false,
|
isColumn: false,
|
||||||
isJSON: false,
|
isJSON: false,
|
||||||
},
|
},
|
||||||
|
aggregateOperator: 'noop',
|
||||||
|
aggregateAttribute: 'k8s_pod_cpu_utilization',
|
||||||
dataSource: DataSource.METRICS,
|
dataSource: DataSource.METRICS,
|
||||||
defaultOpen: false,
|
defaultOpen: false,
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
export const filterDuplicateFilters = (
|
||||||
|
filters: TagFilterItem[],
|
||||||
|
): TagFilterItem[] => {
|
||||||
|
const uniqueFilters = [];
|
||||||
|
const seenIds = new Set();
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
for (const filter of filters) {
|
||||||
|
if (!seenIds.has(filter.id)) {
|
||||||
|
seenIds.add(filter.id);
|
||||||
|
uniqueFilters.push(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniqueFilters;
|
||||||
|
};
|
@ -26,16 +26,9 @@ export interface IEntityColumn {
|
|||||||
canRemove: boolean;
|
canRemove: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPodColumn {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
id: string;
|
|
||||||
canRemove: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const columnProgressBarClassName = 'column-progress-bar';
|
const columnProgressBarClassName = 'column-progress-bar';
|
||||||
|
|
||||||
export const defaultAddedColumns: IPodColumn[] = [
|
export const defaultAddedColumns: IEntityColumn[] = [
|
||||||
{
|
{
|
||||||
label: 'Pod name',
|
label: 'Pod name',
|
||||||
value: 'podName',
|
value: 'podName',
|
||||||
@ -78,12 +71,13 @@ export const defaultAddedColumns: IPodColumn[] = [
|
|||||||
id: 'memory',
|
id: 'memory',
|
||||||
canRemove: false,
|
canRemove: false,
|
||||||
},
|
},
|
||||||
{
|
// TODO - Re-enable the column once backend issue is fixed
|
||||||
label: 'Restarts',
|
// {
|
||||||
value: 'restarts',
|
// label: 'Restarts',
|
||||||
id: 'restarts',
|
// value: 'restarts',
|
||||||
canRemove: false,
|
// id: 'restarts',
|
||||||
},
|
// canRemove: false,
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const defaultAvailableColumns = [
|
export const defaultAvailableColumns = [
|
||||||
@ -131,7 +125,7 @@ export const getK8sPodsListQuery = (): K8sPodsListPayload => ({
|
|||||||
|
|
||||||
const podGroupColumnConfig = {
|
const podGroupColumnConfig = {
|
||||||
title: (
|
title: (
|
||||||
<div className="column-header pod-group-header">
|
<div className="column-header entity-group-header">
|
||||||
<Group size={14} /> POD GROUP
|
<Group size={14} /> POD GROUP
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
@ -140,7 +134,7 @@ const podGroupColumnConfig = {
|
|||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
width: 180,
|
width: 180,
|
||||||
sorter: false,
|
sorter: false,
|
||||||
className: 'column column-pod-group',
|
className: 'column entity-group-header',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dummyColumnConfig = {
|
export const dummyColumnConfig = {
|
||||||
@ -160,11 +154,11 @@ const columnsConfig = [
|
|||||||
key: 'podName',
|
key: 'podName',
|
||||||
width: 180,
|
width: 180,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
sorter: true,
|
sorter: false,
|
||||||
className: 'column column-pod-name',
|
className: 'column column-pod-name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <div className="column-header">CPU Req Usage (%)</div>,
|
title: <div className="column-header med-col">CPU Req Usage (%)</div>,
|
||||||
dataIndex: 'cpu_request',
|
dataIndex: 'cpu_request',
|
||||||
key: 'cpu_request',
|
key: 'cpu_request',
|
||||||
width: 180,
|
width: 180,
|
||||||
@ -174,7 +168,7 @@ const columnsConfig = [
|
|||||||
className: `column ${columnProgressBarClassName}`,
|
className: `column ${columnProgressBarClassName}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <div className="column-header">CPU Limit Usage (%)</div>,
|
title: <div className="column-header med-col">CPU Limit Usage (%)</div>,
|
||||||
dataIndex: 'cpu_limit',
|
dataIndex: 'cpu_limit',
|
||||||
key: 'cpu_limit',
|
key: 'cpu_limit',
|
||||||
width: 120,
|
width: 120,
|
||||||
@ -192,7 +186,7 @@ const columnsConfig = [
|
|||||||
className: `column ${columnProgressBarClassName}`,
|
className: `column ${columnProgressBarClassName}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <div className="column-header">Mem Req Usage (%)</div>,
|
title: <div className="column-heade med-col">Mem Req Usage (%)</div>,
|
||||||
dataIndex: 'memory_request',
|
dataIndex: 'memory_request',
|
||||||
key: 'memory_request',
|
key: 'memory_request',
|
||||||
width: 120,
|
width: 120,
|
||||||
@ -201,7 +195,7 @@ const columnsConfig = [
|
|||||||
className: `column ${columnProgressBarClassName}`,
|
className: `column ${columnProgressBarClassName}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <div className="column-header">Mem Limit Usage (%)</div>,
|
title: <div className="column-header med-col">Mem Limit Usage (%)</div>,
|
||||||
dataIndex: 'memory_limit',
|
dataIndex: 'memory_limit',
|
||||||
key: 'memory_limit',
|
key: 'memory_limit',
|
||||||
width: 120,
|
width: 120,
|
||||||
@ -219,20 +213,21 @@ const columnsConfig = [
|
|||||||
align: 'left',
|
align: 'left',
|
||||||
className: `column ${columnProgressBarClassName}`,
|
className: `column ${columnProgressBarClassName}`,
|
||||||
},
|
},
|
||||||
{
|
// TODO - Re-enable the column once backend issue is fixed
|
||||||
title: (
|
// {
|
||||||
<div className="column-header">
|
// title: (
|
||||||
<Tooltip title="Container Restarts">Restarts</Tooltip>
|
// <div className="column-header">
|
||||||
</div>
|
// <Tooltip title="Container Restarts">Restarts</Tooltip>
|
||||||
),
|
// </div>
|
||||||
dataIndex: 'restarts',
|
// ),
|
||||||
key: 'restarts',
|
// dataIndex: 'restarts',
|
||||||
width: 40,
|
// key: 'restarts',
|
||||||
ellipsis: true,
|
// width: 40,
|
||||||
sorter: true,
|
// ellipsis: true,
|
||||||
align: 'left',
|
// sorter: true,
|
||||||
className: `column ${columnProgressBarClassName}`,
|
// align: 'left',
|
||||||
},
|
// className: `column ${columnProgressBarClassName}`,
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const namespaceColumnConfig = {
|
export const namespaceColumnConfig = {
|
||||||
@ -251,7 +246,7 @@ export const nodeColumnConfig = {
|
|||||||
dataIndex: 'node',
|
dataIndex: 'node',
|
||||||
key: 'node',
|
key: 'node',
|
||||||
width: 100,
|
width: 100,
|
||||||
sorter: true,
|
sorter: false,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
className: 'column column-node',
|
className: 'column column-node',
|
||||||
@ -262,7 +257,7 @@ export const clusterColumnConfig = {
|
|||||||
dataIndex: 'cluster',
|
dataIndex: 'cluster',
|
||||||
key: 'cluster',
|
key: 'cluster',
|
||||||
width: 100,
|
width: 100,
|
||||||
sorter: true,
|
sorter: false,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
className: 'column column-cluster',
|
className: 'column column-cluster',
|
||||||
@ -275,7 +270,7 @@ export const columnConfigMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getK8sPodsListColumns = (
|
export const getK8sPodsListColumns = (
|
||||||
addedColumns: IPodColumn[],
|
addedColumns: IEntityColumn[],
|
||||||
groupBy: IBuilderQuery['groupBy'],
|
groupBy: IBuilderQuery['groupBy'],
|
||||||
): ColumnType<K8sPodsRowData>[] => {
|
): ColumnType<K8sPodsRowData>[] => {
|
||||||
const updatedColumnsConfig = [...columnsConfig];
|
const updatedColumnsConfig = [...columnsConfig];
|
||||||
@ -341,7 +336,7 @@ export const formatDataForTable = (
|
|||||||
attribute="CPU Request"
|
attribute="CPU Request"
|
||||||
>
|
>
|
||||||
<div className="progress-container">
|
<div className="progress-container">
|
||||||
<EntityProgressBar value={pod.podCPURequest} />
|
<EntityProgressBar value={pod.podCPURequest} type="request" />
|
||||||
</div>
|
</div>
|
||||||
</ValidateColumnValueWrapper>
|
</ValidateColumnValueWrapper>
|
||||||
),
|
),
|
||||||
@ -352,7 +347,7 @@ export const formatDataForTable = (
|
|||||||
attribute="CPU Limit"
|
attribute="CPU Limit"
|
||||||
>
|
>
|
||||||
<div className="progress-container">
|
<div className="progress-container">
|
||||||
<EntityProgressBar value={pod.podCPULimit} />
|
<EntityProgressBar value={pod.podCPULimit} type="limit" />
|
||||||
</div>
|
</div>
|
||||||
</ValidateColumnValueWrapper>
|
</ValidateColumnValueWrapper>
|
||||||
),
|
),
|
||||||
@ -368,7 +363,7 @@ export const formatDataForTable = (
|
|||||||
attribute="Memory Request"
|
attribute="Memory Request"
|
||||||
>
|
>
|
||||||
<div className="progress-container">
|
<div className="progress-container">
|
||||||
<EntityProgressBar value={pod.podMemoryRequest} />
|
<EntityProgressBar value={pod.podMemoryRequest} type="request" />
|
||||||
</div>
|
</div>
|
||||||
</ValidateColumnValueWrapper>
|
</ValidateColumnValueWrapper>
|
||||||
),
|
),
|
||||||
@ -379,7 +374,7 @@ export const formatDataForTable = (
|
|||||||
attribute="Memory Limit"
|
attribute="Memory Limit"
|
||||||
>
|
>
|
||||||
<div className="progress-container">
|
<div className="progress-container">
|
||||||
<EntityProgressBar value={pod.podMemoryLimit} />
|
<EntityProgressBar value={pod.podMemoryLimit} type="limit" />
|
||||||
</div>
|
</div>
|
||||||
</ValidateColumnValueWrapper>
|
</ValidateColumnValueWrapper>
|
||||||
),
|
),
|
||||||
|
@ -95,6 +95,7 @@ function QueryBuilderSearch({
|
|||||||
isMulti,
|
isMulti,
|
||||||
isFetching,
|
isFetching,
|
||||||
setSearchKey,
|
setSearchKey,
|
||||||
|
setSearchValue,
|
||||||
searchKey,
|
searchKey,
|
||||||
key,
|
key,
|
||||||
exampleQueries,
|
exampleQueries,
|
||||||
@ -145,7 +146,11 @@ function QueryBuilderSearch({
|
|||||||
|
|
||||||
const tagEditHandler = (value: string): void => {
|
const tagEditHandler = (value: string): void => {
|
||||||
updateTag(value);
|
updateTag(value);
|
||||||
handleSearch(value);
|
if (isInfraMonitoring) {
|
||||||
|
setSearchValue(value);
|
||||||
|
} else {
|
||||||
|
handleSearch(value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDisabled = !!searchValue;
|
const isDisabled = !!searchValue;
|
||||||
|
@ -153,6 +153,7 @@ export const useAutoComplete = (
|
|||||||
isMulti,
|
isMulti,
|
||||||
isFetching,
|
isFetching,
|
||||||
setSearchKey,
|
setSearchKey,
|
||||||
|
setSearchValue,
|
||||||
searchKey,
|
searchKey,
|
||||||
key,
|
key,
|
||||||
exampleQueries,
|
exampleQueries,
|
||||||
@ -172,6 +173,7 @@ interface IAutoComplete {
|
|||||||
isMulti: boolean;
|
isMulti: boolean;
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
setSearchKey: (value: string) => void;
|
setSearchKey: (value: string) => void;
|
||||||
|
setSearchValue: (value: string) => void;
|
||||||
searchKey: string;
|
searchKey: string;
|
||||||
key: string;
|
key: string;
|
||||||
exampleQueries: TagFilter[];
|
exampleQueries: TagFilter[];
|
||||||
|
@ -5,12 +5,12 @@ import { TabRoutes } from 'components/RouteTab/types';
|
|||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useLocation } from 'react-use';
|
import { useLocation } from 'react-use';
|
||||||
|
|
||||||
import { Hosts } from './constants';
|
import { Hosts, Kubernetes } from './constants';
|
||||||
|
|
||||||
export default function InfrastructureMonitoringPage(): JSX.Element {
|
export default function InfrastructureMonitoringPage(): JSX.Element {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
const routes: TabRoutes[] = [Hosts];
|
const routes: TabRoutes[] = [Hosts, Kubernetes];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="infra-monitoring-module-container">
|
<div className="infra-monitoring-module-container">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user