fix(tickets): dropdowns ne sortent plus du viewport en bas d'écran (#3)
Remplace les <select> natifs de la vue Tickets (statut, priorité, tri, lien, agent assigné/assistant, sprint) par TicketViewportSelect, qui repositionne intelligemment son overlay selon l'espace disponible dans la fenêtre au lieu de toujours ouvrir vers le bas. QA vert : 80/80 (frontend/src/features/tickets), tsc --noEmit propre. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -353,9 +353,8 @@ describe("TicketsView", () => {
|
||||
expect(listSpy.mock.calls.at(-1)?.[1]?.sort).toBeUndefined();
|
||||
|
||||
// Choose a field ⇒ ascending by default, relayed in the query.
|
||||
fireEvent.change(screen.getByLabelText("sort tickets by"), {
|
||||
target: { value: "title" },
|
||||
});
|
||||
fireEvent.click(screen.getByLabelText("sort tickets by"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "Titre" }));
|
||||
await waitFor(() =>
|
||||
expect(listSpy.mock.calls.at(-1)?.[1]?.sort).toEqual({
|
||||
field: "title",
|
||||
@ -375,9 +374,8 @@ describe("TicketsView", () => {
|
||||
);
|
||||
|
||||
// Back to « Par défaut » ⇒ `sort` dropped from the query again.
|
||||
fireEvent.change(screen.getByLabelText("sort tickets by"), {
|
||||
target: { value: "" },
|
||||
});
|
||||
fireEvent.click(screen.getByLabelText("sort tickets by"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "Par défaut" }));
|
||||
await waitFor(() =>
|
||||
expect(listSpy.mock.calls.at(-1)?.[1]?.sort).toBeUndefined(),
|
||||
);
|
||||
@ -390,8 +388,8 @@ describe("TicketsView", () => {
|
||||
fireEvent.click(await screen.findByText("Editable"));
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
|
||||
const statusSelect = within(dialog).getByLabelText("ticket status");
|
||||
fireEvent.change(statusSelect, { target: { value: "inProgress" } });
|
||||
fireEvent.click(within(dialog).getByLabelText("ticket status"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "In progress" }));
|
||||
|
||||
await waitFor(async () => {
|
||||
const fresh = await ticket.read(PROJECT_ID, t.ref);
|
||||
@ -426,9 +424,8 @@ describe("TicketsView", () => {
|
||||
fireEvent.click(await screen.findByText("Assignable"));
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
|
||||
fireEvent.change(within(dialog).getByLabelText("assign agent"), {
|
||||
target: { value: known.id },
|
||||
});
|
||||
fireEvent.click(within(dialog).getByLabelText("assign agent"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "Backend" }));
|
||||
fireEvent.click(within(dialog).getByText("Assign"));
|
||||
|
||||
await waitFor(async () => {
|
||||
@ -495,9 +492,8 @@ describe("TicketsView", () => {
|
||||
|
||||
// Change the priority — an immediate-apply mutation that re-fetches the ticket
|
||||
// and bumps its version. The unsaved draft must survive.
|
||||
fireEvent.change(within(dialog).getByLabelText("ticket priority"), {
|
||||
target: { value: "high" },
|
||||
});
|
||||
fireEvent.click(within(dialog).getByLabelText("ticket priority"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "High" }));
|
||||
|
||||
// The backend applied the priority bump…
|
||||
await waitFor(async () => {
|
||||
@ -643,9 +639,8 @@ describe("TicketsView", () => {
|
||||
expect(within(bucket).getByText("Movable")).toBeTruthy();
|
||||
|
||||
// Pick the sprint in the row selector → assign it.
|
||||
fireEvent.change(screen.getByLabelText(`sprint for ${t.ref}`), {
|
||||
target: { value: "s1" },
|
||||
});
|
||||
fireEvent.click(screen.getByLabelText(`sprint for ${t.ref}`));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "Sprint One" }));
|
||||
|
||||
// The gateway recorded the membership…
|
||||
await waitFor(async () => {
|
||||
@ -777,7 +772,8 @@ describe("TicketsView", () => {
|
||||
);
|
||||
expect(within(assistant).getByText("Ouvrir la conversation")).toBeTruthy();
|
||||
|
||||
fireEvent.change(profileSelect, { target: { value: "qa-assistant" } });
|
||||
fireEvent.click(profileSelect);
|
||||
fireEvent.click(await screen.findByRole("option", { name: "QA Assistant" }));
|
||||
fireEvent.click(within(assistant).getByText("Ouvrir la conversation"));
|
||||
|
||||
expect(
|
||||
@ -837,9 +833,8 @@ describe("TicketsView", () => {
|
||||
expect(within(detail).queryByLabelText("link target ref")).toBeNull();
|
||||
|
||||
// Choose the link kind, then open the picker and select the target ticket.
|
||||
fireEvent.change(within(detail).getByLabelText("link kind"), {
|
||||
target: { value: "blocks" },
|
||||
});
|
||||
fireEvent.click(within(detail).getByLabelText("link kind"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "blocks" }));
|
||||
fireEvent.click(within(detail).getByLabelText("add link"));
|
||||
|
||||
// The picker excludes the ticket itself; the target is offered.
|
||||
|
||||
Reference in New Issue
Block a user