diff --git a/frontend/src/pages/clients/ClientsPage.tsx b/frontend/src/pages/clients/ClientsPage.tsx index 42e21bef..dfb155a3 100644 --- a/frontend/src/pages/clients/ClientsPage.tsx +++ b/frontend/src/pages/clients/ClientsPage.tsx @@ -783,28 +783,25 @@ export default function ClientsPage() { hoverable title={
- - {selectedRowKeys.length > 0 && ( + {selectedRowKeys.length === 0 ? ( + + ) : ( <> - - + setSelectedRowKeys([])} + style={{ marginInlineEnd: 0, padding: '4px 8px', fontSize: 13 }} + > + {t('pages.clients.selectedCount', { count: selectedRowKeys.length })} + - - )} @@ -812,33 +809,64 @@ export default function ClientsPage() { trigger={['click']} placement="bottomRight" menu={{ - items: [ - { - key: 'bulk', - icon: , - label: t('pages.clients.bulk'), - onClick: () => setBulkAddOpen(true), - }, - { - key: 'resetAll', - icon: , - label: t('pages.clients.resetAllTraffics'), - onClick: onResetAllTraffics, - }, - { - key: 'delDepleted', - icon: , - label: t('pages.clients.delDepleted'), - danger: true, - onClick: onDelDepleted, - }, - ], + items: selectedRowKeys.length > 0 + ? [ + { + key: 'adjust', + icon: , + label: t('pages.clients.adjust'), + onClick: () => setBulkAdjustOpen(true), + }, + { + key: 'group', + icon: , + label: t('pages.clients.group'), + onClick: () => setBulkGroupOpen(true), + }, + { + key: 'subLinks', + icon: , + label: t('pages.clients.subLinks'), + onClick: () => setSubLinksOpen(true), + }, + ] + : [ + { + key: 'bulk', + icon: , + label: t('pages.clients.bulk'), + onClick: () => setBulkAddOpen(true), + }, + { + key: 'resetAll', + icon: , + label: t('pages.clients.resetAllTraffics'), + onClick: onResetAllTraffics, + }, + { + key: 'delDepleted', + icon: , + label: t('pages.clients.delDepleted'), + danger: true, + onClick: onDelDepleted, + }, + ], }} > + {selectedRowKeys.length > 0 && ( + + )}
} > diff --git a/web/translation/en-US.json b/web/translation/en-US.json index db2db99e..1f1ac320 100644 --- a/web/translation/en-US.json +++ b/web/translation/en-US.json @@ -542,6 +542,10 @@ "assignGroupPlaceholder": "Group name (leave blank to clear)", "assignGroupAssignedToast": "Assigned {count} client(s) to {group}", "assignGroupClearedToast": "Cleared group from {count} client(s)", + "attach": "Attach", + "adjust": "Adjust", + "subLinks": "Sub links", + "selectedCount": "{count} selected", "attachSelected": "Attach ({count})", "attachToInboundsTitle": "Attach {count} client(s) to inbound(s)", "attachToInboundsDesc": "Attaches the selected {count} client(s) (same UUID/password and shared traffic) to the chosen inbound(s). They keep their existing attachments too.", diff --git a/web/translation/fa-IR.json b/web/translation/fa-IR.json index 23779bab..e4e60c4f 100644 --- a/web/translation/fa-IR.json +++ b/web/translation/fa-IR.json @@ -513,6 +513,10 @@ "deleteConfirmContent": "این کلاینت از تمام اینباندهای متصل حذف و سابقه ترافیک آن پاک می‌شود. این عمل غیرقابل بازگشت است.", "deleteSelected": "حذف ({count})", "adjustSelected": "تنظیم ({count})", + "attach": "اتصال", + "adjust": "تنظیم", + "subLinks": "لینک‌های ساب", + "selectedCount": "{count} انتخاب‌شده", "attachSelected": "اتصال ({count})", "attachToInboundsTitle": "اتصال {count} کلاینت به اینباند(ها)", "attachToInboundsDesc": "{count} کلاینت انتخاب‌شده (با همان UUID/پسورد و ترافیک مشترک) به اینباند(های) انتخابی متصل می‌شوند. روی اینباندهای فعلی هم باقی می‌مانند.",