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:
@@ -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. 测试规范
|
||||||
|
|
||||||
### 测试框架
|
### 测试框架
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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" })}
|
||||||
|
|||||||
@@ -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>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user