mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
cleanup Lens repo with tighter linting
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
This commit is contained in:
1 parent
e468105143
commit
b1ff34879a
470 files changed
+8447
-7443
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import "./cluster-issues.scss"
|
||||
import "./cluster-issues.scss";
|
||||
|
||||
import * as React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
@@ -20,7 +20,7 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface IWarning extends ItemObject {
|
||||
interface Warning extends ItemObject {
|
||||
kind: string;
|
||||
message: string;
|
||||
selfLink: string;
|
||||
@@ -34,16 +34,16 @@ enum sortBy {
|
||||
@observer
|
||||
export class ClusterIssues extends React.Component<Props> {
|
||||
private sortCallbacks = {
|
||||
[sortBy.type]: (warning: IWarning) => warning.kind,
|
||||
[sortBy.object]: (warning: IWarning) => warning.getName(),
|
||||
[sortBy.type]: (warning: Warning): string => warning.kind,
|
||||
[sortBy.object]: (warning: Warning): string => warning.getName(),
|
||||
};
|
||||
|
||||
@computed get warnings() {
|
||||
const warnings: IWarning[] = [];
|
||||
@computed get warnings(): Warning[] {
|
||||
const warnings: Warning[] = [];
|
||||
|
||||
// Node bad conditions
|
||||
nodesStore.items.forEach(node => {
|
||||
const { kind, selfLink, getId, getName } = node
|
||||
const { kind, selfLink, getId, getName } = node;
|
||||
node.getWarningConditions().forEach(({ message }) => {
|
||||
warnings.push({
|
||||
kind,
|
||||
@@ -51,8 +51,8 @@ export class ClusterIssues extends React.Component<Props> {
|
||||
getName,
|
||||
selfLink,
|
||||
message,
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Warning events for Workloads
|
||||
@@ -67,13 +67,13 @@ export class ClusterIssues extends React.Component<Props> {
|
||||
kind,
|
||||
selfLink: lookupApiLink(involvedObject, error),
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
getTableRow(uid: string) {
|
||||
getTableRow(uid: string): JSX.Element {
|
||||
const { warnings } = this;
|
||||
const warning = warnings.find(warn => warn.getId() == uid);
|
||||
const { getId, getName, message, kind, selfLink } = warning;
|
||||
@@ -97,7 +97,7 @@ export class ClusterIssues extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
renderContent(): JSX.Element {
|
||||
const { warnings } = this;
|
||||
if (!eventStore.isLoaded) {
|
||||
return (
|
||||
@@ -139,7 +139,7 @@ export class ClusterIssues extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<div className={cssNames("ClusterIssues flex column", this.props.className)}>
|
||||
{this.renderContent()}
|
||||
|
||||
@@ -21,7 +21,9 @@ export const ClusterMetricSwitchers = observer(() => {
|
||||
asButtons
|
||||
className={cssNames("RadioGroup flex gaps", { disabled: disableRoles })}
|
||||
value={metricNodeRole}
|
||||
onChange={(metric: MetricNodeRole) => clusterStore.metricNodeRole = metric}
|
||||
onChange={(metric: MetricNodeRole): void => {
|
||||
clusterStore.metricNodeRole = metric;
|
||||
}}
|
||||
>
|
||||
<Radio label={<Trans>Master</Trans>} value={MetricNodeRole.MASTER}/>
|
||||
<Radio label={<Trans>Worker</Trans>} value={MetricNodeRole.WORKER}/>
|
||||
@@ -32,7 +34,9 @@ export const ClusterMetricSwitchers = observer(() => {
|
||||
asButtons
|
||||
className={cssNames("RadioGroup flex gaps", { disabled: disableMetrics })}
|
||||
value={metricType}
|
||||
onChange={(value: MetricType) => clusterStore.metricType = value}
|
||||
onChange={(value: MetricType): void => {
|
||||
clusterStore.metricType = value;
|
||||
}}
|
||||
>
|
||||
<Radio label={<Trans>CPU</Trans>} value={MetricType.CPU}/>
|
||||
<Radio label={<Trans>Memory</Trans>} value={MetricType.MEMORY}/>
|
||||
|
||||
@@ -34,13 +34,13 @@ export const ClusterMetrics = observer(() => {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
suggestedMax: cpuCapacity,
|
||||
callback: (value) => value
|
||||
callback: (value): any => value
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: ({ index }, data) => {
|
||||
label: ({ index }, data): string => {
|
||||
const value = data.datasets[0].data[index] as ChartPoint;
|
||||
return value.y.toString();
|
||||
}
|
||||
@@ -52,13 +52,13 @@ export const ClusterMetrics = observer(() => {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
suggestedMax: memoryCapacity,
|
||||
callback: (value: string) => !value ? 0 : bytesToUnits(parseInt(value))
|
||||
callback: (value: string): string | number => !value ? 0 : bytesToUnits(parseInt(value))
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: ({ index }, data) => {
|
||||
label: ({ index }, data): string => {
|
||||
const value = data.datasets[0].data[index] as ChartPoint;
|
||||
return bytesToUnits(parseInt(value.y as string), 3);
|
||||
}
|
||||
@@ -67,12 +67,12 @@ export const ClusterMetrics = observer(() => {
|
||||
};
|
||||
const options = metricType === MetricType.CPU ? cpuOptions : memoryOptions;
|
||||
|
||||
const renderMetrics = () => {
|
||||
const renderMetrics = (): JSX.Element => {
|
||||
if ((!metricValues.length || !liveMetricValues.length) && !metricsLoaded) {
|
||||
return <Spinner center/>;
|
||||
}
|
||||
if (!memoryCapacity || !cpuCapacity) {
|
||||
return <ClusterNoMetrics className="empty"/>
|
||||
return <ClusterNoMetrics className="empty"/>;
|
||||
}
|
||||
return (
|
||||
<BarChart
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Props {
|
||||
className: string;
|
||||
}
|
||||
|
||||
export function ClusterNoMetrics({ className }: Props) {
|
||||
export function ClusterNoMetrics({ className }: Props): JSX.Element {
|
||||
return (
|
||||
<div className={cssNames("ClusterNoMetrics flex column box grow justify-center align-center", className)}>
|
||||
<Icon material="info"/>
|
||||
|
||||
@@ -17,16 +17,16 @@ import { getMetricLastPoints } from "../../api/endpoints/metrics.api";
|
||||
export const ClusterPieCharts = observer(() => {
|
||||
const { i18n } = useLingui();
|
||||
|
||||
const renderLimitWarning = () => {
|
||||
const renderLimitWarning = (): JSX.Element => {
|
||||
return (
|
||||
<div className="node-warning flex gaps align-center">
|
||||
<Icon material="info"/>
|
||||
<p><Trans>Specified limits are higher than node capacity!</Trans></p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderCharts = () => {
|
||||
const renderCharts = (): JSX.Element => {
|
||||
const data = getMetricLastPoints(clusterStore.metrics);
|
||||
const { memoryUsage, memoryRequests, memoryCapacity, memoryLimits } = data;
|
||||
const { cpuUsage, cpuRequests, cpuCapacity, cpuLimits } = data;
|
||||
@@ -35,7 +35,9 @@ export const ClusterPieCharts = observer(() => {
|
||||
const memoryLimitsOverload = memoryLimits > memoryCapacity;
|
||||
const defaultColor = themeStore.activeTheme.colors.pieChartDefaultColor;
|
||||
|
||||
if (!memoryCapacity || !cpuCapacity || !podCapacity) return null;
|
||||
if (!memoryCapacity || !cpuCapacity || !podCapacity) {
|
||||
return null;
|
||||
}
|
||||
const cpuData: ChartData = {
|
||||
datasets: [
|
||||
{
|
||||
@@ -168,9 +170,9 @@ export const ClusterPieCharts = observer(() => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
const renderContent = (): JSX.Element => {
|
||||
const { masterNodes, workerNodes } = nodesStore;
|
||||
const { metricNodeRole, metricsLoaded } = clusterStore;
|
||||
const nodes = metricNodeRole === MetricNodeRole.MASTER ? masterNodes : workerNodes;
|
||||
@@ -194,11 +196,11 @@ export const ClusterPieCharts = observer(() => {
|
||||
return <ClusterNoMetrics className="empty"/>;
|
||||
}
|
||||
return renderCharts();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ClusterPieCharts flex">
|
||||
{renderContent()}
|
||||
</div>
|
||||
);
|
||||
})
|
||||
});
|
||||
@@ -3,6 +3,6 @@ import { buildURL } from "../../navigation";
|
||||
|
||||
export const clusterRoute: RouteProps = {
|
||||
path: "/cluster"
|
||||
}
|
||||
};
|
||||
|
||||
export const clusterURL = buildURL(clusterRoute.path)
|
||||
export const clusterURL = buildURL(clusterRoute.path);
|
||||
@@ -1,8 +1,8 @@
|
||||
import { observable, reaction, when } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { Cluster, clusterApi, IClusterMetrics } from "../../api/endpoints";
|
||||
import { autobind, createStorage } from "../../utils";
|
||||
import { IMetricsReqParams, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
||||
import { Cluster, clusterApi, ClusterMetrics } from "../../api/endpoints";
|
||||
import { autobind, StorageHelper } from "../../utils";
|
||||
import { MetricsReqParams, normalizeMetrics, Metrics } from "../../api/endpoints/metrics.api";
|
||||
import { nodesStore } from "../+nodes/nodes.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@@ -20,8 +20,8 @@ export enum MetricNodeRole {
|
||||
export class ClusterStore extends KubeObjectStore<Cluster> {
|
||||
api = clusterApi
|
||||
|
||||
@observable metrics: Partial<IClusterMetrics> = {};
|
||||
@observable liveMetrics: Partial<IClusterMetrics> = {};
|
||||
@observable metrics: Partial<ClusterMetrics> = {};
|
||||
@observable liveMetrics: Partial<ClusterMetrics> = {};
|
||||
@observable metricsLoaded = false;
|
||||
@observable metricType: MetricType;
|
||||
@observable metricNodeRole: MetricNodeRole;
|
||||
@@ -31,18 +31,20 @@ export class ClusterStore extends KubeObjectStore<Cluster> {
|
||||
this.resetMetrics();
|
||||
|
||||
// sync user setting with local storage
|
||||
const storage = createStorage("cluster_metric_switchers", {});
|
||||
const storage = new StorageHelper("cluster_metric_switchers", {});
|
||||
Object.assign(this, storage.get());
|
||||
reaction(() => {
|
||||
const { metricType, metricNodeRole } = this;
|
||||
return { metricType, metricNodeRole }
|
||||
return { metricType, metricNodeRole };
|
||||
},
|
||||
settings => storage.set(settings)
|
||||
);
|
||||
|
||||
// auto-update metrics
|
||||
reaction(() => this.metricNodeRole, () => {
|
||||
if (!this.metricsLoaded) return;
|
||||
if (!this.metricsLoaded) {
|
||||
return;
|
||||
}
|
||||
this.metrics = {};
|
||||
this.liveMetrics = {};
|
||||
this.metricsLoaded = false;
|
||||
@@ -52,29 +54,33 @@ export class ClusterStore extends KubeObjectStore<Cluster> {
|
||||
// check which node type to select
|
||||
reaction(() => nodesStore.items.length, () => {
|
||||
const { masterNodes, workerNodes } = nodesStore;
|
||||
if (!masterNodes.length) this.metricNodeRole = MetricNodeRole.WORKER;
|
||||
if (!workerNodes.length) this.metricNodeRole = MetricNodeRole.MASTER;
|
||||
if (!masterNodes.length) {
|
||||
this.metricNodeRole = MetricNodeRole.WORKER;
|
||||
}
|
||||
if (!workerNodes.length) {
|
||||
this.metricNodeRole = MetricNodeRole.MASTER;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadMetrics(params?: IMetricsReqParams) {
|
||||
async loadMetrics(params?: MetricsReqParams): Promise<ClusterMetrics<Metrics>> {
|
||||
await when(() => nodesStore.isLoaded);
|
||||
const { masterNodes, workerNodes } = nodesStore;
|
||||
const nodes = this.metricNodeRole === MetricNodeRole.MASTER && masterNodes.length ? masterNodes : workerNodes;
|
||||
return clusterApi.getMetrics(nodes.map(node => node.getName()), params);
|
||||
}
|
||||
|
||||
async getAllMetrics() {
|
||||
async getAllMetrics(): Promise<void> {
|
||||
await this.getMetrics();
|
||||
await this.getLiveMetrics();
|
||||
this.metricsLoaded = true;
|
||||
}
|
||||
|
||||
async getMetrics() {
|
||||
async getMetrics(): Promise<void> {
|
||||
this.metrics = await this.loadMetrics();
|
||||
}
|
||||
|
||||
async getLiveMetrics() {
|
||||
async getLiveMetrics(): Promise<void> {
|
||||
const step = 3;
|
||||
const range = 15;
|
||||
const end = Date.now() / 1000;
|
||||
@@ -82,25 +88,25 @@ export class ClusterStore extends KubeObjectStore<Cluster> {
|
||||
this.liveMetrics = await this.loadMetrics({ start, end, step, range });
|
||||
}
|
||||
|
||||
getMetricsValues(source: Partial<IClusterMetrics>): [number, string][] {
|
||||
getMetricsValues(source: Partial<ClusterMetrics>): [number, string][] {
|
||||
switch (this.metricType) {
|
||||
case MetricType.CPU:
|
||||
return normalizeMetrics(source.cpuUsage).data.result[0].values
|
||||
return normalizeMetrics(source.cpuUsage).data.result[0].values;
|
||||
case MetricType.MEMORY:
|
||||
return normalizeMetrics(source.memoryUsage).data.result[0].values
|
||||
return normalizeMetrics(source.memoryUsage).data.result[0].values;
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
resetMetrics() {
|
||||
resetMetrics(): void {
|
||||
this.metrics = {};
|
||||
this.metricsLoaded = false;
|
||||
this.metricType = MetricType.CPU;
|
||||
this.metricNodeRole = MetricNodeRole.WORKER;
|
||||
}
|
||||
|
||||
reset() {
|
||||
reset(): void {
|
||||
super.reset();
|
||||
this.resetMetrics();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./cluster.scss"
|
||||
import "./cluster.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed, reaction } from "mobx";
|
||||
@@ -6,7 +6,7 @@ import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { MainLayout } from "../layout/main-layout";
|
||||
import { ClusterIssues } from "./cluster-issues";
|
||||
import { Spinner } from "../spinner";
|
||||
import { cssNames, interval, isElectron } from "../../utils";
|
||||
import { cssNames, IntervalManager, isElectron } from "../../utils";
|
||||
import { ClusterPieCharts } from "./cluster-pie-charts";
|
||||
import { ClusterMetrics } from "./cluster-metrics";
|
||||
import { nodesStore } from "../+nodes/nodes.store";
|
||||
@@ -18,16 +18,16 @@ import { isAllowedResource } from "../../api/rbac";
|
||||
@observer
|
||||
export class Cluster extends React.Component {
|
||||
private watchers = [
|
||||
interval(60, () => clusterStore.getMetrics()),
|
||||
interval(20, () => eventStore.loadAll())
|
||||
new IntervalManager(60, () => clusterStore.getMetrics()),
|
||||
new IntervalManager(20, () => eventStore.loadAll())
|
||||
];
|
||||
|
||||
private dependentStores = [nodesStore, podsStore];
|
||||
|
||||
async componentDidMount() {
|
||||
async componentDidMount(): Promise<void> {
|
||||
const { dependentStores } = this;
|
||||
if (!isAllowedResource("nodes")) {
|
||||
dependentStores.splice(dependentStores.indexOf(nodesStore), 1)
|
||||
dependentStores.splice(dependentStores.indexOf(nodesStore), 1);
|
||||
}
|
||||
this.watchers.forEach(watcher => watcher.start(true));
|
||||
|
||||
@@ -38,22 +38,22 @@ export class Cluster extends React.Component {
|
||||
|
||||
disposeOnUnmount(this, [
|
||||
...dependentStores.map(store => store.subscribe()),
|
||||
() => this.watchers.forEach(watcher => watcher.stop()),
|
||||
(): void => this.watchers.forEach(watcher => watcher.stop()),
|
||||
reaction(
|
||||
() => clusterStore.metricNodeRole,
|
||||
() => this.watchers.forEach(watcher => watcher.restart())
|
||||
)
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
@computed get isLoaded() {
|
||||
@computed get isLoaded(): boolean {
|
||||
return (
|
||||
nodesStore.isLoaded &&
|
||||
podsStore.isLoaded
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
const { isLoaded } = this;
|
||||
return (
|
||||
<MainLayout>
|
||||
@@ -68,6 +68,6 @@ export class Cluster extends React.Component {
|
||||
)}
|
||||
</div>
|
||||
</MainLayout>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from "./cluster.routes"
|
||||
export * from "./cluster.routes";
|
||||
|
||||
Reference in new issue
Block a user