fix: transfer dialog keeps its body and shows a spinner and progress while sending; LPRA in the header leads to the machines; no settings link on the settings page; corner plus clear of the scrollbar

This commit is contained in:
redtea committed 2026-10-15 10:44:10 +03:00
1 parent fd382d6313
commit 1297ab36d0
8 files changed
+15 -12

No files matched your search

+2
View File
@@ -25,6 +25,8 @@ header.topbar {
padding: 14px 24px; border-bottom: 1px solid var(--border); background: var(--panel); padding: 14px 24px; border-bottom: 1px solid var(--border); background: var(--panel);
} }
header.topbar .brand { font-weight: 600; } header.topbar .brand { font-weight: 600; }
header.topbar .brand a.home { color: inherit; text-decoration: none; transition: color .15s; }
header.topbar .brand a.home:hover { color: var(--accent); }
/* A long machine name gives way: the links and the status stay in sight. */ /* A long machine name gives way: the links and the status stay in sight. */
@media (min-width: 641px) { @media (min-width: 641px) {
header.topbar .brand { flex: 1 1 auto; min-width: 0; margin-right: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } header.topbar .brand { flex: 1 1 auto; min-width: 0; margin-right: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+1 -1
View File
@@ -9,7 +9,7 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Удалённый доступ</div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Удалённый доступ</div>
<nav> <nav>
<a href="/">Машины</a> <a href="/">Машины</a>
<a href="/settings">Настройки</a> <a href="/settings">Настройки</a>
+1 -1
View File
@@ -9,7 +9,7 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Изменить машину</div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Изменить машину</div>
<nav> <nav>
<a href="/">← Машины</a> <a href="/">← Машины</a>
<a href="/agents/{{.Agent.ID}}/terminal">Терминал</a> <a href="/agents/{{.Agent.ID}}/terminal">Терминал</a>
+6 -4
View File
@@ -144,8 +144,9 @@
.mv-bar i { display:block; height:100%; width:0; background:var(--accent); border-radius:3px; transition:width .5s ease; } .mv-bar i { display:block; height:100%; width:0; background:var(--accent); border-radius:3px; transition:width .5s ease; }
.mv-bar.wait i { width:30% !important; animation:mv-slide 1.1s ease-in-out infinite; } .mv-bar.wait i { width:30% !important; animation:mv-slide 1.1s ease-in-out infinite; }
@keyframes mv-slide { from { transform:translateX(-100%); } to { transform:translateX(340%); } } @keyframes mv-slide { from { transform:translateX(-100%); } to { transform:translateX(340%); } }
.mv-pwrap { display:inline-flex; align-items:center; gap:8px; min-width:0; }
.mv-ptext { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:8px; font-size:13px; color:var(--muted); } .mv-ptext { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:8px; font-size:13px; color:var(--muted); }
.mv.busy input, .mv.busy select, .mv.busy textarea, .mv.busy .seg, .mv.busy .mv-net { pointer-events:none; opacity:.6; } .mv.running input, .mv.running select, .mv.running textarea, .mv.running .seg, .mv.running .mv-net { pointer-events:none; opacity:.6; }
.mv-dirbox { position:relative; } .mv-dirbox { position:relative; }
.mv-dirbox input { font-family:ui-monospace,Menlo,monospace; font-size:13px; } .mv-dirbox input { font-family:ui-monospace,Menlo,monospace; font-size:13px; }
.mv-sug { position:absolute; left:0; right:0; top:calc(100% + 4px); z-index:5; max-height:220px; overflow:auto; .mv-sug { position:absolute; left:0; right:0; top:calc(100% + 4px); z-index:5; max-height:220px; overflow:auto;
@@ -285,7 +286,7 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Файлы - {{.Agent.Name}} <span class="muted">({{.Agent.Hostname}})</span></div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Файлы - {{.Agent.Name}} <span class="muted">({{.Agent.Hostname}})</span></div>
<nav> <nav>
<a href="/">← Машины</a> <a href="/">← Машины</a>
<a href="/agents/{{.Agent.ID}}/terminal">Терминал</a> <a href="/agents/{{.Agent.ID}}/terminal">Терминал</a>
@@ -422,7 +423,7 @@
</select> </select>
<div class="mv-prog" id="mv-prog" hidden> <div class="mv-prog" id="mv-prog" hidden>
<div class="mv-bar"><i id="mv-bar"></i></div> <div class="mv-bar"><i id="mv-bar"></i></div>
<div class="mv-ptext"><span id="mv-ptext">подготовка…</span><button type="button" class="btn ghost small" id="mv-stop">Отменить</button></div> <div class="mv-ptext"><span class="mv-pwrap"><span class="spinner"></span><span id="mv-ptext">подготовка…</span></span><button type="button" class="btn ghost small" id="mv-stop">Отменить</button></div>
</div> </div>
<div class="pp-act"><button type="button" id="mv-go">Переместить</button></div> <div class="pp-act"><button type="button" id="mv-go">Переместить</button></div>
</div> </div>
@@ -1325,9 +1326,10 @@
return {t}; return {t};
} }
function busy(on) { function busy(on) {
document.querySelector('#mvdlg .mv').classList.toggle('busy', on); document.querySelector('#mvdlg .mv').classList.toggle('running', on);
$('mv-go').disabled = on; $('mv-go').disabled = on;
$('mv-prog').hidden = !on; $('mv-prog').hidden = !on;
if (on) requestAnimationFrame(() => $('mv-prog').scrollIntoView({block: 'nearest', behavior: 'smooth'}));
} }
// ship sends to the other machine and follows the job to its end. // ship sends to the other machine and follows the job to its end.
async function ship(dir, name, conflict, move) { async function ship(dir, name, conflict, move) {
+1 -1
View File
@@ -38,7 +38,7 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Порты - {{.Agent.Name}} <span class="muted">({{.Agent.Hostname}})</span></div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Порты - {{.Agent.Name}} <span class="muted">({{.Agent.Hostname}})</span></div>
<nav> <nav>
<a href="/">← Машины</a> <a href="/">← Машины</a>
<a href="/agents/{{.Agent.ID}}/terminal">Терминал</a> <a href="/agents/{{.Agent.ID}}/terminal">Терминал</a>
+1 -2
View File
@@ -21,10 +21,9 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Удалённый доступ</div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Удалённый доступ</div>
<nav> <nav>
<a href="/">Машины</a> <a href="/">Машины</a>
<a href="/settings">Настройки</a>
<button type="button" class="btn ghost icon acct-btn" id="acct" title="Аккаунт" aria-label="Аккаунт"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg></button> <button type="button" class="btn ghost icon acct-btn" id="acct" title="Аккаунт" aria-label="Аккаунт"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg></button>
</nav> </nav>
</header> </header>
+1 -1
View File
@@ -43,7 +43,7 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Статус - {{.Agent.Name}} <span class="muted">({{.Agent.Hostname}})</span></div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Статус - {{.Agent.Name}} <span class="muted">({{.Agent.Hostname}})</span></div>
<nav> <nav>
<a href="/">← Машины</a> <a href="/">← Машины</a>
<a href="/agents/{{.Agent.ID}}/terminal">Терминал</a> <a href="/agents/{{.Agent.ID}}/terminal">Терминал</a>
+2 -2
View File
@@ -73,7 +73,7 @@
/* The terminals' area. */ /* The terminals' area. */
.area { position:relative; flex:1; min-height:0; margin:12px 16px 16px; border:1px solid var(--border); border-radius:10px; background:#0c0f13; overflow:hidden; } .area { position:relative; flex:1; min-height:0; margin:12px 16px 16px; border:1px solid var(--border); border-radius:10px; background:#0c0f13; overflow:hidden; }
body.multi .area { margin-top:0; border-top-left-radius:0; } body.multi .area { margin-top:0; border-top-left-radius:0; }
.float-add { position:absolute; top:8px; right:10px; z-index:6; width:28px; height:28px; padding:0; display:inline-flex; .float-add { position:absolute; top:8px; right:38px; z-index:6; width:28px; height:28px; padding:0; display:inline-flex;
align-items:center; justify-content:center; font-size:17px; line-height:1; color:var(--text); align-items:center; justify-content:center; font-size:17px; line-height:1; color:var(--text);
background:transparent; border:1px solid var(--border); opacity:.28; transition:opacity .25s ease, background .25s ease, top .25s ease; } background:transparent; border:1px solid var(--border); opacity:.28; transition:opacity .25s ease, background .25s ease, top .25s ease; }
/* One tab split in panes: below the panes' title bars, clear of their close buttons. */ /* One tab split in panes: below the panes' title bars, clear of their close buttons. */
@@ -161,7 +161,7 @@
</head> </head>
<body> <body>
<header class="topbar"> <header class="topbar">
<div class="brand">LPRA · Терминал - {{.Agent.Name}} <span class="muted">({{.Agent.TerminalUser}}@{{.Agent.Hostname}})</span></div> <div class="brand"><a class="home" href="/" title="К списку машин">LPRA</a> · Терминал - {{.Agent.Name}} <span class="muted">({{.Agent.TerminalUser}}@{{.Agent.Hostname}})</span></div>
<nav> <nav>
<a href="/">← Машины</a> <a href="/">← Машины</a>
<a href="/agents/{{.Agent.ID}}/files">Файлы</a> <a href="/agents/{{.Agent.ID}}/files">Файлы</a>