mirror of
https://github.com/gethomepage/homepage.git
synced 2026-09-25 21:41:17 -07:00
Enhancement: render more docker states (#7099)
Docker CI / Docker Build & Push (push) Has been cancelled
Lint / Linting Checks (push) Has been cancelled
Release Drafter / Update Release Draft (push) Has been cancelled
Release Drafter / Auto Label PR (push) Has been cancelled
Tests / vitest (1) (push) Has been cancelled
Tests / vitest (2) (push) Has been cancelled
Tests / vitest (3) (push) Has been cancelled
Tests / vitest (4) (push) Has been cancelled
Docker CI / Docker Build & Push (push) Has been cancelled
Lint / Linting Checks (push) Has been cancelled
Release Drafter / Update Release Draft (push) Has been cancelled
Release Drafter / Auto Label PR (push) Has been cancelled
Tests / vitest (1) (push) Has been cancelled
Tests / vitest (2) (push) Has been cancelled
Tests / vitest (3) (push) Has been cancelled
Tests / vitest (4) (push) Has been cancelled
This commit is contained in:
@@ -99,7 +99,12 @@
|
|||||||
"unhealthy": "Unhealthy",
|
"unhealthy": "Unhealthy",
|
||||||
"not_found": "Not Found",
|
"not_found": "Not Found",
|
||||||
"exited": "Exited",
|
"exited": "Exited",
|
||||||
"partial": "Partial"
|
"partial": "Partial",
|
||||||
|
"created": "Created",
|
||||||
|
"paused": "Paused",
|
||||||
|
"restarting": "Restarting",
|
||||||
|
"removing": "Removing",
|
||||||
|
"dead": "Dead"
|
||||||
},
|
},
|
||||||
"ping": {
|
"ping": {
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
|
|||||||
@@ -1,6 +1,22 @@
|
|||||||
import { useTranslation } from "next-i18next/pages";
|
import { useTranslation } from "next-i18next/pages";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
|
const WARNING_CLASS = "text-orange-400/50 dark:text-orange-400/80";
|
||||||
|
|
||||||
|
// docker container states other than running
|
||||||
|
const STATE_LABELS = {
|
||||||
|
created: "docker.created",
|
||||||
|
dead: "docker.dead",
|
||||||
|
exited: "docker.exited",
|
||||||
|
"not found": "docker.not_found",
|
||||||
|
paused: "docker.paused",
|
||||||
|
removing: "docker.removing",
|
||||||
|
restarting: "docker.restarting",
|
||||||
|
};
|
||||||
|
|
||||||
|
// states that mean something is wrong rather than merely not started
|
||||||
|
const WARNING_STATES = new Set(["dead", "exited", "not found", "restarting"]);
|
||||||
|
|
||||||
export default function Status({ service, style }) {
|
export default function Status({ service, style }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -16,33 +32,30 @@ export default function Status({ service, style }) {
|
|||||||
if (statusError) {
|
if (statusError) {
|
||||||
statusLabel = t("docker.error");
|
statusLabel = t("docker.error");
|
||||||
colorClass = "text-rose-500/80";
|
colorClass = "text-rose-500/80";
|
||||||
} else if (data) {
|
} else if (data?.status?.includes("running")) {
|
||||||
if (data.status?.includes("running")) {
|
colorClass = "text-emerald-500/80";
|
||||||
colorClass = "text-emerald-500/80";
|
|
||||||
|
|
||||||
if (!data.health) {
|
if (!data.health) {
|
||||||
statusLabel = data.status.replace("running", t("docker.running"));
|
statusLabel = data.status.replace("running", t("docker.running"));
|
||||||
} else {
|
} else {
|
||||||
statusLabel = data.health === "healthy" ? t("docker.healthy") : data.health;
|
statusLabel = data.health === "healthy" ? t("docker.healthy") : data.health;
|
||||||
|
|
||||||
if (data.health === "starting") {
|
if (data.health === "starting") {
|
||||||
statusLabel = t("docker.starting");
|
statusLabel = t("docker.starting");
|
||||||
colorClass = "text-blue-500/80";
|
colorClass = "text-blue-500/80";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.health === "unhealthy") {
|
if (data.health === "unhealthy") {
|
||||||
statusLabel = t("docker.unhealthy");
|
statusLabel = t("docker.unhealthy");
|
||||||
colorClass = "text-orange-400/50 dark:text-orange-400/80";
|
colorClass = WARNING_CLASS;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (data?.status?.startsWith("partial")) {
|
||||||
if (data.status === "not found" || data.status === "exited" || data.status?.startsWith("partial")) {
|
statusLabel = data.status.replace("partial", t("docker.partial"));
|
||||||
if (data.status === "not found") statusLabel = t("docker.not_found");
|
colorClass = WARNING_CLASS;
|
||||||
else if (data.status === "exited") statusLabel = t("docker.exited");
|
} else if (data && STATE_LABELS[data.status]) {
|
||||||
else statusLabel = data.status.replace("partial", t("docker.partial"));
|
statusLabel = t(STATE_LABELS[data.status]);
|
||||||
colorClass = "text-orange-400/50 dark:text-orange-400/80";
|
if (WARNING_STATES.has(data.status)) colorClass = WARNING_CLASS;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (style === "dot") {
|
if (style === "dot") {
|
||||||
|
|||||||
@@ -75,6 +75,46 @@ describe("components/services/status", () => {
|
|||||||
expect(screen.getByText("docker.starting")).toBeInTheDocument();
|
expect(screen.getByText("docker.starting")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("renders the remaining container states instead of falling through to unknown", () => {
|
||||||
|
const states = {
|
||||||
|
created: "docker.created",
|
||||||
|
paused: "docker.paused",
|
||||||
|
restarting: "docker.restarting",
|
||||||
|
removing: "docker.removing",
|
||||||
|
dead: "docker.dead",
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(states).forEach(([status, label]) => {
|
||||||
|
useSWR.mockReturnValue({ data: { statuses: { c: { status } } }, error: undefined });
|
||||||
|
render(<Status service={{ container: "c", server: "s" }} />);
|
||||||
|
expect(screen.getByText(label)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.queryByText("docker.unknown")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("colors problem states as warnings and merely stopped states neutrally", () => {
|
||||||
|
useSWR.mockReturnValue({ data: { statuses: { c: { status: "restarting" } } }, error: undefined });
|
||||||
|
const { container: restarting } = render(<Status service={{ container: "c", server: "s" }} style="dot" />);
|
||||||
|
expect(restarting.querySelector(".bg-orange-400")).toBeInTheDocument();
|
||||||
|
|
||||||
|
useSWR.mockReturnValue({ data: { statuses: { c: { status: "paused" } } }, error: undefined });
|
||||||
|
const { container: paused } = render(<Status service={{ container: "c", server: "s" }} style="dot" />);
|
||||||
|
expect(paused.querySelector(".bg-orange-400")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not surface health for containers that are not running", () => {
|
||||||
|
useSWR.mockReturnValue({
|
||||||
|
data: { statuses: { c: { status: "paused", health: "unhealthy" } } },
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<Status service={{ container: "c", server: "s" }} />);
|
||||||
|
|
||||||
|
expect(screen.getByText("docker.paused")).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText("docker.unhealthy")).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
it("renders a dot when style is dot", () => {
|
it("renders a dot when style is dot", () => {
|
||||||
useSWR.mockReturnValue({ data: { statuses: { c: { status: "running" } } }, error: undefined });
|
useSWR.mockReturnValue({ data: { statuses: { c: { status: "running" } } }, error: undefined });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user