feat(ui): improve client form modal UX

- Rename tabs: "Basic" → "Basics", "Config" → "Credentials"
- Move reverseTag field from Credentials tab to Basics tab
- Move IP log button inline with limitIp field (tooltip button, edit mode only)
- Hide random email button when editing an existing client
- Add tooltips to totalGB and limitIp fields with descriptive hints
- Rename labels: "Total Sent/Received (GB)" → "Traffic Limit (GB)", "Duration" → "Duration (days)"
- Add renewDays translation key for auto-renew label with unit hint
- Remove redundant filterOption and width style from AutoComplete group selectors
- Update all 15 locale files with new and renamed translation keys
This commit is contained in:
MHSanaei
2026-06-12 10:38:26 +02:00
parent 253063b785
commit 7ae3ea66d1
16 changed files with 149 additions and 113 deletions
@@ -66,11 +66,7 @@ export default function BulkAddToGroupModal({
placeholder={t('pages.clients.groupName')} placeholder={t('pages.clients.groupName')}
options={groups.map((g) => ({ value: g }))} options={groups.map((g) => ({ value: g }))}
onChange={(v) => setValue(v ?? '')} onChange={(v) => setValue(v ?? '')}
filterOption={(input, option) =>
String(option?.value ?? '').toLowerCase().includes((input || '').toLowerCase())
}
allowClear allowClear
style={{ width: '100%' }}
autoFocus autoFocus
/> />
</Form.Item> </Form.Item>
@@ -288,11 +288,7 @@ export default function ClientBulkAddModal({
placeholder={t('pages.clients.groupPlaceholder')} placeholder={t('pages.clients.groupPlaceholder')}
options={groups.map((g) => ({ value: g }))} options={groups.map((g) => ({ value: g }))}
onChange={(v) => update('group', v ?? '')} onChange={(v) => update('group', v ?? '')}
filterOption={(input, option) =>
String(option?.value ?? '').toLowerCase().includes((input || '').toLowerCase())
}
allowClear allowClear
style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
+45 -40
View File
@@ -14,6 +14,7 @@ import {
Switch, Switch,
Tabs, Tabs,
Tag, Tag,
Tooltip,
message, message,
} from 'antd'; } from 'antd';
import { EyeOutlined, ReloadOutlined } from '@ant-design/icons'; import { EyeOutlined, ReloadOutlined } from '@ant-design/icons';
@@ -428,7 +429,7 @@ export default function ClientFormModal({
items={[ items={[
{ {
key: 'basic', key: 'basic',
label: t('pages.clients.tabBasic'), label: t('pages.clients.tabBasics'),
children: ( children: (
<> <>
<Row gutter={16}> <Row gutter={16}>
@@ -441,20 +442,31 @@ export default function ClientFormModal({
style={{ flex: 1 }} style={{ flex: 1 }}
onChange={(e) => update('email', e.target.value)} onChange={(e) => update('email', e.target.value)}
/> />
<Button icon={<ReloadOutlined />} onClick={() => update('email', RandomUtil.randomLowerAndNum(12))} /> {!isEdit && (
<Button icon={<ReloadOutlined />} onClick={() => update('email', RandomUtil.randomLowerAndNum(12))} />
)}
</Space.Compact> </Space.Compact>
</Form.Item> </Form.Item>
</Col> </Col>
<Col xs={24} md={8}> <Col xs={24} md={6}>
<Form.Item label={t('pages.clients.totalGB')}> <Form.Item label={t('pages.clients.totalGB')} tooltip={t('pages.clients.totalGBDesc')}>
<InputNumber value={form.totalGB} min={0} step={1} style={{ width: '100%' }} <InputNumber value={form.totalGB} min={0} step={1} style={{ width: '100%' }}
onChange={(v) => update('totalGB', Number(v) || 0)} /> onChange={(v) => update('totalGB', Number(v) || 0)} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col xs={24} md={4}> <Col xs={24} md={6}>
<Form.Item label={t('pages.clients.limitIp')}> <Form.Item label={t('pages.clients.limitIp')} tooltip={t('pages.clients.limitIpDesc')}>
<InputNumber value={form.limitIp} min={0} style={{ width: '100%' }} <Space.Compact style={{ display: 'flex' }}>
onChange={(v) => update('limitIp', Number(v) || 0)} /> <InputNumber value={form.limitIp} min={0} style={{ flex: 1 }}
onChange={(v) => update('limitIp', Number(v) || 0)} />
{isEdit && (
<Tooltip title={t('pages.clients.ipLog')}>
<Button icon={<EyeOutlined />} loading={ipsLoading} onClick={openIpsModal}>
{clientIps.length > 0 ? clientIps.length : ''}
</Button>
</Tooltip>
)}
</Space.Compact>
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
@@ -489,7 +501,7 @@ export default function ClientFormModal({
</Col> </Col>
<Col xs={12} md={6}> <Col xs={12} md={6}>
<Form.Item <Form.Item
label={t('pages.clients.renew')} label={t('pages.clients.renewDays')}
tooltip={t('pages.clients.renewDesc')} tooltip={t('pages.clients.renewDesc')}
> >
<InputNumber value={form.reset} min={0} style={{ width: '100%' }} <InputNumber value={form.reset} min={0} style={{ width: '100%' }}
@@ -499,16 +511,7 @@ export default function ClientFormModal({
</Row> </Row>
<Row gutter={16}> <Row gutter={16}>
{tgBotEnable && ( <Col xs={24} md={12}>
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.telegramId')}>
<InputNumber value={form.tgId} min={0} controls={false}
placeholder={t('pages.clients.telegramIdPlaceholder')} style={{ width: '100%' }}
onChange={(v) => update('tgId', Number(v) || 0)} />
</Form.Item>
</Col>
)}
<Col xs={24} md={tgBotEnable ? 12 : 24}>
<Form.Item label={t('pages.clients.comment')}> <Form.Item label={t('pages.clients.comment')}>
<Input value={form.comment} onChange={(e) => update('comment', e.target.value)} /> <Input value={form.comment} onChange={(e) => update('comment', e.target.value)} />
</Form.Item> </Form.Item>
@@ -520,16 +523,34 @@ export default function ClientFormModal({
placeholder={t('pages.clients.groupPlaceholder')} placeholder={t('pages.clients.groupPlaceholder')}
options={groups.map((g) => ({ value: g }))} options={groups.map((g) => ({ value: g }))}
onChange={(v) => update('group', v ?? '')} onChange={(v) => update('group', v ?? '')}
filterOption={(input, option) =>
String(option?.value ?? '').toLowerCase().includes((input || '').toLowerCase())
}
allowClear allowClear
style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
{(tgBotEnable || showReverseTag) && (
<Row gutter={16}>
{tgBotEnable && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.telegramId')}>
<InputNumber value={form.tgId} min={0} controls={false}
placeholder={t('pages.clients.telegramIdPlaceholder')} style={{ width: '100%' }}
onChange={(v) => update('tgId', Number(v) || 0)} />
</Form.Item>
</Col>
)}
{showReverseTag && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.reverseTag')}>
<Input value={form.reverseTag} placeholder={t('pages.clients.reverseTagPlaceholder')}
onChange={(e) => update('reverseTag', e.target.value)} />
</Form.Item>
</Col>
)}
</Row>
)}
<Form.Item label={t('pages.clients.attachedInbounds')} required={!isEdit}> <Form.Item label={t('pages.clients.attachedInbounds')} required={!isEdit}>
<SelectAllClearButtons <SelectAllClearButtons
options={inboundOptions} options={inboundOptions}
@@ -555,20 +576,12 @@ export default function ClientFormModal({
<Switch checked={form.enable} onChange={(v) => update('enable', v)} /> <Switch checked={form.enable} onChange={(v) => update('enable', v)} />
<span style={{ marginLeft: 8 }}>{t('enable')}</span> <span style={{ marginLeft: 8 }}>{t('enable')}</span>
</Form.Item> </Form.Item>
{isEdit && (
<Form.Item label={t('pages.clients.ipLog')}>
<Button icon={<EyeOutlined />} loading={ipsLoading} onClick={openIpsModal}>
{clientIps.length > 0 ? clientIps.length : ''}
</Button>
</Form.Item>
)}
</> </>
), ),
}, },
{ {
key: 'config', key: 'config',
label: t('pages.clients.tabConfig'), label: t('pages.clients.tabCredentials'),
children: ( children: (
<> <>
<Row gutter={16}> <Row gutter={16}>
@@ -635,14 +648,6 @@ export default function ClientFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
)} )}
{showReverseTag && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.reverseTag')}>
<Input value={form.reverseTag} placeholder={t('pages.clients.reverseTagPlaceholder')}
onChange={(e) => update('reverseTag', e.target.value)} />
</Form.Item>
</Col>
)}
</Row> </Row>
</> </>
), ),
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "أساسي", "tabBasics": "أساسي",
"tabConfig": "التكوين", "tabCredentials": "بيانات الاعتماد",
"add": "إضافة عميل", "add": "إضافة عميل",
"edit": "تعديل العميل", "edit": "تعديل العميل",
"submitAdd": "إضافة عميل", "submitAdd": "إضافة عميل",
@@ -666,10 +666,11 @@
"prefix": "بادئة", "prefix": "بادئة",
"postfix": "لاحقة", "postfix": "لاحقة",
"delayedStart": "البدء بعد أول استخدام", "delayedStart": "البدء بعد أول استخدام",
"expireDays": "المدة", "expireDays": "المدة (أيام)",
"days": "يوم", "days": "يوم",
"renew": "تجديد تلقائي", "renew": "تجديد تلقائي",
"renewDesc": "تجديد تلقائي بعد انتهاء الصلاحية. (0 = تعطيل) (الوحدة: يوم)", "renewDesc": "تجديد تلقائي بعد انتهاء الصلاحية. (0 = تعطيل) (الوحدة: يوم)",
"renewDays": "تجديد تلقائي (أيام)",
"searchPlaceholder": "ابحث بالبريد، التعليق، sub ID، UUID، كلمة المرور، auth…", "searchPlaceholder": "ابحث بالبريد، التعليق، sub ID، UUID، كلمة المرور، auth…",
"filterTitle": "تصفية العملاء", "filterTitle": "تصفية العملاء",
"clearAllFilters": "مسح الكل", "clearAllFilters": "مسح الكل",
@@ -691,10 +692,12 @@
"hasNot": "لا يملك", "hasNot": "لا يملك",
"title": "العملاء", "title": "العملاء",
"actions": "الإجراءات", "actions": "الإجراءات",
"totalGB": "مجموع المرسل/المستقبل (جيجابايت)", "totalGB": "حد البيانات (جيجابايت)",
"totalGBDesc": "حصة البيانات لهذا العميل. 0 = غير محدود.",
"expiryTime": "انتهاء الصلاحية", "expiryTime": "انتهاء الصلاحية",
"addClients": "إضافة عملاء", "addClients": "إضافة عملاء",
"limitIp": "حد عناوين IP", "limitIp": "حد عناوين IP",
"limitIpDesc": "الحد الأقصى لعناوين IP المتزامنة. 0 = غير محدود.",
"password": "كلمة المرور", "password": "كلمة المرور",
"subId": "معرّف الاشتراك", "subId": "معرّف الاشتراك",
"online": "متصل", "online": "متصل",
+7 -4
View File
@@ -638,8 +638,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Basic", "tabBasics": "Basics",
"tabConfig": "Config", "tabCredentials": "Credentials",
"add": "Add Client", "add": "Add Client",
"edit": "Edit Client", "edit": "Edit Client",
"submitAdd": "Add Client", "submitAdd": "Add Client",
@@ -667,10 +667,11 @@
"prefix": "Prefix", "prefix": "Prefix",
"postfix": "Postfix", "postfix": "Postfix",
"delayedStart": "Start After First Use", "delayedStart": "Start After First Use",
"expireDays": "Duration", "expireDays": "Duration (days)",
"days": "Day(s)", "days": "Day(s)",
"renew": "Auto Renew", "renew": "Auto Renew",
"renewDesc": "Auto-renewal after expiration. (0 = disable)(unit: day)", "renewDesc": "Auto-renewal after expiration. (0 = disable)(unit: day)",
"renewDays": "Auto Renew (days)",
"searchPlaceholder": "Search email, comment, sub ID, UUID, password, auth…", "searchPlaceholder": "Search email, comment, sub ID, UUID, password, auth…",
"filterTitle": "Filter clients", "filterTitle": "Filter clients",
"clearAllFilters": "Clear all", "clearAllFilters": "Clear all",
@@ -692,10 +693,12 @@
"hasNot": "Doesn't have", "hasNot": "Doesn't have",
"title": "Clients", "title": "Clients",
"actions": "Actions", "actions": "Actions",
"totalGB": "Total Sent/Received (GB)", "totalGB": "Traffic Limit (GB)",
"totalGBDesc": "Data quota for this client. 0 = unlimited.",
"expiryTime": "Expiry", "expiryTime": "Expiry",
"addClients": "Add Clients", "addClients": "Add Clients",
"limitIp": "IP Limit", "limitIp": "IP Limit",
"limitIpDesc": "Maximum simultaneous IPs. 0 = unlimited.",
"password": "Password", "password": "Password",
"subId": "Subscription ID", "subId": "Subscription ID",
"online": "Online", "online": "Online",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Básico", "tabBasics": "Básico",
"tabConfig": "Configuración", "tabCredentials": "Credenciales",
"add": "Añadir cliente", "add": "Añadir cliente",
"edit": "Editar cliente", "edit": "Editar cliente",
"submitAdd": "Añadir cliente", "submitAdd": "Añadir cliente",
@@ -666,10 +666,11 @@
"prefix": "Prefijo", "prefix": "Prefijo",
"postfix": "Sufijo", "postfix": "Sufijo",
"delayedStart": "Iniciar tras el primer uso", "delayedStart": "Iniciar tras el primer uso",
"expireDays": "Duración", "expireDays": "Duración (días)",
"days": "Día(s)", "days": "Día(s)",
"renew": "Renovación automática", "renew": "Renovación automática",
"renewDesc": "Renovación automática tras la expiración. (0 = desactivado) (unidad: día)", "renewDesc": "Renovación automática tras la expiración. (0 = desactivado) (unidad: día)",
"renewDays": "Renovación automática (días)",
"searchPlaceholder": "Buscar email, comentario, sub ID, UUID, contraseña, auth…", "searchPlaceholder": "Buscar email, comentario, sub ID, UUID, contraseña, auth…",
"filterTitle": "Filtrar clientes", "filterTitle": "Filtrar clientes",
"clearAllFilters": "Limpiar todo", "clearAllFilters": "Limpiar todo",
@@ -691,10 +692,12 @@
"hasNot": "No tiene", "hasNot": "No tiene",
"title": "Clientes", "title": "Clientes",
"actions": "Acciones", "actions": "Acciones",
"totalGB": "Total enviado/recibido (GB)", "totalGB": "Límite de tráfico (GB)",
"totalGBDesc": "Cuota de datos para este cliente. 0 = ilimitado.",
"expiryTime": "Expiración", "expiryTime": "Expiración",
"addClients": "Añadir clientes", "addClients": "Añadir clientes",
"limitIp": "Límite de IP", "limitIp": "Límite de IP",
"limitIpDesc": "Máximo de IP simultáneas. 0 = ilimitado.",
"password": "Contraseña", "password": "Contraseña",
"subId": "ID de suscripción", "subId": "ID de suscripción",
"online": "En línea", "online": "En línea",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "پایه", "tabBasics": "پایه",
"tabConfig": "پیکربندی", "tabCredentials": "اطلاعات اتصال",
"add": "افزودن کلاینت", "add": "افزودن کلاینت",
"edit": "ویرایش کلاینت", "edit": "ویرایش کلاینت",
"submitAdd": "افزودن کلاینت", "submitAdd": "افزودن کلاینت",
@@ -666,10 +666,11 @@
"prefix": "پیشوند", "prefix": "پیشوند",
"postfix": "پسوند", "postfix": "پسوند",
"delayedStart": "شروع پس از اولین استفاده", "delayedStart": "شروع پس از اولین استفاده",
"expireDays": "مدت", "expireDays": "مدت اعتبار (روز)",
"days": "روز", "days": "روز",
"renew": "تمدید خودکار", "renew": "تمدید خودکار",
"renewDesc": "تمدید خودکار پس از انقضا. (۰ = غیرفعال) (واحد: روز)", "renewDesc": "تمدید خودکار پس از انقضا. (۰ = غیرفعال) (واحد: روز)",
"renewDays": "تمدید خودکار (روز)",
"searchPlaceholder": "جستجوی ایمیل، توضیح، Sub ID، UUID، رمز، احراز...", "searchPlaceholder": "جستجوی ایمیل، توضیح، Sub ID، UUID، رمز، احراز...",
"filterTitle": "فیلتر کاربران", "filterTitle": "فیلتر کاربران",
"clearAllFilters": "پاک کردن همه", "clearAllFilters": "پاک کردن همه",
@@ -691,10 +692,12 @@
"hasNot": "ندارد", "hasNot": "ندارد",
"title": "کلاینت‌ها", "title": "کلاینت‌ها",
"actions": "عملیات", "actions": "عملیات",
"totalGB": "مجموع ارسال/دریافت (گیگابایت)", "totalGB": "سقف حجم (گیگابایت)",
"totalGBDesc": "سهمیه‌ی حجم مصرفی کلاینت. ۰ = نامحدود",
"expiryTime": "انقضا", "expiryTime": "انقضا",
"addClients": "افزودن کلاینت‌ها", "addClients": "افزودن کلاینت‌ها",
"limitIp": "محدودیت IP", "limitIp": "محدودیت IP",
"limitIpDesc": "حداکثر تعداد IP همزمان. ۰ = نامحدود",
"password": "رمز عبور", "password": "رمز عبور",
"subId": "شناسه اشتراک", "subId": "شناسه اشتراک",
"online": "آنلاین", "online": "آنلاین",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Dasar", "tabBasics": "Dasar",
"tabConfig": "Konfigurasi", "tabCredentials": "Kredensial",
"add": "Tambah klien", "add": "Tambah klien",
"edit": "Ubah klien", "edit": "Ubah klien",
"submitAdd": "Tambah klien", "submitAdd": "Tambah klien",
@@ -666,10 +666,11 @@
"prefix": "Awalan", "prefix": "Awalan",
"postfix": "Akhiran", "postfix": "Akhiran",
"delayedStart": "Mulai setelah penggunaan pertama", "delayedStart": "Mulai setelah penggunaan pertama",
"expireDays": "Durasi", "expireDays": "Durasi (hari)",
"days": "Hari", "days": "Hari",
"renew": "Perpanjangan otomatis", "renew": "Perpanjangan otomatis",
"renewDesc": "Perpanjangan otomatis setelah kedaluwarsa. (0 = nonaktif) (satuan: hari)", "renewDesc": "Perpanjangan otomatis setelah kedaluwarsa. (0 = nonaktif) (satuan: hari)",
"renewDays": "Perpanjangan otomatis (hari)",
"searchPlaceholder": "Cari email, komentar, sub ID, UUID, kata sandi, auth…", "searchPlaceholder": "Cari email, komentar, sub ID, UUID, kata sandi, auth…",
"filterTitle": "Filter klien", "filterTitle": "Filter klien",
"clearAllFilters": "Hapus semua", "clearAllFilters": "Hapus semua",
@@ -691,10 +692,12 @@
"hasNot": "Tidak memiliki", "hasNot": "Tidak memiliki",
"title": "Klien", "title": "Klien",
"actions": "Aksi", "actions": "Aksi",
"totalGB": "Total Kirim/Terima (GB)", "totalGB": "Batas Trafik (GB)",
"totalGBDesc": "Kuota data untuk klien ini. 0 = tidak terbatas.",
"expiryTime": "Kedaluwarsa", "expiryTime": "Kedaluwarsa",
"addClients": "Tambah klien", "addClients": "Tambah klien",
"limitIp": "Batas IP", "limitIp": "Batas IP",
"limitIpDesc": "Jumlah maksimum IP bersamaan. 0 = tidak terbatas.",
"password": "Kata sandi", "password": "Kata sandi",
"subId": "ID Langganan", "subId": "ID Langganan",
"online": "Online", "online": "Online",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "基本", "tabBasics": "基本",
"tabConfig": "設定", "tabCredentials": "認証情報",
"add": "クライアントを追加", "add": "クライアントを追加",
"edit": "クライアントを編集", "edit": "クライアントを編集",
"submitAdd": "クライアントを追加", "submitAdd": "クライアントを追加",
@@ -666,10 +666,11 @@
"prefix": "プレフィックス", "prefix": "プレフィックス",
"postfix": "サフィックス", "postfix": "サフィックス",
"delayedStart": "初回使用から開始", "delayedStart": "初回使用から開始",
"expireDays": "期間", "expireDays": "期間 (日)",
"days": "日", "days": "日",
"renew": "自動更新", "renew": "自動更新",
"renewDesc": "有効期限切れ後に自動更新します。(0 = 無効) (単位: 日)", "renewDesc": "有効期限切れ後に自動更新します。(0 = 無効) (単位: 日)",
"renewDays": "自動更新 (日)",
"searchPlaceholder": "メール、コメント、sub ID、UUID、パスワード、auth を検索…", "searchPlaceholder": "メール、コメント、sub ID、UUID、パスワード、auth を検索…",
"filterTitle": "クライアントをフィルタ", "filterTitle": "クライアントをフィルタ",
"clearAllFilters": "すべてクリア", "clearAllFilters": "すべてクリア",
@@ -691,10 +692,12 @@
"hasNot": "なし", "hasNot": "なし",
"title": "クライアント", "title": "クライアント",
"actions": "操作", "actions": "操作",
"totalGB": "送受信合計 (GB)", "totalGB": "トラフィック上限 (GB)",
"totalGBDesc": "このクライアントのデータ割当量。0 = 無制限。",
"expiryTime": "有効期限", "expiryTime": "有効期限",
"addClients": "クライアントを追加", "addClients": "クライアントを追加",
"limitIp": "IP 制限", "limitIp": "IP 制限",
"limitIpDesc": "同時接続 IP の最大数。0 = 無制限。",
"password": "パスワード", "password": "パスワード",
"subId": "サブスクリプション ID", "subId": "サブスクリプション ID",
"online": "オンライン", "online": "オンライン",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Básico", "tabBasics": "Básico",
"tabConfig": "Configuração", "tabCredentials": "Credenciais",
"add": "Adicionar cliente", "add": "Adicionar cliente",
"edit": "Editar cliente", "edit": "Editar cliente",
"submitAdd": "Adicionar cliente", "submitAdd": "Adicionar cliente",
@@ -666,10 +666,11 @@
"prefix": "Prefixo", "prefix": "Prefixo",
"postfix": "Sufixo", "postfix": "Sufixo",
"delayedStart": "Iniciar após o primeiro uso", "delayedStart": "Iniciar após o primeiro uso",
"expireDays": "Duração", "expireDays": "Duração (dias)",
"days": "Dia(s)", "days": "Dia(s)",
"renew": "Renovação automática", "renew": "Renovação automática",
"renewDesc": "Renovação automática após a expiração. (0 = desativar) (unidade: dia)", "renewDesc": "Renovação automática após a expiração. (0 = desativar) (unidade: dia)",
"renewDays": "Renovação automática (dias)",
"searchPlaceholder": "Buscar email, comentário, sub ID, UUID, senha, auth…", "searchPlaceholder": "Buscar email, comentário, sub ID, UUID, senha, auth…",
"filterTitle": "Filtrar clientes", "filterTitle": "Filtrar clientes",
"clearAllFilters": "Limpar tudo", "clearAllFilters": "Limpar tudo",
@@ -691,10 +692,12 @@
"hasNot": "Não tem", "hasNot": "Não tem",
"title": "Clientes", "title": "Clientes",
"actions": "Ações", "actions": "Ações",
"totalGB": "Total enviado/recebido (GB)", "totalGB": "Limite de tráfego (GB)",
"totalGBDesc": "Cota de dados para este cliente. 0 = ilimitado.",
"expiryTime": "Expiração", "expiryTime": "Expiração",
"addClients": "Adicionar clientes", "addClients": "Adicionar clientes",
"limitIp": "Limite de IP", "limitIp": "Limite de IP",
"limitIpDesc": "Máximo de IPs simultâneos. 0 = ilimitado.",
"password": "Senha", "password": "Senha",
"subId": "ID da assinatura", "subId": "ID da assinatura",
"online": "Online", "online": "Online",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Основные", "tabBasics": "Основные",
"tabConfig": "Конфигурация", "tabCredentials": "Учетные данные",
"add": "Добавить клиента", "add": "Добавить клиента",
"edit": "Изменить клиента", "edit": "Изменить клиента",
"submitAdd": "Добавить клиента", "submitAdd": "Добавить клиента",
@@ -666,10 +666,11 @@
"prefix": "Префикс", "prefix": "Префикс",
"postfix": "Постфикс", "postfix": "Постфикс",
"delayedStart": "Старт после первого использования", "delayedStart": "Старт после первого использования",
"expireDays": "Длительность", "expireDays": "Длительность (дней)",
"days": "Дни", "days": "Дни",
"renew": "Автопродление", "renew": "Автопродление",
"renewDesc": "Автоматическое продление после окончания. (0 = отключено) (единица: день)", "renewDesc": "Автоматическое продление после окончания. (0 = отключено) (единица: день)",
"renewDays": "Автопродление (дней)",
"searchPlaceholder": "Поиск email, комментария, sub ID, UUID, пароля, auth…", "searchPlaceholder": "Поиск email, комментария, sub ID, UUID, пароля, auth…",
"filterTitle": "Фильтр клиентов", "filterTitle": "Фильтр клиентов",
"clearAllFilters": "Очистить все", "clearAllFilters": "Очистить все",
@@ -691,10 +692,12 @@
"hasNot": "Нет", "hasNot": "Нет",
"title": "Клиенты", "title": "Клиенты",
"actions": "Действия", "actions": "Действия",
"totalGB": "Всего отправлено/получено (ГБ)", "totalGB": "Лимит трафика (ГБ)",
"totalGBDesc": "Квота трафика для этого клиента. 0 = без ограничений.",
"expiryTime": "Срок действия", "expiryTime": "Срок действия",
"addClients": "Добавить клиентов", "addClients": "Добавить клиентов",
"limitIp": "Лимит IP", "limitIp": "Лимит IP",
"limitIpDesc": "Максимум одновременных IP-адресов. 0 = без ограничений.",
"password": "Пароль", "password": "Пароль",
"subId": "ID подписки", "subId": "ID подписки",
"online": "В сети", "online": "В сети",
+7 -4
View File
@@ -638,8 +638,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Temel", "tabBasics": "Temel",
"tabConfig": "Yapılandırma", "tabCredentials": "Kimlik Bilgileri",
"add": "Kullanıcı Ekle", "add": "Kullanıcı Ekle",
"edit": "Kullanıcıyı Düzenle", "edit": "Kullanıcıyı Düzenle",
"submitAdd": "Kullanıcı Ekle", "submitAdd": "Kullanıcı Ekle",
@@ -667,10 +667,11 @@
"prefix": "Önek", "prefix": "Önek",
"postfix": "Sonek", "postfix": "Sonek",
"delayedStart": "İlk Kullanımdan Sonra Başla", "delayedStart": "İlk Kullanımdan Sonra Başla",
"expireDays": "Süre", "expireDays": "Süre (gün)",
"days": "Gün(ler)", "days": "Gün(ler)",
"renew": "Otomatik Yenileme", "renew": "Otomatik Yenileme",
"renewDesc": "Süre dolduktan sonra otomatik yeniler. (0 = devre dışı) (birim: gün)", "renewDesc": "Süre dolduktan sonra otomatik yeniler. (0 = devre dışı) (birim: gün)",
"renewDays": "Otomatik Yenileme (gün)",
"searchPlaceholder": "E-posta, yorum, sub ID, UUID, parola, auth ara…", "searchPlaceholder": "E-posta, yorum, sub ID, UUID, parola, auth ara…",
"filterTitle": "Kullanıcıları Filtrele", "filterTitle": "Kullanıcıları Filtrele",
"clearAllFilters": "Tümünü Temizle", "clearAllFilters": "Tümünü Temizle",
@@ -692,10 +693,12 @@
"hasNot": "Yok", "hasNot": "Yok",
"title": "Kullanıcılar", "title": "Kullanıcılar",
"actions": "İşlemler", "actions": "İşlemler",
"totalGB": "Toplam Gönderilen/Alınan (GB)", "totalGB": "Trafik Limiti (GB)",
"totalGBDesc": "Bu kullanıcı için veri kotası. 0 = sınırsız.",
"expiryTime": "Son Kullanma", "expiryTime": "Son Kullanma",
"addClients": "Kullanıcı Ekle", "addClients": "Kullanıcı Ekle",
"limitIp": "IP Limiti", "limitIp": "IP Limiti",
"limitIpDesc": "Eş zamanlı en fazla IP sayısı. 0 = sınırsız.",
"password": "Şifre", "password": "Şifre",
"subId": "Abonelik ID'si", "subId": "Abonelik ID'si",
"online": "Çevrimiçi", "online": "Çevrimiçi",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Основні", "tabBasics": "Основні",
"tabConfig": "Конфігурація", "tabCredentials": "Облікові дані",
"add": "Додати клієнта", "add": "Додати клієнта",
"edit": "Редагувати клієнта", "edit": "Редагувати клієнта",
"submitAdd": "Додати клієнта", "submitAdd": "Додати клієнта",
@@ -666,10 +666,11 @@
"prefix": "Префікс", "prefix": "Префікс",
"postfix": "Постфікс", "postfix": "Постфікс",
"delayedStart": "Запуск після першого використання", "delayedStart": "Запуск після першого використання",
"expireDays": "Тривалість", "expireDays": "Тривалість (днів)",
"days": "Дні", "days": "Дні",
"renew": "Авто-продовження", "renew": "Авто-продовження",
"renewDesc": "Автоматичне продовження після закінчення. (0 = вимкнено) (одиниця: день)", "renewDesc": "Автоматичне продовження після закінчення. (0 = вимкнено) (одиниця: день)",
"renewDays": "Авто-продовження (днів)",
"searchPlaceholder": "Пошук email, коментаря, sub ID, UUID, паролю, auth…", "searchPlaceholder": "Пошук email, коментаря, sub ID, UUID, паролю, auth…",
"filterTitle": "Фільтр клієнтів", "filterTitle": "Фільтр клієнтів",
"clearAllFilters": "Очистити все", "clearAllFilters": "Очистити все",
@@ -691,10 +692,12 @@
"hasNot": "Не має", "hasNot": "Не має",
"title": "Клієнти", "title": "Клієнти",
"actions": "Дії", "actions": "Дії",
"totalGB": "Усього надіслано/отримано (ГБ)", "totalGB": "Ліміт трафіку (ГБ)",
"totalGBDesc": "Квота трафіку для цього клієнта. 0 = без обмежень.",
"expiryTime": "Термін дії", "expiryTime": "Термін дії",
"addClients": "Додати клієнтів", "addClients": "Додати клієнтів",
"limitIp": "Ліміт IP", "limitIp": "Ліміт IP",
"limitIpDesc": "Максимум одночасних IP-адрес. 0 = без обмежень.",
"password": "Пароль", "password": "Пароль",
"subId": "ID підписки", "subId": "ID підписки",
"online": "У мережі", "online": "У мережі",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "Cơ bản", "tabBasics": "Cơ bản",
"tabConfig": "Cấu hình", "tabCredentials": "Thông tin xác thực",
"add": "Thêm khách hàng", "add": "Thêm khách hàng",
"edit": "Chỉnh sửa khách hàng", "edit": "Chỉnh sửa khách hàng",
"submitAdd": "Thêm khách hàng", "submitAdd": "Thêm khách hàng",
@@ -666,10 +666,11 @@
"prefix": "Tiền tố", "prefix": "Tiền tố",
"postfix": "Hậu tố", "postfix": "Hậu tố",
"delayedStart": "Bắt đầu sau lần dùng đầu", "delayedStart": "Bắt đầu sau lần dùng đầu",
"expireDays": "Thời hạn", "expireDays": "Thời hạn (ngày)",
"days": "Ngày", "days": "Ngày",
"renew": "Tự động gia hạn", "renew": "Tự động gia hạn",
"renewDesc": "Tự động gia hạn sau khi hết hạn. (0 = tắt) (đơn vị: ngày)", "renewDesc": "Tự động gia hạn sau khi hết hạn. (0 = tắt) (đơn vị: ngày)",
"renewDays": "Tự động gia hạn (ngày)",
"searchPlaceholder": "Tìm email, ghi chú, sub ID, UUID, mật khẩu, auth…", "searchPlaceholder": "Tìm email, ghi chú, sub ID, UUID, mật khẩu, auth…",
"filterTitle": "Lọc client", "filterTitle": "Lọc client",
"clearAllFilters": "Xóa tất cả", "clearAllFilters": "Xóa tất cả",
@@ -691,10 +692,12 @@
"hasNot": "Không có", "hasNot": "Không có",
"title": "Khách hàng", "title": "Khách hàng",
"actions": "Hành động", "actions": "Hành động",
"totalGB": "Tổng gửi/nhận (GB)", "totalGB": "Giới hạn lưu lượng (GB)",
"totalGBDesc": "Hạn mức dữ liệu cho khách hàng này. 0 = không giới hạn.",
"expiryTime": "Hết hạn", "expiryTime": "Hết hạn",
"addClients": "Thêm khách hàng", "addClients": "Thêm khách hàng",
"limitIp": "Giới hạn IP", "limitIp": "Giới hạn IP",
"limitIpDesc": "Số IP đồng thời tối đa. 0 = không giới hạn.",
"password": "Mật khẩu", "password": "Mật khẩu",
"subId": "ID đăng ký", "subId": "ID đăng ký",
"online": "Trực tuyến", "online": "Trực tuyến",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "基本", "tabBasics": "基本",
"tabConfig": "配置", "tabCredentials": "凭据",
"add": "添加客户端", "add": "添加客户端",
"edit": "编辑客户端", "edit": "编辑客户端",
"submitAdd": "添加客户端", "submitAdd": "添加客户端",
@@ -666,10 +666,11 @@
"prefix": "前缀", "prefix": "前缀",
"postfix": "后缀", "postfix": "后缀",
"delayedStart": "首次使用后开始", "delayedStart": "首次使用后开始",
"expireDays": "时长", "expireDays": "时长 (天)",
"days": "天", "days": "天",
"renew": "自动续期", "renew": "自动续期",
"renewDesc": "到期后自动续期。(0 = 禁用) (单位: 天)", "renewDesc": "到期后自动续期。(0 = 禁用) (单位: 天)",
"renewDays": "自动续期 (天)",
"searchPlaceholder": "搜索邮箱、备注、sub ID、UUID、密码、auth…", "searchPlaceholder": "搜索邮箱、备注、sub ID、UUID、密码、auth…",
"filterTitle": "筛选客户端", "filterTitle": "筛选客户端",
"clearAllFilters": "清除全部", "clearAllFilters": "清除全部",
@@ -691,10 +692,12 @@
"hasNot": "不拥有", "hasNot": "不拥有",
"title": "客户端", "title": "客户端",
"actions": "操作", "actions": "操作",
"totalGB": "总上传/下载 (GB)", "totalGB": "流量上限 (GB)",
"totalGBDesc": "该客户端的流量配额。0 = 不限制。",
"expiryTime": "过期时间", "expiryTime": "过期时间",
"addClients": "添加客户端", "addClients": "添加客户端",
"limitIp": "IP 限制", "limitIp": "IP 限制",
"limitIpDesc": "最大同时连接 IP 数。0 = 不限制。",
"password": "密码", "password": "密码",
"subId": "订阅 ID", "subId": "订阅 ID",
"online": "在线", "online": "在线",
+7 -4
View File
@@ -637,8 +637,8 @@
} }
}, },
"clients": { "clients": {
"tabBasic": "基本", "tabBasics": "基本",
"tabConfig": "配置", "tabCredentials": "認證資訊",
"add": "新增客戶端", "add": "新增客戶端",
"edit": "編輯客戶端", "edit": "編輯客戶端",
"submitAdd": "新增客戶端", "submitAdd": "新增客戶端",
@@ -666,10 +666,11 @@
"prefix": "前綴", "prefix": "前綴",
"postfix": "後綴", "postfix": "後綴",
"delayedStart": "首次使用後開始", "delayedStart": "首次使用後開始",
"expireDays": "時長", "expireDays": "時長 (天)",
"days": "天", "days": "天",
"renew": "自動續期", "renew": "自動續期",
"renewDesc": "到期後自動續期。(0 = 停用) (單位: 天)", "renewDesc": "到期後自動續期。(0 = 停用) (單位: 天)",
"renewDays": "自動續期 (天)",
"searchPlaceholder": "搜尋電子郵件、備註、sub ID、UUID、密碼、auth…", "searchPlaceholder": "搜尋電子郵件、備註、sub ID、UUID、密碼、auth…",
"filterTitle": "篩選客戶端", "filterTitle": "篩選客戶端",
"clearAllFilters": "清除全部", "clearAllFilters": "清除全部",
@@ -691,10 +692,12 @@
"hasNot": "不擁有", "hasNot": "不擁有",
"title": "客戶端", "title": "客戶端",
"actions": "操作", "actions": "操作",
"totalGB": "總上傳/下載 (GB)", "totalGB": "流量上限 (GB)",
"totalGBDesc": "該客戶端的流量配額。0 = 不限制。",
"expiryTime": "到期時間", "expiryTime": "到期時間",
"addClients": "新增客戶端", "addClients": "新增客戶端",
"limitIp": "IP 限制", "limitIp": "IP 限制",
"limitIpDesc": "最大同時連線 IP 數。0 = 不限制。",
"password": "密碼", "password": "密碼",
"subId": "訂閱 ID", "subId": "訂閱 ID",
"online": "上線", "online": "上線",