hexabot/frontend/src/app-components/attachment/MultipleAttachmentInput.tsx
2024-10-31 19:56:23 +01:00

123 lines
3.7 KiB
TypeScript

/*
* Copyright © 2024 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import { Box, Button, FormHelperText, FormLabel } from "@mui/material";
import { forwardRef, useState } from "react";
import { useHasPermission } from "@/hooks/useHasPermission";
import { EntityType } from "@/services/types";
import { IAttachment } from "@/types/attachment.types";
import { PermissionAction } from "@/types/permission.types";
import AttachmentThumbnail from "./AttachmentThumbnail";
import AttachmentUploader from "./AttachmentUploader";
type MultipleAttachmentInputProps = {
label: string;
value: string[];
format: "small" | "basic" | "full";
accept: string;
enableMediaLibrary?: boolean;
size?: number;
onChange?: (ids: string[]) => void;
error?: boolean;
helperText?: string;
};
const MultipleAttachmentInput = forwardRef<
HTMLDivElement,
MultipleAttachmentInputProps
>(
(
{
label,
value,
format,
accept,
enableMediaLibrary = true,
size,
onChange,
error,
helperText,
},
ref,
) => {
const [attachments, setAttachments] = useState<string[]>(value);
const [uploadKey, setUploadKey] = useState(Date.now());
const hasPermission = useHasPermission();
const handleChange = (attachment?: IAttachment | null, index?: number) => {
if (attachment) {
const updatedAttachments = [...attachments];
if (index !== undefined) {
updatedAttachments[index] = attachment.id;
} else {
updatedAttachments.push(attachment.id);
}
setAttachments(updatedAttachments);
onChange && onChange(updatedAttachments);
setUploadKey(Date.now());
}
};
const handleRemove = (index: number) => {
const updatedAttachments = attachments.filter((_, i) => i !== index);
setAttachments(updatedAttachments);
onChange && onChange(updatedAttachments);
setUploadKey(Date.now());
};
return (
<Box ref={ref}>
<FormLabel
component="label"
style={{ display: "inline-block", marginBottom: 8 }}
>
{label}
</FormLabel>
{attachments.map((attachmentId, index) => (
<Box
key={attachmentId}
sx={{ display: "flex", alignItems: "center", mb: 2 }}
>
<AttachmentThumbnail
id={attachmentId}
format={format}
size={size}
onChange={(newAttachment) => handleChange(newAttachment, index)}
/>
<Button
onClick={() => handleRemove(index)}
sx={{ ml: 2 }}
variant="outlined"
color="secondary"
>
Remove
</Button>
</Box>
))}
{hasPermission(EntityType.ATTACHMENT, PermissionAction.CREATE) && (
<AttachmentUploader
key={uploadKey}
accept={accept}
enableMediaLibrary={enableMediaLibrary}
onChange={(attachment) => handleChange(attachment)}
/>
)}
{helperText && (
<FormHelperText error={error}>{helperText}</FormHelperText>
)}
</Box>
);
},
);
MultipleAttachmentInput.displayName = "MultipleAttachmentInput";
export default MultipleAttachmentInput;