mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-05-31 10:14:15 +00:00
fix(ui): polish across routing, groups, inbounds, mobile sidebar
A bundle of small UI fixes that surfaced together while reviewing the panel. Routing rules — stale Edit after drag: - Dragging a rule and then clicking its Edit button used to open the modal with the *previous* rule's content. Root cause: desktopColumns was memoized with [t, isMobile, rows.length] (rows.length doesn't change on reorder), so the cached render function kept handing AntD the openEdit closure that captured the pre-drag rules array. Fix is a rulesRef updated each render and read inside openEdit, so even the cached closure sees the live array. - Mobile rule cards on the same page were hard to tell apart: bumped the inter-card gap, slightly stronger border, soft shadow, and a small centered divider line between adjacent cards. Mobile drawer (dark / ultra): - The AntD Menu inside the mobile drawer was rendering with its own darkItemBg (#15161a / #050507) while the drawer body used the lighter colorBgElevated, producing visible two-tone seams. Force the drawer-content / drawer-body to the same dark color that the desktop sider uses, and make the menus transparent so they inherit. Row menus — visual grouping: - Groups page row menu: moved Rename above the divider so the ordering reads safe → divider → destructive (Remove from group, Delete clients, Delete group only) instead of mixing the two groups. - Inbounds page row menu: inserted a divider before delAllClients / delete so the destructive items sit visually separated from the earlier safe actions. Dropdown affordances: - Non-danger dropdown items had no perceivable hover state (default colorBgTextHover is too subtle, especially under the light theme). Apply the same primary-tint pattern the sider/drawer menu uses: 14% primary background and primary color on label + icon. - ant-dropdown-menu-item-divider now uses var(--ant-color-border) (and an explicit rgba in dark) so the separator is actually visible in the light theme. Clients toolbar — narrow-desktop wrap: - Between 769px and 920px, the bulk-action bar (Attach / Detach / Add to group / Ungroup / more + Delete) wrapped to two rows with Delete stranded alone on the right. In that range, switch the toolbar buttons to icon-only, tighten gap to 6px and inline padding to 8px so everything stays on one line.
This commit is contained in:
parent
530e338c66
commit
2fea71387b
7 changed files with 77 additions and 10 deletions
|
|
@ -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-nav .ant-menu-item-selected,
|
||||||
.sider-utility .ant-menu-item-selected,
|
.sider-utility .ant-menu-item-selected,
|
||||||
.drawer-menu .ant-menu-item-selected {
|
.drawer-menu .ant-menu-item-selected {
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,19 @@
|
||||||
padding: 6px 0;
|
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 {
|
.email-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,13 @@ export default function GroupsPage() {
|
||||||
label: t('pages.groups.addToGroup'),
|
label: t('pages.groups.addToGroup'),
|
||||||
onClick: () => openAddClientsFor(row),
|
onClick: () => openAddClientsFor(row),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'rename',
|
||||||
|
icon: <EditOutlined />,
|
||||||
|
label: t('pages.groups.rename'),
|
||||||
|
onClick: () => openRename(row),
|
||||||
|
},
|
||||||
|
{ type: 'divider' },
|
||||||
{
|
{
|
||||||
key: 'removeClients',
|
key: 'removeClients',
|
||||||
icon: <UsergroupDeleteOutlined />,
|
icon: <UsergroupDeleteOutlined />,
|
||||||
|
|
@ -340,13 +347,6 @@ export default function GroupsPage() {
|
||||||
disabled: !row.clientCount,
|
disabled: !row.clientCount,
|
||||||
onClick: () => openRemoveClientsFor(row),
|
onClick: () => openRemoveClientsFor(row),
|
||||||
},
|
},
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
key: 'rename',
|
|
||||||
icon: <EditOutlined />,
|
|
||||||
label: t('pages.groups.rename'),
|
|
||||||
onClick: () => openRename(row),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'deleteClients',
|
key: 'deleteClients',
|
||||||
icon: <DeleteOutlined />,
|
icon: <DeleteOutlined />,
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,10 @@ function buildRowActionsMenu({ record, subEnable, t, isMobile, hasClients }: { r
|
||||||
items.push({ key: 'attachClients', icon: <UsergroupAddOutlined />, label: t('pages.inbounds.attachClients') });
|
items.push({ key: 'attachClients', icon: <UsergroupAddOutlined />, label: t('pages.inbounds.attachClients') });
|
||||||
items.push({ key: 'detachClients', icon: <UsergroupDeleteOutlined />, label: t('pages.inbounds.detachClients') });
|
items.push({ key: 'detachClients', icon: <UsergroupDeleteOutlined />, label: t('pages.inbounds.detachClients') });
|
||||||
items.push({ key: 'addToGroup', icon: <TagsOutlined />, label: t('pages.inbounds.addClientsToGroup') });
|
items.push({ key: 'addToGroup', icon: <TagsOutlined />, label: t('pages.inbounds.addClientsToGroup') });
|
||||||
|
items.push({ type: 'divider' });
|
||||||
items.push({ key: 'delAllClients', icon: <UsergroupDeleteOutlined />, danger: true, label: t('pages.inbounds.delAllClients') });
|
items.push({ key: 'delAllClients', icon: <UsergroupDeleteOutlined />, danger: true, label: t('pages.inbounds.delAllClients') });
|
||||||
|
} else {
|
||||||
|
items.push({ type: 'divider' });
|
||||||
}
|
}
|
||||||
items.push({ key: 'delete', icon: <DeleteOutlined />, danger: true, label: t('delete') });
|
items.push({ key: 'delete', icon: <DeleteOutlined />, danger: true, label: t('delete') });
|
||||||
return items;
|
return items;
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
.rule-list {
|
.rule-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rule-card {
|
.rule-card {
|
||||||
|
|
@ -109,11 +109,24 @@
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
background: var(--bg-card, #fff);
|
background: var(--bg-card, #fff);
|
||||||
border: 1px solid var(--ant-color-border-secondary);
|
border: 1px solid var(--ant-color-border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
|
||||||
transition: opacity 0.15s, box-shadow 0.15s;
|
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 {
|
.rule-card.row-dragging {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ export default function RoutingTab({
|
||||||
() => (templateSettings?.routing?.rules || []) as RoutingRule[],
|
() => (templateSettings?.routing?.rules || []) as RoutingRule[],
|
||||||
[templateSettings?.routing?.rules],
|
[templateSettings?.routing?.rules],
|
||||||
);
|
);
|
||||||
|
const rulesRef = useRef(rules);
|
||||||
|
rulesRef.current = rules;
|
||||||
|
|
||||||
const rows: RuleRow[] = useMemo(
|
const rows: RuleRow[] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|
@ -171,7 +173,7 @@ export default function RoutingTab({
|
||||||
setRuleModalOpen(true);
|
setRuleModalOpen(true);
|
||||||
}
|
}
|
||||||
function openEdit(idx: number) {
|
function openEdit(idx: number) {
|
||||||
setEditingRule(rules[idx]);
|
setEditingRule(rulesRef.current[idx]);
|
||||||
setEditingIndex(idx);
|
setEditingIndex(idx);
|
||||||
setRuleModalOpen(true);
|
setRuleModalOpen(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,24 @@
|
||||||
min-height: calc(100vh - 120px);
|
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,
|
.settings-page .header-row,
|
||||||
.xray-page .header-row {
|
.xray-page .header-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue