agents-näkymän tuunailua ja FI/SV/EN kielituen hahmottelua

This commit is contained in:
2026-04-03 09:07:00 +03:00
parent 057d464fdd
commit 0d3e0ff86a
2 changed files with 96 additions and 11 deletions

View File

@@ -36,3 +36,10 @@ echo "[5/5] Käynnistetään palvelut uudelleen..."
ssh $SSH_OPTS $SERVER "cd $REMOTE_DIR && docker compose -f docker-compose.prod.yml down && docker compose -f docker-compose.prod.yml up -d" ssh $SSH_OPTS $SERVER "cd $REMOTE_DIR && docker compose -f docker-compose.prod.yml down && docker compose -f docker-compose.prod.yml up -d"
echo "=== Valmis! https://kipina.studio ===" echo "=== Valmis! https://kipina.studio ==="
# Discord-notifikaatio
DISCORD_WEBHOOK="https://discord.com/api/webhooks/1489504066898755687/8U02d0wug-3MkVax0xMmRoj0s_-V1psnNLPWdSOjnGnKRBUpPjaU6XiX9Iu8DgJI69AP"
COMMIT_MSG=$(git log -1 --pretty=format:"%s" 2>/dev/null || echo "?")
curl -s -H "Content-Type: application/json" \
-d "{\"content\":\"🚀 **Kipinä Studio julkaistu!**\n> ${COMMIT_MSG}\n> https://kipina.studio\"}" \
"$DISCORD_WEBHOOK" > /dev/null

View File

