+ {/* Left side: Cancel button and error message */}
+
-
+
+ {/* Right side: Test button and Create/Update button */}
+
+ {createError && (
+
+ {createError.message}
+
+ )}
+ {renderTestButton()}
+
diff --git a/src/renderer/src/components/DomainManager/DomainList.tsx b/src/renderer/src/components/DomainManager/DomainList.tsx
index b254551..343e1f3 100644
--- a/src/renderer/src/components/DomainManager/DomainList.tsx
+++ b/src/renderer/src/components/DomainManager/DomainList.tsx
@@ -1,33 +1,23 @@
/**
* DomainList Component
- * Displays list of domains with connection status and drag-to-reorder
+ * Displays list of domains with drag-to-reorder functionality
*/
-
import React from "react";
import { useTranslation } from "react-i18next";
-import { Tag, Popconfirm, Space } from "antd";
-import { Button, Tooltip } from "@lobehub/ui";
-import { Avatar } from "@lobehub/ui";
-import {
- Cloud,
- Pencil,
- Trash2,
- CheckCircle,
- XCircle,
- HelpCircle,
- GripVertical,
-} from "lucide-react";
+import { Popconfirm, Space } from "antd";
+import { Button, SortableList, Tooltip } from "@lobehub/ui";
+import { Pencil, Trash2 } from "lucide-react";
import { createStyles } from "antd-style";
-import { useDomainStore, useUIStore } from "@renderer/stores";
+import { useDomainStore } from "@renderer/stores";
import type { Domain } from "@shared/types/domain";
const useStyles = createStyles(({ token, css }) => ({
- item: css`
- padding: ${token.paddingSM}px;
+ itemWrapper: css`
+ width: 100%;
+ padding: ${token.paddingXS}px ${token.paddingSM}px;
border-radius: ${token.borderRadiusLG}px;
background: ${token.colorBgContainer};
border: 1px solid ${token.colorBorderSecondary};
- margin-bottom: ${token.marginXS}px;
transition: all 0.2s;
cursor: pointer;
@@ -35,15 +25,17 @@ const useStyles = createStyles(({ token, css }) => ({
border-color: ${token.colorPrimary};
box-shadow: ${token.boxShadowSecondary};
}
+
+ &:hover .domain-item-actions {
+ opacity: 1;
+ }
`,
+
selectedItem: css`
border-color: ${token.colorPrimary};
background: ${token.colorPrimaryBg};
`,
- itemDragging: css`
- opacity: 0.5;
- border: 2px dashed ${token.colorPrimary};
- `,
+
domainInfo: css`
display: flex;
align-items: center;
@@ -51,6 +43,7 @@ const useStyles = createStyles(({ token, css }) => ({
flex: 1;
min-width: 0;
`,
+
domainName: css`
font-weight: ${token.fontWeightStrong};
font-size: ${token.fontSizeLG}px;
@@ -58,6 +51,7 @@ const useStyles = createStyles(({ token, css }) => ({
text-overflow: ellipsis;
white-space: nowrap;
`,
+
domainUrl: css`
color: ${token.colorTextSecondary};
font-size: ${token.fontSizeSM}px;
@@ -65,33 +59,29 @@ const useStyles = createStyles(({ token, css }) => ({
text-overflow: ellipsis;
white-space: nowrap;
`,
+
actions: css`
+ position: absolute;
+ right: ${token.paddingXS}px;
+ top: 50%;
+ transform: translateY(-50%);
display: flex;
gap: ${token.paddingXS}px;
+ opacity: 0;
+ transition: opacity 0.2s;
+ background: ${token.colorBgContainer};
+ border-radius: ${token.borderRadiusSM}px;
+ padding: 2px;
+ box-shadow: ${token.boxShadowSecondary};
`,
- statusTag: css`
- margin-left: ${token.paddingSM}px;
- `,
- dragHandle: css`
- cursor: grab;
- color: ${token.colorTextTertiary};
- display: flex;
- align-items: center;
- &:hover {
- color: ${token.colorText};
- }
-
- &:active {
- cursor: grabbing;
- }
- `,
itemContent: css`
display: flex;
- justify-content: space-between;
align-items: center;
- gap: ${token.paddingSM}px;
+ gap: ${token.paddingXS}px;
+ position: relative;
`,
+
domainText: css`
flex: 1;
min-width: 0;
@@ -106,17 +96,8 @@ interface DomainListProps {
const DomainList: React.FC
= ({ onEdit }) => {
const { t } = useTranslation("domain");
const { styles } = useStyles();
- const {
- domains,
- currentDomain,
- connectionStatuses,
- switchDomain,
- deleteDomain,
- testConnection,
- reorderDomains,
- } = useDomainStore();
- const { domainIconColors } = useUIStore();
- const [draggingIndex, setDraggingIndex] = React.useState(null);
+ const { domains, currentDomain, switchDomain, deleteDomain, reorderDomains } =
+ useDomainStore();
const handleSelect = (domain: Domain) => {
switchDomain(domain);
@@ -126,131 +107,69 @@ const DomainList: React.FC = ({ onEdit }) => {
await deleteDomain(id);
};
- const getStatusIcon = (id: string) => {
- const status = connectionStatuses[id];
- switch (status) {
- case "connected":
- return ;
- case "error":
- return ;
- default:
- return ;
+ // Handle reorder - convert SortableListItem[] back to reorder action
+ const handleSortChange = (newItems: { id: string }[]) => {
+ const newOrder = newItems.map((item) => item.id);
+ const oldOrder = domains.map((d) => d.id);
+
+ // Find the from and to indices
+ for (let i = 0; i < oldOrder.length; i++) {
+ if (oldOrder[i] !== newOrder[i]) {
+ const fromIndex = i;
+ const toIndex = newOrder.indexOf(oldOrder[i]);
+ reorderDomains(fromIndex, toIndex);
+ break;
+ }
}
};
- const getStatusTag = (id: string) => {
- const status = connectionStatuses[id];
- switch (status) {
- case "connected":
- return {t("connected")};
- case "error":
- return {t("connectionFailed")};
- default:
- return {t("notTested")};
- }
- };
+ const renderItem = (item: { id: string }) => {
+ const domain = domains.find((d) => d.id === item.id);
+ if (!domain) return null;
- const getDomainIconColor = (domainId: string, isSelected: boolean) => {
- if (domainIconColors[domainId]) {
- return domainIconColors[domainId];
- }
- return isSelected ? "#1890ff" : "#87d068";
- };
+ const isSelected = currentDomain?.id === domain.id;
- // Drag and drop handlers
- const handleDragStart = (index: number) => {
- setDraggingIndex(index);
- };
-
- const handleDragOver = (e: React.DragEvent, index: number) => {
- e.preventDefault();
- if (draggingIndex === null || draggingIndex === index) return;
- };
-
- const handleDrop = (e: React.DragEvent, index: number) => {
- e.preventDefault();
- if (draggingIndex === null || draggingIndex === index) return;
- reorderDomains(draggingIndex, index);
- setDraggingIndex(null);
- };
-
- const handleDragEnd = () => {
- setDraggingIndex(null);
- };
-
- return (
- <>
- {domains.map((domain, index) => {
- const isSelected = currentDomain?.id === domain.id;
- const isDragging = draggingIndex === index;
-
- return (
- handleSelect(domain)}
- draggable
- onDragStart={() => handleDragStart(index)}
- onDragOver={(e) => handleDragOver(e, index)}
- onDrop={(e) => handleDrop(e, index)}
- onDragEnd={handleDragEnd}
- >
-
-
-
-
-
-
}
- style={{
- backgroundColor: getDomainIconColor(domain.id, isSelected),
- }}
- />
-
-
- {domain.name}
- {getStatusTag(domain.id)}
-
-
- {domain.domain} · {domain.username}
-
+ return (
+
+ handleSelect(domain)}
+ >
+
+
+
+
+
{domain.name}
+
+ {domain.username} · {domain.domain}
+
-
-
-
-
- }
- onClick={(e) => {
- e.stopPropagation();
- onEdit(domain.id);
- }}
- />
-
- {
- e?.stopPropagation();
- handleDelete(domain.id);
+
+
+ }
+ onClick={(e) => {
+ e.stopPropagation();
+ onEdit(domain.id);
}}
- onCancel={(e) => e?.stopPropagation()}
- okText={t("delete", { ns: "common" })}
- cancelText={t("cancel", { ns: "common" })}
- >
+ />
+
+ {
+ e?.stopPropagation();
+ handleDelete(domain.id);
+ }}
+ onCancel={(e) => e?.stopPropagation()}
+ okText={t("delete", { ns: "common" })}
+ cancelText={t("cancel", { ns: "common" })}
+ >
+
-
-
+
+
+
- );
- })}
- >
+
+
+ );
+ };
+
+ return (
+
);
};
diff --git a/src/renderer/src/components/DomainManager/DomainManager.tsx b/src/renderer/src/components/DomainManager/DomainManager.tsx
index 0d28593..1295049 100644
--- a/src/renderer/src/components/DomainManager/DomainManager.tsx
+++ b/src/renderer/src/components/DomainManager/DomainManager.tsx
@@ -38,10 +38,9 @@ const useStyles = createStyles(({ token, css }) => ({
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: ${token.marginLG}px;
+ margin-bottom: ${token.marginXXS}px;
padding: 0 ${token.paddingLG}px;
- padding-top: ${token.paddingLG}px;
- border-bottom: 1px solid ${token.colorBorderSecondary};
+ padding-top: ${token.paddingXS}px;
`,
title: css`
font-size: ${token.fontSizeHeading4}px;
@@ -56,7 +55,7 @@ const useStyles = createStyles(({ token, css }) => ({
content: css`
flex: 1;
overflow: auto;
- padding: 0 ${token.paddingLG}px;
+ padding: 0 ${token.paddingSM}px;
`,
loading: css`
display: flex;
@@ -194,7 +193,7 @@ const DomainManager: React.FC
= ({
{currentDomain.name}
- {currentDomain.domain}
+ {currentDomain.username} · {currentDomain.domain}
>
) : (
@@ -256,11 +255,7 @@ const DomainManager: React.FC
= ({
) : domains.length === 0 ? (
-
) : (
diff --git a/src/renderer/src/components/VersionHistory/VersionHistory.tsx b/src/renderer/src/components/VersionHistory/VersionHistory.tsx
index effff54..a6ba88a 100644
--- a/src/renderer/src/components/VersionHistory/VersionHistory.tsx
+++ b/src/renderer/src/components/VersionHistory/VersionHistory.tsx
@@ -194,7 +194,6 @@ const VersionHistory: React.FC = () => {
@@ -230,7 +229,6 @@ const VersionHistory: React.FC = () => {
{versions.length === 0 ? (
) : (