feat(ui): migrate Ant Design components to LobeHub UI

- Replace Button, Avatar, Tooltip, Empty, Select, Modal, Form with LobeHub UI
- Migrate icons from @ant-design/icons to lucide-react
- Keep Settings icon using SettingOutlined from @ant-design/icons
- Update all components to use LobeHub UI styling patterns
This commit is contained in:
2026-03-15 14:52:13 +08:00
parent 078bfd10ee
commit d1903b1fe7
12 changed files with 151 additions and 162 deletions

View File

@@ -169,12 +169,12 @@ eval "$(fnm env --use-on-cd)" && npm run dev
4. **禁止 `as any`**: 使用类型守卫或 `unknown` 4. **禁止 `as any`**: 使用类型守卫或 `unknown`
5. **函数组件优先**: 禁止 class 组件 5. **函数组件优先**: 禁止 class 组件
## 13. 沟通规范 ## 11. 沟通规范
1. **人设**: 在回答的末尾加上「🦆」,用于确认上下文是否被正确保留 1. **人设**: 在回答的末尾加上「🦐」,用于确认上下文是否被正确保留
2. **语言**: 使用中文进行回答 2. **语言**: 使用中文进行回答
## 11. MVP Phase - Breaking Changes ## 12. MVP Phase - Breaking Changes
**This is MVP phase - breaking changes are acceptable for better design.** However, you MUST: **This is MVP phase - breaking changes are acceptable for better design.** However, you MUST:
@@ -182,6 +182,7 @@ eval "$(fnm env --use-on-cd)" && npm run dev
- **Compare old vs new approach**: Show the differences and improvements - **Compare old vs new approach**: Show the differences and improvements
- **Document the tradeoffs**: What are the pros and cons of this change - **Document the tradeoffs**: What are the pros and cons of this change
- **Ask for confirmation**: If the change is significant (affects multiple modules or core architecture) - **Ask for confirmation**: If the change is significant (affects multiple modules or core architecture)
- 对于代码修改,必须将相关的、不再需要的代码全部删除,不需要保留,保持代码洁净
**Examples of acceptable breaking changes during MVP**: **Examples of acceptable breaking changes during MVP**:
@@ -199,7 +200,7 @@ eval "$(fnm env --use-on-cd)" && npm run dev
4. If significant, ask user for confirmation before implementing 4. If significant, ask user for confirmation before implementing
5. Update related documentation after implementation 5. Update related documentation after implementation
## 12. 测试规范 ## 13. 测试规范
### 测试框架 ### 测试框架

View File

