mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Switch to use KubeResourceStatusIcon
Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>
This commit is contained in:
parent
42829ade73
commit
9faea8885a
5
extensions/event-resource-status/Makefile
Normal file
5
extensions/event-resource-status/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
install-deps:
|
||||||
|
npm install
|
||||||
|
|
||||||
|
build: install-deps
|
||||||
|
npm run build
|
||||||
3512
extensions/event-resource-status/package-lock.json
generated
Normal file
3512
extensions/event-resource-status/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
extensions/event-resource-status/package.json
Normal file
23
extensions/event-resource-status/package.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "event-resource-status",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Adds resource status from events",
|
||||||
|
"renderer": "dist/renderer.js",
|
||||||
|
"lens": {
|
||||||
|
"metadata": {},
|
||||||
|
"styles": []
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --config webpack.config.js",
|
||||||
|
"dev": "npm run build --watch"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"@k8slens/extensions": "file:../../src/extensions/npm/extensions",
|
||||||
|
"ts-loader": "^8.0.4",
|
||||||
|
"typescript": "^4.0.3",
|
||||||
|
"webpack": "^4.44.2",
|
||||||
|
"mobx": "^5.15.5",
|
||||||
|
"react": "^16.13.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
42
extensions/event-resource-status/renderer.tsx
Normal file
42
extensions/event-resource-status/renderer.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { LensRendererExtension, K8sApi } from "@k8slens/extensions";
|
||||||
|
import { resolveStatus, resolveStatusForCronJobs, resolveStatusForPods } from "./src/resolver"
|
||||||
|
|
||||||
|
export default class NodeMenuRendererExtension extends LensRendererExtension {
|
||||||
|
resourceStatusTexts = [
|
||||||
|
{
|
||||||
|
kind: "Pod",
|
||||||
|
apiVersions: ["v1"],
|
||||||
|
resolve: (object: K8sApi.Pod) => resolveStatusForPods(object)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "ReplicaSet",
|
||||||
|
apiVersions: ["v1"],
|
||||||
|
resolve: (object: K8sApi.KubeObject) => resolveStatus(object)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "Deployment",
|
||||||
|
apiVersions: ["apps/v1"],
|
||||||
|
resolve: (object: K8sApi.KubeObject) => resolveStatus(object)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "StatefulSet",
|
||||||
|
apiVersions: ["apps/v1"],
|
||||||
|
resolve: (object: K8sApi.KubeObject) => resolveStatus(object)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "DaemonSet",
|
||||||
|
apiVersions: ["apps/v1"],
|
||||||
|
resolve: (object: K8sApi.KubeObject) => resolveStatus(object)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "Job",
|
||||||
|
apiVersions: ["batch/v1"],
|
||||||
|
resolve: (object: K8sApi.KubeObject) => resolveStatus(object)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "CronJob",
|
||||||
|
apiVersions: ["batch/v1"],
|
||||||
|
resolve: (cronJob: K8sApi.CronJob) => resolveStatusForCronJobs(cronJob)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
52
extensions/event-resource-status/src/resolver.tsx
Normal file
52
extensions/event-resource-status/src/resolver.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { ResourceStatus, K8sApi } from "@k8slens/extensions";
|
||||||
|
|
||||||
|
export function resolveStatus(object: K8sApi.KubeObject): ResourceStatus.Status {
|
||||||
|
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||||
|
const events = (eventStore as K8sApi.EventStore).getEventsByObject(object);
|
||||||
|
let warnings = events.filter(evt => evt.isWarning());
|
||||||
|
if (!events.length || !warnings.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const event = [...warnings, ...events][0]; // get latest event
|
||||||
|
return {
|
||||||
|
level: ResourceStatus.Level.WARNING,
|
||||||
|
text: `${event.message}`,
|
||||||
|
timestamp: event.metadata.creationTimestamp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveStatusForPods(pod: K8sApi.Pod): ResourceStatus.Status {
|
||||||
|
if (!pod.hasIssues()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||||
|
const events = (eventStore as K8sApi.EventStore).getEventsByObject(pod);
|
||||||
|
let warnings = events.filter(evt => evt.isWarning());
|
||||||
|
if (!events.length || !warnings.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const event = [...warnings, ...events][0]; // get latest event
|
||||||
|
return {
|
||||||
|
level: ResourceStatus.Level.WARNING,
|
||||||
|
text: `${event.message}`,
|
||||||
|
timestamp: event.metadata.creationTimestamp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveStatusForCronJobs(cronJob: K8sApi.CronJob): ResourceStatus.Status {
|
||||||
|
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||||
|
let events = (eventStore as K8sApi.EventStore).getEventsByObject(cronJob);
|
||||||
|
let warnings = events.filter(evt => evt.isWarning());
|
||||||
|
if (cronJob.isNeverRun()) {
|
||||||
|
events = events.filter(event => event.reason != "FailedNeedsStart");
|
||||||
|
}
|
||||||
|
if (!events.length || !warnings.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const event = [...warnings, ...events][0]; // get latest event
|
||||||
|
return {
|
||||||
|
level: ResourceStatus.Level.WARNING,
|
||||||
|
text: `${event.message}`,
|
||||||
|
timestamp: event.metadata.creationTimestamp
|
||||||
|
}
|
||||||
|
}
|
||||||
26
extensions/event-resource-status/tsconfig.json
Normal file
26
extensions/event-resource-status/tsconfig.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"module": "CommonJS",
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"sourceMap": false,
|
||||||
|
"declaration": false,
|
||||||
|
"strict": false,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"jsx": "react"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./*.ts",
|
||||||
|
"./*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"*.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
35
extensions/event-resource-status/webpack.config.js
Normal file
35
extensions/event-resource-status/webpack.config.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
entry: './renderer.tsx',
|
||||||
|
context: __dirname,
|
||||||
|
target: "electron-renderer",
|
||||||
|
mode: "production",
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
externals: [
|
||||||
|
{
|
||||||
|
"@k8slens/extensions": "var global.LensExtensions",
|
||||||
|
"react": "var global.React",
|
||||||
|
"mobx": "var global.Mobx"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
extensions: [ '.tsx', '.ts', '.js' ],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
libraryTarget: "commonjs2",
|
||||||
|
globalObject: "this",
|
||||||
|
filename: 'renderer.js',
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
@ -190,7 +190,8 @@
|
|||||||
"node-menu",
|
"node-menu",
|
||||||
"metrics-cluster-feature",
|
"metrics-cluster-feature",
|
||||||
"license-menu-item",
|
"license-menu-item",
|
||||||
"support-page"
|
"support-page",
|
||||||
|
"event-resource-status"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -59,11 +59,8 @@ export class ExtensionLoader {
|
|||||||
this.autoloadExtensions((extension: LensRendererExtension) => {
|
this.autoloadExtensions((extension: LensRendererExtension) => {
|
||||||
extension.registerTo(clusterPageRegistry, extension.clusterPages)
|
extension.registerTo(clusterPageRegistry, extension.clusterPages)
|
||||||
extension.registerTo(kubeObjectMenuRegistry, extension.kubeObjectMenuItems)
|
extension.registerTo(kubeObjectMenuRegistry, extension.kubeObjectMenuItems)
|
||||||
<<<<<<< HEAD
|
|
||||||
extension.registerTo(kubeObjectDetailRegistry, extension.kubeObjectDetailItems)
|
extension.registerTo(kubeObjectDetailRegistry, extension.kubeObjectDetailItems)
|
||||||
=======
|
|
||||||
extension.registerTo(resourceStatusRegistry, extension.resourceStatusTexts)
|
extension.registerTo(resourceStatusRegistry, extension.resourceStatusTexts)
|
||||||
>>>>>>> 4f6b790d... Implement API ResourceStatusText extension
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,21 +2,22 @@ import { KubeObject } from "../renderer-api/k8s-api";
|
|||||||
|
|
||||||
import { BaseRegistry } from "./base-registry";
|
import { BaseRegistry } from "./base-registry";
|
||||||
|
|
||||||
export enum ResourceStatusColor {
|
export enum ResourceStatusLevel {
|
||||||
INFO = "info",
|
INFO = 1,
|
||||||
SUCCESS = "success",
|
WARNING = 2,
|
||||||
ERROR = "error"
|
CRITICAL = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ResourceStatus = {
|
export type ResourceStatus = {
|
||||||
|
level: number;
|
||||||
text: string;
|
text: string;
|
||||||
color: string;
|
timestamp?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResourceStatusRegistration {
|
export interface ResourceStatusRegistration {
|
||||||
kind: string;
|
kind: string;
|
||||||
apiVersions: string[];
|
apiVersions: string[];
|
||||||
resolver: (object: KubeObject) => ResourceStatus;
|
resolve: (object: KubeObject) => ResourceStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResourceStatusRegistry extends BaseRegistry<ResourceStatusRegistration> {
|
export class ResourceStatusRegistry extends BaseRegistry<ResourceStatusRegistration> {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ export { isAllowedResource } from "../../common/rbac"
|
|||||||
export { apiManager } from "../../renderer/api/api-manager";
|
export { apiManager } from "../../renderer/api/api-manager";
|
||||||
export { KubeObjectStore } from "../../renderer/kube-object.store"
|
export { KubeObjectStore } from "../../renderer/kube-object.store"
|
||||||
export { KubeApi, forCluster, IKubeApiCluster } from "../../renderer/api/kube-api";
|
export { KubeApi, forCluster, IKubeApiCluster } from "../../renderer/api/kube-api";
|
||||||
|
export type { EventStore } from "../../renderer/components/+events/event.store"
|
||||||
export { KubeObject } from "../../renderer/api/kube-object";
|
export { KubeObject } from "../../renderer/api/kube-object";
|
||||||
export { Pod, podsApi, IPodContainer, IPodContainerStatus } from "../../renderer/api/endpoints";
|
export { Pod, podsApi, IPodContainer, IPodContainerStatus } from "../../renderer/api/endpoints";
|
||||||
export { Node, nodesApi } from "../../renderer/api/endpoints";
|
export { Node, nodesApi } from "../../renderer/api/endpoints";
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
export { ResourceStatus as Status, ResourceStatusColor as Color } from "../registries/resource-status-registry"
|
export { ResourceStatus as Status, ResourceStatusLevel as Level } from "../registries/resource-status-registry"
|
||||||
@ -6,6 +6,10 @@
|
|||||||
flex: 1.5;
|
flex: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.metrics {
|
&.metrics {
|
||||||
flex: 1.5;
|
flex: 1.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,14 +4,13 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IHpaRouteParams } from "./hpa.route";
|
import { IHpaRouteParams } from "./hpa.route";
|
||||||
import { HorizontalPodAutoscaler, hpaApi } from "../../api/endpoints/hpa.api";
|
import { HorizontalPodAutoscaler } from "../../api/endpoints/hpa.api";
|
||||||
import { hpaStore } from "./hpa.store";
|
import { hpaStore } from "./hpa.store";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -52,6 +51,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Horizontal Pod Autoscalers</Trans>}
|
renderHeaderTitle={<Trans>Horizontal Pod Autoscalers</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Metrics</Trans>, className: "metrics" },
|
{ title: <Trans>Metrics</Trans>, className: "metrics" },
|
||||||
{ title: <Trans>Min Pods</Trans>, className: "min-pods", sortBy: sortBy.minPods },
|
{ title: <Trans>Min Pods</Trans>, className: "min-pods", sortBy: sortBy.minPods },
|
||||||
@ -62,6 +62,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
|
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
|
||||||
hpa.getName(),
|
hpa.getName(),
|
||||||
|
<KubeResourceStatusIcon object={hpa} />,
|
||||||
hpa.getNs(),
|
hpa.getNs(),
|
||||||
this.getTargets(hpa),
|
this.getTargets(hpa),
|
||||||
hpa.getMinPods(),
|
hpa.getMinPods(),
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
flex: 2;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.keys {
|
&.keys {
|
||||||
flex: 2.5;
|
flex: 2.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-
|
|||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IConfigMapsRouteParams } from "./config-maps.route";
|
import { IConfigMapsRouteParams } from "./config-maps.route";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -40,12 +41,14 @@ export class ConfigMaps extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Config Maps</Trans>}
|
renderHeaderTitle={<Trans>Config Maps</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(configMap: ConfigMap) => [
|
renderTableContents={(configMap: ConfigMap) => [
|
||||||
configMap.getName(),
|
configMap.getName(),
|
||||||
|
<KubeResourceStatusIcon object={configMap}/>,
|
||||||
configMap.getNs(),
|
configMap.getNs(),
|
||||||
configMap.getKeys().join(", "),
|
configMap.getKeys().join(", "),
|
||||||
configMap.getAge(),
|
configMap.getAge(),
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
flex: 2;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.keys {
|
&.keys {
|
||||||
flex: 2.5;
|
flex: 2.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-
|
|||||||
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
|
||||||
import { IPodDisruptionBudgetsRouteParams } from "./pod-disruption-budgets.route";
|
import { IPodDisruptionBudgetsRouteParams } from "./pod-disruption-budgets.route";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -46,6 +47,7 @@ export class PodDisruptionBudgets extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Pod Disruption Budgets</Trans>}
|
renderHeaderTitle={<Trans>Pod Disruption Budgets</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Min Available</Trans>, className: "min-available", sortBy: sortBy.minAvailable },
|
{ title: <Trans>Min Available</Trans>, className: "min-available", sortBy: sortBy.minAvailable },
|
||||||
{ title: <Trans>Max Unavailable</Trans>, className: "max-unavailable", sortBy: sortBy.maxUnavailable },
|
{ title: <Trans>Max Unavailable</Trans>, className: "max-unavailable", sortBy: sortBy.maxUnavailable },
|
||||||
@ -56,6 +58,7 @@ export class PodDisruptionBudgets extends React.Component<Props> {
|
|||||||
renderTableContents={(pdb: PodDisruptionBudget) => {
|
renderTableContents={(pdb: PodDisruptionBudget) => {
|
||||||
return [
|
return [
|
||||||
pdb.getName(),
|
pdb.getName(),
|
||||||
|
<KubeResourceStatusIcon object={pdb} />,
|
||||||
pdb.getNs(),
|
pdb.getNs(),
|
||||||
pdb.getMinAvailable(),
|
pdb.getMinAvailable(),
|
||||||
pdb.getMaxUnavailable(),
|
pdb.getMaxUnavailable(),
|
||||||
|
|||||||
@ -1,2 +1,7 @@
|
|||||||
.ResourceQuotas {
|
.ResourceQuotas {
|
||||||
|
.TableCell {
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -11,6 +11,7 @@ import { AddQuotaDialog } from "./add-quota-dialog";
|
|||||||
import { resourceQuotaStore } from "./resource-quotas.store";
|
import { resourceQuotaStore } from "./resource-quotas.store";
|
||||||
import { IResourceQuotaRouteParams } from "./resource-quotas.route";
|
import { IResourceQuotaRouteParams } from "./resource-quotas.route";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -40,11 +41,13 @@ export class ResourceQuotas extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Resource Quotas</Trans>}
|
renderHeaderTitle={<Trans>Resource Quotas</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(resourceQuota: ResourceQuota) => [
|
renderTableContents={(resourceQuota: ResourceQuota) => [
|
||||||
resourceQuota.getName(),
|
resourceQuota.getName(),
|
||||||
|
<KubeResourceStatusIcon object={resourceQuota}/>,
|
||||||
resourceQuota.getNs(),
|
resourceQuota.getNs(),
|
||||||
resourceQuota.getAge(),
|
resourceQuota.getAge(),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
flex: 1.5;
|
flex: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.labels {
|
&.labels {
|
||||||
@include table-cell-labels-offsets;
|
@include table-cell-labels-offsets;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { KubeObjectListLayout } from "../kube-object";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { secretsStore } from "./secrets.store";
|
import { secretsStore } from "./secrets.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -47,6 +48,7 @@ export class Secrets extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Secrets</Trans>}
|
renderHeaderTitle={<Trans>Secrets</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
||||||
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
||||||
@ -55,6 +57,7 @@ export class Secrets extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(secret: Secret) => [
|
renderTableContents={(secret: Secret) => [
|
||||||
secret.getName(),
|
secret.getName(),
|
||||||
|
<KubeResourceStatusIcon object={secret} />,
|
||||||
secret.getNs(),
|
secret.getNs(),
|
||||||
secret.getLabels().map(label => <Badge key={label} label={label}/>),
|
secret.getLabels().map(label => <Badge key={label} label={label}/>),
|
||||||
secret.getKeys().join(", "),
|
secret.getKeys().join(", "),
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
flex: 2;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.labels {
|
&.labels {
|
||||||
flex: 4;
|
flex: 4;
|
||||||
@include table-cell-labels-offsets;
|
@include table-cell-labels-offsets;
|
||||||
|
|||||||
@ -2,16 +2,15 @@ import "./namespaces.scss"
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { Namespace, namespacesApi, NamespaceStatus } from "../../api/endpoints";
|
import { Namespace, NamespaceStatus } from "../../api/endpoints";
|
||||||
import { AddNamespaceDialog } from "./add-namespace-dialog";
|
import { AddNamespaceDialog } from "./add-namespace-dialog";
|
||||||
import { TabLayout } from "../layout/tab-layout";
|
import { TabLayout } from "../layout/tab-layout";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { INamespacesRouteParams } from "./namespaces.route";
|
import { INamespacesRouteParams } from "./namespaces.route";
|
||||||
import { namespaceStore } from "./namespace.store";
|
import { namespaceStore } from "./namespace.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -43,12 +42,14 @@ export class Namespaces extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Namespaces</Trans>}
|
renderHeaderTitle={<Trans>Namespaces</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(item: Namespace) => [
|
renderTableContents={(item: Namespace) => [
|
||||||
item.getName(),
|
item.getName(),
|
||||||
|
<KubeResourceStatusIcon object={item} />,
|
||||||
item.getLabels().map(label => <Badge key={label} label={label}/>),
|
item.getLabels().map(label => <Badge key={label} label={label}/>),
|
||||||
item.getAge(),
|
item.getAge(),
|
||||||
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },
|
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },
|
||||||
|
|||||||
@ -3,5 +3,9 @@
|
|||||||
&.endpoints {
|
&.endpoints {
|
||||||
flex-grow: 5.0;
|
flex-grow: 5.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,12 +4,11 @@ import React from "react"
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router-dom"
|
import { RouteComponentProps } from "react-router-dom"
|
||||||
import { EndpointRouteParams } from "./endpoints.route"
|
import { EndpointRouteParams } from "./endpoints.route"
|
||||||
import { Endpoint, endpointApi } from "../../api/endpoints/endpoint.api"
|
import { Endpoint } from "../../api/endpoints/endpoint.api"
|
||||||
import { endpointStore } from "./endpoints.store";
|
import { endpointStore } from "./endpoints.store";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -37,12 +36,14 @@ export class Endpoints extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Endpoints</Trans>}
|
renderHeaderTitle={<Trans>Endpoints</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Endpoints</Trans>, className: "endpoints" },
|
{ title: <Trans>Endpoints</Trans>, className: "endpoints" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(endpoint: Endpoint) => [
|
renderTableContents={(endpoint: Endpoint) => [
|
||||||
endpoint.getName(),
|
endpoint.getName(),
|
||||||
|
<KubeResourceStatusIcon object={endpoint} />,
|
||||||
endpoint.getNs(),
|
endpoint.getNs(),
|
||||||
endpoint.toString(),
|
endpoint.toString(),
|
||||||
endpoint.getAge(),
|
endpoint.getAge(),
|
||||||
|
|||||||
@ -3,5 +3,9 @@
|
|||||||
&.rules {
|
&.rules {
|
||||||
flex-grow: 3.0;
|
flex-grow: 3.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,12 +4,11 @@ import React from "react"
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router-dom"
|
import { RouteComponentProps } from "react-router-dom"
|
||||||
import { IngressRouteParams } from "./ingresses.route"
|
import { IngressRouteParams } from "./ingresses.route"
|
||||||
import { Ingress, ingressApi } from "../../api/endpoints/ingress.api"
|
import { Ingress } from "../../api/endpoints/ingress.api"
|
||||||
import { ingressStore } from "./ingress.store";
|
import { ingressStore } from "./ingress.store";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -38,6 +37,7 @@ export class Ingresses extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Ingresses</Trans>}
|
renderHeaderTitle={<Trans>Ingresses</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>LoadBalancers</Trans>, className: "loadbalancers" },
|
{ title: <Trans>LoadBalancers</Trans>, className: "loadbalancers" },
|
||||||
{ title: <Trans>Rules</Trans>, className: "rules" },
|
{ title: <Trans>Rules</Trans>, className: "rules" },
|
||||||
@ -45,6 +45,7 @@ export class Ingresses extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(ingress: Ingress) => [
|
renderTableContents={(ingress: Ingress) => [
|
||||||
ingress.getName(),
|
ingress.getName(),
|
||||||
|
<KubeResourceStatusIcon object={ingress} />,
|
||||||
ingress.getNs(),
|
ingress.getNs(),
|
||||||
ingress.getLoadBalancers().map(lb => <p key={lb}>{lb}</p>),
|
ingress.getLoadBalancers().map(lb => <p key={lb}>{lb}</p>),
|
||||||
ingress.getRoutes().map(route => <p key={route}>{route}</p>),
|
ingress.getRoutes().map(route => <p key={route}>{route}</p>),
|
||||||
|
|||||||
@ -1,2 +1,7 @@
|
|||||||
.NetworkPolicies {
|
.NetworkPolicies {
|
||||||
|
.TableCell {
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,12 +4,11 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
import { NetworkPolicy, networkPolicyApi } from "../../api/endpoints/network-policy.api";
|
import { NetworkPolicy } from "../../api/endpoints/network-policy.api";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { INetworkPoliciesRouteParams } from "./network-policies.route";
|
import { INetworkPoliciesRouteParams } from "./network-policies.route";
|
||||||
import { networkPolicyStore } from "./network-policy.store";
|
import { networkPolicyStore } from "./network-policy.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -37,12 +36,14 @@ export class NetworkPolicies extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Network Policies</Trans>}
|
renderHeaderTitle={<Trans>Network Policies</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Policy Types</Trans>, className: "type" },
|
{ title: <Trans>Policy Types</Trans>, className: "type" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(item: NetworkPolicy) => [
|
renderTableContents={(item: NetworkPolicy) => [
|
||||||
item.getName(),
|
item.getName(),
|
||||||
|
<KubeResourceStatusIcon object={item} />,
|
||||||
item.getNs(),
|
item.getNs(),
|
||||||
item.getTypes().join(", "),
|
item.getTypes().join(", "),
|
||||||
item.getAge(),
|
item.getAge(),
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
flex: 0.6;
|
flex: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.age {
|
&.age {
|
||||||
flex: 0.4;
|
flex: 0.4;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,12 +5,11 @@ import { observer } from "mobx-react";
|
|||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { IServicesRouteParams } from "./services.route";
|
import { IServicesRouteParams } from "./services.route";
|
||||||
import { Service, serviceApi } from "../../api/endpoints/service.api";
|
import { Service } from "../../api/endpoints/service.api";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { serviceStore } from "./services.store";
|
import { serviceStore } from "./services.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -50,6 +49,7 @@ export class Services extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Services</Trans>}
|
renderHeaderTitle={<Trans>Services</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Type</Trans>, className: "type", sortBy: sortBy.type },
|
{ title: <Trans>Type</Trans>, className: "type", sortBy: sortBy.type },
|
||||||
{ title: <Trans>Cluster IP</Trans>, className: "clusterIp", sortBy: sortBy.clusterIp, },
|
{ title: <Trans>Cluster IP</Trans>, className: "clusterIp", sortBy: sortBy.clusterIp, },
|
||||||
@ -61,6 +61,7 @@ export class Services extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(service: Service) => [
|
renderTableContents={(service: Service) => [
|
||||||
service.getName(),
|
service.getName(),
|
||||||
|
<KubeResourceStatusIcon object={service} />,
|
||||||
service.getNs(),
|
service.getNs(),
|
||||||
service.getType(),
|
service.getType(),
|
||||||
service.getClusterIp(),
|
service.getClusterIp(),
|
||||||
|
|||||||
@ -7,6 +7,10 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.cpu {
|
&.cpu {
|
||||||
flex: 1.0;
|
flex: 1.0;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { bytesToUnits } from "../../utils/convertMemory";
|
|||||||
import { Tooltip, TooltipPosition } from "../tooltip";
|
import { Tooltip, TooltipPosition } from "../tooltip";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import upperFirst from "lodash/upperFirst";
|
import upperFirst from "lodash/upperFirst";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -148,6 +149,7 @@ export class Nodes extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Nodes</Trans>}
|
renderHeaderTitle={<Trans>Nodes</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>CPU</Trans>, className: "cpu", sortBy: sortBy.cpu },
|
{ title: <Trans>CPU</Trans>, className: "cpu", sortBy: sortBy.cpu },
|
||||||
{ title: <Trans>Memory</Trans>, className: "memory", sortBy: sortBy.memory },
|
{ title: <Trans>Memory</Trans>, className: "memory", sortBy: sortBy.memory },
|
||||||
{ title: <Trans>Disk</Trans>, className: "disk", sortBy: sortBy.disk },
|
{ title: <Trans>Disk</Trans>, className: "disk", sortBy: sortBy.disk },
|
||||||
@ -161,6 +163,7 @@ export class Nodes extends React.Component<Props> {
|
|||||||
const tooltipId = `node-taints-${node.getId()}`;
|
const tooltipId = `node-taints-${node.getId()}`;
|
||||||
return [
|
return [
|
||||||
node.getName(),
|
node.getName(),
|
||||||
|
<KubeResourceStatusIcon object={node} />,
|
||||||
this.renderCpuUsage(node),
|
this.renderCpuUsage(node),
|
||||||
this.renderMemoryUsage(node),
|
this.renderMemoryUsage(node),
|
||||||
this.renderDiskUsage(node),
|
this.renderDiskUsage(node),
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
&.volumes {
|
&.volumes {
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,10 +4,9 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { podSecurityPoliciesStore } from "./pod-security-policies.store";
|
import { podSecurityPoliciesStore } from "./pod-security-policies.store";
|
||||||
import { PodSecurityPolicy, pspApi } from "../../api/endpoints";
|
import { PodSecurityPolicy, pspApi } from "../../api/endpoints";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -38,6 +37,7 @@ export class PodSecurityPolicies extends React.Component {
|
|||||||
renderHeaderTitle={<Trans>Pod Security Policies</Trans>}
|
renderHeaderTitle={<Trans>Pod Security Policies</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Privileged</Trans>, className: "privileged", sortBy: sortBy.privileged },
|
{ title: <Trans>Privileged</Trans>, className: "privileged", sortBy: sortBy.privileged },
|
||||||
{ title: <Trans>Volumes</Trans>, className: "volumes", sortBy: sortBy.volumes },
|
{ title: <Trans>Volumes</Trans>, className: "volumes", sortBy: sortBy.volumes },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
@ -45,6 +45,7 @@ export class PodSecurityPolicies extends React.Component {
|
|||||||
renderTableContents={(item: PodSecurityPolicy) => {
|
renderTableContents={(item: PodSecurityPolicy) => {
|
||||||
return [
|
return [
|
||||||
item.getName(),
|
item.getName(),
|
||||||
|
<KubeResourceStatusIcon object={item} />,
|
||||||
item.isPrivileged() ? <Trans>Yes</Trans> : <Trans>No</Trans>,
|
item.isPrivileged() ? <Trans>Yes</Trans> : <Trans>No</Trans>,
|
||||||
item.getVolumes().join(", "),
|
item.getVolumes().join(", "),
|
||||||
item.getAge(),
|
item.getAge(),
|
||||||
|
|||||||
@ -3,5 +3,9 @@
|
|||||||
&.is-default {
|
&.is-default {
|
||||||
flex: .5;
|
flex: .5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,11 +5,10 @@ import { RouteComponentProps } from "react-router-dom";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { StorageClass, storageClassApi } from "../../api/endpoints/storage-class.api";
|
import { StorageClass, storageClassApi } from "../../api/endpoints/storage-class.api";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IStorageClassesRouteParams } from "./storage-classes.route";
|
import { IStorageClassesRouteParams } from "./storage-classes.route";
|
||||||
import { storageClassStore } from "./storage-class.store";
|
import { storageClassStore } from "./storage-class.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -41,6 +40,7 @@ export class StorageClasses extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Storage Classes</Trans>}
|
renderHeaderTitle={<Trans>Storage Classes</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Provisioner</Trans>, className: "provisioner", sortBy: sortBy.provisioner },
|
{ title: <Trans>Provisioner</Trans>, className: "provisioner", sortBy: sortBy.provisioner },
|
||||||
{ title: <Trans>Reclaim Policy</Trans>, className: "reclaim-policy", sortBy: sortBy.reclaimPolicy },
|
{ title: <Trans>Reclaim Policy</Trans>, className: "reclaim-policy", sortBy: sortBy.reclaimPolicy },
|
||||||
{ title: <Trans>Default</Trans>, className: "is-default" },
|
{ title: <Trans>Default</Trans>, className: "is-default" },
|
||||||
@ -48,6 +48,7 @@ export class StorageClasses extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(storageClass: StorageClass) => [
|
renderTableContents={(storageClass: StorageClass) => [
|
||||||
storageClass.getName(),
|
storageClass.getName(),
|
||||||
|
<KubeResourceStatusIcon object={storageClass} />,
|
||||||
storageClass.provisioner,
|
storageClass.provisioner,
|
||||||
storageClass.getReclaimPolicy(),
|
storageClass.getReclaimPolicy(),
|
||||||
storageClass.isDefault() ? <Trans>Yes</Trans> : null,
|
storageClass.isDefault() ? <Trans>Yes</Trans> : null,
|
||||||
|
|||||||
@ -6,6 +6,10 @@
|
|||||||
flex-grow: 3;
|
flex-grow: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.storage {
|
&.storage {
|
||||||
flex: 0.6;
|
flex: 0.6;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,7 @@ import { observer } from "mobx-react";
|
|||||||
import { Link, RouteComponentProps } from "react-router-dom";
|
import { Link, RouteComponentProps } from "react-router-dom";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { volumeClaimStore } from "./volume-claim.store";
|
import { volumeClaimStore } from "./volume-claim.store";
|
||||||
import { PersistentVolumeClaim, pvcApi } from "../../api/endpoints/persistent-volume-claims.api";
|
import { PersistentVolumeClaim } from "../../api/endpoints/persistent-volume-claims.api";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IVolumeClaimsRouteParams } from "./volume-claims.route";
|
import { IVolumeClaimsRouteParams } from "./volume-claims.route";
|
||||||
@ -14,7 +13,7 @@ import { unitsToBytes } from "../../utils/convertMemory";
|
|||||||
import { stopPropagation } from "../../utils";
|
import { stopPropagation } from "../../utils";
|
||||||
import { getDetailsUrl } from "../../navigation";
|
import { getDetailsUrl } from "../../navigation";
|
||||||
import { storageClassApi } from "../../api/endpoints";
|
import { storageClassApi } from "../../api/endpoints";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -53,6 +52,7 @@ export class PersistentVolumeClaims extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Persistent Volume Claims</Trans>}
|
renderHeaderTitle={<Trans>Persistent Volume Claims</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Storage class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
{ title: <Trans>Storage class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
||||||
{ title: <Trans>Size</Trans>, className: "size", sortBy: sortBy.size },
|
{ title: <Trans>Size</Trans>, className: "size", sortBy: sortBy.size },
|
||||||
@ -68,6 +68,7 @@ export class PersistentVolumeClaims extends React.Component<Props> {
|
|||||||
}));
|
}));
|
||||||
return [
|
return [
|
||||||
pvc.getName(),
|
pvc.getName(),
|
||||||
|
<KubeResourceStatusIcon object={pvc} />,
|
||||||
pvc.getNs(),
|
pvc.getNs(),
|
||||||
<Link to={storageClassDetailsUrl} onClick={stopPropagation}>
|
<Link to={storageClassDetailsUrl} onClick={stopPropagation}>
|
||||||
{storageClassName}
|
{storageClassName}
|
||||||
|
|||||||
@ -6,6 +6,10 @@
|
|||||||
flex-grow: 3;
|
flex-grow: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.storage {
|
&.storage {
|
||||||
flex: 0.6;
|
flex: 0.6;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,15 +4,14 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { Link, RouteComponentProps } from "react-router-dom";
|
import { Link, RouteComponentProps } from "react-router-dom";
|
||||||
import { PersistentVolume, persistentVolumeApi } from "../../api/endpoints/persistent-volume.api";
|
import { PersistentVolume } from "../../api/endpoints/persistent-volume.api";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IVolumesRouteParams } from "./volumes.route";
|
import { IVolumesRouteParams } from "./volumes.route";
|
||||||
import { stopPropagation } from "../../utils";
|
import { stopPropagation } from "../../utils";
|
||||||
import { getDetailsUrl } from "../../navigation";
|
import { getDetailsUrl } from "../../navigation";
|
||||||
import { volumesStore } from "./volumes.store";
|
import { volumesStore } from "./volumes.store";
|
||||||
import { pvcApi, storageClassApi } from "../../api/endpoints";
|
import { pvcApi, storageClassApi } from "../../api/endpoints";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -46,6 +45,7 @@ export class PersistentVolumes extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Persistent Volumes</Trans>}
|
renderHeaderTitle={<Trans>Persistent Volumes</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Storage Class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
{ title: <Trans>Storage Class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
||||||
{ title: <Trans>Capacity</Trans>, className: "capacity", sortBy: sortBy.capacity },
|
{ title: <Trans>Capacity</Trans>, className: "capacity", sortBy: sortBy.capacity },
|
||||||
{ title: <Trans>Claim</Trans>, className: "claim" },
|
{ title: <Trans>Claim</Trans>, className: "claim" },
|
||||||
@ -59,6 +59,7 @@ export class PersistentVolumes extends React.Component<Props> {
|
|||||||
}));
|
}));
|
||||||
return [
|
return [
|
||||||
volume.getName(),
|
volume.getName(),
|
||||||
|
<KubeResourceStatusIcon object={volume} />,
|
||||||
<Link to={storageClassDetailsUrl} onClick={stopPropagation}>
|
<Link to={storageClassDetailsUrl} onClick={stopPropagation}>
|
||||||
{storageClassName}
|
{storageClassName}
|
||||||
</Link>,
|
</Link>,
|
||||||
|
|||||||
@ -2,4 +2,10 @@
|
|||||||
.help-icon {
|
.help-icon {
|
||||||
margin-left: $margin / 2;
|
margin-left: $margin / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.TableCell {
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,15 +4,12 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { Icon } from "../icon";
|
|
||||||
import { IRoleBindingsRouteParams } from "../+user-management/user-management.route";
|
import { IRoleBindingsRouteParams } from "../+user-management/user-management.route";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
import { RoleBinding } from "../../api/endpoints";
|
||||||
import { clusterRoleBindingApi, RoleBinding, roleBindingApi } from "../../api/endpoints";
|
|
||||||
import { roleBindingsStore } from "./role-bindings.store";
|
import { roleBindingsStore } from "./role-bindings.store";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
|
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
|
||||||
import { KubeObject } from "../../api/kube-object";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
import { apiManager } from "../../api/api-manager";
|
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -44,12 +41,14 @@ export class RoleBindings extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Role Bindings</Trans>}
|
renderHeaderTitle={<Trans>Role Bindings</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Bindings</Trans>, className: "bindings", sortBy: sortBy.bindings },
|
{ title: <Trans>Bindings</Trans>, className: "bindings", sortBy: sortBy.bindings },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(binding: RoleBinding) => [
|
renderTableContents={(binding: RoleBinding) => [
|
||||||
binding.getName(),
|
binding.getName(),
|
||||||
|
<KubeResourceStatusIcon object={binding} />,
|
||||||
binding.getSubjectNames(),
|
binding.getSubjectNames(),
|
||||||
binding.getNs() || "-",
|
binding.getNs() || "-",
|
||||||
binding.getAge(),
|
binding.getAge(),
|
||||||
|
|||||||
@ -2,4 +2,10 @@
|
|||||||
.help-icon {
|
.help-icon {
|
||||||
margin-left: $margin / 2;
|
margin-left: $margin / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.TableCell {
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@ import { rolesStore } from "./roles.store";
|
|||||||
import { Role } from "../../api/endpoints";
|
import { Role } from "../../api/endpoints";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { AddRoleDialog } from "./add-role-dialog";
|
import { AddRoleDialog } from "./add-role-dialog";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -38,11 +39,13 @@ export class Roles extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Roles</Trans>}
|
renderHeaderTitle={<Trans>Roles</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(role: Role) => [
|
renderTableContents={(role: Role) => [
|
||||||
role.getName(),
|
role.getName(),
|
||||||
|
<KubeResourceStatusIcon object={role} />,
|
||||||
role.getNs() || "-",
|
role.getNs() || "-",
|
||||||
role.getAge(),
|
role.getAge(),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -1,2 +1,7 @@
|
|||||||
.ServiceAccounts {
|
.ServiceAccounts {
|
||||||
|
.TableCell {
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -14,6 +14,7 @@ import { IServiceAccountsRouteParams } from "../+user-management";
|
|||||||
import { serviceAccountsStore } from "./service-accounts.store";
|
import { serviceAccountsStore } from "./service-accounts.store";
|
||||||
import { CreateServiceAccountDialog } from "./create-service-account-dialog";
|
import { CreateServiceAccountDialog } from "./create-service-account-dialog";
|
||||||
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -42,11 +43,13 @@ export class ServiceAccounts extends React.Component<Props> {
|
|||||||
renderHeaderTitle={<Trans>Service Accounts</Trans>}
|
renderHeaderTitle={<Trans>Service Accounts</Trans>}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||||
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(account: ServiceAccount) => [
|
renderTableContents={(account: ServiceAccount) => [
|
||||||
account.getName(),
|
account.getName(),
|
||||||
|
<KubeResourceStatusIcon object={account} />,
|
||||||
account.getNs(),
|
account.getNs(),
|
||||||
account.getAge(),
|
account.getAge(),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -13,10 +13,10 @@ import { eventStore } from "../+events/event.store";
|
|||||||
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||||
import { ICronJobsRouteParams } from "../+workloads";
|
import { ICronJobsRouteParams } from "../+workloads";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
|
||||||
import { _i18n } from "../../i18n";
|
import { _i18n } from "../../i18n";
|
||||||
import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
|
import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
|
||||||
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -62,11 +62,7 @@ export class CronJobs extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(cronJob: CronJob) => [
|
renderTableContents={(cronJob: CronJob) => [
|
||||||
cronJob.getName(),
|
cronJob.getName(),
|
||||||
<KubeEventIcon object={cronJob} filterEvents={events => {
|
<KubeResourceStatusIcon object={cronJob} />,
|
||||||
if (!cronJob.isNeverRun()) return events;
|
|
||||||
return events.filter(event => event.reason != "FailedNeedsStart");
|
|
||||||
}
|
|
||||||
}/>,
|
|
||||||
cronJob.getNs(),
|
cronJob.getNs(),
|
||||||
cronJob.isNeverRun() ? <Trans>never</Trans> : cronJob.getSchedule(),
|
cronJob.isNeverRun() ? <Trans>never</Trans> : cronJob.getSchedule(),
|
||||||
cronJob.getSuspendFlag(),
|
cronJob.getSuspendFlag(),
|
||||||
|
|||||||
@ -3,8 +3,7 @@ import "./daemonsets.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { DaemonSet, daemonSetApi } from "../../api/endpoints";
|
import { DaemonSet } from "../../api/endpoints";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { eventStore } from "../+events/event.store";
|
import { eventStore } from "../+events/event.store";
|
||||||
import { daemonSetStore } from "./daemonsets.store";
|
import { daemonSetStore } from "./daemonsets.store";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
@ -13,8 +12,7 @@ import { KubeObjectListLayout } from "../kube-object";
|
|||||||
import { IDaemonSetsRouteParams } from "../+workloads";
|
import { IDaemonSetsRouteParams } from "../+workloads";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
import { apiManager } from "../../api/api-manager";
|
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -66,7 +64,7 @@ export class DaemonSets extends React.Component<Props> {
|
|||||||
daemonSet.getName(),
|
daemonSet.getName(),
|
||||||
daemonSet.getNs(),
|
daemonSet.getNs(),
|
||||||
this.getPodsLength(daemonSet),
|
this.getPodsLength(daemonSet),
|
||||||
<KubeEventIcon object={daemonSet}/>,
|
<KubeResourceStatusIcon object={daemonSet}/>,
|
||||||
this.renderNodeSelector(daemonSet),
|
this.renderNodeSelector(daemonSet),
|
||||||
daemonSet.getAge(),
|
daemonSet.getAge(),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -20,8 +20,8 @@ import { _i18n } from "../../i18n";
|
|||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import orderBy from "lodash/orderBy";
|
import orderBy from "lodash/orderBy";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
|
||||||
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -81,7 +81,7 @@ export class Deployments extends React.Component<Props> {
|
|||||||
deployment.getNs(),
|
deployment.getNs(),
|
||||||
this.renderPods(deployment),
|
this.renderPods(deployment),
|
||||||
deployment.getReplicas(),
|
deployment.getReplicas(),
|
||||||
<KubeEventIcon object={deployment}/>,
|
<KubeResourceStatusIcon object={deployment}/>,
|
||||||
deployment.getAge(),
|
deployment.getAge(),
|
||||||
this.renderConditions(deployment),
|
this.renderConditions(deployment),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -7,13 +7,11 @@ import { Trans } from "@lingui/macro";
|
|||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { jobStore } from "./job.store";
|
import { jobStore } from "./job.store";
|
||||||
import { eventStore } from "../+events/event.store";
|
import { eventStore } from "../+events/event.store";
|
||||||
import { Job, jobApi } from "../../api/endpoints/job.api";
|
import { Job } from "../../api/endpoints/job.api";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IJobsRouteParams } from "../+workloads";
|
import { IJobsRouteParams } from "../+workloads";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -56,7 +54,7 @@ export class Jobs extends React.Component<Props> {
|
|||||||
job.getName(),
|
job.getName(),
|
||||||
job.getNs(),
|
job.getNs(),
|
||||||
`${job.getCompletions()} / ${job.getDesiredCompletions()}`,
|
`${job.getCompletions()} / ${job.getDesiredCompletions()}`,
|
||||||
<KubeEventIcon object={job}/>,
|
<KubeResourceStatusIcon object={job}/>,
|
||||||
job.getAge(),
|
job.getAge(),
|
||||||
condition && {
|
condition && {
|
||||||
title: condition.type,
|
title: condition.type,
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { Trans } from "@lingui/macro";
|
|||||||
import { podsStore } from "./pods.store";
|
import { podsStore } from "./pods.store";
|
||||||
import { Pod } from "../../api/endpoints";
|
import { Pod } from "../../api/endpoints";
|
||||||
import { autobind, bytesToUnits, cssNames, interval, prevDefault } from "../../utils";
|
import { autobind, bytesToUnits, cssNames, interval, prevDefault } from "../../utils";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
|
||||||
import { LineProgress } from "../line-progress";
|
import { LineProgress } from "../line-progress";
|
||||||
import { KubeObject } from "../../api/kube-object";
|
import { KubeObject } from "../../api/kube-object";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
@ -15,6 +14,7 @@ import { showDetails } from "../../navigation";
|
|||||||
import { reaction } from "mobx";
|
import { reaction } from "mobx";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import { DrawerTitle } from "../drawer";
|
import { DrawerTitle } from "../drawer";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -107,7 +107,7 @@ export class PodDetailsList extends React.Component<Props> {
|
|||||||
onClick={prevDefault(() => showDetails(pod.selfLink, false))}
|
onClick={prevDefault(() => showDetails(pod.selfLink, false))}
|
||||||
>
|
>
|
||||||
<TableCell className="name">{pod.getName()}</TableCell>
|
<TableCell className="name">{pod.getName()}</TableCell>
|
||||||
<TableCell className="warning">{pod.hasIssues() && <KubeEventIcon object={pod}/>}</TableCell>
|
<TableCell className="warning"><KubeResourceStatusIcon object={pod}/></TableCell>
|
||||||
<TableCell className="namespace">{pod.getNs()}</TableCell>
|
<TableCell className="namespace">{pod.getNs()}</TableCell>
|
||||||
<TableCell className="cpu">{this.renderCpuUsage(`cpu-${pod.getId()}`, metrics.cpu)}</TableCell>
|
<TableCell className="cpu">{this.renderCpuUsage(`cpu-${pod.getId()}`, metrics.cpu)}</TableCell>
|
||||||
<TableCell className="memory">{this.renderMemoryUsage(`memory-${pod.getId()}`, metrics.memory)}</TableCell>
|
<TableCell className="memory">{this.renderMemoryUsage(`memory-${pod.getId()}`, metrics.memory)}</TableCell>
|
||||||
|
|||||||
@ -13,13 +13,13 @@ import { KubeObjectListLayout } from "../kube-object";
|
|||||||
import { Pod } from "../../api/endpoints";
|
import { Pod } from "../../api/endpoints";
|
||||||
import { StatusBrick } from "../status-brick";
|
import { StatusBrick } from "../status-brick";
|
||||||
import { cssNames, stopPropagation } from "../../utils";
|
import { cssNames, stopPropagation } from "../../utils";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
|
||||||
import { getDetailsUrl } from "../../navigation";
|
import { getDetailsUrl } from "../../navigation";
|
||||||
import toPairs from "lodash/toPairs";
|
import toPairs from "lodash/toPairs";
|
||||||
import startCase from "lodash/startCase";
|
import startCase from "lodash/startCase";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { lookupApiLink } from "../../api/kube-api";
|
import { lookupApiLink } from "../../api/kube-api";
|
||||||
import { resourceStatusRegistry } from "../../../extensions/registries/resource-status-registry";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -69,24 +69,21 @@ export class Pods extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderPodStatus(pod: Pod) {
|
renderPodStatus(pod: Pod) {
|
||||||
const podStatusTextsFromExtensions = resourceStatusRegistry.getItemsForKind(pod.kind, pod.apiVersion).map((item, index) => {
|
|
||||||
const podStatusResolver = item.resolver(pod)
|
|
||||||
return (
|
|
||||||
<span key={`resource-status-${index}`} className={podStatusResolver.getStatusColor()}>
|
|
||||||
{podStatusResolver.getStatusText()}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
className: kebabCase(pod.getStatusMessage()),
|
className: kebabCase(pod.getStatusMessage()),
|
||||||
children: (
|
children: (
|
||||||
<span>
|
<span>
|
||||||
{pod.getStatusMessage()} {podStatusTextsFromExtensions}
|
{pod.getStatusMessage()}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderPodStatusIcons(pod: Pod) {
|
||||||
|
return (
|
||||||
|
<KubeResourceStatusIcon object={pod} />
|
||||||
|
)
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<KubeObjectListLayout
|
<KubeObjectListLayout
|
||||||
@ -120,7 +117,7 @@ export class Pods extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderTableContents={(pod: Pod) => [
|
renderTableContents={(pod: Pod) => [
|
||||||
pod.getName(),
|
pod.getName(),
|
||||||
pod.hasIssues() && <KubeEventIcon object={pod}/>,
|
this.renderPodStatusIcons(pod),
|
||||||
pod.getNs(),
|
pod.getNs(),
|
||||||
this.renderContainersStatus(pod),
|
this.renderContainersStatus(pod),
|
||||||
pod.getRestartsCount(),
|
pod.getRestartsCount(),
|
||||||
|
|||||||
@ -19,6 +19,10 @@
|
|||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
@include table-cell-warning;
|
||||||
|
}
|
||||||
|
|
||||||
&.namespace {
|
&.namespace {
|
||||||
flex-grow: 1.2;
|
flex-grow: 1.2;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { DrawerTitle } from "../drawer";
|
|||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { showDetails } from "../../navigation";
|
import { showDetails } from "../../navigation";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -56,6 +57,7 @@ export class ReplicaSets extends React.Component<Props> {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="name" sortBy={sortBy.name}><Trans>Name</Trans></TableCell>
|
<TableCell className="name" sortBy={sortBy.name}><Trans>Name</Trans></TableCell>
|
||||||
|
<TableCell className="warning"/>
|
||||||
<TableCell className="namespace" sortBy={sortBy.namespace}>Namespace</TableCell>
|
<TableCell className="namespace" sortBy={sortBy.namespace}>Namespace</TableCell>
|
||||||
<TableCell className="pods" sortBy={sortBy.pods}><Trans>Pods</Trans></TableCell>
|
<TableCell className="pods" sortBy={sortBy.pods}><Trans>Pods</Trans></TableCell>
|
||||||
<TableCell className="age" sortBy={sortBy.age}><Trans>Age</Trans></TableCell>
|
<TableCell className="age" sortBy={sortBy.age}><Trans>Age</Trans></TableCell>
|
||||||
@ -71,6 +73,7 @@ export class ReplicaSets extends React.Component<Props> {
|
|||||||
onClick={prevDefault(() => showDetails(replica.selfLink, false))}
|
onClick={prevDefault(() => showDetails(replica.selfLink, false))}
|
||||||
>
|
>
|
||||||
<TableCell className="name">{replica.getName()}</TableCell>
|
<TableCell className="name">{replica.getName()}</TableCell>
|
||||||
|
<TableCell className="warning"><KubeResourceStatusIcon object={replica}/></TableCell>
|
||||||
<TableCell className="namespace">{replica.getNs()}</TableCell>
|
<TableCell className="namespace">{replica.getNs()}</TableCell>
|
||||||
<TableCell className="pods">{this.getPodsLength(replica)}</TableCell>
|
<TableCell className="pods">{this.getPodsLength(replica)}</TableCell>
|
||||||
<TableCell className="age">{replica.getAge()}</TableCell>
|
<TableCell className="age">{replica.getAge()}</TableCell>
|
||||||
|
|||||||
@ -4,16 +4,14 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { StatefulSet, statefulSetApi } from "../../api/endpoints";
|
import { StatefulSet } from "../../api/endpoints";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { statefulSetStore } from "./statefulset.store";
|
import { statefulSetStore } from "./statefulset.store";
|
||||||
import { nodesStore } from "../+nodes/nodes.store";
|
import { nodesStore } from "../+nodes/nodes.store";
|
||||||
import { eventStore } from "../+events/event.store";
|
import { eventStore } from "../+events/event.store";
|
||||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IStatefulSetsRouteParams } from "../+workloads";
|
import { IStatefulSetsRouteParams } from "../+workloads";
|
||||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
import { apiManager } from "../../api/api-manager";
|
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
name = "name",
|
name = "name",
|
||||||
@ -57,7 +55,7 @@ export class StatefulSets extends React.Component<Props> {
|
|||||||
statefulSet.getName(),
|
statefulSet.getName(),
|
||||||
statefulSet.getNs(),
|
statefulSet.getNs(),
|
||||||
this.getPodsLength(statefulSet),
|
this.getPodsLength(statefulSet),
|
||||||
<KubeEventIcon object={statefulSet}/>,
|
<KubeResourceStatusIcon object={statefulSet}/>,
|
||||||
statefulSet.getAge(),
|
statefulSet.getAge(),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -161,6 +161,10 @@ a {
|
|||||||
color: $colorError;
|
color: $colorError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.warning {
|
||||||
|
color: $colorWarning;
|
||||||
|
}
|
||||||
|
|
||||||
.contrast {
|
.contrast {
|
||||||
color: $textColorAccent;
|
color: $textColorAccent;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import React from "react";
|
|||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { IKubeMetaField, KubeObject } from "../../api/kube-object";
|
import { IKubeMetaField, KubeObject } from "../../api/kube-object";
|
||||||
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
||||||
import { WorkloadKubeObject } from "../../api/workload-kube-object";
|
|
||||||
import { getDetailsUrl } from "../../navigation";
|
import { getDetailsUrl } from "../../navigation";
|
||||||
import { lookupApiLink } from "../../api/kube-api";
|
import { lookupApiLink } from "../../api/kube-api";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { KubeResourceStatusIcon } from "../kube-resource-status-icon";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
object: KubeObject;
|
object: KubeObject;
|
||||||
@ -37,7 +37,7 @@ export class KubeObjectMeta extends React.Component<Props> {
|
|||||||
{getAge(true, false)} <Trans>ago</Trans> ({creationTimestamp})
|
{getAge(true, false)} <Trans>ago</Trans> ({creationTimestamp})
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Name</Trans>} hidden={this.isHidden("name")}>
|
<DrawerItem name={<Trans>Name</Trans>} hidden={this.isHidden("name")}>
|
||||||
{getName()}
|
{getName()} <KubeResourceStatusIcon object={object} />
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Namespace</Trans>} hidden={this.isHidden("namespace") || !getNs()}>
|
<DrawerItem name={<Trans>Namespace</Trans>} hidden={this.isHidden("namespace") || !getNs()}>
|
||||||
{getNs()}
|
{getNs()}
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
export * from "./kube-resource-status-icon"
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
.ResourceStatusIcon {
|
||||||
|
&.warning {
|
||||||
|
color: $golden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ResourceStatusTooltip {
|
||||||
|
white-space: normal;
|
||||||
|
|
||||||
|
|
||||||
|
.ResourceStatusLevel {
|
||||||
|
padding: 4px;
|
||||||
|
|
||||||
|
&:not(:only-child):not(:last-child) {
|
||||||
|
border-bottom: 1px solid $borderFaintColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg {
|
||||||
|
margin: $margin / 2
|
||||||
|
}
|
||||||
|
.age {
|
||||||
|
color: $halfGray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ResourceStatusTitle {
|
||||||
|
font-weight: bold;
|
||||||
|
.Icon {
|
||||||
|
margin-right: $margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
import "./kube-resource-status-icon.scss";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { Icon } from "../icon";
|
||||||
|
import { KubeObject } from "../../api/kube-object";
|
||||||
|
import { cssNames, formatDuration } from "../../utils";
|
||||||
|
import { ResourceStatusRegistration, ResourceStatus, ResourceStatusLevel, resourceStatusRegistry } from "../../../extensions/registries/resource-status-registry"
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
object: KubeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class KubeResourceStatusIcon extends React.Component<Props> {
|
||||||
|
@computed get resourceStatuses() {
|
||||||
|
const { object } = this.props;
|
||||||
|
const registrations = resourceStatusRegistry.getItemsForKind(object.kind, object.apiVersion)
|
||||||
|
return registrations.map((item: ResourceStatusRegistration) => { return item.resolve(object) }).filter((item: ResourceStatus) => !!item)
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceStatusClassName(level: number): string {
|
||||||
|
switch (level) {
|
||||||
|
case ResourceStatusLevel.INFO:
|
||||||
|
return "info"
|
||||||
|
case ResourceStatusLevel.WARNING:
|
||||||
|
return "warning"
|
||||||
|
case ResourceStatusLevel.CRITICAL:
|
||||||
|
return "error"
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceStatusTitle(level: number): string {
|
||||||
|
switch (level) {
|
||||||
|
case ResourceStatusLevel.INFO:
|
||||||
|
return "Info"
|
||||||
|
case ResourceStatusLevel.WARNING:
|
||||||
|
return "Warning"
|
||||||
|
case ResourceStatusLevel.CRITICAL:
|
||||||
|
return "Critical"
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getAge(timestamp: string) {
|
||||||
|
if (!timestamp) return ""
|
||||||
|
const diff = new Date().getTime() - new Date(timestamp).getTime();
|
||||||
|
return formatDuration(diff, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStatuses(statuses: ResourceStatus[], level: number) {
|
||||||
|
const filteredStatuses = statuses.filter((item) => item.level == level)
|
||||||
|
|
||||||
|
return filteredStatuses.length > 0 && (
|
||||||
|
<div className={cssNames("ResourceStatusLevel", this.resourceStatusClassName(level))}>
|
||||||
|
<span className="ResourceStatusTitle">
|
||||||
|
{this.resourceStatusTitle(level)}
|
||||||
|
</span>
|
||||||
|
{ filteredStatuses.map((status, index) =>{
|
||||||
|
return (
|
||||||
|
<div key={`kube-resource-status-${level}-${index}`} className={cssNames("status", "msg")}>
|
||||||
|
- {status.text} <span className="age"> · { this.getAge(status.timestamp) }</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { resourceStatuses} = this
|
||||||
|
if (!resourceStatuses.length) return null
|
||||||
|
|
||||||
|
const sortedStatuses = resourceStatuses.sort((a: ResourceStatus, b: ResourceStatus) => {
|
||||||
|
if (a.level < b.level ) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (a.level > b.level ) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const level = this.resourceStatusClassName(sortedStatuses[0].level)
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
material={level}
|
||||||
|
className={cssNames("ResourceStatusIcon", level)}
|
||||||
|
tooltip={{
|
||||||
|
children: (
|
||||||
|
<div className="ResourceStatusTooltip">
|
||||||
|
{this.renderStatuses(sortedStatuses, ResourceStatusLevel.CRITICAL)}
|
||||||
|
{this.renderStatuses(sortedStatuses, ResourceStatusLevel.WARNING)}
|
||||||
|
{this.renderStatuses(sortedStatuses, ResourceStatusLevel.INFO)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user