v0.1.29: светлый Nubes-дизайн консоли, читаемая модалка Credentials (env + файл кредов)

This commit is contained in:
“Naeel”
2026-08-14 09:56:18 +04:00
parent a85e086c94
commit cfea73cdea
2 changed files with 92 additions and 52 deletions
+91 -51
View File
@@ -14,23 +14,25 @@
<title>SQS Console — Nubes</title>
<link rel="icon" href="https://terra.k8c.ru/docs/nubes/nubes/2.0.2/30_registry/assets/favicon.png">
<style>
/* Nubes palette — идентично iot.kube5s.ru/console */
/* Nubes design systemсветлая тема (deck) */
:root {
--bg-page: #001120;
--bg-surface: #001929;
--bg-navbar: #001C34;
--border: #0b2d50;
--accent: #1a7fd4;
--accent-hover: #2196f3;
--text-primary: #e2ecf6;
--text-secondary: #6b8eaa;
--danger: #e74c3c;
--success: #27ae60;
--warning: #f39c12;
--bg-page: #fafafa;
--bg-surface: #ffffff;
--bg-navbar: #ffffff;
--border: #d1d5db;
--accent: #2563eb;
--accent-hover: #1d4ed8;
--text-primary: #1a1a1a;
--text-secondary: #6b7280;
--danger: #dc2626;
--success: #16a34a;
--warning: #d97706;
--brand-grey-light: #f3f4f6;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px;
background: var(--bg-page);
color: var(--text-primary);
min-height: 100vh;
@@ -55,7 +57,6 @@ a:hover { color: var(--accent-hover); }
}
.navbar-brand img {
height: 28px;
filter: brightness(0) invert(1);
}
.navbar-brand span {
font-size: 16px;
@@ -88,7 +89,8 @@ a:hover { color: var(--accent-hover); }
.card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 8px;
border-radius: 12px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
padding: 20px;
margin-bottom: 20px;
}
@@ -111,15 +113,17 @@ a:hover { color: var(--accent-hover); }
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 8px;
border-radius: 12px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
padding: 20px;
text-align: center;
}
.stat-value {
font-size: 36px;
font-size: 30px;
font-weight: 700;
color: var(--accent);
color: var(--text-primary);
}
.stat-value.accent { color: var(--accent); }
.stat-label {
font-size: 12px;
color: var(--text-secondary);
@@ -149,7 +153,7 @@ tbody td {
padding: 12px 16px;
border-bottom: 1px solid var(--border);
}
tbody tr:hover { background: rgba(26, 127, 212, 0.05); }
tbody tr:hover { background: var(--brand-grey-light); }
tbody tr { cursor: pointer; }
/* Buttons */
@@ -168,8 +172,8 @@ tbody tr { cursor: pointer; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #c0392b; }
.btn-sm { padding: 4px 12px; font-size: 12px; }
.btn-danger:hover { background: #b91c1c; }
.btn-sm { padding: 4px 12px; font-size: 13px; }
/* Forms */
.form-group { margin-bottom: 16px; }
@@ -182,9 +186,9 @@ tbody tr { cursor: pointer; }
.form-group input {
width: 100%;
padding: 10px 14px;
background: var(--bg-page);
background: #ffffff;
border: 1px solid var(--border);
border-radius: 4px;
border-radius: 8px;
color: var(--text-primary);
font-size: 14px;
}
@@ -208,10 +212,10 @@ tbody tr { cursor: pointer; }
width: 400px;
text-align: center;
}
.login-box img { height: 40px; filter: brightness(0) invert(1); margin-bottom: 12px; }
.login-box img { height: 40px; margin-bottom: 12px; }
.login-box h1 {
font-size: 18px;
letter-spacing: 2px;
font-size: 22px;
letter-spacing: 1px;
margin-bottom: 32px;
color: var(--text-primary);
}
@@ -225,15 +229,15 @@ tbody tr { cursor: pointer; }
/* Badges */
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
font-size: 11px;
padding: 2px 10px;
border-radius: 999px;
font-size: 12px;
font-weight: 600;
}
.badge-active { background: rgba(39,174,96,0.15); color: var(--success); }
.badge-inactive { background: rgba(231,76,60,0.15); color: var(--danger); }
.badge-active { background: rgba(22,163,74,0.12); color: var(--success); }
.badge-inactive { background: rgba(220,38,38,0.1); color: var(--danger); }
.badge-count {
background: rgba(26,127,212,0.15);
background: rgba(37,99,235,0.1);
color: var(--accent);
min-width: 24px;
text-align: center;
@@ -252,7 +256,7 @@ tbody tr { cursor: pointer; }
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.6);
background: rgba(0,0,0,0.45);
display: flex;
align-items: center;
justify-content: center;
@@ -262,12 +266,15 @@ tbody tr { cursor: pointer; }
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
padding: 32px;
width: 480px;
max-width: 90vw;
width: 560px;
max-width: 92vw;
max-height: 88vh;
overflow-y: auto;
}
.modal h2 {
font-size: 18px;
font-size: 20px;
margin-bottom: 20px;
}
.modal-actions {
@@ -304,7 +311,7 @@ tbody tr { cursor: pointer; }
margin-bottom: 16px;
}
.toolbar h2 {
font-size: 18px;
font-size: 20px;
font-weight: 600;
}
.auto-refresh {
@@ -315,6 +322,36 @@ tbody tr { cursor: pointer; }
color: var(--text-secondary);
}
/* Credentials modal — подсказка */
.creds-hint {
font-size: 13px;
color: #374151;
background: var(--brand-grey-light);
border: 1px solid var(--border);
border-radius: 8px;
padding: 12px 14px;
margin-bottom: 16px;
line-height: 1.6;
}
.creds-hint .warn {
color: var(--warning);
font-weight: 600;
}
.creds-hint p { margin: 6px 0; }
.creds-hint .creds-sub { font-weight: 600; margin-top: 10px; color: var(--text-primary); }
.creds-hint pre {
background: #ffffff;
border: 1px solid var(--border);
border-radius: 6px;
padding: 8px 10px;
font-family: ui-monospace, Menlo, Consolas, monospace;
font-size: 12px;
line-height: 1.5;
overflow-x: auto;
white-space: pre;
margin: 6px 0 10px;
}
/* Expandable message rows */
td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
.msg-expand-inner { padding: 12px 20px; background: var(--bg-page); }
@@ -347,7 +384,7 @@ td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
<div>Admin API: <span style="font-family:monospace">POST /admin/tenants</span> (Bearer token)</div>
<div>Realm: <span style="font-family:monospace">iot-naeel</span> · Persistence: Managed Redis</div>
<div>Версия: <span id="svc-version" style="font-family:monospace"></span></div>
<div>Образ: <span style="font-family:monospace">naeel/shared-sqs:v0.1.28</span></div>
<div>Образ: <span style="font-family:monospace">naeel/shared-sqs:v0.1.29</span></div>
<div style="margin-top:8px;color:var(--warning)">Статус: тестирование</div>
</div>
</div>
@@ -397,16 +434,19 @@ td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
<div id="modal-creds" class="modal-overlay hidden" onclick="if(event.target===this)closeCredsModal()">
<div class="modal">
<h2>Credentials</h2>
<p style="color:var(--warning);font-size:13px;margin-bottom:12px">
⚠ Сохраните ключи — это креды вашего тенанта для AWS CLI/SDK.
</p>
<div style="font-size:12px;color:var(--text-secondary);background:var(--bg-page);border:1px solid var(--border);border-radius:4px;padding:10px 12px;margin-bottom:16px;line-height:1.8;word-break:break-all">
<strong>Зачем:</strong> приложения подключаются к SQS API по протоколу AWS
(подпись Signature V4). Токен входа в консоль для этого не подходит.<br>
<strong>Что делать:</strong><br>
<code>export AWS_ACCESS_KEY_ID=&lt;Access Key&gt;</code><br>
<code>export AWS_SECRET_ACCESS_KEY=&lt;Secret Key&gt;</code><br>
<code>aws sqs list-queues --endpoint-url https://sqs.containerk8s.dev.nubes.ru --region us-east-1</code>
<div class="creds-hint">
<p class="warn">⚠ Сохраните ключи — это креды вашего тенанта для AWS CLI/SDK.</p>
<p><strong>Зачем:</strong> приложения подключаются к SQS API по протоколу AWS (подпись Signature V4). Токен входа в консоль для этого не подходит.</p>
<p><strong>Что делать:</strong> укажите ключи одним из двух способов:</p>
<p class="creds-sub">Способ 1 — переменные окружения:</p>
<pre>export AWS_ACCESS_KEY_ID=&lt;Access Key&gt;
export AWS_SECRET_ACCESS_KEY=&lt;Secret Key&gt;</pre>
<p class="creds-sub">Способ 2 — файл ~/.aws/credentials:</p>
<pre>[sqs]
aws_access_key_id = &lt;Access Key&gt;
aws_secret_access_key = &lt;Secret Key&gt;</pre>
<p>Дальше выполняйте команды (для способа 2 добавьте <code>--profile sqs</code>):</p>
<pre>aws sqs list-queues --endpoint-url https://sqs.containerk8s.dev.nubes.ru --region us-east-1 --profile sqs</pre>
</div>
<div class="form-group">
<label>Access Key</label>
@@ -428,7 +468,7 @@ td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
<h2>Отправить сообщение</h2>
<div class="form-group">
<label for="send-body">Тело сообщения</label>
<textarea id="send-body" rows="6" style="width:100%;background:var(--bg-page);border:1px solid var(--border);border-radius:4px;color:var(--text-primary);padding:10px 14px;font-family:monospace;font-size:13px;resize:vertical"></textarea>
<textarea id="send-body" rows="6" style="width:100%;background:#ffffff;border:1px solid var(--border);border-radius:8px;color:var(--text-primary);padding:10px 14px;font-family:monospace;font-size:13px;resize:vertical"></textarea>
</div>
<div id="send-error" class="login-error"></div>
<div class="modal-actions">
@@ -448,7 +488,7 @@ td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
</div>
<div class="form-group">
<label>Body (нажмите, чтобы скопировать)</label>
<textarea id="msg-detail-body" readonly rows="8" style="width:100%;background:var(--bg-page);border:1px solid var(--border);border-radius:4px;color:var(--text-primary);padding:10px 14px;font-family:monospace;font-size:13px;resize:vertical;cursor:pointer" onclick="copyTextarea(this)"></textarea>
<textarea id="msg-detail-body" readonly rows="8" style="width:100%;background:#ffffff;border:1px solid var(--border);border-radius:8px;color:var(--text-primary);padding:10px 14px;font-family:monospace;font-size:13px;resize:vertical;cursor:pointer" onclick="copyTextarea(this)"></textarea>
</div>
<div class="form-group">
<label>Отправлено</label>
@@ -988,7 +1028,7 @@ function renderQueueMessages(queueName, msgs) {
<tbody>
${msgs.map(m => `
<tr onclick="openMsgDetail('${esc(m.id)}')" style="cursor:pointer"
onmouseover="this.style.background='rgba(26,127,212,0.08)'" onmouseout="this.style.background=''">
onmouseover="this.style.background='var(--brand-grey-light)'" onmouseout="this.style.background=''">
<td style="padding:6px 12px;font-family:monospace;color:var(--text-secondary)">${esc(m.id).substring(0,8)}…</td>
<td style="padding:6px 12px;max-width:380px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${esc(m.body || '').substring(0,120)}${(m.body||'').length>120?'…':''}</td>
<td style="padding:6px 12px;color:var(--text-secondary)">${fmtDate(m.sent_at)}</td>