diff --git a/__tests__/components/automations/automation-view-toggle.test.tsx b/__tests__/components/automations/automation-view-toggle.test.tsx
index 6fcbd5d6..96d103aa 100644
--- a/__tests__/components/automations/automation-view-toggle.test.tsx
+++ b/__tests__/components/automations/automation-view-toggle.test.tsx
@@ -23,4 +23,24 @@ describe("AutomationViewToggle", () => {
expect(onChange).toHaveBeenCalledWith("list");
});
+
+ it("does not open the menu or fire onChange when disabled", async () => {
+ // Arrange
+ const user = userEvent.setup();
+ const onChange = vi.fn();
+ render(
+ ,
+ );
+ const trigger = screen.getByTestId("automations-view-toggle");
+
+ // Act — try to open the menu
+ await user.click(trigger);
+
+ // Assert — menu items never render and onChange stays untouched
+ expect(trigger).toBeDisabled();
+ expect(
+ screen.queryByTestId("automations-view-toggle-list"),
+ ).not.toBeInTheDocument();
+ expect(onChange).not.toHaveBeenCalled();
+ });
});
diff --git a/__tests__/routes/automations-list.test.tsx b/__tests__/routes/automations-list.test.tsx
index 47175e9b..ea19ad6a 100644
--- a/__tests__/routes/automations-list.test.tsx
+++ b/__tests__/routes/automations-list.test.tsx
@@ -166,4 +166,27 @@ describe("AutomationsList — view mode toggle", () => {
"list",
);
});
+
+ it("disables the view-mode toggle when the user has no automations", async () => {
+ // Arrange — service returns an empty list, so the page lands on EmptyState.
+ vi.mocked(AutomationService.getAutomations).mockResolvedValue({
+ automations: [],
+ total: 0,
+ });
+ const user = userEvent.setup();
+ renderList();
+ await waitFor(() => {
+ expect(AutomationService.getAutomations).toHaveBeenCalledTimes(1);
+ });
+
+ // Act — try to open the toggle's grid/list menu.
+ const trigger = await screen.findByTestId("automations-view-toggle");
+ await user.click(trigger);
+
+ // Assert — toggle is disabled and clicking it does not reveal the menu.
+ expect(trigger).toBeDisabled();
+ expect(
+ screen.queryByTestId("automations-view-toggle-list"),
+ ).not.toBeInTheDocument();
+ });
});
diff --git a/src/components/features/automations/automation-view-toggle.tsx b/src/components/features/automations/automation-view-toggle.tsx
index 64dba89c..1f37fbb2 100644
--- a/src/components/features/automations/automation-view-toggle.tsx
+++ b/src/components/features/automations/automation-view-toggle.tsx
@@ -11,6 +11,7 @@ import type { AutomationViewMode } from "./automation-view-mode";
interface AutomationViewToggleProps {
view: AutomationViewMode;
onChange: (view: AutomationViewMode) => void;
+ disabled?: boolean;
}
const VIEW_OPTIONS: {
@@ -59,6 +60,7 @@ function ViewMenuItemContent({
export function AutomationViewToggle({
view,
onChange,
+ disabled = false,
}: AutomationViewToggleProps) {
const { t } = useTranslation("openhands");
const [open, setOpen] = useState(false);
@@ -156,9 +158,15 @@ export function AutomationViewToggle({
aria-label={t(I18nKey.AUTOMATIONS$VIEW_MODE)}
aria-haspopup="menu"
aria-expanded={open}
- onClick={() => setOpen((current) => !current)}
+ aria-disabled={disabled}
+ disabled={disabled}
+ onClick={() => {
+ if (disabled) return;
+ setOpen((current) => !current);
+ }}
className={cn(
"inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-lg border border-[var(--oh-border)] bg-base-secondary text-white transition-colors hover:bg-[var(--oh-interactive-hover)] focus-visible:border-white/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white/20",
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-base-secondary",
)}
>
diff --git a/src/routes/automations-list.tsx b/src/routes/automations-list.tsx
index b284cd6f..349cf234 100644
--- a/src/routes/automations-list.tsx
+++ b/src/routes/automations-list.tsx
@@ -124,6 +124,8 @@ export default function AutomationsList() {
}, []);
const hasMore = data ? data.total > data.automations.length : false;
+ const hasNoAutomations =
+ !isLoading && !isError && data?.automations.length === 0;
// Show loading state while checking health
if (isHealthLoading) {
@@ -193,6 +195,7 @@ export default function AutomationsList() {
@@ -208,9 +211,7 @@ export default function AutomationsList() {
{isError && !isLoading && }
- {!isLoading && !isError && data?.automations.length === 0 && (
-
- )}
+ {hasNoAutomations && }
{!isLoading && !isError && data && data.automations.length > 0 && (
<>