mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-13 14:50:59 +00:00
i18n(panel): migrate hardcoded panel strings to en-US and translate all locales
Surface ~400 hardcoded English labels, tooltips, placeholders, dt/divider text, modal okText/cancelText, and Spin loading from the panel pages (clients/groups/inbounds/nodes/settings/xray/sub/index) into web/translation/en-US.json under existing pages.<page>.* namespaces, with JSX swapped to t(...). Brand and protocol identifiers (TLS, MTU, SNI, NordVPN, Cloudflare WARP, etc.) stay literal. Sync all 12 non-English locales (ar-EG, es-ES, fa-IR, id-ID, ja-JP, pt-BR, ru-RU, tr-TR, uk-UA, vi-VN, zh-CN, zh-TW) to match en-US's structure and translate the 521 new key paths per locale. Every locale file now has 1539 lines, mirroring en-US ordering. Also remove a dead duplicate "info": "Info" key under pages.inbounds that collided with the new pages.inbounds.info.* object. Backend: bulk attach/detach errors in web/service/client.go now route through logger.Warningf (so they appear under /panel/api/server/logs/) instead of only living on the response payload.
This commit is contained in:
@@ -160,8 +160,8 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
|
||||
|
||||
<SettingListItem
|
||||
paddings="small"
|
||||
title="Trusted proxy CIDRs"
|
||||
description="Comma-separated IPs/CIDRs allowed to set forwarded host, proto, and client IP headers."
|
||||
title={t('pages.settings.trustedProxyCidrs')}
|
||||
description={t('pages.settings.trustedProxyCidrsDesc')}
|
||||
>
|
||||
<Input
|
||||
value={allSetting.trustedProxyCIDRs}
|
||||
@@ -271,58 +271,58 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
|
||||
label: 'LDAP',
|
||||
children: (
|
||||
<>
|
||||
<SettingListItem paddings="small" title="Enable LDAP sync">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.enable')}>
|
||||
<Switch checked={allSetting.ldapEnable} onChange={(v) => updateSetting({ ldapEnable: v })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="LDAP host">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.host')}>
|
||||
<Input value={allSetting.ldapHost} onChange={(e) => updateSetting({ ldapHost: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="LDAP port">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.port')}>
|
||||
<InputNumber value={allSetting.ldapPort} min={1} max={65535} style={{ width: '100%' }}
|
||||
onChange={(v) => updateSetting({ ldapPort: Number(v) || 0 })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Use TLS (LDAPS)">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.useTls')}>
|
||||
<Switch checked={allSetting.ldapUseTLS} onChange={(v) => updateSetting({ ldapUseTLS: v })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Bind DN">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.bindDn')}>
|
||||
<Input value={allSetting.ldapBindDN} onChange={(e) => updateSetting({ ldapBindDN: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem
|
||||
paddings="small"
|
||||
title={t('password')}
|
||||
description={allSetting.hasLdapPassword ? 'Configured; leave blank to keep current password.' : 'Not configured.'}
|
||||
description={allSetting.hasLdapPassword ? t('pages.settings.ldap.passwordConfigured') : t('pages.settings.ldap.passwordUnconfigured')}
|
||||
>
|
||||
<Input.Password
|
||||
value={allSetting.ldapPassword}
|
||||
placeholder={allSetting.hasLdapPassword ? 'Configured - enter a new value to replace' : ''}
|
||||
placeholder={allSetting.hasLdapPassword ? t('pages.settings.ldap.passwordPlaceholder') : ''}
|
||||
onChange={(e) => updateSetting({ ldapPassword: e.target.value })}
|
||||
/>
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Base DN">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.baseDn')}>
|
||||
<Input value={allSetting.ldapBaseDN} onChange={(e) => updateSetting({ ldapBaseDN: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="User filter">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.userFilter')}>
|
||||
<Input value={allSetting.ldapUserFilter} onChange={(e) => updateSetting({ ldapUserFilter: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="User attribute (username/email)">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.userAttr')}>
|
||||
<Input value={allSetting.ldapUserAttr} onChange={(e) => updateSetting({ ldapUserAttr: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="VLESS flag attribute">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.vlessField')}>
|
||||
<Input value={allSetting.ldapVlessField} onChange={(e) => updateSetting({ ldapVlessField: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Generic flag attribute (optional)" description="If set, overrides VLESS flag — e.g. shadowInactive.">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.flagField')} description={t('pages.settings.ldap.flagFieldDesc')}>
|
||||
<Input value={allSetting.ldapFlagField} onChange={(e) => updateSetting({ ldapFlagField: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Truthy values" description="Comma-separated; default: true,1,yes,on">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.truthyValues')} description={t('pages.settings.ldap.truthyValuesDesc')}>
|
||||
<Input value={allSetting.ldapTruthyValues} onChange={(e) => updateSetting({ ldapTruthyValues: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Invert flag" description="Enable when the attribute means disabled (e.g. shadowInactive).">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.invertFlag')} description={t('pages.settings.ldap.invertFlagDesc')}>
|
||||
<Switch checked={allSetting.ldapInvertFlag} onChange={(v) => updateSetting({ ldapInvertFlag: v })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Sync schedule" description="Cron-like string, e.g. @every 1m">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.syncSchedule')} description={t('pages.settings.ldap.syncScheduleDesc')}>
|
||||
<Input value={allSetting.ldapSyncCron} onChange={(e) => updateSetting({ ldapSyncCron: e.target.value })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Inbound tags" description="Inbounds that LDAP sync may auto-create or auto-delete clients on.">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.inboundTags')} description={t('pages.settings.ldap.inboundTagsDesc')}>
|
||||
<>
|
||||
<Select
|
||||
mode="multiple"
|
||||
@@ -332,25 +332,25 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
|
||||
options={inboundOptions}
|
||||
/>
|
||||
{inboundOptions.length === 0 && (
|
||||
<div className="ldap-no-inbounds">No inbounds found. Create one in Inbounds first.</div>
|
||||
<div className="ldap-no-inbounds">{t('pages.settings.ldap.noInbounds')}</div>
|
||||
)}
|
||||
</>
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Auto create clients">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.autoCreate')}>
|
||||
<Switch checked={allSetting.ldapAutoCreate} onChange={(v) => updateSetting({ ldapAutoCreate: v })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Auto delete clients">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.autoDelete')}>
|
||||
<Switch checked={allSetting.ldapAutoDelete} onChange={(v) => updateSetting({ ldapAutoDelete: v })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Default total (GB)">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.defaultTotalGb')}>
|
||||
<InputNumber value={allSetting.ldapDefaultTotalGB} min={0} style={{ width: '100%' }}
|
||||
onChange={(v) => updateSetting({ ldapDefaultTotalGB: Number(v) || 0 })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Default expiry (days)">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.defaultExpiryDays')}>
|
||||
<InputNumber value={allSetting.ldapDefaultExpiryDays} min={0} style={{ width: '100%' }}
|
||||
onChange={(v) => updateSetting({ ldapDefaultExpiryDays: Number(v) || 0 })} />
|
||||
</SettingListItem>
|
||||
<SettingListItem paddings="small" title="Default IP limit">
|
||||
<SettingListItem paddings="small" title={t('pages.settings.ldap.defaultIpLimit')}>
|
||||
<InputNumber value={allSetting.ldapDefaultLimitIP} min={0} style={{ width: '100%' }}
|
||||
onChange={(v) => updateSetting({ ldapDefaultLimitIP: Number(v) || 0 })} />
|
||||
</SettingListItem>
|
||||
|
||||
Reference in New Issue
Block a user