|
150 | 150 |
|
151 | 151 | <div class="upd-steps" id="updSteps"></div> |
152 | 152 |
|
153 | | - <div class="upd-terminal" id="updTerminal" style="display:none;"> |
154 | | - <div class="upd-terminal-bar"> |
155 | | - <span class="upd-dot r"></span><span class="upd-dot y"></span><span class="upd-dot g"></span> |
156 | | - <span class="upd-terminal-title"><%= t('settings.updateTerminalTitle') || 'updater' %></span> |
157 | | - </div> |
158 | | - <pre class="upd-terminal-body" id="updLog"></pre> |
| 153 | + <div class="upd-log-wrap" id="updLogWrap" style="display:none;"> |
| 154 | + <button type="button" class="upd-log-toggle" id="updLogToggle" aria-expanded="false"> |
| 155 | + <i class="ti ti-chevron-right" id="updLogChevron"></i> |
| 156 | + <span><%= t('settings.updateDetails') || 'Детали' %></span> |
| 157 | + </button> |
| 158 | + <pre class="upd-log" id="updLog" style="display:none;"></pre> |
159 | 159 | </div> |
160 | 160 |
|
161 | 161 | <!-- Shown only when the flow ends in error/timeout so the admin can leave. --> |
|
193 | 193 | .upd-step.is-done .upd-step-label{color:var(--text-secondary,#a1a1aa);} |
194 | 194 | .upd-step.is-error .upd-step-label{color:#fca5a5;font-weight:600;} |
195 | 195 | @keyframes upd-spin{to{transform:rotate(360deg)}} |
196 | | -.upd-terminal{border:1px solid var(--border,#27272a);border-radius:var(--radius-sm,10px);overflow:hidden;background:#0c0c0e;margin-bottom:18px;} |
197 | | -.upd-terminal-bar{display:flex;align-items:center;gap:6px;padding:8px 12px;background:rgba(255,255,255,.03);border-bottom:1px solid var(--border,#27272a);} |
198 | | -.upd-dot{width:10px;height:10px;border-radius:50%;} |
199 | | -.upd-dot.r{background:#ef4444;}.upd-dot.y{background:#eab308;}.upd-dot.g{background:#22c55e;} |
200 | | -.upd-terminal-title{margin-left:8px;font-size:11px;color:var(--text-muted,#71717a);font-family:'JetBrains Mono',monospace;} |
201 | | -.upd-terminal-body{margin:0;padding:12px 14px;max-height:220px;overflow:auto;font-family:'JetBrains Mono',monospace;font-size:11.5px;line-height:1.65;color:#a1a1aa;white-space:pre-wrap;word-break:break-word;} |
| 196 | +.upd-log-wrap{margin-bottom:18px;} |
| 197 | +.upd-log-toggle{display:inline-flex;align-items:center;gap:6px;padding:0;background:none;border:none;cursor:pointer;font-size:12.5px;color:var(--text-muted,#71717a);transition:color .2s;font-family:inherit;} |
| 198 | +.upd-log-toggle:hover{color:var(--text-secondary,#a1a1aa);} |
| 199 | +.upd-log-toggle i{font-size:14px;transition:transform .2s;} |
| 200 | +.upd-log-toggle.is-open i{transform:rotate(90deg);} |
| 201 | +.upd-log{margin:10px 0 0;padding:12px 14px;max-height:220px;overflow:auto;background:rgba(0,0,0,.28);border:1px solid var(--border,#27272a);border-radius:var(--radius-sm,10px);font-family:'JetBrains Mono',monospace;font-size:11.5px;line-height:1.65;color:var(--text-secondary,#a1a1aa);white-space:pre-wrap;word-break:break-word;} |
202 | 202 | .upd-actions{display:flex;justify-content:flex-end;} |
203 | 203 | </style> |
204 | 204 |
|
|
470 | 470 | const titleEl = document.getElementById('updTitle'); |
471 | 471 | const subEl = document.getElementById('updSub'); |
472 | 472 | const elapsedEl = document.getElementById('updElapsed'); |
473 | | - const termEl = document.getElementById('updTerminal'); |
| 473 | + const logWrapEl = document.getElementById('updLogWrap'); |
| 474 | + const logToggleEl = document.getElementById('updLogToggle'); |
474 | 475 | const logEl = document.getElementById('updLog'); |
475 | 476 | const actionsEl = document.getElementById('updActions'); |
476 | 477 |
|
| 478 | + logToggleEl.onclick = () => { |
| 479 | + const open = logEl.style.display !== 'none'; |
| 480 | + logEl.style.display = open ? 'none' : ''; |
| 481 | + logToggleEl.classList.toggle('is-open', !open); |
| 482 | + logToggleEl.setAttribute('aria-expanded', String(!open)); |
| 483 | + if (!open) logEl.scrollTop = logEl.scrollHeight; |
| 484 | + }; |
| 485 | +
|
477 | 486 | renderStages(); |
478 | 487 | titleEl.textContent = t.inProgress; |
479 | 488 | subEl.textContent = 'v' + currentVersion + ' → v' + targetVersion; |
|
496 | 505 |
|
497 | 506 | function showLog(lines) { |
498 | 507 | if (!lines || !lines.length) return; |
499 | | - termEl.style.display = ''; |
| 508 | + logWrapEl.style.display = ''; |
500 | 509 | const text = lines.join('\n'); |
501 | 510 | if (logEl.textContent !== text) { |
502 | 511 | logEl.textContent = text; |
503 | | - logEl.scrollTop = logEl.scrollHeight; |
| 512 | + if (logEl.style.display !== 'none') logEl.scrollTop = logEl.scrollHeight; |
504 | 513 | } |
505 | 514 | } |
506 | 515 |
|
| 516 | + function openLog() { |
| 517 | + logWrapEl.style.display = ''; |
| 518 | + logEl.style.display = ''; |
| 519 | + logToggleEl.classList.add('is-open'); |
| 520 | + logToggleEl.setAttribute('aria-expanded', 'true'); |
| 521 | + logEl.scrollTop = logEl.scrollHeight; |
| 522 | + } |
| 523 | +
|
507 | 524 | // Advance the visible stage monotonically (never jump backwards on a |
508 | 525 | // transient status blip). |
509 | 526 | function advance(idx) { |
|
530 | 547 | iconEl.innerHTML = '<i class="ti ti-alert-triangle"></i>'; |
531 | 548 | titleEl.textContent = t.failed; |
532 | 549 | subEl.textContent = message || ''; |
533 | | - if (log && log.length) showLog(log); |
| 550 | + if (log && log.length) { showLog(log); openLog(); } |
534 | 551 | actionsEl.style.display = ''; |
535 | 552 | } |
536 | 553 |
|
|
0 commit comments