refactor(ServerGroupCard): update layout and improve server information display in expanded view
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m53s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m53s
This commit is contained in:
@@ -38,7 +38,6 @@ export default function ServerGroupCard({
|
|||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const first = servers[0];
|
const first = servers[0];
|
||||||
const title = groupKey || (first?.dns?.split('.')[0] || 'Группа');
|
const title = groupKey || (first?.dns?.split('.')[0] || 'Группа');
|
||||||
const provider = first?.provider || '';
|
|
||||||
const tunnel = first?.tunnel;
|
const tunnel = first?.tunnel;
|
||||||
const wanCount = servers.length;
|
const wanCount = servers.length;
|
||||||
const anySelected = servers.some((s) => selectedSet.has(s.ip));
|
const anySelected = servers.some((s) => selectedSet.has(s.ip));
|
||||||
@@ -81,7 +80,7 @@ export default function ServerGroupCard({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Центр: флаг, название, провайдер; ниже DNS и теги */}
|
{/* Центр: в свёрнутом виде — все провайдеры и домены, чтобы было однозначно */}
|
||||||
<div
|
<div
|
||||||
className="flex-grow-1 py-2 px-3"
|
className="flex-grow-1 py-2 px-3"
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
@@ -91,21 +90,22 @@ export default function ServerGroupCard({
|
|||||||
<span className="me-2" style={{ fontSize: '1.25rem' }}>{countryToFlag(first?.country)}</span>
|
<span className="me-2" style={{ fontSize: '1.25rem' }}>{countryToFlag(first?.country)}</span>
|
||||||
<div>
|
<div>
|
||||||
<span className="fw-semibold">{title}</span>
|
<span className="fw-semibold">{title}</span>
|
||||||
{provider && (
|
<span className="text-muted ms-2">· мультиван</span>
|
||||||
<>
|
|
||||||
<span className="text-muted mx-2">•</span>
|
|
||||||
<span className="text-muted">{provider}</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<span className="badge bg-success-lt text-success ms-auto">
|
<span className="badge bg-success-lt text-success ms-auto">
|
||||||
{wanCount} WAN
|
{wanCount} WAN
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex align-items-center gap-2">
|
<div className="d-flex flex-wrap align-items-center gap-2">
|
||||||
<code className="text-muted" style={{ fontSize: '0.8rem' }}>
|
<span className="text-muted small">
|
||||||
{first?.dns || first?.ip || ''}
|
{servers.map((s) => s.dns?.split('.')[0] || s.ip).join(', ')}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted small">—</span>
|
||||||
|
{servers.map((s, i) => (
|
||||||
|
<code key={s.id || s.ip} className="text-muted" style={{ fontSize: '0.75rem' }}>
|
||||||
|
{s.dns || s.ip}{i < servers.length - 1 ? ' · ' : ''}
|
||||||
</code>
|
</code>
|
||||||
|
))}
|
||||||
{tunnel && (
|
{tunnel && (
|
||||||
<span className="badge bg-secondary-lt text-secondary">
|
<span className="badge bg-secondary-lt text-secondary">
|
||||||
<IconNetwork size={12} className="me-1" />
|
<IconNetwork size={12} className="me-1" />
|
||||||
@@ -147,9 +147,20 @@ export default function ServerGroupCard({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Развёрнутый список WAN */}
|
{/* Развёрнутый список WAN: визуально отделённый блок, у каждой строки — бейдж HOME */}
|
||||||
{expanded && (
|
{expanded && (
|
||||||
<div className="border-top bg-light" style={{ borderBottomLeftRadius: '7px', borderBottomRightRadius: '7px' }}>
|
<div
|
||||||
|
className="border-top border-start border-3 border-green bg-green-lt"
|
||||||
|
style={{
|
||||||
|
borderBottomLeftRadius: '7px',
|
||||||
|
borderBottomRightRadius: '7px',
|
||||||
|
borderLeftColor: 'var(--tblr-green)',
|
||||||
|
backgroundColor: 'rgba(34, 197, 94, 0.06)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="small text-muted px-3 py-1 border-bottom bg-green-lt" style={{ fontSize: '0.7rem' }}>
|
||||||
|
WAN-подключения группы
|
||||||
|
</div>
|
||||||
<div className="p-2">
|
<div className="p-2">
|
||||||
{servers.map((server) => {
|
{servers.map((server) => {
|
||||||
const isSelected = selectedSet.has(server.ip);
|
const isSelected = selectedSet.has(server.ip);
|
||||||
@@ -157,11 +168,21 @@ export default function ServerGroupCard({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={server.id || server.ip}
|
key={server.id || server.ip}
|
||||||
className={`d-flex align-items-center rounded p-2 mb-1 ${isSelected ? 'bg-primary-lt' : ''}`}
|
className={`d-flex align-items-stretch rounded mb-1 overflow-hidden ${isSelected ? 'bg-primary-lt' : 'bg-white'}`}
|
||||||
|
style={{ boxShadow: '0 0 0 1px rgba(0,0,0,0.06)' }}
|
||||||
>
|
>
|
||||||
|
{/* Бейдж HOME у вложенного роутера */}
|
||||||
|
<div
|
||||||
|
className="d-flex align-items-center justify-content-center bg-green-lt text-green px-2"
|
||||||
|
style={{ minWidth: '52px', fontSize: '0.6rem', fontWeight: 700, letterSpacing: '0.5px' }}
|
||||||
|
>
|
||||||
|
<IconRouter size={14} className="me-1" />
|
||||||
|
HOME
|
||||||
|
</div>
|
||||||
|
<div className="d-flex align-items-center flex-grow-1 py-2 px-2 min-w-0">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-ghost-secondary btn-icon btn-sm p-0 me-2"
|
className="btn btn-ghost-secondary btn-icon btn-sm p-0 me-2 flex-shrink-0"
|
||||||
onClick={() => onSelect?.(server)}
|
onClick={() => onSelect?.(server)}
|
||||||
title={isSelected ? 'Снять выбор' : 'Выбрать'}
|
title={isSelected ? 'Снять выбор' : 'Выбрать'}
|
||||||
>
|
>
|
||||||
@@ -171,12 +192,13 @@ export default function ServerGroupCard({
|
|||||||
<IconSquare size={18} className="text-muted" />
|
<IconSquare size={18} className="text-muted" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<span className="me-2" style={{ fontSize: '1.1rem' }}>{countryToFlag(server.country)}</span>
|
<span className="me-2 flex-shrink-0" style={{ fontSize: '1.1rem' }}>{countryToFlag(server.country)}</span>
|
||||||
<div className="flex-grow-1 min-w-0">
|
<div className="min-w-0">
|
||||||
<span className="fw-medium">{serverName}</span>
|
<span className="fw-medium">{serverName}</span>
|
||||||
<span className="text-muted ms-2 small">{server.dns || server.ip}</span>
|
<span className="text-muted ms-2 small">{server.dns || server.ip}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="btn-list gap-1">
|
</div>
|
||||||
|
<div className="d-flex align-items-center btn-list gap-1 px-2 border-start">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-outline-secondary btn-sm"
|
className="btn btn-outline-secondary btn-sm"
|
||||||
|
|||||||
Reference in New Issue
Block a user