типизация фронтенд: убран дубликат MemberBrief, мёртвые slug params, typed WS events
This commit is contained in:
parent
6ea653dbb1
commit
a948b2f6fb
@ -49,21 +49,21 @@ export default function KanbanBoard({ projectId, projectSlug }: Props) {
|
|||||||
loadTasks();
|
loadTasks();
|
||||||
|
|
||||||
// Subscribe to WebSocket events for real-time updates
|
// Subscribe to WebSocket events for real-time updates
|
||||||
const unsubscribeCreated = wsClient.on("task.created", (data: any) => {
|
const unsubscribeCreated = wsClient.on("task.created", (data: Task) => {
|
||||||
if (data.project_id === projectId) {
|
if (data.project_id === projectId) {
|
||||||
setTasks((prev) => [...prev, data as Task]);
|
setTasks((prev) => prev.some((t) => t.id === data.id) ? prev : [...prev, data]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsubscribeUpdated = wsClient.on("task.updated", (data: any) => {
|
const unsubscribeUpdated = wsClient.on("task.updated", (data: Task) => {
|
||||||
if (data.project_id === projectId) {
|
if (data.project_id === projectId) {
|
||||||
setTasks((prev) => prev.map((t) => t.id === data.id ? { ...t, ...data } : t));
|
setTasks((prev) => prev.map((t) => t.id === data.id ? data : t));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsubscribeAssigned = wsClient.on("task.assigned", (data: any) => {
|
const unsubscribeAssigned = wsClient.on("task.assigned", (data: Task) => {
|
||||||
if (data.project_id === projectId) {
|
if (data.project_id === projectId) {
|
||||||
setTasks((prev) => prev.map((t) => t.id === data.id ? { ...t, assignee_id: data.assignee_id, assignee: data.assignee, assigned_at: data.assigned_at } : t));
|
setTasks((prev) => prev.map((t) => t.id === data.id ? data : t));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -251,7 +251,7 @@ export default function TaskModal({ task, projectId: _projectId, projectSlug: _p
|
|||||||
<div key={msg.id} className="text-sm">
|
<div key={msg.id} className="text-sm">
|
||||||
<div className="flex items-center gap-1 text-xs text-[var(--muted)] mb-0.5">
|
<div className="flex items-center gap-1 text-xs text-[var(--muted)] mb-0.5">
|
||||||
<span>{AUTHOR_ICON[msg.author_type] || "👤"}</span>
|
<span>{AUTHOR_ICON[msg.author_type] || "👤"}</span>
|
||||||
<span className="font-medium">{msg.author?.slug || msg.author_id}</span>
|
<span className="font-medium">{msg.author_type === "system" ? "System" : (msg.author?.name || msg.author?.slug || "Unknown")}</span>
|
||||||
<span>·</span>
|
<span>·</span>
|
||||||
<span>{new Date(msg.created_at).toLocaleString("ru-RU", { hour: "2-digit", minute: "2-digit" })}</span>
|
<span>{new Date(msg.created_at).toLocaleString("ru-RU", { hour: "2-digit", minute: "2-digit" })}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -60,12 +60,6 @@ export interface AgentConfig {
|
|||||||
model: string | null;
|
model: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MemberBrief {
|
|
||||||
id: string;
|
|
||||||
slug: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Member {
|
export interface Member {
|
||||||
id: string;
|
id: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
@ -214,8 +208,8 @@ export async function deleteTask(taskId: string): Promise<void> {
|
|||||||
await request(`/api/v1/tasks/${taskId}`, { method: "DELETE" });
|
await request(`/api/v1/tasks/${taskId}`, { method: "DELETE" });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function takeTask(taskId: string, slug: string): Promise<Task> {
|
export async function takeTask(taskId: string): Promise<Task> {
|
||||||
return request(`/api/v1/tasks/${taskId}/take?slug=${slug}`, { method: "POST" });
|
return request(`/api/v1/tasks/${taskId}/take`, { method: "POST" });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function rejectTask(taskId: string, reason: string): Promise<{ok: boolean; reason: string; old_assignee: string}> {
|
export async function rejectTask(taskId: string, reason: string): Promise<{ok: boolean; reason: string; old_assignee: string}> {
|
||||||
@ -232,12 +226,12 @@ export async function assignTask(taskId: string, assigneeId: string): Promise<Ta
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function watchTask(taskId: string, slug: string): Promise<{ok: boolean; watchers: string[]}> {
|
export async function watchTask(taskId: string): Promise<{ok: boolean; watcher_ids: string[]}> {
|
||||||
return request(`/api/v1/tasks/${taskId}/watch?slug=${slug}`, { method: "POST" });
|
return request(`/api/v1/tasks/${taskId}/watch`, { method: "POST" });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function unwatchTask(taskId: string, slug: string): Promise<{ok: boolean; watchers: string[]}> {
|
export async function unwatchTask(taskId: string): Promise<{ok: boolean; watcher_ids: string[]}> {
|
||||||
return request(`/api/v1/tasks/${taskId}/watch?slug=${slug}`, { method: "DELETE" });
|
return request(`/api/v1/tasks/${taskId}/watch`, { method: "DELETE" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Steps ---
|
// --- Steps ---
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user