feat: team assignment on tickets + My team's tickets view

Backend:
- team_id column on tickets table
- team_id filter in GET /tickets (resolves team members)
- team_id in UpdateTicketSchema + PATCH handler
- SetTeam transaction type

Frontend:
- Team selector in ticket detail properties sidebar
- My team's tickets in sidebar (when user belongs to a team)
- team_id passed through to API from ticket list page

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Gjermund Høsøien Wiggen
2026-06-09 14:40:00 +02:00
parent 4157a7b0af
commit 3d7ba0d6a7
11 changed files with 1412 additions and 4 deletions

View File

@@ -43,6 +43,7 @@ export async function getTickets(params?: {
status?: string;
q?: string;
owner_id?: string;
team_id?: string;
custom_fields?: Record<string, string>;
}): Promise<{ data: Ticket[] | null; error: string | null }> {
const sp = new URLSearchParams();
@@ -50,6 +51,7 @@ export async function getTickets(params?: {
if (params?.status) sp.set("status", params.status);
if (params?.q) sp.set("q", params.q);
if (params?.owner_id) sp.set("owner_id", params.owner_id);
if (params?.team_id) sp.set("team_id", params.team_id);
if (params?.custom_fields) {
for (const [fieldId, value] of Object.entries(params.custom_fields)) {
if (value) sp.set(`cf.${fieldId}`, value);
@@ -72,7 +74,7 @@ export async function createTicket(data: {
return request<UpdateResult>("/tickets", { method: "POST", body: JSON.stringify(data) });
}
export async function updateTicket(id: number, data: { subject?: string; status?: string; owner_id?: string | null }): Promise<{ data: UpdateResult | null; error: string | null }> {
export async function updateTicket(id: number, data: { subject?: string; status?: string; owner_id?: string | null; team_id?: string | null }): Promise<{ data: UpdateResult | null; error: string | null }> {
return request<UpdateResult>(`/tickets/${id}`, { method: "PATCH", body: JSON.stringify(data) });
}