Compare commits
4 Commits
v0.100.1
...
chore/k8s-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d758b6981 | ||
|
|
d721c3f316 | ||
|
|
2df1344ee3 | ||
|
|
3fa27f55ac |
@@ -50,6 +50,8 @@ export interface HostListResponse {
|
|||||||
total: number;
|
total: number;
|
||||||
sentAnyHostMetricsData: boolean;
|
sentAnyHostMetricsData: boolean;
|
||||||
isSendingK8SAgentMetrics: boolean;
|
isSendingK8SAgentMetrics: boolean;
|
||||||
|
clusterNames: string[];
|
||||||
|
nodeNames: string[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
47
frontend/src/api/infraMonitoring/getK8sEntityStatus.ts
Normal file
47
frontend/src/api/infraMonitoring/getK8sEntityStatus.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import axios from 'api';
|
||||||
|
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
|
|
||||||
|
export interface K8sRequiredMetadataFields {
|
||||||
|
clusterName: string;
|
||||||
|
nodeName: string;
|
||||||
|
namespaceName: string;
|
||||||
|
podName: string;
|
||||||
|
hasClusterName: boolean;
|
||||||
|
hasNodeName: boolean;
|
||||||
|
hasNamespaceName: boolean;
|
||||||
|
hasDeploymentName: boolean;
|
||||||
|
hasStatefulsetName: boolean;
|
||||||
|
hasDaemonsetName: boolean;
|
||||||
|
hasCronjobName: boolean;
|
||||||
|
hasJobName: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface K8sEntityStatusResponse {
|
||||||
|
didSendPodMetrics: boolean;
|
||||||
|
didSendNodeMetrics: boolean;
|
||||||
|
didSendClusterMetrics: boolean;
|
||||||
|
isSendingOptionalPodMetrics: boolean;
|
||||||
|
isSendingRequiredMetadata: Array<K8sRequiredMetadataFields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getK8sEntityStatus = async (
|
||||||
|
signal?: AbortSignal,
|
||||||
|
headers?: Record<string, string>,
|
||||||
|
): Promise<SuccessResponse<K8sEntityStatusResponse> | ErrorResponse> => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get('/infra_onboarding/k8s/status', {
|
||||||
|
signal,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
error: null,
|
||||||
|
message: 'Success',
|
||||||
|
payload: response.data.data,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return ErrorResponseHandler(error as AxiosError);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -18,11 +18,13 @@ export const REACT_QUERY_KEY = {
|
|||||||
GET_ALL_ALLERTS: 'GET_ALL_ALLERTS',
|
GET_ALL_ALLERTS: 'GET_ALL_ALLERTS',
|
||||||
REMOVE_ALERT_RULE: 'REMOVE_ALERT_RULE',
|
REMOVE_ALERT_RULE: 'REMOVE_ALERT_RULE',
|
||||||
DUPLICATE_ALERT_RULE: 'DUPLICATE_ALERT_RULE',
|
DUPLICATE_ALERT_RULE: 'DUPLICATE_ALERT_RULE',
|
||||||
GET_HOST_LIST: 'GET_HOST_LIST',
|
|
||||||
UPDATE_ALERT_RULE: 'UPDATE_ALERT_RULE',
|
UPDATE_ALERT_RULE: 'UPDATE_ALERT_RULE',
|
||||||
GET_ACTIVE_LICENSE_V3: 'GET_ACTIVE_LICENSE_V3',
|
GET_ACTIVE_LICENSE_V3: 'GET_ACTIVE_LICENSE_V3',
|
||||||
GET_TRACE_V2_WATERFALL: 'GET_TRACE_V2_WATERFALL',
|
GET_TRACE_V2_WATERFALL: 'GET_TRACE_V2_WATERFALL',
|
||||||
GET_TRACE_V2_FLAMEGRAPH: 'GET_TRACE_V2_FLAMEGRAPH',
|
GET_TRACE_V2_FLAMEGRAPH: 'GET_TRACE_V2_FLAMEGRAPH',
|
||||||
|
|
||||||
|
// Infra Monitoring Query Keys
|
||||||
|
GET_HOST_LIST: 'GET_HOST_LIST',
|
||||||
GET_POD_LIST: 'GET_POD_LIST',
|
GET_POD_LIST: 'GET_POD_LIST',
|
||||||
GET_NODE_LIST: 'GET_NODE_LIST',
|
GET_NODE_LIST: 'GET_NODE_LIST',
|
||||||
GET_DEPLOYMENT_LIST: 'GET_DEPLOYMENT_LIST',
|
GET_DEPLOYMENT_LIST: 'GET_DEPLOYMENT_LIST',
|
||||||
@@ -32,6 +34,7 @@ export const REACT_QUERY_KEY = {
|
|||||||
GET_JOB_LIST: 'GET_JOB_LIST',
|
GET_JOB_LIST: 'GET_JOB_LIST',
|
||||||
GET_DAEMONSET_LIST: 'GET_DAEMONSET_LIST,',
|
GET_DAEMONSET_LIST: 'GET_DAEMONSET_LIST,',
|
||||||
GET_VOLUME_LIST: 'GET_VOLUME_LIST',
|
GET_VOLUME_LIST: 'GET_VOLUME_LIST',
|
||||||
|
GET_K8S_ENTITY_STATUS: 'GET_K8S_ENTITY_STATUS',
|
||||||
|
|
||||||
// AWS Integration Query Keys
|
// AWS Integration Query Keys
|
||||||
AWS_ACCOUNTS: 'AWS_ACCOUNTS',
|
AWS_ACCOUNTS: 'AWS_ACCOUNTS',
|
||||||
|
|||||||
@@ -3,10 +3,72 @@ import { Typography } from 'antd';
|
|||||||
export default function HostsEmptyOrIncorrectMetrics({
|
export default function HostsEmptyOrIncorrectMetrics({
|
||||||
noData,
|
noData,
|
||||||
incorrectData,
|
incorrectData,
|
||||||
|
clusterNames,
|
||||||
|
nodeNames,
|
||||||
}: {
|
}: {
|
||||||
noData: boolean;
|
noData: boolean;
|
||||||
incorrectData: boolean;
|
incorrectData: boolean;
|
||||||
|
clusterNames: string[];
|
||||||
|
nodeNames: string[];
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
|
let emptyStateMessage = (
|
||||||
|
<Typography.Text className="no-hosts-message-text">
|
||||||
|
No host metrics were detected. To monitor your hosts, you'll need to
|
||||||
|
send{' '}
|
||||||
|
<a
|
||||||
|
href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/system/system-metrics.md"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
OpenTelemetry system metrics
|
||||||
|
</a>
|
||||||
|
. Check out our host metrics setup guide{' '}
|
||||||
|
<a
|
||||||
|
href="https://signoz.io/docs/userguide/hostmetrics"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</a>{' '}
|
||||||
|
to get started.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nodeNames.length > 0) {
|
||||||
|
const nodeNamesString =
|
||||||
|
nodeNames.length > 1
|
||||||
|
? `${nodeNames.slice(0, -1).join(', ')} and ${
|
||||||
|
nodeNames[nodeNames.length - 1]
|
||||||
|
}`
|
||||||
|
: nodeNames[0];
|
||||||
|
emptyStateMessage = (
|
||||||
|
<Typography.Text className="no-hosts-message-text">
|
||||||
|
The k8s-infra chart version installed in nodes {nodeNamesString} has a known
|
||||||
|
issue where container metrics from agent pods are incorrectly categorized as
|
||||||
|
host metrics. To resolve this, please update to the latest version of the
|
||||||
|
SigNoz k8s-infra chart. Reach out to support if you need help with this.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clusterNames.length > 0) {
|
||||||
|
const clusterNamesString =
|
||||||
|
clusterNames.length > 1
|
||||||
|
? `${clusterNames.slice(0, -1).join(', ')} and ${
|
||||||
|
clusterNames[clusterNames.length - 1]
|
||||||
|
}`
|
||||||
|
: clusterNames[0];
|
||||||
|
emptyStateMessage = (
|
||||||
|
<Typography.Text className="no-hosts-message-text">
|
||||||
|
The k8s-infra chart version installed in clusters {clusterNamesString} has a
|
||||||
|
known issue where container metrics from agent pods are incorrectly
|
||||||
|
categorized as host metrics. To resolve this, please update to the latest
|
||||||
|
version of the SigNoz k8s-infra chart. Reach out to support if you need help
|
||||||
|
with this.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hosts-empty-state-container">
|
<div className="hosts-empty-state-container">
|
||||||
<div className="hosts-empty-state-container-content">
|
<div className="hosts-empty-state-container-content">
|
||||||
@@ -18,29 +80,11 @@ export default function HostsEmptyOrIncorrectMetrics({
|
|||||||
No host metrics data received yet.
|
No host metrics data received yet.
|
||||||
</Typography.Title>
|
</Typography.Title>
|
||||||
|
|
||||||
<Typography.Text className="no-hosts-message-text">
|
{emptyStateMessage}
|
||||||
Infrastructure monitoring requires the{' '}
|
|
||||||
<a
|
|
||||||
href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/system/system-metrics.md"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
OpenTelemetry system metrics
|
|
||||||
</a>
|
|
||||||
. Please refer to{' '}
|
|
||||||
<a
|
|
||||||
href="https://signoz.io/docs/userguide/hostmetrics"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
this
|
|
||||||
</a>{' '}
|
|
||||||
to learn how to send host metrics to SigNoz.
|
|
||||||
</Typography.Text>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{incorrectData && (
|
{!clusterNames.length && !nodeNames.length && incorrectData && (
|
||||||
<Typography.Text className="incorrect-metrics-message">
|
<Typography.Text className="incorrect-metrics-message">
|
||||||
To see host metrics, upgrade to the latest version of SigNoz k8s-infra
|
To see host metrics, upgrade to the latest version of SigNoz k8s-infra
|
||||||
chart. Please contact support if you need help.
|
chart. Please contact support if you need help.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { LoadingOutlined } from '@ant-design/icons';
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
import {
|
import {
|
||||||
Skeleton,
|
|
||||||
Spin,
|
Spin,
|
||||||
Table,
|
Table,
|
||||||
TablePaginationConfig,
|
TablePaginationConfig,
|
||||||
@@ -103,6 +102,8 @@ export default function HostsListTable({
|
|||||||
<HostsEmptyOrIncorrectMetrics
|
<HostsEmptyOrIncorrectMetrics
|
||||||
noData={!sentAnyHostMetricsData}
|
noData={!sentAnyHostMetricsData}
|
||||||
incorrectData={isSendingIncorrectK8SAgentMetrics}
|
incorrectData={isSendingIncorrectK8SAgentMetrics}
|
||||||
|
clusterNames={data?.payload?.data?.clusterNames || []}
|
||||||
|
nodeNames={data?.payload?.data?.nodeNames || []}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -125,31 +126,6 @@ export default function HostsListTable({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<Table
|
<Table
|
||||||
className="hosts-list-table"
|
className="hosts-list-table"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { K8sClustersListPayload } from 'api/infraMonitoring/getK8sClustersList';
|
import { K8sClustersListPayload } from 'api/infraMonitoring/getK8sClustersList';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { useGetK8sClustersList } from 'hooks/infraMonitoring/useGetK8sClustersList';
|
import { useGetK8sClustersList } from 'hooks/infraMonitoring/useGetK8sClustersList';
|
||||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
@@ -30,6 +31,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -47,10 +49,12 @@ function K8sClustersList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -490,54 +494,58 @@ function K8sClustersList({
|
|||||||
entity={K8sCategory.NODES}
|
entity={K8sCategory.NODES}
|
||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
<EntityStatusEmptyStateWrapper
|
||||||
|
category={K8sCategory.CLUSTERS}
|
||||||
|
data={entityStatus}
|
||||||
|
>
|
||||||
|
<Table
|
||||||
|
className="k8s-list-table clusters-list-table"
|
||||||
|
dataSource={isFetching || isLoading ? [] : formattedClustersData}
|
||||||
|
columns={columns}
|
||||||
|
pagination={{
|
||||||
|
current: currentPage,
|
||||||
|
pageSize,
|
||||||
|
total: totalCount,
|
||||||
|
showSizeChanger: true,
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
onChange: onPaginationChange,
|
||||||
|
}}
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
|
||||||
<Table
|
<Typography.Text className="no-filtered-hosts-message">
|
||||||
className="k8s-list-table clusters-list-table"
|
This query had no results. Edit your query and try again!
|
||||||
dataSource={isFetching || isLoading ? [] : formattedClustersData}
|
</Typography.Text>
|
||||||
columns={columns}
|
</div>
|
||||||
pagination={{
|
|
||||||
current: currentPage,
|
|
||||||
pageSize,
|
|
||||||
total: totalCount,
|
|
||||||
showSizeChanger: true,
|
|
||||||
hideOnSinglePage: false,
|
|
||||||
onChange: onPaginationChange,
|
|
||||||
}}
|
|
||||||
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">
|
|
||||||
This query had no results. Edit your query and try again!
|
|
||||||
</Typography.Text>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
),
|
||||||
),
|
}}
|
||||||
}}
|
tableLayout="fixed"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<ClusterDetails
|
<ClusterDetails
|
||||||
cluster={selectedClusterData}
|
cluster={selectedClusterData}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { K8sDaemonSetsListPayload } from 'api/infraMonitoring/getK8sDaemonSetsList';
|
import { K8sDaemonSetsListPayload } from 'api/infraMonitoring/getK8sDaemonSetsList';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useGetK8sDaemonSetsList } from 'hooks/infraMonitoring/useGetK8sDaemonSetsList';
|
import { useGetK8sDaemonSetsList } from 'hooks/infraMonitoring/useGetK8sDaemonSetsList';
|
||||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
@@ -31,6 +32,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -48,10 +50,12 @@ function K8sDaemonSetsList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -498,55 +502,60 @@ function K8sDaemonSetsList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className={classNames('k8s-list-table', 'daemonSets-list-table', {
|
category={K8sCategory.DAEMONSETS}
|
||||||
'expanded-daemonsets-list-table': isGroupedByAttribute,
|
data={entityStatus}
|
||||||
})}
|
>
|
||||||
dataSource={isFetching || isLoading ? [] : formattedDaemonSetsData}
|
<Table
|
||||||
columns={columns}
|
className={classNames('k8s-list-table', 'daemonSets-list-table', {
|
||||||
pagination={{
|
'expanded-daemonsets-list-table': isGroupedByAttribute,
|
||||||
current: currentPage,
|
})}
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedDaemonSetsData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<DaemonSetDetails
|
<DaemonSetDetails
|
||||||
daemonSet={selectedDaemonSetData}
|
daemonSet={selectedDaemonSetData}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import { K8sDeploymentsListPayload } from 'api/infraMonitoring/getK8sDeploymentsList';
|
import { K8sDeploymentsListPayload } from 'api/infraMonitoring/getK8sDeploymentsList';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useGetK8sDeploymentsList } from 'hooks/infraMonitoring/useGetK8sDeploymentsList';
|
import { useGetK8sDeploymentsList } from 'hooks/infraMonitoring/useGetK8sDeploymentsList';
|
||||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
@@ -31,6 +32,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -48,10 +50,12 @@ function K8sDeploymentsList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -502,55 +506,60 @@ function K8sDeploymentsList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className={classNames('k8s-list-table', 'deployments-list-table', {
|
category={K8sCategory.DEPLOYMENTS}
|
||||||
'expanded-deployments-list-table': isGroupedByAttribute,
|
data={entityStatus}
|
||||||
})}
|
>
|
||||||
dataSource={isFetching || isLoading ? [] : formattedDeploymentsData}
|
<Table
|
||||||
columns={columns}
|
className={classNames('k8s-list-table', 'deployments-list-table', {
|
||||||
pagination={{
|
'expanded-deployments-list-table': isGroupedByAttribute,
|
||||||
current: currentPage,
|
})}
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedDeploymentsData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<DeploymentDetails
|
<DeploymentDetails
|
||||||
deployment={selectedDeploymentData}
|
deployment={selectedDeploymentData}
|
||||||
|
|||||||
@@ -0,0 +1,193 @@
|
|||||||
|
import { Typography } from 'antd';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
|
|
||||||
|
import { K8sCategory } from './constants';
|
||||||
|
|
||||||
|
interface EntityStatusEmptyStateProps {
|
||||||
|
category: K8sCategory;
|
||||||
|
data: K8sEntityStatusResponse | null | undefined;
|
||||||
|
children: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
|
function EntityStatusEmptyStateWrapper({
|
||||||
|
category,
|
||||||
|
data,
|
||||||
|
children,
|
||||||
|
}: EntityStatusEmptyStateProps): JSX.Element {
|
||||||
|
if (!data) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
didSendPodMetrics,
|
||||||
|
didSendNodeMetrics,
|
||||||
|
didSendClusterMetrics,
|
||||||
|
isSendingOptionalPodMetrics,
|
||||||
|
isSendingRequiredMetadata,
|
||||||
|
} = data;
|
||||||
|
|
||||||
|
const metaData = isSendingRequiredMetadata.length
|
||||||
|
? isSendingRequiredMetadata[0]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const noK8sMetrics = (
|
||||||
|
<Typography.Text>
|
||||||
|
No k8s metrics were detected. To monitor your k8s infra, you will need to
|
||||||
|
send{' '}
|
||||||
|
<Typography.Link href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/kubeletstatsreceiver">
|
||||||
|
kubelet
|
||||||
|
</Typography.Link>{' '}
|
||||||
|
and{' '}
|
||||||
|
<Typography.Link href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/k8sclusterreceiver">
|
||||||
|
k8scluster
|
||||||
|
</Typography.Link>{' '}
|
||||||
|
metrics. Check out our k8s infra installation guide{' '}
|
||||||
|
<Typography.Link href="https://signoz.io/docs/tutorial/kubernetes-infra-metrics/">
|
||||||
|
here
|
||||||
|
</Typography.Link>{' '}
|
||||||
|
to get started. Reach out to support if you need further assistance.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
|
||||||
|
const partialMetrics = (
|
||||||
|
<Typography.Text>
|
||||||
|
Partial metrics detected. The following metrics from the kubelet metrics are
|
||||||
|
not received. They help monitor the resource utilisation to their
|
||||||
|
requests/limits. Learn more{' '}
|
||||||
|
<Typography.Link
|
||||||
|
// TODO: Add link to docs
|
||||||
|
href="placeholder"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</Typography.Link>{' '}
|
||||||
|
about how to send them. Reach out to support if you need further assistance.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
|
||||||
|
const noMetadata = (
|
||||||
|
<Typography>
|
||||||
|
The following shows the sample pods without required metadata. Learn more{' '}
|
||||||
|
<Typography.Link
|
||||||
|
// TODO: Add link to docs
|
||||||
|
href="placeholder"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</Typography.Link>{' '}
|
||||||
|
on how to send enriched data for k8s metrics
|
||||||
|
<ul>
|
||||||
|
{!metaData?.hasClusterName && <li>No cluster name found</li>}
|
||||||
|
{!metaData?.hasNodeName && <li>No node name found</li>}
|
||||||
|
{!metaData?.hasNamespaceName && <li>No namespace found</li>}
|
||||||
|
{!metaData?.hasDeploymentName &&
|
||||||
|
!metaData?.hasStatefulsetName &&
|
||||||
|
!metaData?.hasDaemonsetName &&
|
||||||
|
!metaData?.hasCronjobName &&
|
||||||
|
!metaData?.hasJobName && (
|
||||||
|
<li>
|
||||||
|
Pod doesn't have any of the following set:
|
||||||
|
<ul>
|
||||||
|
<li>deployment</li>
|
||||||
|
<li>daemonset</li>
|
||||||
|
<li>statefulset</li>
|
||||||
|
<li>job</li>
|
||||||
|
<li>cronjob</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
|
||||||
|
const noNodeMetrics = (
|
||||||
|
<Typography.Text>
|
||||||
|
No node metrics were detected. This is likely due to not adding
|
||||||
|
"node" to the metric groups of kubelet receiver. Please update the
|
||||||
|
config and check back. Learn more{' '}
|
||||||
|
<Typography.Link
|
||||||
|
// TODO: Add link to docs
|
||||||
|
href="placeholder"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</Typography.Link>
|
||||||
|
. Reach out to support if you need further assistance.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
|
||||||
|
const noClusterMetrics = (
|
||||||
|
<Typography.Text>
|
||||||
|
We are receiving kubelet metrics but not k8scluster receiver metrics. Follow
|
||||||
|
the cluster metrics setup{' '}
|
||||||
|
<Typography.Link
|
||||||
|
// TODO: Add link to docs
|
||||||
|
href="placeholder"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</Typography.Link>
|
||||||
|
. Reach out to support if you need further assistance.
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
|
||||||
|
let emptyStateContent;
|
||||||
|
|
||||||
|
if (category === K8sCategory.NODES) {
|
||||||
|
console.log({ didSendPodMetrics, didSendNodeMetrics });
|
||||||
|
if (didSendPodMetrics && !didSendNodeMetrics) {
|
||||||
|
emptyStateContent = noNodeMetrics;
|
||||||
|
} else if (!didSendClusterMetrics && !didSendNodeMetrics) {
|
||||||
|
emptyStateContent = noK8sMetrics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category === K8sCategory.NAMESPACES && !didSendPodMetrics) {
|
||||||
|
emptyStateContent = noK8sMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category === K8sCategory.CLUSTERS) {
|
||||||
|
if (didSendPodMetrics && !didSendClusterMetrics) {
|
||||||
|
emptyStateContent = noClusterMetrics;
|
||||||
|
}
|
||||||
|
if (!didSendPodMetrics && !didSendClusterMetrics) {
|
||||||
|
emptyStateContent = noK8sMetrics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
K8sCategory.PODS,
|
||||||
|
K8sCategory.NAMESPACES,
|
||||||
|
K8sCategory.DEPLOYMENTS,
|
||||||
|
K8sCategory.DAEMONSETS,
|
||||||
|
K8sCategory.JOBS,
|
||||||
|
K8sCategory.STATEFULSETS,
|
||||||
|
].includes(category)
|
||||||
|
) {
|
||||||
|
if (!didSendPodMetrics && !isSendingOptionalPodMetrics) {
|
||||||
|
emptyStateContent = noK8sMetrics;
|
||||||
|
} else if (didSendPodMetrics && !isSendingOptionalPodMetrics) {
|
||||||
|
emptyStateContent = partialMetrics;
|
||||||
|
} else if (isSendingRequiredMetadata.length > 0) {
|
||||||
|
emptyStateContent = noMetadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emptyStateContent) {
|
||||||
|
return (
|
||||||
|
<div className="entity-status-empty-state-container">
|
||||||
|
<img
|
||||||
|
src="/Icons/emptyState.svg"
|
||||||
|
alt="thinking-emoji"
|
||||||
|
className="empty-state-svg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Typography.Text className="entity-status-empty-state-message">
|
||||||
|
{emptyStateContent}
|
||||||
|
</Typography.Text>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EntityStatusEmptyStateWrapper;
|
||||||
@@ -888,3 +888,16 @@
|
|||||||
.expanded-clickable-row {
|
.expanded-clickable-row {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entity-status-empty-state-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 48px 120px;
|
||||||
|
|
||||||
|
.entity-status-empty-state-message {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Collapse, Tooltip, Typography } from 'antd';
|
|||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import QuickFilters from 'components/QuickFilters/QuickFilters';
|
import QuickFilters from 'components/QuickFilters/QuickFilters';
|
||||||
import { QuickFiltersSource } from 'components/QuickFilters/types';
|
import { QuickFiltersSource } from 'components/QuickFilters/types';
|
||||||
|
import { useGetK8sEntityStatus } from 'hooks/infraMonitoring/useGetK8sEntityStatus';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||||
import {
|
import {
|
||||||
@@ -54,6 +55,9 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
|
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
|
const { data: k8sEntityStatusData } = useGetK8sEntityStatus();
|
||||||
|
const k8sEntityStatus = k8sEntityStatusData?.payload;
|
||||||
|
|
||||||
const handleFilterVisibilityChange = (): void => {
|
const handleFilterVisibilityChange = (): void => {
|
||||||
setShowFilters(!showFilters);
|
setShowFilters(!showFilters);
|
||||||
};
|
};
|
||||||
@@ -335,6 +339,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -343,6 +348,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -351,6 +357,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -359,6 +366,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -367,6 +375,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -375,6 +384,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -383,6 +393,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -391,6 +402,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -399,6 +411,7 @@ export default function InfraMonitoringK8s(): JSX.Element {
|
|||||||
isFiltersVisible={showFilters}
|
isFiltersVisible={showFilters}
|
||||||
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
handleFilterVisibilityChange={handleFilterVisibilityChange}
|
||||||
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
quickFiltersLastUpdated={quickFiltersLastUpdated}
|
||||||
|
entityStatus={k8sEntityStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { K8sJobsListPayload } from 'api/infraMonitoring/getK8sJobsList';
|
import { K8sJobsListPayload } from 'api/infraMonitoring/getK8sJobsList';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useGetK8sJobsList } from 'hooks/infraMonitoring/useGetK8sJobsList';
|
import { useGetK8sJobsList } from 'hooks/infraMonitoring/useGetK8sJobsList';
|
||||||
@@ -31,6 +32,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -48,10 +50,12 @@ function K8sJobsList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -474,56 +478,60 @@ function K8sJobsList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className={classNames('k8s-list-table', 'jobs-list-table', {
|
category={K8sCategory.JOBS}
|
||||||
'expanded-jobs-list-table': isGroupedByAttribute,
|
data={entityStatus}
|
||||||
})}
|
>
|
||||||
dataSource={isFetching || isLoading ? [] : formattedJobsData}
|
<Table
|
||||||
columns={columns}
|
className={classNames('k8s-list-table', 'jobs-list-table', {
|
||||||
pagination={{
|
'expanded-jobs-list-table': isGroupedByAttribute,
|
||||||
current: currentPage,
|
})}
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedJobsData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<JobDetails
|
<JobDetails
|
||||||
job={selectedJobData}
|
job={selectedJobData}
|
||||||
isModalTimeSelection
|
isModalTimeSelection
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { K8sNamespacesListPayload } from 'api/infraMonitoring/getK8sNamespacesList';
|
import { K8sNamespacesListPayload } from 'api/infraMonitoring/getK8sNamespacesList';
|
||||||
import { useGetK8sNamespacesList } from 'hooks/infraMonitoring/useGetK8sNamespacesList';
|
import { useGetK8sNamespacesList } from 'hooks/infraMonitoring/useGetK8sNamespacesList';
|
||||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
@@ -30,6 +31,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -47,10 +49,12 @@ function K8sNamespacesList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -499,53 +503,59 @@ function K8sNamespacesList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className="k8s-list-table namespaces-list-table"
|
category={K8sCategory.NAMESPACES}
|
||||||
dataSource={isFetching || isLoading ? [] : formattedNamespacesData}
|
data={entityStatus}
|
||||||
columns={columns}
|
>
|
||||||
pagination={{
|
<Table
|
||||||
current: currentPage,
|
className="k8s-list-table namespaces-list-table"
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedNamespacesData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<NamespaceDetails
|
<NamespaceDetails
|
||||||
namespace={selectedNamespaceData}
|
namespace={selectedNamespaceData}
|
||||||
isModalTimeSelection
|
isModalTimeSelection
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { K8sNodesListPayload } from 'api/infraMonitoring/getK8sNodesList';
|
import { K8sNodesListPayload } from 'api/infraMonitoring/getK8sNodesList';
|
||||||
import { useGetK8sNodesList } from 'hooks/infraMonitoring/useGetK8sNodesList';
|
import { useGetK8sNodesList } from 'hooks/infraMonitoring/useGetK8sNodesList';
|
||||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
@@ -30,6 +31,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -47,10 +49,12 @@ function K8sNodesList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -477,53 +481,58 @@ function K8sNodesList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className="k8s-list-table nodes-list-table"
|
category={K8sCategory.NODES}
|
||||||
dataSource={isFetching || isLoading ? [] : formattedNodesData}
|
data={entityStatus}
|
||||||
columns={columns}
|
>
|
||||||
pagination={{
|
<Table
|
||||||
current: currentPage,
|
className="k8s-list-table nodes-list-table"
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedNodesData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<NodeDetails
|
<NodeDetails
|
||||||
node={selectedNodeData}
|
node={selectedNodeData}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
|||||||
import get from 'api/browser/localstorage/get';
|
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 { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { K8sPodsListPayload } from 'api/infraMonitoring/getK8sPodsList';
|
import { K8sPodsListPayload } from 'api/infraMonitoring/getK8sPodsList';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useGetK8sPodsList } from 'hooks/infraMonitoring/useGetK8sPodsList';
|
import { useGetK8sPodsList } from 'hooks/infraMonitoring/useGetK8sPodsList';
|
||||||
@@ -31,6 +32,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import {
|
import {
|
||||||
@@ -50,10 +52,12 @@ function K8sPodsList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -538,55 +542,60 @@ function K8sPodsList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className={classNames('k8s-list-table', {
|
category={K8sCategory.PODS}
|
||||||
'expanded-k8s-list-table': isGroupedByAttribute,
|
data={entityStatus}
|
||||||
})}
|
>
|
||||||
dataSource={isFetching || isLoading ? [] : formattedPodsData}
|
<Table
|
||||||
columns={columns}
|
className={classNames('k8s-list-table', {
|
||||||
pagination={{
|
'expanded-k8s-list-table': isGroupedByAttribute,
|
||||||
current: currentPage,
|
})}
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedPodsData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
loading={{
|
showSizeChanger: true,
|
||||||
spinning: isFetching || isLoading,
|
hideOnSinglePage: false,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
onChange: onPaginationChange,
|
||||||
}}
|
}}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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>
|
),
|
||||||
),
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
scroll={{ x: true }}
|
tableLayout="fixed"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
{selectedPodData && (
|
{selectedPodData && (
|
||||||
<PodDetails
|
<PodDetails
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { K8sStatefulSetsListPayload } from 'api/infraMonitoring/getsK8sStatefulSetsList';
|
import { K8sStatefulSetsListPayload } from 'api/infraMonitoring/getsK8sStatefulSetsList';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useGetK8sStatefulSetsList } from 'hooks/infraMonitoring/useGetK8sStatefulSetsList';
|
import { useGetK8sStatefulSetsList } from 'hooks/infraMonitoring/useGetK8sStatefulSetsList';
|
||||||
@@ -31,6 +32,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -48,10 +50,12 @@ function K8sStatefulSetsList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -499,55 +503,60 @@ function K8sStatefulSetsList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className={classNames('k8s-list-table', 'statefulSets-list-table', {
|
category={K8sCategory.STATEFULSETS}
|
||||||
'expanded-statefulsets-list-table': isGroupedByAttribute,
|
data={entityStatus}
|
||||||
})}
|
>
|
||||||
dataSource={isFetching || isLoading ? [] : formattedStatefulSetsData}
|
<Table
|
||||||
columns={columns}
|
className={classNames('k8s-list-table', 'statefulSets-list-table', {
|
||||||
pagination={{
|
'expanded-statefulsets-list-table': isGroupedByAttribute,
|
||||||
current: currentPage,
|
})}
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedStatefulSetsData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<StatefulSetDetails
|
<StatefulSetDetails
|
||||||
statefulSet={selectedStatefulSetData}
|
statefulSet={selectedStatefulSetData}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
import { ColumnType, SorterResult } from 'antd/es/table/interface';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { K8sEntityStatusResponse } from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
import { K8sVolumesListPayload } from 'api/infraMonitoring/getK8sVolumesList';
|
import { K8sVolumesListPayload } from 'api/infraMonitoring/getK8sVolumesList';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useGetK8sVolumesList } from 'hooks/infraMonitoring/useGetK8sVolumesList';
|
import { useGetK8sVolumesList } from 'hooks/infraMonitoring/useGetK8sVolumesList';
|
||||||
@@ -31,6 +32,7 @@ import {
|
|||||||
K8sCategory,
|
K8sCategory,
|
||||||
K8sEntityToAggregateAttributeMapping,
|
K8sEntityToAggregateAttributeMapping,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import EntityStatusEmptyStateWrapper from '../EntityStatusEmptyStateWrapper';
|
||||||
import K8sHeader from '../K8sHeader';
|
import K8sHeader from '../K8sHeader';
|
||||||
import LoadingContainer from '../LoadingContainer';
|
import LoadingContainer from '../LoadingContainer';
|
||||||
import { usePageSize } from '../utils';
|
import { usePageSize } from '../utils';
|
||||||
@@ -48,10 +50,12 @@ function K8sVolumesList({
|
|||||||
isFiltersVisible,
|
isFiltersVisible,
|
||||||
handleFilterVisibilityChange,
|
handleFilterVisibilityChange,
|
||||||
quickFiltersLastUpdated,
|
quickFiltersLastUpdated,
|
||||||
|
entityStatus,
|
||||||
}: {
|
}: {
|
||||||
isFiltersVisible: boolean;
|
isFiltersVisible: boolean;
|
||||||
handleFilterVisibilityChange: () => void;
|
handleFilterVisibilityChange: () => void;
|
||||||
quickFiltersLastUpdated: number;
|
quickFiltersLastUpdated: number;
|
||||||
|
entityStatus: K8sEntityStatusResponse | null | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
@@ -484,55 +488,60 @@ function K8sVolumesList({
|
|||||||
/>
|
/>
|
||||||
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
{isError && <Typography>{data?.error || 'Something went wrong'}</Typography>}
|
||||||
|
|
||||||
<Table
|
<EntityStatusEmptyStateWrapper
|
||||||
className={classNames('k8s-list-table', 'volumes-list-table', {
|
category={K8sCategory.VOLUMES}
|
||||||
'expanded-volumes-list-table': isGroupedByAttribute,
|
data={entityStatus}
|
||||||
})}
|
>
|
||||||
dataSource={isFetching || isLoading ? [] : formattedVolumesData}
|
<Table
|
||||||
columns={columns}
|
className={classNames('k8s-list-table', 'volumes-list-table', {
|
||||||
pagination={{
|
'expanded-volumes-list-table': isGroupedByAttribute,
|
||||||
current: currentPage,
|
})}
|
||||||
pageSize,
|
dataSource={isFetching || isLoading ? [] : formattedVolumesData}
|
||||||
total: totalCount,
|
columns={columns}
|
||||||
showSizeChanger: true,
|
pagination={{
|
||||||
hideOnSinglePage: false,
|
current: currentPage,
|
||||||
onChange: onPaginationChange,
|
pageSize,
|
||||||
}}
|
total: totalCount,
|
||||||
scroll={{ x: true }}
|
showSizeChanger: true,
|
||||||
loading={{
|
hideOnSinglePage: false,
|
||||||
spinning: isFetching || isLoading,
|
onChange: onPaginationChange,
|
||||||
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
}}
|
||||||
}}
|
scroll={{ x: true }}
|
||||||
locale={{
|
loading={{
|
||||||
emptyText:
|
spinning: isFetching || isLoading,
|
||||||
isFetching || isLoading ? null : (
|
indicator: <Spin indicator={<LoadingOutlined size={14} spin />} />,
|
||||||
<div className="no-filtered-hosts-message-container">
|
}}
|
||||||
<div className="no-filtered-hosts-message-content">
|
locale={{
|
||||||
<img
|
emptyText:
|
||||||
src="/Icons/emptyState.svg"
|
isFetching || isLoading ? null : (
|
||||||
alt="thinking-emoji"
|
<div className="no-filtered-hosts-message-container">
|
||||||
className="empty-state-svg"
|
<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"
|
||||||
tableLayout="fixed"
|
onChange={handleTableChange}
|
||||||
onChange={handleTableChange}
|
onRow={(record): { onClick: () => void; className: string } => ({
|
||||||
onRow={(record): { onClick: () => void; className: string } => ({
|
onClick: (): void => handleRowClick(record),
|
||||||
onClick: (): void => handleRowClick(record),
|
className: 'clickable-row',
|
||||||
className: 'clickable-row',
|
})}
|
||||||
})}
|
expandable={{
|
||||||
expandable={{
|
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
||||||
expandedRowRender: isGroupedByAttribute ? expandedRowRender : undefined,
|
expandIcon: expandRowIconRenderer,
|
||||||
expandIcon: expandRowIconRenderer,
|
expandedRowKeys,
|
||||||
expandedRowKeys,
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</EntityStatusEmptyStateWrapper>
|
||||||
|
|
||||||
<VolumeDetails
|
<VolumeDetails
|
||||||
volume={selectedVolumeData}
|
volume={selectedVolumeData}
|
||||||
|
|||||||
45
frontend/src/hooks/infraMonitoring/useGetK8sEntityStatus.ts
Normal file
45
frontend/src/hooks/infraMonitoring/useGetK8sEntityStatus.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import {
|
||||||
|
getK8sEntityStatus,
|
||||||
|
K8sEntityStatusResponse,
|
||||||
|
} from 'api/infraMonitoring/getK8sEntityStatus';
|
||||||
|
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { useQuery, UseQueryOptions, UseQueryResult } from 'react-query';
|
||||||
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
|
|
||||||
|
type UseGetK8sEntityStatus = (
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
SuccessResponse<K8sEntityStatusResponse> | ErrorResponse,
|
||||||
|
Error
|
||||||
|
>,
|
||||||
|
headers?: Record<string, string>,
|
||||||
|
) => UseQueryResult<
|
||||||
|
SuccessResponse<K8sEntityStatusResponse> | ErrorResponse,
|
||||||
|
Error
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const useGetK8sEntityStatus: UseGetK8sEntityStatus = (
|
||||||
|
options,
|
||||||
|
headers,
|
||||||
|
) => {
|
||||||
|
const queryKey = useMemo(() => {
|
||||||
|
if (options?.queryKey && Array.isArray(options.queryKey)) {
|
||||||
|
return [...options.queryKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.queryKey && typeof options.queryKey === 'string') {
|
||||||
|
return options.queryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [REACT_QUERY_KEY.GET_K8S_ENTITY_STATUS];
|
||||||
|
}, [options?.queryKey]);
|
||||||
|
|
||||||
|
return useQuery<
|
||||||
|
SuccessResponse<K8sEntityStatusResponse> | ErrorResponse,
|
||||||
|
Error
|
||||||
|
>({
|
||||||
|
queryFn: ({ signal }) => getK8sEntityStatus(signal, headers),
|
||||||
|
...options,
|
||||||
|
queryKey,
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user