feat(frontend): UI archivos en cards (issue 0128)
- CardFilesPanel: tab Archivos con grid thumbs + boton subir/borrar - CardForm: drag&drop en descripcion, inserta ref markdown en cursor - CardChatPanel: drag&drop + boton paperclip, sube y envia ref como mensaje - MessageBody: renderer markdown minimo (img inline + link chip) - api.ts: listCardFiles, uploadCardFile (multipart), deleteCardFile - types.ts: CardFile
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type {
|
||||
Board,
|
||||
Card,
|
||||
CardFile,
|
||||
CardHistoryResponse,
|
||||
CardMessage,
|
||||
Column,
|
||||
@@ -380,6 +381,42 @@ export function listRequesters(): Promise<string[]> {
|
||||
return fetchJSON("/requesters");
|
||||
}
|
||||
|
||||
// --- Files (issue 0128) -----------------------------------------------------
|
||||
|
||||
export function listCardFiles(cardId: string): Promise<CardFile[]> {
|
||||
return fetchJSON(`/cards/${cardId}/files`);
|
||||
}
|
||||
|
||||
export async function uploadCardFile(
|
||||
cardId: string,
|
||||
file: File,
|
||||
source: "upload" | "description" | "chat" = "upload"
|
||||
): Promise<CardFile> {
|
||||
const fd = new FormData();
|
||||
fd.append("file", file);
|
||||
fd.append("source", source);
|
||||
const res = await fetch(`${BASE}/cards/${cardId}/files`, {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
body: fd,
|
||||
});
|
||||
if (!res.ok) {
|
||||
let msg = `upload failed: ${res.status}`;
|
||||
try {
|
||||
const body = (await res.json()) as { Message?: string; message?: string };
|
||||
if (body.Message || body.message) msg = body.Message || body.message || msg;
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
throw new HTTPError(res.status, msg);
|
||||
}
|
||||
return (await res.json()) as CardFile;
|
||||
}
|
||||
|
||||
export function deleteCardFile(fileId: string): Promise<void> {
|
||||
return fetchJSON(`/files/${fileId}`, { method: "DELETE" });
|
||||
}
|
||||
|
||||
export function getMetrics(f: MetricsFilter): Promise<Metrics> {
|
||||
const qs = new URLSearchParams();
|
||||
if (f.from) qs.set("from", f.from);
|
||||
|
||||
Reference in New Issue
Block a user