1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Fixing tolerations list layout (#2002)

* Expanding tolerations div width

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Adding tolerations table

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Fixing tolerations table styles

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Adding <PodTolerations/> tests

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Add new line at the end of the file for linter

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2021-01-22 10:27:54 +03:00 committed by GitHub
parent 2e2283bcc9
commit a92ed46f0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 165 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import get from "lodash/get"; import get from "lodash/get";
import { KubeObject } from "./kube-object"; import { KubeObject } from "./kube-object";
interface IToleration { export interface IToleration {
key?: string; key?: string;
operator?: string; operator?: string;
effect?: string; effect?: string;

View File

@ -0,0 +1,59 @@
/**
* @jest-environment jsdom
*/
import React from "react";
import "@testing-library/jest-dom/extend-expect";
import { fireEvent, render } from "@testing-library/react";
import { IToleration } from "../../../api/workload-kube-object";
import { PodTolerations } from "../pod-tolerations";
const tolerations: IToleration[] =[
{
key: "CriticalAddonsOnly",
operator: "Exist",
effect: "NoExecute",
tolerationSeconds: 3600
},
{
key: "node.kubernetes.io/not-ready",
operator: "NoExist",
effect: "NoSchedule",
tolerationSeconds: 7200
},
];
describe("<PodTolerations />", () => {
it("renders w/o errors", () => {
const { container } = render(<PodTolerations tolerations={tolerations} />);
expect(container).toBeInstanceOf(HTMLElement);
});
it("shows all tolerations", () => {
const { container } = render(<PodTolerations tolerations={tolerations} />);
const rows = container.querySelectorAll(".TableRow");
expect(rows[0].querySelector(".key").textContent).toBe("CriticalAddonsOnly");
expect(rows[0].querySelector(".operator").textContent).toBe("Exist");
expect(rows[0].querySelector(".effect").textContent).toBe("NoExecute");
expect(rows[0].querySelector(".seconds").textContent).toBe("3600");
expect(rows[1].querySelector(".key").textContent).toBe("node.kubernetes.io/not-ready");
expect(rows[1].querySelector(".operator").textContent).toBe("NoExist");
expect(rows[1].querySelector(".effect").textContent).toBe("NoSchedule");
expect(rows[1].querySelector(".seconds").textContent).toBe("7200");
});
it("sorts table properly", () => {
const { container, getByText } = render(<PodTolerations tolerations={tolerations} />);
const headCell = getByText("Key");
fireEvent.click(headCell);
fireEvent.click(headCell);
const rows = container.querySelectorAll(".TableRow");
expect(rows[0].querySelector(".key").textContent).toBe("node.kubernetes.io/not-ready");
});
});

View File

@ -1,5 +1,23 @@
.PodDetailsTolerations { .PodDetailsTolerations {
.toleration { grid-template-columns: auto;
margin-bottom: $margin;
.PodTolerations {
margin-top: var(--margin);
}
// Expanding value cell to cover 2 columns (whole Drawer width)
> .name {
grid-row-start: 1;
grid-column-start: 1;
}
> .value {
grid-row-start: 1;
grid-column-start: 1;
}
.DrawerParamToggler > .params {
margin-left: var(--drawer-item-title-width);
} }
} }

View File

@ -1,10 +1,11 @@
import "./pod-details-tolerations.scss"; import "./pod-details-tolerations.scss";
import React from "react"; import React from "react";
import { Pod, Deployment, DaemonSet, StatefulSet, ReplicaSet, Job } from "../../api/endpoints";
import { DrawerParamToggler, DrawerItem } from "../drawer"; import { DrawerParamToggler, DrawerItem } from "../drawer";
import { WorkloadKubeObject } from "../../api/workload-kube-object";
import { PodTolerations } from "./pod-tolerations";
interface Props { interface Props {
workload: Pod | Deployment | DaemonSet | StatefulSet | ReplicaSet | Job; workload: WorkloadKubeObject;
} }
export class PodDetailsTolerations extends React.Component<Props> { export class PodDetailsTolerations extends React.Component<Props> {
@ -17,20 +18,7 @@ export class PodDetailsTolerations extends React.Component<Props> {
return ( return (
<DrawerItem name="Tolerations" className="PodDetailsTolerations"> <DrawerItem name="Tolerations" className="PodDetailsTolerations">
<DrawerParamToggler label={tolerations.length}> <DrawerParamToggler label={tolerations.length}>
{ <PodTolerations tolerations={tolerations} />
tolerations.map((toleration, index) => {
const { key, operator, effect, tolerationSeconds } = toleration;
return (
<div className="toleration" key={index}>
<DrawerItem name="Key">{key}</DrawerItem>
{operator && <DrawerItem name="Operator">{operator}</DrawerItem>}
{effect && <DrawerItem name="Effect">{effect}</DrawerItem>}
{!!tolerationSeconds && <DrawerItem name="Effect">{tolerationSeconds}</DrawerItem>}
</div>
);
})
}
</DrawerParamToggler> </DrawerParamToggler>
</DrawerItem> </DrawerItem>
); );

View File

@ -0,0 +1,14 @@
.PodTolerations {
.TableHead {
background-color: var(--drawerSubtitleBackground);
}
.TableCell {
white-space: normal;
word-break: normal;
&.key {
flex-grow: 3;
}
}
}

View File

@ -0,0 +1,63 @@
import "./pod-tolerations.scss";
import React from "react";
import uniqueId from "lodash/uniqueId";
import { IToleration } from "../../api/workload-kube-object";
import { Table, TableCell, TableHead, TableRow } from "../table";
interface Props {
tolerations: IToleration[];
}
enum sortBy {
Key = "key",
Operator = "operator",
Effect = "effect",
Seconds = "seconds",
}
const sortingCallbacks = {
[sortBy.Key]: (toleration: IToleration) => toleration.key,
[sortBy.Operator]: (toleration: IToleration) => toleration.operator,
[sortBy.Effect]: (toleration: IToleration) => toleration.effect,
[sortBy.Seconds]: (toleration: IToleration) => toleration.tolerationSeconds,
};
const getTableRow = (toleration: IToleration) => {
const { key, operator, effect, tolerationSeconds } = toleration;
return (
<TableRow
key={uniqueId("toleration-")}
sortItem={toleration}
nowrap
>
<TableCell className="key">{key}</TableCell>
<TableCell className="operator">{operator}</TableCell>
<TableCell className="effect">{effect}</TableCell>
<TableCell className="seconds">{tolerationSeconds}</TableCell>
</TableRow>
);
};
export function PodTolerations({ tolerations }: Props) {
return (
<Table
selectable
scrollable={false}
sortable={sortingCallbacks}
sortSyncWithUrl={false}
className="PodTolerations"
>
<TableHead sticky={false}>
<TableCell className="key" sortBy={sortBy.Key}>Key</TableCell>
<TableCell className="operator" sortBy={sortBy.Operator}>Operator</TableCell>
<TableCell className="effect" sortBy={sortBy.Effect}>Effect</TableCell>
<TableCell className="seconds" sortBy={sortBy.Seconds}>Seconds</TableCell>
</TableHead>
{
tolerations.map(getTableRow)
}
</Table>
);
}

View File

@ -1,6 +1,8 @@
.DrawerItem { .DrawerItem {
--drawer-item-title-width: 30%;
display: grid; display: grid;
grid-template-columns: minmax(30%, min-content) auto; grid-template-columns: minmax(var(--drawer-item-title-width), min-content) auto;
border-bottom: 1px solid $borderFaintColor; border-bottom: 1px solid $borderFaintColor;
padding: $padding 0; padding: $padding 0;

View File

@ -25,7 +25,7 @@ export class DrawerParamToggler extends React.Component<DrawerParamTogglerProps,
return ( return (
<div className="DrawerParamToggler"> <div className="DrawerParamToggler">
<div className="flex gaps align-center"> <div className="flex gaps align-center params">
<div className="param-label">{label}</div> <div className="param-label">{label}</div>
<div className="param-link" onClick={this.toggle}> <div className="param-link" onClick={this.toggle}>
<span className="param-link-text">{link}</span> <span className="param-link-text">{link}</span>

View File

@ -69,7 +69,6 @@
padding: var(--spacing); padding: var(--spacing);
.Table .TableHead { .Table .TableHead {
background-color: $contentColor;
border-bottom: 1px solid $borderFaintColor; border-bottom: 1px solid $borderFaintColor;
} }
} }