From fbca9d9a7a85ffa27ccc53234ddf35dd8e95c147 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 2 May 2025 16:53:06 +0530 Subject: [PATCH] [WEB-3996] fix: attachment icon rendering and added support for rar and zip icons (#7007) * chore: zip and rar file icon * chore: zip and rar file icon * fix: attachment icon * chore: application/x-rar type added * fix: compressed file extensions * chore: updated file upload extensions --------- Co-authored-by: sriram veeraghanta --- apiserver/plane/settings/common.py | 13 ++++++++++++- .../icons/attachment/attachment-icon.tsx | 6 ++++++ web/core/components/icons/attachment/index.ts | 2 ++ .../icons/attachment/rar-file-icon.tsx | 10 ++++++++++ .../icons/attachment/zip-file-icon.tsx | 10 ++++++++++ .../issues/attachment/attachment-list-item.tsx | 2 +- web/public/attachment/rar-icon.png | Bin 0 -> 10465 bytes web/public/attachment/zip-icon.png | Bin 0 -> 7217 bytes 8 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 web/core/components/icons/attachment/rar-file-icon.tsx create mode 100644 web/core/components/icons/attachment/zip-file-icon.tsx create mode 100644 web/public/attachment/rar-icon.png create mode 100644 web/public/attachment/zip-icon.png diff --git a/apiserver/plane/settings/common.py b/apiserver/plane/settings/common.py index 67f51f7bf..15d7a21b3 100644 --- a/apiserver/plane/settings/common.py +++ b/apiserver/plane/settings/common.py @@ -376,10 +376,21 @@ ATTACHMENT_MIME_TYPES = [ "video/x-ms-wmv", # Archives "application/zip", + "application/x-rar", "application/x-rar-compressed", - "application/x-zip-compressed", "application/x-tar", "application/gzip", + "application/x-zip", + "application/x-zip-compressed", + "application/x-7z-compressed", + "application/x-compressed", + "application/x-compressed-tar", + "application/x-compressed-tar-gz", + "application/x-compressed-tar-bz2", + "application/x-compressed-tar-zip", + "application/x-compressed-tar-7z", + "application/x-compressed-tar-rar", + "application/x-compressed-tar-zip", # 3D Models "model/gltf-binary", "model/gltf+json", diff --git a/web/core/components/icons/attachment/attachment-icon.tsx b/web/core/components/icons/attachment/attachment-icon.tsx index 61835abab..e21ae8893 100644 --- a/web/core/components/icons/attachment/attachment-icon.tsx +++ b/web/core/components/icons/attachment/attachment-icon.tsx @@ -10,10 +10,12 @@ import { JpgIcon, PdfIcon, PngIcon, + RarIcon, SheetIcon, SvgIcon, TxtIcon, VideoIcon, + ZipIcon, } from "@/components/icons/attachment"; export const getFileIcon = (fileType: string, size: number = 28) => { @@ -52,6 +54,10 @@ export const getFileIcon = (fileType: string, size: number = 28) => { return ; case "mkv": return ; + case "zip": + return ; + case "rar": + return ; default: return ; diff --git a/web/core/components/icons/attachment/index.ts b/web/core/components/icons/attachment/index.ts index f7f1e6ed3..a2c65ceef 100644 --- a/web/core/components/icons/attachment/index.ts +++ b/web/core/components/icons/attachment/index.ts @@ -18,3 +18,5 @@ export * from "./svg-file-icon"; export * from "./tune-icon"; export * from "./txt-file-icon"; export * from "./video-file-icon"; +export * from "./zip-file-icon"; +export * from "./rar-file-icon"; diff --git a/web/core/components/icons/attachment/rar-file-icon.tsx b/web/core/components/icons/attachment/rar-file-icon.tsx new file mode 100644 index 000000000..0c3dd88e1 --- /dev/null +++ b/web/core/components/icons/attachment/rar-file-icon.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import Image from "next/image"; +// image +import RarFileIcon from "@/public/attachment/rar-icon.png"; +// type +import type { ImageIconPros } from "../types"; + +export const RarIcon: React.FC = ({ width, height }) => ( + RarFileIcon +); diff --git a/web/core/components/icons/attachment/zip-file-icon.tsx b/web/core/components/icons/attachment/zip-file-icon.tsx new file mode 100644 index 000000000..8f5d0388b --- /dev/null +++ b/web/core/components/icons/attachment/zip-file-icon.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import Image from "next/image"; +// image +import ZipFileIcon from "@/public/attachment/zip-icon.png"; +// type +import type { ImageIconPros } from "../types"; + +export const ZipIcon: React.FC = ({ width, height }) => ( + ZipFileIcon +); diff --git a/web/core/components/issues/attachment/attachment-list-item.tsx b/web/core/components/issues/attachment/attachment-list-item.tsx index 027369405..0458f4485 100644 --- a/web/core/components/issues/attachment/attachment-list-item.tsx +++ b/web/core/components/issues/attachment/attachment-list-item.tsx @@ -38,7 +38,7 @@ export const IssueAttachmentsListItem: FC = observer( // derived values const attachment = attachmentId ? getAttachmentById(attachmentId) : undefined; const fileName = getFileName(attachment?.attributes.name ?? ""); - const fileExtension = getFileExtension(attachment?.asset_url ?? ""); + const fileExtension = getFileExtension(attachment?.attributes.name ?? ""); const fileIcon = getFileIcon(fileExtension, 18); const fileURL = getFileURL(attachment?.asset_url ?? ""); // hooks diff --git a/web/public/attachment/rar-icon.png b/web/public/attachment/rar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7305455bd9a56e904db4677238d9f343042af8b4 GIT binary patch literal 10465 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 literal 0 HcmV?d00001 diff --git a/web/public/attachment/zip-icon.png b/web/public/attachment/zip-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0db1da136dfc502e25795ee67c7c9893c1644a65 GIT binary patch literal 7217 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 WT8Yo+4`QM6164&Wg)(`Ip#K4@{jZV$ literal 0 HcmV?d00001