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,8 +1,9 @@
|
||||
import { Box, Divider, Group, Tabs, Text } from "@mantine/core";
|
||||
import { Box, Divider, Group, Tabs } from "@mantine/core";
|
||||
import { IconLink, IconMessage, IconPaperclip } from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import type { Card, CardMessage, User } from "../types";
|
||||
import { CardChatPanel } from "./CardChatPanel";
|
||||
import { CardFilesPanel } from "./CardFilesPanel";
|
||||
import { CardLinksPanel } from "./CardLinksPanel";
|
||||
import { CardForm, CardFormValues } from "./CardForm";
|
||||
|
||||
@@ -27,12 +28,15 @@ export function CardEditPanel({
|
||||
}: Props) {
|
||||
const [messages, setMessages] = useState<CardMessage[]>([]);
|
||||
const [liveCard, setLiveCard] = useState(card);
|
||||
const [filesRefreshKey, setFilesRefreshKey] = useState(0);
|
||||
|
||||
const wrappedSubmit = async (v: CardFormValues) => {
|
||||
setLiveCard((c) => ({ ...c, title: v.title, description: v.description, requester: v.requester, tags: v.tags, assignee_id: v.assignee_id }));
|
||||
await onSubmit(v);
|
||||
};
|
||||
|
||||
const bumpFiles = () => setFilesRefreshKey((k) => k + 1);
|
||||
|
||||
return (
|
||||
<Group align="stretch" gap="md" wrap="nowrap" style={{ minHeight: 460 }}>
|
||||
<Box style={{ flex: "1 1 0", minWidth: 320 }}>
|
||||
@@ -48,6 +52,8 @@ export function CardEditPanel({
|
||||
tags: liveCard.tags || [],
|
||||
}}
|
||||
submitLabel="Guardar"
|
||||
cardId={liveCard.id}
|
||||
onFileUploaded={bumpFiles}
|
||||
onSubmit={wrappedSubmit}
|
||||
onCancel={onCancel}
|
||||
/>
|
||||
@@ -58,7 +64,7 @@ export function CardEditPanel({
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="chat" leftSection={<IconMessage size={14} />}>Chat</Tabs.Tab>
|
||||
<Tabs.Tab value="links" leftSection={<IconLink size={14} />}>Enlaces</Tabs.Tab>
|
||||
<Tabs.Tab value="files" leftSection={<IconPaperclip size={14} />} disabled>Archivos</Tabs.Tab>
|
||||
<Tabs.Tab value="files" leftSection={<IconPaperclip size={14} />}>Archivos</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Box pt="xs" style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }}>
|
||||
<Tabs.Panel value="chat" style={{ flex: 1, minHeight: 0, display: "flex" }}>
|
||||
@@ -68,6 +74,7 @@ export function CardEditPanel({
|
||||
users={users}
|
||||
currentUserId={currentUserId}
|
||||
onMessagesChange={setMessages}
|
||||
onFileUploaded={bumpFiles}
|
||||
/>
|
||||
</Box>
|
||||
</Tabs.Panel>
|
||||
@@ -75,9 +82,7 @@ export function CardEditPanel({
|
||||
<CardLinksPanel card={liveCard} messages={messages} />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="files">
|
||||
<Text size="sm" c="dimmed" ta="center" p="md">
|
||||
Proximamente: adjuntos de archivos.
|
||||
</Text>
|
||||
<CardFilesPanel cardId={liveCard.id} refreshKey={filesRefreshKey} />
|
||||
</Tabs.Panel>
|
||||
</Box>
|
||||
</Tabs>
|
||||
|
||||
Reference in New Issue
Block a user