import React from "react"; import Attachment from "./Attachment"; import Placeholder from "./Placeholder"; import FileUploadButton from "../FileUploadButton"; import { post } from "../../lib/request"; import * as Attachments from "../../types/Attachments"; import * as Drag from "../../types/Drag"; import { createDraggable, draggedOrder, useDragUploader } from "../drag"; interface Props extends Attachments.Options { state: Attachments.State; } function filenameToName(str: string): string { return str.replace(/\.[\w\d]+$/, "").replace(/_/g, " "); } export default function List(props: Props) { const { collection, deleted, setDeleted } = props.state; const locales = props.locales ? Object.keys(props.locales) : [props.locale]; const uploadAttachment = (file: File) => { const name = {}; locales.forEach((l) => (name[l] = file.name)); const draggable = createDraggable({ attachment: { filename: file.name, name: name }, uploading: true }); const data = new FormData(); data.append("attachment[file]", file); locales.forEach((l) => { data.append(`attachment[name][${l}]`, filenameToName(file.name)); }); void post("/admin/attachments.json", data).then( (json: Attachments.Resource) => { collection.dispatch({ type: "update", payload: { ...draggable, record: { attachment: json, uploading: false } } }); } ); return draggable; }; const receiveFiles = (files: File[]) => { collection.dispatch({ type: "append", payload: files.map((f) => uploadAttachment(f)) }); }; const dragEnd = (dragState: Drag.State, files: File[]) => { collection.dispatch({ type: "reorder", payload: draggedOrder(collection, dragState) }); collection.dispatch({ type: "insertFiles", payload: files.map((f) => uploadAttachment(f)) }); }; const [dragState, dragStart, listeners] = useDragUploader( [collection], dragEnd ); const position = (record: Attachments.Record) => { return ( [ ...collection.draggables.map( (d: Drag.Draggable) => d.record ), ...deleted ].indexOf(record) + 1 ); }; const attrName = (record: Attachments.Record) => { return `${props.attribute}[${position(record)}]`; }; const update = (draggable: Drag.Draggable) => (attachment: Partial) => { const { record } = draggable; const updated = { ...draggable, record: { ...record, attachment: { ...record.attachment, ...attachment } } }; collection.dispatch({ type: "update", payload: updated }); }; const remove = (draggable: Drag.Draggable) => () => { collection.dispatch({ type: "remove", payload: draggable }); if (draggable.record.id) { setDeleted([...deleted, draggable.record]); } }; const attachment = (draggable: Drag.Item) => { const { dragging } = dragState; if (draggable === "Files") { return ; } return ( ); }; const dragOrder = draggedOrder(collection, dragState); const classes = ["attachments"]; if (dragState.dragging) { classes.push("dragover"); } return (
{dragOrder.map((d) => attachment(d))}
{deleted.map((r) => ( ))}
); }