Skip to content

Commit 2e8e4f2

Browse files
committed
Optimize panel queries and runtime stability
1 parent cd5ea65 commit 2e8e4f2

2 files changed

Lines changed: 57 additions & 130 deletions

File tree

public/css/style.css

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,56 +1083,71 @@ html {
10831083

10841084
/* Logs search */
10851085
.logs-search-wrap {
1086-
position: relative;
10871086
display: flex;
10881087
align-items: center;
1088+
gap: 6px;
10891089
}
10901090

10911091
.logs-search-input {
1092-
background: var(--bg-primary);
1092+
background: var(--bg-secondary);
10931093
border: 1px solid var(--border);
1094-
border-radius: var(--radius-sm, 6px);
1094+
border-radius: var(--radius-sm);
10951095
color: var(--text-primary);
1096-
font-size: 12px;
1097-
padding: 4px 28px 4px 10px;
1098-
width: 160px;
1096+
font-size: 13px;
1097+
padding: 7px 12px;
1098+
width: 180px;
10991099
outline: none;
1100-
transition: border-color 0.2s, width 0.2s;
1100+
transition: all 0.2s ease;
1101+
}
1102+
1103+
.logs-search-input:hover {
1104+
border-color: var(--border-light);
11011105
}
11021106

11031107
.logs-search-input:focus {
1104-
border-color: var(--primary);
1108+
border-color: var(--accent);
1109+
box-shadow: 0 0 0 3px var(--accent-glow);
1110+
background: var(--bg-tertiary);
11051111
width: 220px;
11061112
}
11071113

1114+
.logs-search-input::placeholder {
1115+
color: var(--text-muted);
1116+
}
1117+
11081118
.logs-search-count {
11091119
font-size: 11px;
11101120
color: var(--text-muted);
11111121
white-space: nowrap;
1112-
margin-right: 2px;
1113-
min-width: 24px;
1114-
text-align: right;
1122+
background: var(--bg-tertiary);
1123+
border: 1px solid var(--border);
1124+
border-radius: 10px;
1125+
padding: 3px 8px;
1126+
min-width: 20px;
1127+
text-align: center;
1128+
}
1129+
1130+
.logs-search-count:empty {
1131+
display: none;
11151132
}
11161133

11171134
.logs-search-clear {
1118-
position: absolute;
1119-
right: 6px;
1135+
display: none;
1136+
align-items: center;
1137+
justify-content: center;
11201138
background: none;
11211139
border: none;
11221140
color: var(--text-muted);
11231141
cursor: pointer;
1124-
font-size: 11px;
1125-
padding: 0;
1126-
display: none;
1127-
align-items: center;
1128-
justify-content: center;
1129-
width: 16px;
1130-
height: 16px;
1131-
border-radius: 50%;
1132-
transition: color 0.15s;
1142+
font-size: 14px;
1143+
padding: 4px;
1144+
border-radius: 4px;
1145+
transition: all 0.15s ease;
1146+
margin-left: -4px;
11331147
}
11341148

11351149
.logs-search-clear:hover {
1150+
background: var(--bg-tertiary);
11361151
color: var(--text-primary);
11371152
}
11381153

@@ -1958,6 +1973,15 @@ html {
19581973
width: 100%;
19591974
}
19601975

1976+
.logs-search-wrap {
1977+
flex: 1;
1978+
min-width: 0;
1979+
}
1980+
1981+
.logs-search-input {
1982+
width: 100% !important;
1983+
}
1984+
19611985
/* Tables - скрываем на мобилках */
19621986
.table-wrapper {
19631987
display: none;

views/dashboard.ejs

Lines changed: 11 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,9 @@
175175
</h2>
176176
<div class="logs-controls">
177177
<div class="logs-search-wrap" id="logsSearchWrap">
178-
<span class="logs-search-icon"><i class="ti ti-search"></i></span>
179178
<input type="text" class="logs-search-input" id="logsSearch" placeholder="<%= t('common.search') %>..." oninput="onLogsSearchInput(this.value)">
180179
<span class="logs-search-count" id="logsSearchCount"></span>
181-
<span class="logs-search-loading" id="logsSearchLoading" aria-hidden="true"><i class="ti ti-loader-2"></i></span>
182-
<button class="logs-search-clear" id="logsSearchClear" onclick="clearLogsSearch()" title="<%= t('common.clear') %>"></button>
180+
<button class="logs-search-clear" id="logsSearchClear" onclick="clearLogsSearch()" title="<%= t('common.clear') %>"><i class="ti ti-x"></i></button>
183181
</div>
184182
<button class="btn btn-sm" id="logsToggleBtn" onclick="toggleLogs()" title="<%= t('dashboard.pauseLogs') %>"><i class="ti ti-player-pause"></i></button>
185183
<button class="btn btn-sm" onclick="clearLogs()" title="<%= t('common.clear') %>"><i class="ti ti-trash"></i></button>
@@ -301,98 +299,14 @@
301299
.logs-controls {
302300
display: flex;
303301
gap: 8px;
304-
}
305-
.logs-search-wrap {
306-
display: flex;
307-
align-items: center;
308-
gap: 8px;
309-
min-width: 300px;
310-
padding: 0 10px;
311-
border: 1px solid var(--border);
312-
border-radius: 10px;
313-
background: var(--bg-tertiary);
314-
transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
315-
}
316-
.logs-search-wrap:focus-within {
317-
border-color: var(--primary);
318-
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
319-
background: var(--bg-secondary);
320-
}
321-
.logs-search-wrap.searching .logs-search-loading {
322-
display: inline-flex;
323-
}
324-
.logs-search-wrap.searching .logs-search-icon {
325-
color: var(--primary);
326-
}
327-
.logs-search-icon {
328-
display: inline-flex;
329-
color: var(--text-muted);
330-
}
331-
.logs-search-input {
332-
flex: 1;
333-
min-width: 140px;
334-
border: none;
335-
background: transparent;
336-
color: var(--text-primary);
337-
outline: none;
338-
height: 36px;
339-
font-size: 0.9rem;
340-
}
341-
.logs-search-input::placeholder {
342-
color: var(--text-muted);
343-
}
344-
.logs-search-count {
345-
display: inline-flex;
346-
align-items: center;
347-
justify-content: center;
348-
min-width: 22px;
349-
height: 22px;
350-
padding: 0 6px;
351-
border-radius: 999px;
352-
font-size: 0.75rem;
353-
color: var(--text-primary);
354-
background: var(--bg-card);
355-
border: 1px solid var(--border);
356-
}
357-
.logs-search-loading {
358-
display: none;
359302
align-items: center;
360-
color: var(--text-muted);
361-
}
362-
.logs-search-loading .ti-loader-2 {
363-
animation: spin 0.8s linear infinite;
364-
}
365-
.logs-search-clear {
366-
display: none;
367-
align-items: center;
368-
justify-content: center;
369-
width: 22px;
370-
height: 22px;
371-
border: none;
372-
border-radius: 6px;
373-
background: transparent;
374-
color: var(--text-muted);
375-
cursor: pointer;
376-
}
377-
.logs-search-clear:hover {
378-
background: var(--bg-card);
379-
color: var(--text-primary);
380303
}
381304
.logs-hit {
382-
background: rgba(99, 102, 241, 0.22);
305+
background: rgba(99, 102, 241, 0.25);
383306
color: inherit;
384-
border-radius: 4px;
385-
padding: 0 2px;
386-
}
387-
@media (max-width: 768px) {
388-
.logs-controls {
389-
width: 100%;
390-
flex-wrap: wrap;
391-
}
392-
.logs-search-wrap {
393-
min-width: 0;
394-
width: 100%;
395-
}
307+
border-radius: 3px;
308+
padding: 1px 3px;
309+
margin: 0 1px;
396310
}
397311
@keyframes pulse {
398312
0%, 100% { opacity: 1; }
@@ -565,9 +479,10 @@ function appendLog(log) {
565479
566480
function onLogsSearchInput(value) {
567481
const clearBtn = document.getElementById('logsSearchClear');
482+
const countEl = document.getElementById('logsSearchCount');
568483
const hasValue = value.trim().length > 0;
569484
clearBtn.style.display = hasValue ? 'flex' : 'none';
570-
setLogsSearchUiState(hasValue ? 'typing' : 'idle');
485+
if (!hasValue && countEl) countEl.textContent = '';
571486
572487
clearTimeout(logsSearchDebounce);
573488
logsSearchDebounce = setTimeout(() => {
@@ -585,10 +500,9 @@ async function execLogsSearch(q) {
585500
logsSearchMode = true;
586501
const container = document.getElementById('logsContainer');
587502
const countEl = document.getElementById('logsSearchCount');
588-
setLogsSearchUiState('searching');
589503
590504
container.innerHTML = '<div class="logs-loading">' + i18n.loading + '</div>';
591-
if (countEl) countEl.textContent = '';
505+
if (countEl) countEl.textContent = '...';
592506
593507
try {
594508
const res = await fetch(`/panel/logs/search?q=${encodeURIComponent(q)}&limit=200`, { credentials: 'include' });
@@ -601,20 +515,16 @@ async function execLogsSearch(q) {
601515
if (countEl) {
602516
const shown = data.matches.length;
603517
const total = data.total;
604-
countEl.textContent = shown < total
605-
? `${shown} / ${total}`
606-
: `${total}`;
518+
countEl.textContent = shown < total ? `${shown}/${total}` : `${total}`;
607519
}
608-
setLogsSearchUiState('active');
609520
} else {
610521
container.innerHTML = '<div class="logs-empty">' + i18n.noLogs + '</div>';
611522
if (countEl) countEl.textContent = '0';
612-
setLogsSearchUiState('active');
613523
}
614524
} catch (e) {
615525
if (logsSearchMode) {
616526
container.innerHTML = '<div class="logs-empty">—</div>';
617-
setLogsSearchUiState('typing');
527+
if (countEl) countEl.textContent = '';
618528
}
619529
}
620530
}
@@ -624,7 +534,6 @@ function exitLogsSearchMode() {
624534
logsSearchRequestId += 1;
625535
const countEl = document.getElementById('logsSearchCount');
626536
if (countEl) countEl.textContent = '';
627-
setLogsSearchUiState('idle');
628537
const container = document.getElementById('logsContainer');
629538
container.innerHTML = '<div class="logs-loading">' + i18n.loading + '</div>';
630539
if (logsWs) {
@@ -643,13 +552,7 @@ function clearLogsSearch() {
643552
}
644553
645554
function setLogsSearchUiState(state) {
646-
const wrap = document.getElementById('logsSearchWrap');
647-
if (!wrap) return;
648-
649-
wrap.classList.remove('searching');
650-
if (state === 'searching') {
651-
wrap.classList.add('searching');
652-
}
555+
// Оставлен для совместимости, состояние теперь отображается через count badge
653556
}
654557
655558
function scrollLogsToBottom() {

0 commit comments

Comments
 (0)