@@ -491,18 +491,31 @@
align-items: center; align-items: center;
} }
.agent-prompt-label strong { color: var(--text-color); } .agent-prompt-label strong { color: var(--text-color); }
.lang-selector { display: flex; gap: 6px; background: #010409; padding: 4px; border-radius: 6px; border: 1px solid var(--border-color); }
.lang-btn { background: transparent; border: none; color: #8b949e; font-size: 11px; font-weight: 600; cursor: pointer; padding: 4px 8px; border-radius: 4px; transition: all 0.2s; }
.lang-btn:hover { color: #c9d1d9; }
.lang-btn.active { background: rgba(88, 166, 255, 0.15); color: var(--accent-color); }
</style> </style>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h1>Kipinä <span>Agent Dashboard</span></h1> <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;">
<p class="sub">Hajautettu WebGPU Laskentaverkko · <span id="hub-version" style="color:#58a6ff">-</span></p> <div>
<h1 style="margin-bottom:0;" data-i18n="main_title">Kipinä <span>Agent Dashboard</span></h1>
<p class="sub" style="margin-bottom:0;"><span data-i18n="main_subtitle">Hajautettu WebGPU Laskentaverkko</span> · <span id="hub-version" style="color:#58a6ff">-</span></p>
</div>
<div class="lang-selector">
<button class="lang-btn active" onclick="setLanguage('fi')" data-lang="fi">FI</button>
<button class="lang-btn" onclick="setLanguage('se')" data-lang="se">SE</button>
<button class="lang-btn" onclick="setLanguage('en')" data-lang="en">EN</button>
</div>
</div>
<!-- Päävälilehdet --> <!-- Päävälilehdet -->
<div class="main-tabs"> <div class="main-tabs">
<div class="main-tab active" onclick="switchMainTab('network')">Laskentaverkko</div> <div class="main-tab active" onclick="switchMainTab('network')" data-i18n="tab_network">Laskentaverkko</div>
<div class="main-tab" onclick="switchMainTab('codelab')">Koodilaboratorio</div> <div class="main-tab" onclick="switchMainTab('codelab')" data-i18n="tab_codelab">Koodilaboratorio</div>
<div class="main-tab" onclick="switchMainTab('agents')">Agents & CLI</div> <div class="main-tab" onclick="switchMainTab('agents')" data-i18n="tab_agents">Agents & CLI</div>
</div> </div>
<!-- PANEELI 1: Laskentaverkko --> <!-- PANEELI 1: Laskentaverkko -->
@@ -512,15 +525,15 @@
<div class="dashboard-panel"> <div class="dashboard-panel">
<div class="stat-box" style="border-right: 1px solid #30363d;"> <div class="stat-box" style="border-right: 1px solid #30363d;">
<h3 id="stat-nodes">0</h3> <h3 id="stat-nodes">0</h3>
<p>Aktiivisia Nodeja</p> <p data-i18n="stat_nodes_lbl">Aktiivisia Nodeja</p>
</div> </div>
<div class="stat-box" style="border-right: 1px solid #30363d;"> <div class="stat-box" style="border-right: 1px solid #30363d;">
<h3 id="stat-tasks">0</h3> <h3 id="stat-tasks">0</h3>
<p>Verkossa Suoritettua Tehtävää (Globaali)</p> <p data-i18n="stat_tasks_lbl">Verkossa Suoritettua Tehtävää (Globaali)</p>
</div> </div>
<div class="stat-box"> <div class="stat-box">
<h3 id="stat-vram">0 GB</h3> <h3 id="stat-vram">0 GB</h3>
<p>Verkon yhteis-VRAM</p> <p data-i18n="stat_vram_lbl">Verkon yhteis-VRAM</p>
</div> </div>
</div> </div>
@@ -814,7 +827,7 @@
<!-- Taso 2 --> <!-- Taso 2 -->
<div class="org-level" style="position: relative;"> <div class="org-level" style="position: relative;">
<!-- Tarkkailija laitetaan erilleen kauemmas sivuun jotta se näyttää itsenäiseltä valvojalta --> <!-- Tarkkailija laitetaan erilleen kauemmas sivuun jotta se näyttää itsenäiseltä valvojalta -->
<div class="avatar-card" id="avatar-observer" data-agent="observer" onclick="selectAgent('observer')" style="position: absolute; right: calc(50% + 240px); top: 0;"> <div class="avatar-card" id="avatar-observer" data-agent="observer" onclick="selectAgent('observer')" style="position: absolute; right: calc(50% + 350px); top: 0;">
<img src="/avatars/aikuinen_susi.png" alt="Tarkkailija (Aikuinen Susi)"> <img src="/avatars/aikuinen_susi.png" alt="Tarkkailija (Aikuinen Susi)">
<div class="avatar-name">Tarkkailija</div> <div class="avatar-name">Tarkkailija</div>
<div class="avatar-role">Laadunvalvonta</div> <div class="avatar-role">Laadunvalvonta</div>
@@ -909,12 +922,13 @@
const textEl = document.getElementById('agent-prompt-text'); const textEl = document.getElementById('agent-prompt-text');
const sharedEl = document.getElementById('shared-prompt-section'); const sharedEl = document.getElementById('shared-prompt-section');
const btnAll = document.getElementById('btn-toggle-all'); const btnAll = document.getElementById('btn-toggle-all');
const t = window.currentLangDict || { btn_clear_all: 'Tyhjennä valinnat', btn_select_all: 'Valitse kaikki' };
if (btnAll) { if (btnAll) {
if (selectedAgents.size === Object.keys(agentPrompts).length) { if (selectedAgents.size === Object.keys(agentPrompts).length) {
btnAll.textContent = 'Tyhjennä valinnat'; btnAll.textContent = t.btn_clear_all;
} else { } else {
btnAll.textContent = 'Valitse kaikki'; btnAll.textContent = t.btn_select_all;
} }
} }
@@ -2027,6 +2041,70 @@
codeSendBtn?.addEventListener('click', handleCodeSubmit); codeSendBtn?.addEventListener('click', handleCodeSubmit);
textInput?.addEventListener('keydown', (e) => { if (e.key === 'Enter') handleCodeSubmit(); }); textInput?.addEventListener('keydown', (e) => { if (e.key === 'Enter') handleCodeSubmit(); });
const translations = {
fi: {
main_title: "Kipinä <span>Agent Dashboard</span>",
main_subtitle: "Hajautettu WebGPU Laskentaverkko",
tab_network: "Laskentaverkko",
tab_codelab: "Koodilaboratorio",
tab_agents: "Agents & CLI",
stat_nodes_lbl: "Aktiivisia Nodeja",
stat_tasks_lbl: "Verkossa Suoritettua Tehtävää (Globaali)",
stat_vram_lbl: "Verkon yhteis-VRAM",
btn_select_all: "Valitse kaikki",
btn_clear_all: "Tyhjennä valinnat"
},
se: {
main_title: "Kipinä <span>Agent Dashboard</span>",
main_subtitle: "Decentraliserat WebGPU Beräkningsnätverk",
tab_network: "Kalkylnätverk",
tab_codelab: "Kodlaboratorium",
tab_agents: "Agenter & CLI",
stat_nodes_lbl: "Aktiva Noder",
stat_tasks_lbl: "Slutförda Uppgifter (Globalt)",
stat_vram_lbl: "Nätverkets totala VRAM",
btn_select_all: "Välj alla",
btn_clear_all: "Rensa val"
},
en: {
main_title: "Kipinä <span>Agent Dashboard</span>",
main_subtitle: "Decentralized WebGPU Compute Network",
tab_network: "Compute Network",
tab_codelab: "Code Laboratory",
tab_agents: "Agents & CLI",
stat_nodes_lbl: "Active Nodes",
stat_tasks_lbl: "Tasks Completed (Global)",
stat_vram_lbl: "Total Network VRAM",
btn_select_all: "Select all",
btn_clear_all: "Clear selection"
}
};
window.setLanguage = function(lang) {
localStorage.setItem('kpn_lang', lang);
document.querySelectorAll('.lang-btn').forEach(b => b.classList.remove('active'));
const btn = document.querySelector(`.lang-btn[data-lang="${lang}"]`);
if (btn) btn.classList.add('active');
const t = translations[lang] || translations.fi;
window.currentLangDict = t;
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
if (t[key]) {
if(t[key].includes('<')) el.innerHTML = t[key];
else el.textContent = t[key];
}
});
if(window.updatePromptEditor) window.updatePromptEditor();
};
document.addEventListener('DOMContentLoaded', () => {
const savedLang = localStorage.getItem('kpn_lang') || 'fi';
setLanguage(savedLang);
});
</script> </script>
</body> </body>
</html> </html>