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

This commit is contained in:
shamoon
2026-09-05 10:24:59 -07:00
committed by GitHub
parent 7de1faa769
commit 1c2cb76702
3 changed files with 81 additions and 23 deletions
+6 -1
View File
@@ -99,7 +99,12 @@
"unhealthy": "Unhealthy",
"not_found": "Not Found",
"exited": "Exited",
"partial": "Partial"
"partial": "Partial",
"created": "Created",
"paused": "Paused",
"restarting": "Restarting",
"removing": "Removing",
"dead": "Dead"
},
"ping": {
"error": "Error",
+35 -22
View File
@@ -1,6 +1,22 @@
import { useTranslation } from "next-i18next/pages";
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 }) {
const { t } = useTranslation();
@@ -16,33 +32,30 @@ export default function Status({ service, style }) {
if (statusError) {
statusLabel = t("docker.error");
colorClass = "text-rose-500/80";
} else if (data) {
if (data.status?.includes("running")) {
colorClass = "text-emerald-500/80";
} else if (data?.status?.includes("running")) {
colorClass = "text-emerald-500/80";
if (!data.health) {
statusLabel = data.status.replace("running", t("docker.running"));
} else {
statusLabel = data.health === "healthy" ? t("docker.healthy") : data.health;
if (!data.health) {
statusLabel = data.status.replace("running", t("docker.running"));
} else {
statusLabel = data.health === "healthy" ? t("docker.healthy") : data.health;
if (data.health === "starting") {
statusLabel = t("docker.starting");
colorClass = "text-blue-500/80";
}
if (data.health === "starting") {
statusLabel = t("docker.starting");
colorClass = "text-blue-500/80";
}
if (data.health === "unhealthy") {
statusLabel = t("docker.unhealthy");
colorClass = "text-orange-400/50 dark:text-orange-400/80";
}
if (data.health === "unhealthy") {
statusLabel = t("docker.unhealthy");
colorClass = WARNING_CLASS;
}
}
if (data.status === "not found" || data.status === "exited" || data.status?.startsWith("partial")) {
if (data.status === "not found") statusLabel = t("docker.not_found");
else if (data.status === "exited") statusLabel = t("docker.exited");
else statusLabel = data.status.replace("partial", t("docker.partial"));
colorClass = "text-orange-400/50 dark:text-orange-400/80";
}
} else if (data?.status?.startsWith("partial")) {
statusLabel = data.status.replace("partial", t("docker.partial"));
colorClass = WARNING_CLASS;
} else if (data && STATE_LABELS[data.status]) {
statusLabel = t(STATE_LABELS[data.status]);
if (WARNING_STATES.has(data.status)) colorClass = WARNING_CLASS;
}
if (style === "dot") {
+40
View File
@@ -75,6 +75,46 @@ describe("components/services/status", () => {
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", () => {
useSWR.mockReturnValue({ data: { statuses: { c: { status: "running" } } }, error: undefined });