From 14c5a6135055b06893dbbe70f07cc9bc7f3b2565 Mon Sep 17 00:00:00 2001
From: euvre <93761161+euvre@users.noreply.github.com>
Date: Fri, 14 Aug 2026 00:59:17 -0700
Subject: [PATCH] fix(web): render file-type icons for mp3/svg and fall back to
a default file icon (#18230)
---
web/src/components/file-icon/index.tsx | 9 +++++++--
web/src/components/icon-font.tsx | 18 ++++++++++++++----
web/src/components/svg-icon.tsx | 20 +++-----------------
3 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/web/src/components/file-icon/index.tsx b/web/src/components/file-icon/index.tsx
index 1289298afe..b113df10da 100644
--- a/web/src/components/file-icon/index.tsx
+++ b/web/src/components/file-icon/index.tsx
@@ -15,7 +15,8 @@
*/
import { getExtension } from '@/utils/document-util';
-import SvgIcon from '../svg-icon';
+import { File as LucideFile } from 'lucide-react';
+import SvgIcon, { hasSvgIcon } from '../svg-icon';
import { useFetchDocumentThumbnailsByIds } from '@/hooks/use-document-request';
import { useAuthenticatedImageUrl } from '@/components/image';
@@ -41,10 +42,14 @@ const FileIcon = ({ name, id }: IProps) => {
}
}, [id, setDocumentIds]);
+ const iconName = `file-icon/${fileExtension}`;
+
return blobUrl ? (
+ ) : hasSvgIcon(iconName) ? (
+
) : (
-
+
);
};
diff --git a/web/src/components/icon-font.tsx b/web/src/components/icon-font.tsx
index 8cc2c8a853..41576e290c 100644
--- a/web/src/components/icon-font.tsx
+++ b/web/src/components/icon-font.tsx
@@ -17,8 +17,9 @@
import { FileIconMap } from '@/constants/file';
import { cn } from '@/lib/utils';
import { getExtension } from '@/utils/document-util';
+import { File as LucideFile } from 'lucide-react';
import { CSSProperties } from 'react';
-import SvgIcon from './svg-icon';
+import SvgIcon, { hasSvgIcon } from './svg-icon';
type IconFontType = {
name: string;
@@ -54,6 +55,9 @@ export function FileIcon({
}: IconFontType & { type?: string }) {
const isFolder = type === 'folder';
const isSkills = type === 'skills';
+ const extension = getExtension(name);
+ const spriteIcon = FileIconMap[extension as keyof typeof FileIconMap];
+ const assetIcon = `file-icon/${extension}`;
if (isSkills) {
return (
@@ -63,9 +67,15 @@ export function FileIcon({
}
return (
-
+ {isFolder ? (
+
+ ) : spriteIcon ? (
+
+ ) : hasSvgIcon(assetIcon) ? (
+
+ ) : (
+
+ )}
);
}
diff --git a/web/src/components/svg-icon.tsx b/web/src/components/svg-icon.tsx
index 33dc7ffb23..4d4a9e305d 100644
--- a/web/src/components/svg-icon.tsx
+++ b/web/src/components/svg-icon.tsx
@@ -23,23 +23,6 @@ import { IconFontFill } from './icon-font';
import { RAGFlowAvatar } from './ragflow-avatar';
import { useIsDarkTheme } from './theme-provider';
-// const importAll = (requireContext: __WebpackModuleApi.RequireContext) => {
-// const list = requireContext.keys().map((key) => {
-// const name = key.replace(/\.\/(.*)\.\w+$/, '$1');
-// return { name, value: requireContext(key) };
-// });
-// return list;
-// };
-
-// let routeList: { name: string; value: string }[] = [];
-
-// try {
-// routeList = importAll(require.context('@/assets/svg', true, /\.svg$/));
-// } catch (error) {
-// console.warn(error);
-// routeList = [];
-// }
-
const svgModules = import.meta.glob('@/assets/svg/**/*.svg', {
eager: true,
query: '?url',
@@ -53,6 +36,9 @@ const routeList: { name: string; value: string }[] = Object.entries(
return { name, value: module.default || module };
});
+export const hasSvgIcon = (name: string) =>
+ routeList.some((item) => item.name === name);
+
interface IProps extends IconComponentProps {
name: string;
width: string | number;