refactor: Update Mikrotik config validation logic to improve brace counting accuracy and enhance AutoUrlManager UI with consistent card layouts, larger icons, and refined button styles for better user experience.
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m50s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m50s
This commit is contained in:
@@ -39,8 +39,11 @@ function validateMikrotikConfig(config) {
|
||||
inBlock = true;
|
||||
blockName = line.match(/^\/\w+(\s+\w+)*/)?.[0] || '';
|
||||
currentBlockLine = lineNum;
|
||||
braceBalance++;
|
||||
continue;
|
||||
// Считаем скобки только один раз для этой строки (чтобы не дублировать подсчёт ниже)
|
||||
const openBraces = (line.match(/\{/g) || []).length;
|
||||
const closeBraces = (line.match(/\}/g) || []).length;
|
||||
braceBalance += openBraces - closeBraces;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Подсчет фигурных скобок
|
||||
|
||||
@@ -385,69 +385,53 @@ function AutoUrlManager() {
|
||||
{!loading && urls.length > 0 && (
|
||||
<div className="row g-3 mb-4">
|
||||
<div className="col-md-3">
|
||||
<div className="card card-sm">
|
||||
<div className="card-body">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-auto">
|
||||
<span className="avatar avatar-lg bg-blue-lt text-blue">
|
||||
<IconWorld size={24} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="font-weight-medium">{stats.total}</div>
|
||||
<div className="text-muted small">Всего URL</div>
|
||||
</div>
|
||||
<div className="card h-100">
|
||||
<div className="card-body d-flex align-items-center">
|
||||
<span className="avatar avatar-lg me-3 bg-blue-lt text-blue border-0">
|
||||
<IconWorld size={32} />
|
||||
</span>
|
||||
<div>
|
||||
<div className="h3 mb-0 fw-bold">{stats.total}</div>
|
||||
<div className="text-muted small">Всего URL</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<div className="card card-sm">
|
||||
<div className="card-body">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-auto">
|
||||
<span className="avatar avatar-lg bg-green-lt text-green">
|
||||
<IconCheck size={24} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="font-weight-medium">{stats.valid}</div>
|
||||
<div className="text-muted small">Валидных</div>
|
||||
</div>
|
||||
<div className="card h-100">
|
||||
<div className="card-body d-flex align-items-center">
|
||||
<span className="avatar avatar-lg me-3 bg-green-lt text-green border-0">
|
||||
<IconCheck size={32} />
|
||||
</span>
|
||||
<div>
|
||||
<div className="h3 mb-0 fw-bold">{stats.valid}</div>
|
||||
<div className="text-muted small">Валидных</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<div className="card card-sm">
|
||||
<div className="card-body">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-auto">
|
||||
<span className="avatar avatar-lg bg-red-lt text-red">
|
||||
<IconAlertCircle size={24} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="font-weight-medium">{stats.invalid}</div>
|
||||
<div className="text-muted small">Невалидных</div>
|
||||
</div>
|
||||
<div className="card h-100">
|
||||
<div className="card-body d-flex align-items-center">
|
||||
<span className="avatar avatar-lg me-3 bg-red-lt text-red border-0">
|
||||
<IconAlertCircle size={32} />
|
||||
</span>
|
||||
<div>
|
||||
<div className="h3 mb-0 fw-bold">{stats.invalid}</div>
|
||||
<div className="text-muted small">Невалидных</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<div className="card card-sm">
|
||||
<div className="card-body">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-auto">
|
||||
<span className="avatar avatar-lg bg-orange-lt text-orange">
|
||||
<IconLink size={24} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="font-weight-medium">{filteredAndSortedUrls.length}</div>
|
||||
<div className="text-muted small">Отображается</div>
|
||||
</div>
|
||||
<div className="card h-100">
|
||||
<div className="card-body d-flex align-items-center">
|
||||
<span className="avatar avatar-lg me-3 bg-azure-lt text-azure border-0">
|
||||
<IconLink size={32} />
|
||||
</span>
|
||||
<div>
|
||||
<div className="h3 mb-0 fw-bold">{filteredAndSortedUrls.length}</div>
|
||||
<div className="text-muted small">Отображается</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -465,8 +449,8 @@ function AutoUrlManager() {
|
||||
</h3>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<div className="input-group" style={{ maxWidth: 300 }}>
|
||||
<span className="input-group-text">
|
||||
<div className="input-icon" style={{ maxWidth: 320 }}>
|
||||
<span className="input-icon-addon">
|
||||
<IconSearch size={16} />
|
||||
</span>
|
||||
<input
|
||||
@@ -479,7 +463,7 @@ function AutoUrlManager() {
|
||||
/>
|
||||
{searchTerm && (
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
className="btn btn-icon btn-sm btn-outline-secondary position-absolute top-50 end-0 translate-middle-y me-1"
|
||||
type="button"
|
||||
onClick={() => setSearchTerm('')}
|
||||
title="Очистить поиск"
|
||||
@@ -490,16 +474,16 @@ function AutoUrlManager() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<div className="btn-group">
|
||||
<div className="btn-group btn-group-sm">
|
||||
<button
|
||||
className={`btn btn-sm ${filterValid === 'all' ? 'btn-primary' : 'btn-outline-secondary'}`}
|
||||
className={`btn ${filterValid === 'all' ? 'btn-primary' : 'btn-outline-secondary'}`}
|
||||
onClick={() => setFilterValid('all')}
|
||||
title="Все записи"
|
||||
>
|
||||
Все
|
||||
</button>
|
||||
<button
|
||||
className={`btn btn-sm ${filterValid === 'valid' ? 'btn-success' : 'btn-outline-success'}`}
|
||||
className={`btn ${filterValid === 'valid' ? 'btn-success' : 'btn-outline-success'}`}
|
||||
onClick={() => setFilterValid('valid')}
|
||||
title="Только валидные"
|
||||
>
|
||||
@@ -507,7 +491,7 @@ function AutoUrlManager() {
|
||||
Валидные
|
||||
</button>
|
||||
<button
|
||||
className={`btn btn-sm ${filterValid === 'invalid' ? 'btn-danger' : 'btn-outline-danger'}`}
|
||||
className={`btn ${filterValid === 'invalid' ? 'btn-danger' : 'btn-outline-danger'}`}
|
||||
onClick={() => setFilterValid('invalid')}
|
||||
title="Только невалидные"
|
||||
>
|
||||
@@ -647,7 +631,7 @@ function AutoUrlManager() {
|
||||
return (
|
||||
<tr
|
||||
key={originalIndex}
|
||||
className={`${isSelected ? 'table-active' : ''} ${isInvalid ? 'table-danger' : isValid ? 'table-success' : ''}`}
|
||||
className={isSelected ? 'table-active' : ''}
|
||||
>
|
||||
<td>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user