diff --git a/frontend/src/components/AppSidebar.css b/frontend/src/components/AppSidebar.css
index ac1de456..4784572f 100644
--- a/frontend/src/components/AppSidebar.css
+++ b/frontend/src/components/AppSidebar.css
@@ -247,6 +247,24 @@
}
}
+body.dark .ant-drawer-content,
+body.dark .ant-drawer-body {
+ background-color: #15161a;
+}
+
+html[data-theme="ultra-dark"] body.dark .ant-drawer-content,
+html[data-theme="ultra-dark"] body.dark .ant-drawer-body {
+ background-color: #050507;
+}
+
+body.dark .ant-drawer-body .drawer-menu,
+body.dark .ant-drawer-body .drawer-menu.ant-menu-dark,
+body.dark .ant-drawer-body .drawer-menu .ant-menu-item,
+body.dark .ant-drawer-body .drawer-menu .ant-menu-sub,
+body.dark .ant-drawer-body .drawer-menu .ant-menu-item-group-list {
+ background-color: transparent;
+}
+
.sider-nav .ant-menu-item-selected,
.sider-utility .ant-menu-item-selected,
.drawer-menu .ant-menu-item-selected {
diff --git a/frontend/src/pages/clients/ClientsPage.css b/frontend/src/pages/clients/ClientsPage.css
index 8eaba3fa..085ce490 100644
--- a/frontend/src/pages/clients/ClientsPage.css
+++ b/frontend/src/pages/clients/ClientsPage.css
@@ -77,6 +77,19 @@
padding: 6px 0;
}
+@media (min-width: 769px) and (max-width: 920px) {
+ .card-toolbar {
+ gap: 6px;
+ }
+ .card-toolbar .ant-btn .ant-btn-icon + span,
+ .card-toolbar .ant-btn > span:not(.ant-btn-icon):not(.ant-tag):not(.anticon) {
+ display: none;
+ }
+ .card-toolbar .ant-btn {
+ padding-inline: 8px;
+ }
+}
+
.email-cell {
display: flex;
flex-direction: column;
diff --git a/frontend/src/pages/groups/GroupsPage.tsx b/frontend/src/pages/groups/GroupsPage.tsx
index 1e1cc896..6d16e4d3 100644
--- a/frontend/src/pages/groups/GroupsPage.tsx
+++ b/frontend/src/pages/groups/GroupsPage.tsx
@@ -332,6 +332,13 @@ export default function GroupsPage() {
label: t('pages.groups.addToGroup'),
onClick: () => openAddClientsFor(row),
},
+ {
+ key: 'rename',
+ icon: ,
+ label: t('pages.groups.rename'),
+ onClick: () => openRename(row),
+ },
+ { type: 'divider' },
{
key: 'removeClients',
icon: ,
@@ -340,13 +347,6 @@ export default function GroupsPage() {
disabled: !row.clientCount,
onClick: () => openRemoveClientsFor(row),
},
- { type: 'divider' },
- {
- key: 'rename',
- icon: ,
- label: t('pages.groups.rename'),
- onClick: () => openRename(row),
- },
{
key: 'deleteClients',
icon: ,
diff --git a/frontend/src/pages/inbounds/InboundList.tsx b/frontend/src/pages/inbounds/InboundList.tsx
index c0168190..7bf8f9e0 100644
--- a/frontend/src/pages/inbounds/InboundList.tsx
+++ b/frontend/src/pages/inbounds/InboundList.tsx
@@ -264,7 +264,10 @@ function buildRowActionsMenu({ record, subEnable, t, isMobile, hasClients }: { r
items.push({ key: 'attachClients', icon: , label: t('pages.inbounds.attachClients') });
items.push({ key: 'detachClients', icon: , label: t('pages.inbounds.detachClients') });
items.push({ key: 'addToGroup', icon: , label: t('pages.inbounds.addClientsToGroup') });
+ items.push({ type: 'divider' });
items.push({ key: 'delAllClients', icon: , danger: true, label: t('pages.inbounds.delAllClients') });
+ } else {
+ items.push({ type: 'divider' });
}
items.push({ key: 'delete', icon: , danger: true, label: t('delete') });
return items;
diff --git a/frontend/src/pages/xray/RoutingTab.css b/frontend/src/pages/xray/RoutingTab.css
index 6ad04cec..d79b2f17 100644
--- a/frontend/src/pages/xray/RoutingTab.css
+++ b/frontend/src/pages/xray/RoutingTab.css
@@ -99,7 +99,7 @@
.rule-list {
display: flex;
flex-direction: column;
- gap: 8px;
+ gap: 14px;
}
.rule-card {
@@ -109,11 +109,24 @@
gap: 8px;
padding: 10px 12px;
background: var(--bg-card, #fff);
- border: 1px solid var(--ant-color-border-secondary);
+ border: 1px solid var(--ant-color-border);
border-radius: 8px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
transition: opacity 0.15s, box-shadow 0.15s;
}
+.rule-list > .rule-card:not(:last-child)::after {
+ content: '';
+ position: absolute;
+ left: 50%;
+ bottom: -8px;
+ width: 32px;
+ height: 1px;
+ background: var(--ant-color-border);
+ transform: translateX(-50%);
+ opacity: 0.7;
+}
+
.rule-card.row-dragging {
opacity: 0.4;
}
diff --git a/frontend/src/pages/xray/RoutingTab.tsx b/frontend/src/pages/xray/RoutingTab.tsx
index d9d89b67..8943ad6e 100644
--- a/frontend/src/pages/xray/RoutingTab.tsx
+++ b/frontend/src/pages/xray/RoutingTab.tsx
@@ -88,6 +88,8 @@ export default function RoutingTab({
() => (templateSettings?.routing?.rules || []) as RoutingRule[],
[templateSettings?.routing?.rules],
);
+ const rulesRef = useRef(rules);
+ rulesRef.current = rules;
const rows: RuleRow[] = useMemo(
() =>
@@ -171,7 +173,7 @@ export default function RoutingTab({
setRuleModalOpen(true);
}
function openEdit(idx: number) {
- setEditingRule(rules[idx]);
+ setEditingRule(rulesRef.current[idx]);
setEditingIndex(idx);
setRuleModalOpen(true);
}
diff --git a/frontend/src/styles/page-shell.css b/frontend/src/styles/page-shell.css
index ce504c05..d8c64e93 100644
--- a/frontend/src/styles/page-shell.css
+++ b/frontend/src/styles/page-shell.css
@@ -89,6 +89,24 @@
min-height: calc(100vh - 120px);
}
+.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover,
+.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover .ant-dropdown-menu-title-content,
+.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover > .anticon {
+ color: var(--ant-color-primary) !important;
+}
+
+.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover {
+ background-color: color-mix(in srgb, var(--ant-color-primary) 14%, transparent) !important;
+}
+
+.ant-dropdown-menu-item-divider {
+ background-color: var(--ant-color-border) !important;
+}
+
+body.dark .ant-dropdown-menu-item-divider {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
.settings-page .header-row,
.xray-page .header-row {
display: flex;