fix: use long press for mobile task actions (#1673)

This commit is contained in:
Carlos Florêncio
2026-07-13 13:56:55 +01:00
committed by GitHub
parent 892ce9bf09
commit c4dd45f9ac
3 changed files with 82 additions and 4 deletions
+7 -3
View File
@@ -273,9 +273,12 @@ function TaskItemStatsRow({
function DiffStatsRight({ diffStats, menuOpen }: { diffStats: DiffStats; menuOpen: boolean }) {
return (
<div
data-testid="sidebar-task-diff-stats"
className={cn(
"shrink-0 self-center font-mono text-[11px] transition-opacity duration-100",
menuOpen ? "opacity-0" : "group-hover:opacity-0 group-focus-within:opacity-0",
menuOpen
? "opacity-0"
: "[@media(hover:hover)]:group-hover:opacity-0 group-focus-within:opacity-0",
)}
>
<span className="text-emerald-500">+{diffStats.additions}</span>{" "}
@@ -558,15 +561,16 @@ function TaskMenuButton({ visible }: { visible: boolean }) {
<div
className={cn(
"self-center shrink-0 flex items-center transition-opacity duration-100",
!visible && "[@media(hover:none)]:hidden",
visible
? "opacity-100"
: "opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:pointer-events-auto [@media(hover:none)]:opacity-100 [@media(hover:none)]:pointer-events-auto",
: "opacity-0 pointer-events-none [@media(hover:hover)]:group-hover:opacity-100 [@media(hover:hover)]:group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:pointer-events-auto",
)}
>
<button
type="button"
className={cn(
"flex h-6 w-6 items-center justify-center rounded-md cursor-pointer",
"flex size-6 items-center justify-center rounded-md cursor-pointer",
"text-muted-foreground hover:text-foreground hover:bg-foreground/10",
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring transition-colors",
)}
@@ -40,7 +40,21 @@ test.describe("Mobile sidebar — external link menu", () => {
hasText: "Mobile external link task",
});
await expect(taskRow).toBeVisible({ timeout: 10_000 });
await taskRow.getByRole("button", { name: "Task actions" }).click();
await taskRow.dispatchEvent("pointerdown", {
pointerType: "touch",
isPrimary: true,
button: 0,
clientX: 120,
clientY: 240,
});
await testPage.waitForTimeout(1000);
await taskRow.dispatchEvent("pointerup", {
pointerType: "touch",
isPrimary: true,
button: 0,
clientX: 120,
clientY: 240,
});
const linkTrigger = testPage.getByRole("menuitem", { name: /^Link$/ });
await expect(linkTrigger).toBeVisible();
@@ -0,0 +1,60 @@
import { test, expect } from "../../fixtures/test-base";
import { SessionPage } from "../../pages/session-page";
test.describe("Mobile sidebar task actions", () => {
test("opens task actions on long press without covering diff stats", async ({
testPage,
apiClient,
seedData,
}) => {
const taskTitle = "Mobile task with diff stats";
const task = await apiClient.createTaskWithAgent(
seedData.workspaceId,
taskTitle,
seedData.agentProfileId,
{
description: "/e2e:diff-update-setup",
workflow_id: seedData.workflowId,
workflow_step_id: seedData.startStepId,
repository_ids: [seedData.repositoryId],
executor_profile_id: seedData.worktreeExecutorProfileId,
},
);
await testPage.goto(`/t/${task.id}`);
const session = new SessionPage(testPage);
await session.waitForLoad();
await expect(
session.chat.getByText("diff-update-setup complete", { exact: false }),
).toBeVisible({
timeout: 60_000,
});
await testPage.getByTestId("mobile-session-menu").click();
const sheet = testPage.getByRole("dialog");
const taskRow = sheet.getByTestId("sidebar-task-item").filter({ hasText: taskTitle });
const diffStats = taskRow.getByTestId("sidebar-task-diff-stats");
const actions = taskRow.getByRole("button", { name: "Task actions" });
await expect(diffStats).toBeVisible({ timeout: 15_000 });
await expect(actions).toBeHidden();
await taskRow.dispatchEvent("pointerdown", {
pointerType: "touch",
isPrimary: true,
button: 0,
clientX: 120,
clientY: 240,
});
await testPage.waitForTimeout(1000);
await taskRow.dispatchEvent("pointerup", {
pointerType: "touch",
isPrimary: true,
button: 0,
clientX: 120,
clientY: 240,
});
await expect(testPage.getByRole("menuitem", { name: "Archive" })).toBeVisible();
});
});