Skip to content

Commit 4ebce5c

Browse files
authored
♻️ Front-end model configuration, chat page related constants and types are placed in specific files
2 parents 6acbbab + 7ea2d74 commit 4ebce5c

40 files changed

+785
-677
lines changed

frontend/app/[locale]/chat/components/chatAgentSelector.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,7 @@ import { ChevronDown, MousePointerClick } from "lucide-react";
77

88
import { fetchAllAgents } from "@/services/agentConfigService";
99
import { getUrlParam } from "@/lib/utils";
10-
11-
interface Agent {
12-
agent_id: number;
13-
name: string;
14-
display_name: string;
15-
description: string;
16-
is_available: boolean;
17-
}
18-
19-
interface ChatAgentSelectorProps {
20-
selectedAgentId: number | null;
21-
onAgentSelect: (agentId: number | null) => void;
22-
disabled?: boolean;
23-
isInitialMode?: boolean;
24-
}
10+
import { Agent, ChatAgentSelectorProps } from "@/types/chat";
2511

2612
export function ChatAgentSelector({
2713
selectedAgentId,

frontend/app/[locale]/chat/components/chatInput.tsx

Lines changed: 55 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { Textarea } from "@/components/ui/textarea";
2727
import { conversationService } from "@/services/conversationService";
2828
import { useConfig } from "@/hooks/useConfig";
2929
import { extractColorsFromUri } from "@/lib/avatar";
30+
import { chatConfig } from "@/const/chatConfig";
31+
import { FilePreview } from "@/types/chat";
3032

3133
import { ChatAgentSelector } from "./chatAgentSelector";
3234

@@ -122,33 +124,7 @@ function FileViewer({ file, onClose }: { file: File; onClose: () => void }) {
122124

123125
// Determine if it is a text file
124126
const isTextFile = (type: string, ext: string) => {
125-
const textTypes = [
126-
"text/plain",
127-
"text/html",
128-
"text/css",
129-
"text/javascript",
130-
"application/json",
131-
"application/xml",
132-
"text/markdown",
133-
];
134-
135-
const textExtensions = [
136-
"txt",
137-
"html",
138-
"htm",
139-
"css",
140-
"js",
141-
"ts",
142-
"jsx",
143-
"tsx",
144-
"json",
145-
"xml",
146-
"md",
147-
"markdown",
148-
"csv",
149-
];
150-
151-
return textTypes.includes(type) || textExtensions.includes(ext);
127+
return chatConfig.textTypes.includes(type) || chatConfig.textExtensions.includes(ext);
152128
};
153129

154130
// Render file content
@@ -240,15 +216,7 @@ function FileViewer({ file, onClose }: { file: File; onClose: () => void }) {
240216
);
241217
}
242218

243-
// Add file preview type
244-
export interface FilePreview {
245-
id: string;
246-
file: File;
247-
type: "image" | "file";
248-
fileType?: string;
249-
extension?: string;
250-
previewUrl?: string;
251-
}
219+
252220

253221
// Get file extension
254222
const getFileExtension = (filename: string): string => {
@@ -279,58 +247,50 @@ const getFileIcon = (file: File) => {
279247
return <AiFillFileImage size={iconSize} color="#8e44ad" />;
280248
}
281249

282-
// Identify by extension
283-
switch (extension) {
284-
// Document files
285-
case "pdf":
286-
return <AiFillFilePdf size={iconSize} color="#e74c3c" />;
287-
case "doc":
288-
case "docx":
289-
return <AiFillFileWord size={iconSize} color="#3498db" />;
290-
case "txt":
291-
return <AiFillFileText size={iconSize} color="#7f8c8d" />;
292-
case "md":
293-
return <AiFillFileMarkdown size={iconSize} color="#34495e" />;
294-
295-
// Table files
296-
case "xls":
297-
case "xlsx":
298-
case "csv":
299-
return <AiFillFileExcel size={iconSize} color="#27ae60" />;
300-
301-
// Demo files
302-
case "ppt":
303-
case "pptx":
304-
return <AiFillFilePpt size={iconSize} color="#e67e22" />;
305-
306-
// Code files
307-
case "html":
308-
case "htm":
309-
return <AiFillHtml5 size={iconSize} color="#e67e22" />;
310-
case "css":
311-
case "js":
312-
case "ts":
313-
case "jsx":
314-
case "tsx":
315-
case "php":
316-
case "py":
317-
case "java":
318-
case "c":
319-
case "cpp":
320-
case "cs":
321-
return <AiFillCode size={iconSize} color="#f39c12" />;
322-
case "json":
323-
return <AiFillCode size={iconSize} color="#f1c40f" />;
324-
325-
// Default file icon
326-
default:
327-
return <AiFillFileUnknown size={iconSize} color="#95a5a6" />;
250+
// Check each file type category using config
251+
if (chatConfig.fileIcons.pdf.includes(extension)) {
252+
return <AiFillFilePdf size={iconSize} color="#e74c3c" />;
253+
}
254+
255+
if (chatConfig.fileIcons.word.includes(extension)) {
256+
return <AiFillFileWord size={iconSize} color="#3498db" />;
257+
}
258+
259+
if (chatConfig.fileIcons.text.includes(extension)) {
260+
return <AiFillFileText size={iconSize} color="#7f8c8d" />;
261+
}
262+
263+
if (chatConfig.fileIcons.markdown.includes(extension)) {
264+
return <AiFillFileMarkdown size={iconSize} color="#34495e" />;
265+
}
266+
267+
if (chatConfig.fileIcons.excel.includes(extension)) {
268+
return <AiFillFileExcel size={iconSize} color="#27ae60" />;
328269
}
270+
271+
if (chatConfig.fileIcons.powerpoint.includes(extension)) {
272+
return <AiFillFilePpt size={iconSize} color="#e67e22" />;
273+
}
274+
275+
if (chatConfig.fileIcons.html.includes(extension)) {
276+
return <AiFillHtml5 size={iconSize} color="#e67e22" />;
277+
}
278+
279+
if (chatConfig.fileIcons.code.includes(extension)) {
280+
return <AiFillCode size={iconSize} color="#f39c12" />;
281+
}
282+
283+
if (chatConfig.fileIcons.json.includes(extension)) {
284+
return <AiFillCode size={iconSize} color="#f1c40f" />;
285+
}
286+
287+
// Default file icon
288+
return <AiFillFileUnknown size={iconSize} color="#95a5a6" />;
329289
};
330290

331-
// File limit constants
332-
const MAX_FILE_COUNT = 50;
333-
const MAX_FILE_SIZE = 5 * 1024 * 1024; // Single file maximum 5MB
291+
// File limit constants from config
292+
const MAX_FILE_COUNT = chatConfig.maxFileCount;
293+
const MAX_FILE_SIZE = chatConfig.maxFileSize;
334294

335295
interface ChatInputProps {
336296
input: string;
@@ -798,19 +758,17 @@ export function ChatInput({
798758
// Supported image file types
799759
const isImage =
800760
file.type.startsWith("image/") ||
801-
["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp"].includes(extension);
761+
chatConfig.imageExtensions.includes(extension);
802762

803763
// Supported document file types
804764
const isDocument =
805-
["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(
806-
extension
807-
) ||
765+
chatConfig.documentExtensions.includes(extension) ||
808766
file.type === "application/pdf" ||
809767
file.type.includes("officedocument");
810768

811769
// Supported text file types
812770
const isSupportedTextFile =
813-
["md", "markdown", "txt"].includes(extension) ||
771+
chatConfig.supportedTextExtensions.includes(extension) ||
814772
file.type === "text/csv" ||
815773
file.type === "text/plain";
816774

@@ -821,7 +779,7 @@ export function ChatInput({
821779
newAttachments.push({
822780
id: fileId,
823781
file,
824-
type: isImage ? "image" : "file",
782+
type: isImage ? chatConfig.filePreviewTypes.image : chatConfig.filePreviewTypes.file,
825783
fileType: file.type,
826784
extension,
827785
previewUrl,
@@ -888,7 +846,7 @@ export function ChatInput({
888846

889847
// Handle viewing images
890848
const handleViewImage = (attachment: FilePreview) => {
891-
if (attachment.type === "image" && attachment.file) {
849+
if (attachment.type === chatConfig.filePreviewTypes.image && attachment.file) {
892850
// To ensure the preview URL is valid, create a new blob URL
893851
// This avoids using a cached URL that may have expired
894852
const fileReader = new FileReader();
@@ -930,7 +888,7 @@ export function ChatInput({
930888
className="relative group rounded-md border border-slate-200 bg-white shadow-sm hover:shadow transition-all duration-200 w-[190px] mb-1"
931889
>
932890
<div className="relative p-2 h-[52px] flex items-center">
933-
{attachment.type === "image" ? (
891+
{attachment.type === chatConfig.filePreviewTypes.image ? (
934892
<div className="flex items-center gap-3 w-full">
935893
<div
936894
className="w-10 h-10 flex-shrink-0 overflow-hidden rounded-md cursor-pointer"
@@ -1116,7 +1074,7 @@ export function ChatInput({
11161074
id="file-upload-regular"
11171075
className="hidden"
11181076
onChange={handleFileUpload}
1119-
accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.tsv,.md,.markdown,.txt"
1077+
accept={`image/*,${Object.values(chatConfig.fileIcons).flat().map(ext => `.${ext}`).join(',')}`}
11201078
multiple
11211079
/>
11221080
</Button>
@@ -1234,15 +1192,13 @@ export function ChatInput({
12341192

12351193
const isImage =
12361194
fileType.startsWith("image/") ||
1237-
["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp"].includes(extension);
1195+
chatConfig.imageExtensions.includes(extension);
12381196
const isDocument =
1239-
["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(
1240-
extension
1241-
) ||
1197+
chatConfig.documentExtensions.includes(extension) ||
12421198
fileType === "application/pdf" ||
12431199
fileType.includes("officedocument");
12441200
const isSupportedTextFile =
1245-
["md", "markdown", "txt"].includes(extension) ||
1201+
chatConfig.supportedTextExtensions.includes(extension) ||
12461202
fileType === "text/csv" ||
12471203
fileType === "text/plain";
12481204

frontend/app/[locale]/chat/components/chatLeftSidebar.tsx

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@ import {
3434
TooltipTrigger,
3535
} from "@/components/ui/tooltip";
3636
import { StaticScrollArea } from "@/components/ui/scrollArea";
37+
import { USER_ROLES } from "@/const/modelConfig";
3738
import { useConfig } from "@/hooks/useConfig";
3839
import { useResponsiveTextSize } from "@/hooks/useResponsiveTextSize";
3940
import { Spin, Tag, ConfigProvider } from "antd";
4041
import { getRoleColor } from "@/lib/auth";
4142
import { useAuth } from "@/hooks/useAuth";
4243
import { extractColorsFromUri } from "@/lib/avatar";
4344
import { useTranslation } from "react-i18next";
44-
import { ConversationListItem } from "@/types/chat";
45+
import { ConversationListItem, ChatSidebarProps } from "@/types/chat";
4546

4647
// conversation status indicator component
4748
const ConversationStatusIndicator = ({
@@ -74,24 +75,6 @@ const ConversationStatusIndicator = ({
7475
return null;
7576
};
7677

77-
interface ChatSidebarProps {
78-
conversationList: ConversationListItem[];
79-
selectedConversationId: number | null;
80-
openDropdownId: string | null;
81-
streamingConversations: Set<number>;
82-
completedConversations: Set<number>;
83-
onNewConversation: () => void;
84-
onDialogClick: (dialog: ConversationListItem) => void;
85-
onRename: (dialogId: number, title: string) => void;
86-
onDelete: (dialogId: number) => void;
87-
onSettingsClick: () => void;
88-
onDropdownOpenChange: (open: boolean, id: string | null) => void;
89-
onToggleSidebar: () => void;
90-
expanded: boolean;
91-
userEmail: string | undefined;
92-
userAvatarUrl: string | undefined;
93-
userRole: string | undefined;
94-
}
9578

9679
// Helper function - dialog classification
9780
const categorizeDialogs = (dialogs: ConversationListItem[]) => {
@@ -142,7 +125,7 @@ export function ChatSidebar({
142125
expanded,
143126
userEmail,
144127
userAvatarUrl,
145-
userRole = "user",
128+
userRole = USER_ROLES.USER,
146129
}: ChatSidebarProps) {
147130
const { t } = useTranslation();
148131
const { today, week, older } = categorizeDialogs(conversationList);

frontend/app/[locale]/chat/components/chatRightPanel.tsx

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,10 @@ import { ExternalLink, Database, X } from "lucide-react";
55
import { Button } from "@/components/ui/button";
66
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
77
import { StaticScrollArea } from "@/components/ui/scrollArea";
8-
import { ChatMessageType } from "@/types/chat";
8+
import { ChatMessageType, ImageItem, ChatRightPanelProps, SearchResult } from "@/types/chat";
99
import { API_ENDPOINTS } from "@/services/api";
1010
import { formatDate, formatUrl } from "@/lib/utils";
1111

12-
interface ImageItem {
13-
base64Data: string;
14-
contentType: string;
15-
isLoading: boolean;
16-
error?: string;
17-
loadAttempts?: number; // Load attempts
18-
}
19-
20-
interface SearchResult {
21-
title: string;
22-
url: string;
23-
text: string;
24-
published_date: string;
25-
source_type?: string;
26-
filename?: string;
27-
score?: number;
28-
score_details?: any;
29-
isExpanded?: boolean;
30-
}
31-
32-
interface ChatRightPanelProps {
33-
messages: ChatMessageType[];
34-
onImageError: (imageUrl: string) => void;
35-
maxInitialImages?: number;
36-
isVisible?: boolean;
37-
toggleRightPanel?: () => void;
38-
selectedMessageId?: string;
39-
}
4012

4113
export function ChatRightPanel({
4214
messages,

frontend/app/[locale]/chat/internal/chatAttachment.tsx

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,7 @@ import {
2222
DialogTitle,
2323
} from "@/components/ui/dialog";
2424
import { cn } from "@/lib/utils";
25-
26-
// Interface for attachment items
27-
export interface AttachmentItem {
28-
type: string;
29-
name: string;
30-
size: number;
31-
url?: string;
32-
contentType?: string;
33-
}
34-
35-
// Interface for the chat attachment component
36-
interface ChatAttachmentProps {
37-
attachments: AttachmentItem[];
38-
onImageClick?: (url: string) => void;
39-
className?: string;
40-
}
25+
import { AttachmentItem, ChatAttachmentProps } from "@/types/chat";
4126

4227
// Image viewer component
4328
const ImageViewer = ({

frontend/app/[locale]/chat/internal/chatInterface.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { conversationService } from "@/services/conversationService";
1414
import { storageService } from "@/services/storageService";
1515

1616
import { ChatSidebar } from "../components/chatLeftSidebar";
17-
import { FilePreview } from "../components/chatInput";
17+
import { FilePreview } from "@/types/chat";
1818
import { ChatHeader } from "../components/chatHeader";
1919
import { ChatRightPanel } from "../components/chatRightPanel";
2020
import { ChatStreamMain } from "../streaming/chatStreamMain";

frontend/app/[locale]/chat/internal/chatPreprocess.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AgentStep } from "@/types/chat";
22
import { conversationService } from "@/services/conversationService";
33
import { storageService } from "@/services/storageService";
44

5-
import { FilePreview } from "../components/chatInput";
5+
import { FilePreview } from "@/types/chat";
66

77
// Step ID Counter
88
const stepIdCounter = { current: 0 };

0 commit comments

Comments
 (0)