mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-29 06:27:14 +00:00
feat(clients/inbounds): IP log popups, clearer titles, tag-based inbound labels
Add an IP Log popup (view list + refresh + clear) to the client edit form and the Client Information modal, with IPs stacked vertically. Identify inbounds by their xray tag (not remark/protocol:port) across every picker and chip: attach/detach modals, the attached-inbounds column and field, the filter drawer, and bulk-add. Add the tag field to the InboundOption schema (the backend already returned it). Clarify modal titles/labels: Client Information (was More Information) and Inbound Information (was Inbound's Data); Client Information / QR Code titles now include the client email. i18n: rename keys moreInformation->clientInfo and inboundData->inboundInfo with proper translations in all languages; addTitle->addClient, editTitle->editClient, addToGroupPlaceholder->groupName.
This commit is contained in:
@@ -69,7 +69,7 @@ export default function AttachClientsModal({
|
||||
if (!source) return [];
|
||||
return (dbInbounds || [])
|
||||
.filter((ib) => ib.id !== source.id && isInboundMultiUser(ib))
|
||||
.map((ib) => ({ value: ib.id, label: `${ib.remark} (${ib.protocol}@${ib.port})` }));
|
||||
.map((ib) => ({ value: ib.id, label: ib.tag ?? '' }));
|
||||
}, [dbInbounds, source]);
|
||||
|
||||
const filteredRows = useMemo(() => {
|
||||
@@ -150,7 +150,7 @@ export default function AttachClientsModal({
|
||||
}}
|
||||
okText={t('pages.inbounds.attachClients')}
|
||||
cancelText={t('cancel')}
|
||||
title={t('pages.inbounds.attachClientsTitle', { remark: source?.remark ?? '' })}
|
||||
title={t('pages.inbounds.attachClientsTitle', { remark: source?.tag ?? '' })}
|
||||
width={680}
|
||||
>
|
||||
{messageContextHolder}
|
||||
|
||||
@@ -139,7 +139,7 @@ export default function DetachClientsModal({
|
||||
}}
|
||||
okText={t('pages.inbounds.detachClients')}
|
||||
cancelText={t('cancel')}
|
||||
title={t('pages.inbounds.detachClientsTitle', { remark: source?.remark ?? '' })}
|
||||
title={t('pages.inbounds.detachClientsTitle', { remark: source?.tag ?? '' })}
|
||||
width={680}
|
||||
>
|
||||
{messageContextHolder}
|
||||
|
||||
@@ -480,7 +480,7 @@ export default function InboundInfoModal({
|
||||
|
||||
if (!dbInbound || !inbound) {
|
||||
return (
|
||||
<Modal open={open} onCancel={onClose} title={t('pages.inbounds.inboundData')} footer={null} width={640} />
|
||||
<Modal open={open} onCancel={onClose} title={t('pages.inbounds.inboundInfo')} footer={null} width={640} />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1074,7 +1074,7 @@ export default function InboundInfoModal({
|
||||
tabItems.push({ key: 'inbound', label: t('pages.xray.rules.inbound'), children: inboundTab });
|
||||
|
||||
return (
|
||||
<Modal open={open} onCancel={onClose} title={t('pages.inbounds.inboundData')} footer={null} width={640} destroyOnHidden>
|
||||
<Modal open={open} onCancel={onClose} title={t('pages.inbounds.inboundInfo')} footer={null} width={640} destroyOnHidden>
|
||||
<Tabs activeKey={activeTab} onChange={setActiveTab} items={tabItems} />
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -255,7 +255,7 @@ function buildRowActionsMenu({ record, subEnable, t, isMobile, hasClients }: { r
|
||||
});
|
||||
}
|
||||
} else {
|
||||
items.push({ key: 'showInfo', icon: <InfoCircleOutlined />, label: t('info') });
|
||||
items.push({ key: 'showInfo', icon: <InfoCircleOutlined />, label: t('pages.inbounds.inboundInfo') });
|
||||
}
|
||||
items.push({ key: 'clipboard', icon: <CopyOutlined />, label: t('pages.inbounds.exportInbound') });
|
||||
items.push({ key: 'resetTraffic', icon: <RetweetOutlined />, label: t('pages.inbounds.resetTraffic') });
|
||||
@@ -626,7 +626,7 @@ export default function InboundList({
|
||||
<span className="card-id">#{record.id}</span>
|
||||
<span className="tag-name">{record.remark}</span>
|
||||
<div className="card-actions" onClick={(e) => e.stopPropagation()}>
|
||||
<Tooltip title={t('info')}>
|
||||
<Tooltip title={t('pages.inbounds.inboundInfo')}>
|
||||
<InfoCircleOutlined className="row-action-trigger" onClick={() => setStatsRecord(record)} />
|
||||
</Tooltip>
|
||||
<Switch
|
||||
|
||||
Reference in New Issue
Block a user