Files
coder/site/src/modules/apps/AppStatusStateIcon.tsx
T
Asher 48bb534a51 chore: fix idle state icon when disabled (#18554)
When the workspace is off, we set a disabled text/stroke color, but for
the idle icon that also needs a fill, this only changed the outline
making it look weird. Instead, move the disabled logic into the
component so we can apply a matching fill.

I felt it looked too thick with both the outline and fill, so I also
removed the outline.

Really I think maybe the workspace status should be a separate column
rather than disabling these icons, but this maintains the status quo.


Before with mismatching stroke and fill color:


![screenshot](https://github.com/user-attachments/assets/961014b7-1e26-49f0-aa87-834f2f367618)


After with disabled fill and stroke removal:


![screenshot](https://github.com/user-attachments/assets/205e4515-dc01-4437-87ec-a0f8a546da3b)


Enabled fill and stroke removal:


![screenshot](https://github.com/user-attachments/assets/04f5914e-f96c-4c75-8873-e3fc9c854d95)
2025-06-25 10:06:57 -08:00

71 lines
1.6 KiB
TypeScript

import type { WorkspaceAppStatusState } from "api/typesGenerated";
import { Spinner } from "components/Spinner/Spinner";
import {
BanIcon,
CircleAlertIcon,
CircleCheckIcon,
HourglassIcon,
PauseIcon,
TriangleAlertIcon,
} from "lucide-react";
import type { FC } from "react";
import { cn } from "utils/cn";
type AppStatusStateIconProps = {
state: WorkspaceAppStatusState;
latest: boolean;
disabled?: boolean;
className?: string;
};
export const AppStatusStateIcon: FC<AppStatusStateIconProps> = ({
state,
disabled,
latest,
className: customClassName,
}) => {
const className = cn([
"size-4 shrink-0",
customClassName,
disabled && "text-content-disabled",
]);
switch (state) {
case "idle":
// The pause icon is outlined; add a fill since it is hard to see and
// remove the stroke so it is not overly thick.
return (
<PauseIcon
css={{ strokeWidth: 0 }}
className={cn([
"text-content-secondary",
className,
disabled ? "fill-content-disabled" : "fill-content-secondary",
])}
/>
);
case "complete":
return (
<CircleCheckIcon className={cn(["text-content-success", className])} />
);
case "failure":
return (
<CircleAlertIcon className={cn(["text-content-warning", className])} />
);
case "working":
return disabled ? (
<BanIcon className={cn(["text-content-disabled", className])} />
) : latest ? (
<Spinner size="sm" className="shrink-0" loading />
) : (
<HourglassIcon className={cn(["text-content-secondary", className])} />
);
default:
return (
<TriangleAlertIcon
className={cn(["text-content-secondary", className])}
/>
);
}
};