v0.1.29: светлый Nubes-дизайн консоли, читаемая модалка Credentials (env + файл кредов)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# Registry: Docker Hub (naeel/shared-sqs)
|
||||
|
||||
IMAGE_REPO=naeel/shared-sqs
|
||||
VERSION=v0.1.28
|
||||
VERSION=v0.1.29
|
||||
LDFLAGS=-X shared-sqs/app/models.Version=$(VERSION)
|
||||
BINARY=shared-sqs
|
||||
|
||||
|
||||
+91
-51
@@ -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=<Access Key></code><br>
|
||||
<code>export AWS_SECRET_ACCESS_KEY=<Secret Key></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=<Access Key>
|
||||
export AWS_SECRET_ACCESS_KEY=<Secret Key></pre>
|
||||
<p class="creds-sub">Способ 2 — файл ~/.aws/credentials:</p>
|
||||
<pre>[sqs]
|
||||
aws_access_key_id = <Access Key>
|
||||
aws_secret_access_key = <Secret Key></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>
|
||||
|
||||
Reference in New Issue
Block a user