feat: Восстановить классические карточки добавления новых ASN, доменов и IP-диапазонов в соответствующих менеджерах, улучшив интерфейс для ввода данных пользователем
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m49s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m49s
This commit is contained in:
@@ -466,6 +466,64 @@ function ASNsNewManager() {
|
|||||||
/>
|
/>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-3">
|
<div className="col-lg-3">
|
||||||
|
{/* Classic Add New ASN Card (restored) */}
|
||||||
|
<div className="card card-md">
|
||||||
|
<div className="card-header">
|
||||||
|
<h3 className="card-title">
|
||||||
|
<IconPlus className="icon me-2" />
|
||||||
|
Добавить новый ASN
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<form onSubmit={(e) => { e.preventDefault(); handleAddItem(); }}>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Номер AS</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className={`form-control${newInvalid.asn ? ' is-invalid' : ''}`}
|
||||||
|
placeholder="12345"
|
||||||
|
value={newItem.asn}
|
||||||
|
onChange={(e) => setNewItem({ ...newItem, asn: e.target.value })}
|
||||||
|
/>
|
||||||
|
{newInvalid.asn && <div className="invalid-feedback">Только цифры</div>}
|
||||||
|
<div className="form-text">Формат: только цифры, например 12345</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Community</label>
|
||||||
|
<CommunityAutocompleteInput
|
||||||
|
value={newItem.community}
|
||||||
|
onChange={(v) => setNewItem({ ...newItem, community: v })}
|
||||||
|
communities={communities}
|
||||||
|
placeholder="Начните вводить номер или имя"
|
||||||
|
className={`form-control${newInvalid.community ? ' is-invalid' : ''}`}
|
||||||
|
/>
|
||||||
|
{newInvalid.community && <div className="invalid-feedback">Только цифры</div>}
|
||||||
|
<div className="form-text">Формат: N или N:N (например 65000:100)</div>
|
||||||
|
{(() => {
|
||||||
|
const match = communities.find(c => c.value === String(newItem.community).trim());
|
||||||
|
if (!match) return null;
|
||||||
|
return (
|
||||||
|
<div className="form-text">
|
||||||
|
{match.name && (<><strong>{match.name}</strong> — </>)}
|
||||||
|
{match.description || ''}
|
||||||
|
{match.tags && match.tags.length > 0 && (
|
||||||
|
<> (<span className="text-muted">{match.tags.join(', ')}</span>)</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
<div className="form-footer">
|
||||||
|
<button type="submit" className="btn btn-primary w-100">
|
||||||
|
<IconPlus className="icon me-2" />
|
||||||
|
Добавить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* QuickAdd stays for batch input */}
|
||||||
<QuickAddBar
|
<QuickAddBar
|
||||||
placeholder={'12345 65000:100'}
|
placeholder={'12345 65000:100'}
|
||||||
help={'Вставьте строки: ASN ПРОБЕЛ COMMUNITY'}
|
help={'Вставьте строки: ASN ПРОБЕЛ COMMUNITY'}
|
||||||
|
|||||||
@@ -471,6 +471,65 @@ function DomainsNewManager() {
|
|||||||
/>
|
/>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-3">
|
<div className="col-lg-3">
|
||||||
|
{/* Classic Add New Domain Card (restored) */}
|
||||||
|
<div className="card card-md">
|
||||||
|
<div className="card-header">
|
||||||
|
<h3 className="card-title">
|
||||||
|
<IconPlus className="icon me-2" />
|
||||||
|
Добавить новый домен
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<form onSubmit={(e) => { e.preventDefault(); handleAddItem(); }}>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Домен</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className={`form-control${newInvalid.domain ? ' is-invalid' : ''}`}
|
||||||
|
placeholder="example.com"
|
||||||
|
value={newItem.domain}
|
||||||
|
onChange={(e) => setNewItem({ ...newItem, domain: e.target.value })}
|
||||||
|
/>
|
||||||
|
{newInvalid.domain && <div className="invalid-feedback">Неверный формат домена</div>}
|
||||||
|
<div className="form-text">Без http/https, только доменное имя</div>
|
||||||
|
<div className="form-text">Формат: sub.domain.tld (например foo.example.org)</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Community</label>
|
||||||
|
<CommunityAutocompleteInput
|
||||||
|
value={newItem.community}
|
||||||
|
onChange={(v) => setNewItem({ ...newItem, community: v })}
|
||||||
|
communities={communities}
|
||||||
|
placeholder="Начните вводить номер или имя"
|
||||||
|
className={`form-control${newInvalid.community ? ' is-invalid' : ''}`}
|
||||||
|
/>
|
||||||
|
{newInvalid.community && <div className="invalid-feedback">Только цифры</div>}
|
||||||
|
<div className="form-text">Формат: N или N:N (например 65000:100)</div>
|
||||||
|
{(() => {
|
||||||
|
const match = communities.find(c => c.value === String(newItem.community).trim());
|
||||||
|
if (!match) return null;
|
||||||
|
return (
|
||||||
|
<div className="form-text">
|
||||||
|
{match.name && (<><strong>{match.name}</strong> — </>)}
|
||||||
|
{match.description || ''}
|
||||||
|
{match.tags && match.tags.length > 0 && (
|
||||||
|
<> (<span className="text-muted">{match.tags.join(', ')}</span>)</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
<div className="form-footer">
|
||||||
|
<button type="submit" className="btn btn-primary w-100">
|
||||||
|
<IconPlus className="icon me-2" />
|
||||||
|
Добавить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* QuickAdd stays for batch input */}
|
||||||
<QuickAddBar
|
<QuickAddBar
|
||||||
placeholder={'example.com 65000:100'}
|
placeholder={'example.com 65000:100'}
|
||||||
help={'Вставьте строки: DOMAIN ПРОБЕЛ COMMUNITY'}
|
help={'Вставьте строки: DOMAIN ПРОБЕЛ COMMUNITY'}
|
||||||
|
|||||||
@@ -723,6 +723,63 @@ function IPRangesManager() {
|
|||||||
/>
|
/>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-3">
|
<div className="col-lg-3">
|
||||||
|
{/* Classic Add New Item Card (restored) */}
|
||||||
|
<div className="card card-md">
|
||||||
|
<div className="card-header">
|
||||||
|
<h3 className="card-title">
|
||||||
|
<IconPlus className="icon me-2" />
|
||||||
|
Добавить новый IP-диапазон
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<form onSubmit={(e) => { e.preventDefault(); handleAddItem(); }}>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">IP-диапазон</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className={`form-control${newInvalid.ipRange ? ' is-invalid' : ''}`}
|
||||||
|
placeholder="192.168.1.0/24"
|
||||||
|
value={newItem.ipRange}
|
||||||
|
onChange={(e) => setNewItem({ ...newItem, ipRange: e.target.value })}
|
||||||
|
/>
|
||||||
|
{newInvalid.ipRange && <div className="invalid-feedback">Некорректный CIDR</div>}
|
||||||
|
<div className="form-text">Формат: A.B.C.D/Маска, например 10.0.0.0/24</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label">Community</label>
|
||||||
|
<CommunityAutocompleteInput
|
||||||
|
value={newItem.community}
|
||||||
|
onChange={(v) => setNewItem({ ...newItem, community: v })}
|
||||||
|
communities={communities}
|
||||||
|
placeholder="Начните вводить номер или имя"
|
||||||
|
className={`form-control${newInvalid.community ? ' is-invalid' : ''}`}
|
||||||
|
/>
|
||||||
|
{newInvalid.community && <div className="invalid-feedback">Только цифры</div>}
|
||||||
|
{(() => {
|
||||||
|
const match = communities.find(c => c.value === String(newItem.community).trim());
|
||||||
|
if (!match) return null;
|
||||||
|
return (
|
||||||
|
<div className="form-text">
|
||||||
|
{match.name && (<><strong>{match.name}</strong> — </>)}
|
||||||
|
{match.description || ''}
|
||||||
|
{match.tags && match.tags.length > 0 && (
|
||||||
|
<> (<span className="text-muted">{match.tags.join(', ')}</span>)</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
<div className="form-footer">
|
||||||
|
<button type="submit" className="btn btn-primary w-100">
|
||||||
|
<IconPlus className="icon me-2" />
|
||||||
|
Добавить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* QuickAdd stays for batch input */}
|
||||||
<QuickAddBar
|
<QuickAddBar
|
||||||
placeholder={'192.168.1.0/24 65000:100'}
|
placeholder={'192.168.1.0/24 65000:100'}
|
||||||
help={'Вставьте строки: CIDR ПРОБЕЛ COMMUNITY'}
|
help={'Вставьте строки: CIDR ПРОБЕЛ COMMUNITY'}
|
||||||
|
|||||||
Reference in New Issue
Block a user