feat(tickets): affiche le créateur d'un ticket et filtre la liste par créateur
createdBy était déjà présent dans le frontmatter des tickets mais ni exposé ni exploitable côté UI. Ajout du DTO (domain/ports/mock), affichage dans TicketDetail, colonne/filtre créateur dans TicketsPanel, et persistance du filtre. ticketActor.ts introduit pour porter la logique de filtrage côté frontend, sans changement backend nécessaire (lot frontend pur). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -103,6 +103,28 @@ describe("MockTicketGateway", () => {
|
||||
expect(search.items.map((i) => i.ref)).toEqual(["#2"]);
|
||||
});
|
||||
|
||||
it("filters by creator and exposes createdBy on summaries (#109)", async () => {
|
||||
await ticket.create(PROJECT_ID, { title: "User ticket" });
|
||||
const agentTicket = await ticket.create(PROJECT_ID, { title: "Agent ticket" });
|
||||
ticket._seedTicket(PROJECT_ID, {
|
||||
...agentTicket,
|
||||
createdBy: { kind: "agent", agentId: "agent-1" },
|
||||
});
|
||||
|
||||
const byUser = await ticket.list(PROJECT_ID, { createdBy: { kind: "user" } });
|
||||
expect(byUser.items.map((i) => i.title)).toEqual(["User ticket"]);
|
||||
expect(byUser.items[0]?.createdBy).toEqual({ kind: "user" });
|
||||
|
||||
const byAgent = await ticket.list(PROJECT_ID, {
|
||||
createdBy: { kind: "agent", agentId: "agent-1" },
|
||||
});
|
||||
expect(byAgent.items.map((i) => i.title)).toEqual(["Agent ticket"]);
|
||||
expect(byAgent.items[0]?.createdBy).toEqual({
|
||||
kind: "agent",
|
||||
agentId: "agent-1",
|
||||
});
|
||||
});
|
||||
|
||||
it("combines status and priority facets with AND (#12)", async () => {
|
||||
await ticket.create(PROJECT_ID, {
|
||||
title: "a",
|
||||
@ -419,6 +441,45 @@ describe("TicketsView", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("shows ticket creators and filters the list by creator (#109)", async () => {
|
||||
const creator = await seedAgent(agent, "CreatorAgent");
|
||||
await ticket.create(PROJECT_ID, { title: "Created by user" });
|
||||
const agentTicket = await ticket.create(PROJECT_ID, {
|
||||
title: "Created by agent",
|
||||
});
|
||||
ticket._seedTicket(PROJECT_ID, {
|
||||
...agentTicket,
|
||||
createdBy: { kind: "agent", agentId: creator.id },
|
||||
});
|
||||
const listSpy = vi.spyOn(ticket, "list");
|
||||
|
||||
renderView(ticket, system, agent);
|
||||
|
||||
await screen.findByText("Created by user");
|
||||
expect(screen.getByText("Créé par : Utilisateur")).toBeTruthy();
|
||||
expect(screen.getByText("Créé par : Agent : CreatorAgent")).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByLabelText("filter by creator"));
|
||||
fireEvent.click(await screen.findByRole("option", { name: "CreatorAgent" }));
|
||||
|
||||
await waitFor(() =>
|
||||
expect(listSpy.mock.calls.at(-1)?.[1]?.createdBy).toEqual({
|
||||
kind: "agent",
|
||||
agentId: creator.id,
|
||||
}),
|
||||
);
|
||||
await waitFor(() => expect(screen.queryByText("Created by user")).toBeNull());
|
||||
expect(screen.getByText("Created by agent")).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByText("Created by agent"));
|
||||
const dialog = await screen.findByRole("dialog", {
|
||||
name: `ticket ${agentTicket.ref}`,
|
||||
});
|
||||
expect(
|
||||
within(dialog).getByText("Créé par : Agent : CreatorAgent"),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it("opens the detail and edits status with a version bump", async () => {
|
||||
const t = await ticket.create(PROJECT_ID, { title: "Editable" });
|
||||
renderView(ticket, system, agent);
|
||||
|
||||
Reference in New Issue
Block a user