@@ -11,20 +11,19 @@ import {
theme, theme,
ConfigProvider, ConfigProvider,
App as AntApp, App as AntApp,
Button,
Space, Space,
Dropdown,
Tooltip,
} from "antd"; } from "antd";
import { Button, Tooltip, DropdownMenu } from "@lobehub/ui";
import { SettingOutlined } from "@ant-design/icons";
import { import {
SettingOutlined, Github,
GithubOutlined, Cloud,
CloudServerOutlined, CloudUpload,
CloudUploadOutlined, History,
HistoryOutlined, PanelLeftClose,
MenuFoldOutlined, PanelLeftOpen,
MenuUnfoldOutlined, } from "lucide-react";
} from "@ant-design/icons";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import zhCN from "antd/locale/zh_CN"; import zhCN from "antd/locale/zh_CN";
import { useDomainStore } from "@renderer/stores"; import { useDomainStore } from "@renderer/stores";
@@ -222,15 +221,16 @@ const App: React.FC = () => {
<div <div
style={{ display: "flex", alignItems: "center", gap: 8 }} style={{ display: "flex", alignItems: "center", gap: 8 }}
> >
<CloudServerOutlined <Cloud
style={{ fontSize: 24, color: "#1890ff" }} size={24}
style={{ color: "#1890ff" }}
/> />
<span className={styles.logoText}>Kintone Manager</span> <span className={styles.logoText}>Kintone Manager</span>
</div> </div>
<Tooltip title={t("collapseSidebar")} mouseEnterDelay={0.5}> <Tooltip title={t("collapseSidebar")} mouseEnterDelay={0.5}>
<Button <Button
type="text" type="text"
icon={<MenuFoldOutlined />} icon={<PanelLeftClose size={16} />}
onClick={toggleSider} onClick={toggleSider}
className={styles.siderCloseButton} className={styles.siderCloseButton}
size="small" size="small"
@@ -277,7 +277,7 @@ const App: React.FC = () => {
<Tooltip title={t("expandSidebar")} mouseEnterDelay={0.5}> <Tooltip title={t("expandSidebar")} mouseEnterDelay={0.5}>
<Button <Button
type="text" type="text"
icon={<MenuUnfoldOutlined />} icon={<PanelLeftOpen size={16} />}
onClick={toggleSider} onClick={toggleSider}
size="small" size="small"
/> />
@@ -292,41 +292,33 @@ const App: React.FC = () => {
<Space> <Space>
<Button <Button
type="primary" type="primary"
icon={<CloudUploadOutlined />} icon={<CloudUpload size={16} />}
onClick={() => setDeployDialogOpen(true)} onClick={() => setDeployDialogOpen(true)}
disabled={!currentDomain} disabled={!currentDomain}
> >
{t("deployFiles")} {t("deployFiles")}
</Button> </Button>
<Button icon={<HistoryOutlined />} disabled={!currentDomain}> <Button icon={<History size={16} />} disabled={!currentDomain}>
{t("versionHistory")} {t("versionHistory")}
</Button> </Button>
<Dropdown <DropdownMenu
menu={{ trigger={<Button icon={<SettingOutlined />} />}
items: [ items={[
{ {
key: "settings", key: "settings",
icon: <SettingOutlined />, icon: <SettingOutlined />,
label: t("settings"), label: t("settings"),
}, onClick: () => setSettingsOpen(true),
{ type: "divider" },
{
key: "github",
icon: <GithubOutlined />,
label: "GitHub",
},
],
onClick: ({ key }) => {
if (key === "settings") {
setSettingsOpen(true);
} else if (key === "github") {
window.open("https://github.com", "_blank");
}
}, },
}} { type: "divider" },
> {
<Button icon={<SettingOutlined />} /> key: "github",
</Dropdown> icon: <Github size={16} />,
label: "GitHub",
onClick: () => window.open("https://github.com", "_blank"),
},
]}
/>
</Space> </Space>
</Header> </Header>

View File

@@ -8,19 +8,18 @@ import { useTranslation } from "react-i18next";
import { import {
Descriptions, Descriptions,
Tabs, Tabs,
Empty,
Spin, Spin,
Tag, Tag,
Button,
Space, Space,
} from "antd"; } from "antd";
import { Button, Empty } from "@lobehub/ui";
import { import {
AppstoreOutlined, LayoutGrid,
DownloadOutlined, Download,
HistoryOutlined, History,
CodeOutlined, Code,
FileTextOutlined, FileText,
} from "@ant-design/icons"; } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useAppStore } from "@renderer/stores"; import { useAppStore } from "@renderer/stores";
import { useDomainStore } from "@renderer/stores"; import { useDomainStore } from "@renderer/stores";
@@ -196,7 +195,7 @@ const AppDetail: React.FC = () => {
}} }}
> >
<div className={styles.fileInfo}> <div className={styles.fileInfo}>
<FileTextOutlined /> <FileText size={16} />
<div> <div>
<div className={styles.fileName}>{fileName}</div> <div className={styles.fileName}>{fileName}</div>
<div className={styles.fileType}> <div className={styles.fileType}>
@@ -210,7 +209,7 @@ const AppDetail: React.FC = () => {
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<CodeOutlined />} icon={<Code size={16} />}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setSelectedFile({ type, fileKey, name: fileName }); setSelectedFile({ type, fileKey, name: fileName });
@@ -219,7 +218,7 @@ const AppDetail: React.FC = () => {
> >
{t("view")} {t("view")}
</Button> </Button>
<Button type="text" size="small" icon={<DownloadOutlined />}> <Button type="text" size="small" icon={<Download size={16} />}>
{t("download", { ns: "common" })} {t("download", { ns: "common" })}
</Button> </Button>
</Space> </Space>
@@ -235,13 +234,13 @@ const AppDetail: React.FC = () => {
<div className={styles.container}> <div className={styles.container}>
<div className={styles.header}> <div className={styles.header}>
<div className={styles.title}> <div className={styles.title}>
<AppstoreOutlined style={{ fontSize: 24, color: "#1890ff" }} /> <LayoutGrid size={24} style={{ color: "#1890ff" }} />
<h3 className={styles.appName}>{currentApp.name}</h3> <h3 className={styles.appName}>{currentApp.name}</h3>
<Tag color="blue">{currentApp.appId}</Tag> <Tag color="blue">{currentApp.appId}</Tag>
</div> </div>
<Space> <Space>
<Button icon={<HistoryOutlined />}>{t("versionHistory", { ns: "common" })}</Button> <Button icon={<History size={16} />}>{t("versionHistory", { ns: "common" })}</Button>
<Button type="primary" icon={<DownloadOutlined />}> <Button type="primary" icon={<Download size={16} />}>
{t("downloadAll")} {t("downloadAll")}
</Button> </Button>
</Space> </Space>

View File

@@ -6,24 +6,20 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import {
Button,
Input, Input,
Empty,
Spin, Spin,
Typography, Typography,
Space, Space,
Tooltip,
Select,
} from "antd"; } from "antd";
import { Button, Tooltip, Empty, Select } from "@lobehub/ui";
import { import {
ReloadOutlined, RefreshCw,
SearchOutlined, Search,
AppstoreOutlined, LayoutGrid,
PushpinOutlined, Pin,
PushpinFilled, ArrowUpDown,
SortAscendingOutlined, ArrowDownUp,
SortDescendingOutlined, } from "lucide-react";
} from "@ant-design/icons";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useAppStore } from "@renderer/stores"; import { useAppStore } from "@renderer/stores";
import { useDomainStore } from "@renderer/stores"; import { useDomainStore } from "@renderer/stores";
@@ -280,10 +276,10 @@ const AppList: React.FC = () => {
className={`${styles.pinIcon} ${isPinned ? styles.pinIconPinned : ""}`} className={`${styles.pinIcon} ${isPinned ? styles.pinIconPinned : ""}`}
onClick={(e) => handlePinToggle(e, app.appId)} onClick={(e) => handlePinToggle(e, app.appId)}
> >
{isPinned ? <PushpinFilled /> : <PushpinOutlined />} {isPinned ? <Pin size={16} className="fill-current" /> : <Pin size={16} />}
</span> </span>
</Tooltip> </Tooltip>
<AppstoreOutlined style={{ color: "#1890ff", fontSize: 16 }} /> <LayoutGrid size={16} style={{ color: "#1890ff" }} />
<Tooltip title={app.name}> <Tooltip title={app.name}>
<span className={styles.appName}>{app.name}</span> <span className={styles.appName}>{app.name}</span>
</Tooltip> </Tooltip>
@@ -310,7 +306,7 @@ const AppList: React.FC = () => {
<div className={styles.searchWrapper}> <div className={styles.searchWrapper}>
<Input <Input
placeholder={t("searchApp")} placeholder={t("searchApp")}
prefix={<SearchOutlined />} prefix={<Search size={16} />}
value={searchText} value={searchText}
onChange={(e) => setSearchText(e.target.value)} onChange={(e) => setSearchText(e.target.value)}
allowClear allowClear
@@ -337,9 +333,9 @@ const AppList: React.FC = () => {
size="small" size="small"
icon={ icon={
appSortOrder === "asc" ? ( appSortOrder === "asc" ? (
<SortAscendingOutlined /> <ArrowUpDown size={16} />
) : ( ) : (
<SortDescendingOutlined /> <ArrowDownUp size={16} />
) )
} }
onClick={toggleSortOrder} onClick={toggleSortOrder}
@@ -348,7 +344,7 @@ const AppList: React.FC = () => {
<Tooltip title={apps.length > 0 ? t("reload") : t("loadApps")}> <Tooltip title={apps.length > 0 ? t("reload") : t("loadApps")}>
<Button <Button
type="text" type="text"
icon={<ReloadOutlined />} icon={<RefreshCw size={16} />}
onClick={handleLoadApps} onClick={handleLoadApps}
loading={loading} loading={loading}
size="small" size="small"

View File

@@ -5,12 +5,12 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Spin, Alert, Empty, Button, Space, message } from "antd"; import { Spin, Alert, Space, message } from "antd";
import { Button, Empty } from "@lobehub/ui";
import { import {
CopyOutlined, Copy,
DownloadOutlined, Download,
FullscreenOutlined, } from "lucide-react";
} from "@ant-design/icons";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import CodeMirror from "@uiw/react-codemirror"; import CodeMirror from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript"; import { javascript } from "@codemirror/lang-javascript";
@@ -186,7 +186,7 @@ const CodeViewer: React.FC<CodeViewerProps> = ({
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<CopyOutlined />} icon={<Copy size={16} />}
onClick={handleCopy} onClick={handleCopy}
> >
{t("copy", { ns: "common" })} {t("copy", { ns: "common" })}
@@ -194,7 +194,7 @@ const CodeViewer: React.FC<CodeViewerProps> = ({
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<DownloadOutlined />} icon={<Download size={16} />}
onClick={handleDownload} onClick={handleDownload}
> >
{t("download", { ns: "common" })} {t("download", { ns: "common" })}

View File

@@ -6,25 +6,24 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import {
Modal,
Steps, Steps,
Button,
Space, Space,
Alert, Alert,
Spin, Spin,
Result, Result,
Select,
Table, Table,
Tag, Tag,
Typography, Typography,
Divider, Divider,
} from "antd"; } from "antd";
import { Button, Modal, Select } from "@lobehub/ui";
import { import {
CloudUploadOutlined, CloudUpload,
CheckCircleOutlined, CheckCircle,
CloseCircleOutlined, XCircle,
LoadingOutlined, Loader2,
} from "@ant-design/icons"; } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { FileUploader } from "../FileUploader"; import { FileUploader } from "../FileUploader";
import { useDeployStore } from "@renderer/stores"; import { useDeployStore } from "@renderer/stores";
@@ -291,7 +290,7 @@ const DeployDialog: React.FC<DeployDialogProps> = ({
style={{ textAlign: "center", padding: 48 }} style={{ textAlign: "center", padding: 48 }}
> >
<Spin <Spin
indicator={<LoadingOutlined style={{ fontSize: 48 }} spin />} indicator={<Loader2 size={48} className="animate-spin" />}
/> />
<div style={{ marginTop: 24 }}> <div style={{ marginTop: 24 }}>
<Text>{t("deploying")}</Text> <Text>{t("deploying")}</Text>
@@ -352,7 +351,7 @@ const DeployDialog: React.FC<DeployDialogProps> = ({
<Modal <Modal
title={ title={
<Space> <Space>
<CloudUploadOutlined /> <CloudUpload size={16} />
{t("title")} {t("title")}
</Space> </Space>
} }

View File

@@ -5,7 +5,8 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Button, Form, Input, Modal, message } from "antd"; import { Button, Form, Modal } from "@lobehub/ui";
import { Input, message } from "antd";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useDomainStore } from "@renderer/stores"; import { useDomainStore } from "@renderer/stores";
import type { CreateDomainParams, UpdateDomainParams } from "@shared/types/ipc"; import type { CreateDomainParams, UpdateDomainParams } from "@shared/types/ipc";

View File

@@ -5,16 +5,18 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Avatar, Tag, Button, Popconfirm, Space, Tooltip } from "antd"; import { Tag, Popconfirm, Space } from "antd";
import { Button, Tooltip } from "@lobehub/ui";
import { Avatar } from "@lobehub/ui";
import { import {
CloudServerOutlined, Cloud,
EditOutlined, Pencil,
DeleteOutlined, Trash2,
CheckCircleOutlined, CheckCircle,
CloseCircleOutlined, XCircle,
QuestionCircleOutlined, HelpCircle,
HolderOutlined, GripVertical,
} from "@ant-design/icons"; } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useDomainStore, useUIStore } from "@renderer/stores"; import { useDomainStore, useUIStore } from "@renderer/stores";
import type { Domain } from "@shared/types/domain"; import type { Domain } from "@shared/types/domain";
@@ -128,11 +130,11 @@ const DomainList: React.FC<DomainListProps> = ({ onEdit }) => {
const status = connectionStatuses[id]; const status = connectionStatuses[id];
switch (status) { switch (status) {
case "connected": case "connected":
return <CheckCircleOutlined style={{ color: "#52c41a" }} />; return <CheckCircle size={16} style={{ color: "#52c41a" }} />;
case "error": case "error":
return <CloseCircleOutlined style={{ color: "#ff4d4f" }} />; return <XCircle size={16} style={{ color: "#ff4d4f" }} />;
default: default:
return <QuestionCircleOutlined style={{ color: "#faad14" }} />; return <HelpCircle size={16} style={{ color: "#faad14" }} />;
} }
}; };
@@ -195,11 +197,11 @@ const DomainList: React.FC<DomainListProps> = ({ onEdit }) => {
> >
<div className={styles.itemContent}> <div className={styles.itemContent}>
<div className={styles.dragHandle}> <div className={styles.dragHandle}>
<HolderOutlined /> <GripVertical size={16} />
</div> </div>
<div className={styles.domainInfo}> <div className={styles.domainInfo}>
<Avatar <Avatar
icon={<CloudServerOutlined />} icon={<Cloud size={16} />}
style={{ style={{
backgroundColor: getDomainIconColor(domain.id, isSelected), backgroundColor: getDomainIconColor(domain.id, isSelected),
}} }}
@@ -231,7 +233,7 @@ const DomainList: React.FC<DomainListProps> = ({ onEdit }) => {
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<EditOutlined />} icon={<Pencil size={16} />}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onEdit(domain.id); onEdit(domain.id);
@@ -253,7 +255,7 @@ const DomainList: React.FC<DomainListProps> = ({ onEdit }) => {
type="text" type="text"
size="small" size="small"
danger danger
icon={<DeleteOutlined />} icon={<Trash2 size={16} />}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
/> />
</Popconfirm> </Popconfirm>

View File

@@ -6,14 +6,15 @@
*/ */
import React from "react"; import React from "react";
import { Button, Empty, Spin, Tooltip, Avatar, Space } from "antd"; import { Spin, Space } from "antd";
import { Button, Tooltip, Avatar, Empty } from "@lobehub/ui";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import {
PlusOutlined, Plus,
CloudServerOutlined, Cloud,
UpOutlined, ChevronUp,
DownOutlined, ChevronDown,
} from "@ant-design/icons"; } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useDomainStore, useUIStore } from "@renderer/stores"; import { useDomainStore, useUIStore } from "@renderer/stores";
import DomainList from "./DomainList"; import DomainList from "./DomainList";
@@ -180,7 +181,7 @@ const DomainManager: React.FC<DomainManagerProps> = ({
<div className={styles.collapsedHeader}> <div className={styles.collapsedHeader}>
<div className={styles.collapsedInfo}> <div className={styles.collapsedInfo}>
<Avatar <Avatar
icon={<CloudServerOutlined />} icon={<Cloud size={14} />}
size="small" size="small"
style={{ style={{
backgroundColor: getDomainIconColor(currentDomain?.id), backgroundColor: getDomainIconColor(currentDomain?.id),
@@ -207,7 +208,7 @@ const DomainManager: React.FC<DomainManagerProps> = ({
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<PlusOutlined />} icon={<Plus size={16} />}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
handleAdd(); handleAdd();
@@ -223,7 +224,7 @@ const DomainManager: React.FC<DomainManagerProps> = ({
onMouseEnter={() => setIsHoveringToggle(true)} onMouseEnter={() => setIsHoveringToggle(true)}
onMouseLeave={() => setIsHoveringToggle(false)} onMouseLeave={() => setIsHoveringToggle(false)}
> >
<DownOutlined /> <ChevronDown size={16} />
</div> </div>
<DomainForm <DomainForm
@@ -241,7 +242,7 @@ const DomainManager: React.FC<DomainManagerProps> = ({
<div className={styles.header}> <div className={styles.header}>
<h2 className={styles.title}>{t("domainManagement")}</h2> <h2 className={styles.title}>{t("domainManagement")}</h2>
<div className={styles.actions}> <div className={styles.actions}>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}> <Button type="primary" icon={<Plus size={16} />} onClick={handleAdd}>
{t("add")} {t("add")}
</Button> </Button>
</div> </div>
@@ -273,7 +274,7 @@ const DomainManager: React.FC<DomainManagerProps> = ({
onMouseEnter={() => setIsHoveringToggle(true)} onMouseEnter={() => setIsHoveringToggle(true)}
onMouseLeave={() => setIsHoveringToggle(false)} onMouseLeave={() => setIsHoveringToggle(false)}
> >
<UpOutlined /> <ChevronUp size={16} />
</div> </div>
<DomainForm <DomainForm

View File

@@ -5,14 +5,15 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Upload, Button, List, Space, Tag, message, Popconfirm } from "antd"; import { Upload, List, Space, Tag, message, Popconfirm } from "antd";
import { Button } from "@lobehub/ui";
import { import {
InboxOutlined, Inbox,
DeleteOutlined, Trash2,
FileTextOutlined, FileText,
FileOutlined, File,
CodeOutlined, Code,
} from "@ant-design/icons"; } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import type { UploadFile, UploadProps } from "antd"; import type { UploadFile, UploadProps } from "antd";
import type { DeployFile } from "@shared/types/ipc"; import type { DeployFile } from "@shared/types/ipc";
@@ -130,7 +131,7 @@ const FileUploader: React.FC<FileUploaderProps> = ({
accept=".js,.css" accept=".js,.css"
> >
<p className="ant-upload-drag-icon"> <p className="ant-upload-drag-icon">
<InboxOutlined /> <Inbox size={24} />
</p> </p>
<p className="ant-upload-text">{t("clickOrDragToUpload")}</p> <p className="ant-upload-text">{t("clickOrDragToUpload")}</p>
<p className="ant-upload-hint"> <p className="ant-upload-hint">
@@ -167,11 +168,9 @@ const FileUploader: React.FC<FileUploaderProps> = ({
renderItem={(file, index) => ( renderItem={(file, index) => (
<div className={styles.fileItem}> <div className={styles.fileItem}>
<div className={styles.fileInfo}> <div className={styles.fileInfo}>
<FileOutlined <File
style={{ size={20}
fontSize: 20, style={{ color: getFileTypeColor(file.fileType) }}
color: getFileTypeColor(file.fileType),
}}
/> />
<div> <div>
<div className={styles.fileName}>{file.fileName}</div> <div className={styles.fileName}>{file.fileName}</div>
@@ -189,7 +188,7 @@ const FileUploader: React.FC<FileUploaderProps> = ({
<Button <Button
type="text" type="text"
danger danger
icon={<DeleteOutlined />} icon={<Trash2 size={16} />}
onClick={() => handleRemove(index)} onClick={() => handleRemove(index)}
/> />
</div> </div>

View File

@@ -5,8 +5,9 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Typography, Radio, Divider, Button } from "antd"; import { Typography, Radio, Divider } from "antd";
import { GlobalOutlined, CloseCircleOutlined } from "@ant-design/icons"; import { Button } from "@lobehub/ui";
import { Globe, XCircle } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useLocaleStore } from "@renderer/stores/localeStore"; import { useLocaleStore } from "@renderer/stores/localeStore";
import { LOCALES, type LocaleCode } from "@shared/types/locale"; import { LOCALES, type LocaleCode } from "@shared/types/locale";
@@ -100,7 +101,7 @@ const Settings: React.FC<SettingsProps> = ({ onClose }) => {
{onClose && ( {onClose && (
<Button <Button
type="text" type="text"
icon={<CloseCircleOutlined />} icon={<XCircle size={16} />}
onClick={onClose} onClick={onClose}
/> />
)} )}
@@ -109,7 +110,7 @@ const Settings: React.FC<SettingsProps> = ({ onClose }) => {
{/* Language Section */} {/* Language Section */}
<div className={styles.section}> <div className={styles.section}>
<div className={styles.sectionTitle}> <div className={styles.sectionTitle}>
<GlobalOutlined /> <Globe size={16} />
<Title level={5} style={{ margin: 0 }}> <Title level={5} style={{ margin: 0 }}>
{t("language")} {t("language")}
</Title> </Title>

View File

@@ -7,25 +7,23 @@ import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import {
List, List,
Avatar,
Tag, Tag,
Button,
Space, Space,
Empty,
Spin, Spin,
Popconfirm, Popconfirm,
Typography, Typography,
Tooltip,
} from "antd"; } from "antd";
import { Button, Tooltip, Empty, Avatar } from "@lobehub/ui";
import { import {
HistoryOutlined, History,
DownloadOutlined, Download,
DeleteOutlined, Trash2,
RollbackOutlined, Undo2,
TagOutlined, Tag,
CodeOutlined, Code,
FileTextOutlined, FileText,
} from "@ant-design/icons"; } from "lucide-react";
import { createStyles } from "antd-style"; import { createStyles } from "antd-style";
import { useVersionStore } from "@renderer/stores"; import { useVersionStore } from "@renderer/stores";
import { useDomainStore } from "@renderer/stores"; import { useDomainStore } from "@renderer/stores";
@@ -215,12 +213,12 @@ const VersionHistory: React.FC = () => {
<div className={styles.container}> <div className={styles.container}>
<div className={styles.header}> <div className={styles.header}>
<div className={styles.title}> <div className={styles.title}>
<HistoryOutlined style={{ fontSize: 20 }} /> <History size={20} />
<Text strong>{t("title")}</Text> <Text strong>{t("title")}</Text>
<Tag>{t("totalVersions", { count: versions.length })}</Tag> <Tag>{t("totalVersions", { count: versions.length })}</Tag>
</div> </div>
<Button <Button
icon={<DownloadOutlined />} icon={<Download size={16} />}
onClick={loadVersions} onClick={loadVersions}
loading={loading} loading={loading}
> >
@@ -245,9 +243,9 @@ const VersionHistory: React.FC = () => {
<Avatar <Avatar
icon={ icon={
version.fileType === "js" ? ( version.fileType === "js" ? (
<CodeOutlined /> <Code size={16} />
) : ( ) : (
<FileTextOutlined /> <FileText size={16} />
) )
} }
style={{ style={{
@@ -272,7 +270,7 @@ const VersionHistory: React.FC = () => {
{version.tags.map((tag, i) => ( {version.tags.map((tag, i) => (
<Tag <Tag
key={i} key={i}
icon={<TagOutlined />} icon={<Tag size={14} />}
color="processing" color="processing"
> >
{tag} {tag}
@@ -291,14 +289,14 @@ const VersionHistory: React.FC = () => {
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<CodeOutlined />} icon={<Code size={16} />}
/> />
</Tooltip> </Tooltip>
<Tooltip title={t("download", { ns: "common" })}> <Tooltip title={t("download", { ns: "common" })}>
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<DownloadOutlined />} icon={<Download size={16} />}
/> />
</Tooltip> </Tooltip>
<Tooltip title={t("confirmRollback")}> <Tooltip title={t("confirmRollback")}>
@@ -312,7 +310,7 @@ const VersionHistory: React.FC = () => {
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<RollbackOutlined />} icon={<Undo2 size={16} />}
/> />
</Popconfirm> </Popconfirm>
</Tooltip> </Tooltip>
@@ -327,7 +325,7 @@ const VersionHistory: React.FC = () => {
type="text" type="text"
size="small" size="small"
danger danger
icon={<DeleteOutlined />} icon={<Trash2 size={16} />}
/> />
</Popconfirm> </Popconfirm>
</Space> </Space>