Update agents, dashboard, kb +2 more (+6 ~11)

This commit is contained in:
Echo
2026-01-31 22:05:53 +00:00
parent 6555ea28ee
commit d2d9016da5
17 changed files with 900 additions and 187 deletions

View File

@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<title>Echo · Dashboard</title>
<link rel="stylesheet" href="common.css">
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
@@ -14,61 +15,6 @@
padding: var(--space-5);
}
/* Stats Summary */
.stats-summary {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--space-3);
margin-bottom: var(--space-4);
}
@media (max-width: 768px) {
.stats-summary {
grid-template-columns: repeat(2, 1fr);
}
}
.stat-card {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-4);
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
}
.stat-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: var(--accent-subtle);
border-radius: var(--radius-md);
color: var(--accent);
}
.stat-icon svg {
width: 20px;
height: 20px;
}
.stat-content {
flex: 1;
}
.stat-value {
font-size: var(--text-xl);
font-weight: 700;
color: var(--text-primary);
}
.stat-label {
font-size: var(--text-xs);
color: var(--text-muted);
}
.page-header {
margin-bottom: var(--space-4);
}
@@ -518,6 +464,11 @@
color: #f97316;
}
.activity-icon.git-file {
background: rgba(234, 179, 8, 0.2);
color: #eab308;
}
.activity-icon.file {
background: rgba(20, 184, 166, 0.2);
color: #14b8a6;
@@ -1000,38 +951,6 @@
</div>
</div>
<!-- Stats Summary -->
<div class="stats-summary" id="statsSummary">
<div class="stat-card" title="Task-uri completate azi">
<div class="stat-icon"><i data-lucide="check-circle"></i></div>
<div class="stat-content">
<div class="stat-value" id="statToday">0</div>
<div class="stat-label">Tasks azi</div>
</div>
</div>
<div class="stat-card" title="Task-uri completate săptămâna aceasta">
<div class="stat-icon"><i data-lucide="calendar"></i></div>
<div class="stat-content">
<div class="stat-value" id="statWeek">0</div>
<div class="stat-label">Tasks săpt.</div>
</div>
</div>
<div class="stat-card" title="Task-uri completate luna aceasta">
<div class="stat-icon"><i data-lucide="trending-up"></i></div>
<div class="stat-content">
<div class="stat-value" id="statMonth">0</div>
<div class="stat-label">Tasks lună</div>
</div>
</div>
<div class="stat-card" title="Număr de fișiere insights">
<div class="stat-icon"><i data-lucide="lightbulb"></i></div>
<div class="stat-content">
<div class="stat-value" id="statInsights">0</div>
<div class="stat-label">Insights</div>
</div>
</div>
</div>
<div class="dashboard-grid">
<!-- Activity Panel -->
<div class="panel activity-panel" id="activityPanel">
@@ -1297,40 +1216,28 @@
// Update details
const details = document.getElementById('gitDetails');
const GITEA_URL = 'https://gitea.romfast.ro/romfast/clawd';
let html = `
<div class="status-detail-item">
<i data-lucide="git-branch"></i>
<span>Branch: <strong>${git.branch}</strong></span>
</div>
<div class="status-detail-item">
<i data-lucide="git-commit"></i>
<span>Last: <code>${git.lastCommit.hash}</code> ${git.lastCommit.message} (${git.lastCommit.time})</span>
<span><a href="${GITEA_URL}/commit/${git.lastCommit.hash}" target="_blank" style="color:var(--accent)">${git.lastCommit.hash}</a> ${git.lastCommit.message.substring(0, 40)}${git.lastCommit.message.length > 40 ? '...' : ''} <small>(${git.lastCommit.time})</small></span>
</div>
`;
if (git.uncommittedCount > 0) {
const files = git.uncommitted.slice(0, 3).map(f => f.trim().split(' ').pop()).join(', ');
const more = git.uncommittedCount > 3 ? ` +${git.uncommittedCount - 3}` : '';
html += `<div class="status-detail-item uncommitted">
<i data-lucide="alert-circle"></i>
<span><strong>${git.uncommittedCount}</strong> fișiere necomise:</span>
</div>`;
git.uncommitted.slice(0, 5).forEach(file => {
html += `<div class="status-detail-item uncommitted">
<i data-lucide="file"></i>
<code>${file}</code>
</div>`;
});
if (git.uncommittedCount > 5) {
html += `<div class="status-detail-item uncommitted">
<span>... și încă ${git.uncommittedCount - 5}</span>
</div>`;
}
} else {
html += `<div class="status-detail-item">
<i data-lucide="check-circle"></i>
<span>Totul comis ✓</span>
<span><a href="files.html?git=1" style="color:var(--warning)"><strong>${git.uncommittedCount}</strong> necomise</a>: <small>${files}${more}</small></span>
</div>`;
}
html += `<div class="status-detail-item">
<i data-lucide="external-link"></i>
<a href="${GITEA_URL}" target="_blank" style="color:var(--accent);font-size:var(--text-xs)">gitea.romfast.ro/romfast/clawd</a>
</div>`;
details.innerHTML = html;
lucide.createIcons();
@@ -1354,7 +1261,9 @@
badge.className = 'status-badge ' + (status.anaf.ok !== false ? 'ok' : 'warning');
const subtitle = document.getElementById('anafSubtitle');
subtitle.textContent = status.anaf.message || 'Nicio modificare detectată';
const lastCheck = status.anaf.lastCheck || '-';
const msg = status.anaf.ok !== false ? 'Nicio modificare' : (status.anaf.message || 'Modificări!');
subtitle.textContent = `${msg} · ${lastCheck}`;
if (status.anaf.lastCheck) {
document.getElementById('anafLastCheck').textContent =
@@ -1542,51 +1451,9 @@
function refreshActivity() {
loadActivity();
loadStats();
showToast('Activitate reîmprospătată');
}
async function loadStats() {
try {
// Load tasks
const tasksRes = await fetch('tasks.json');
const tasksData = await tasksRes.json();
// Get done tasks
const doneColumn = tasksData.columns.find(c => c.id === 'done');
const doneTasks = doneColumn ? doneColumn.tasks : [];
const now = new Date();
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const weekStart = new Date(todayStart);
weekStart.setDate(weekStart.getDate() - weekStart.getDay() + 1); // Monday
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
let today = 0, week = 0, month = 0;
doneTasks.forEach(task => {
if (!task.completed) return;
const completed = new Date(task.completed);
if (completed >= todayStart) today++;
if (completed >= weekStart) week++;
if (completed >= monthStart) month++;
});
document.getElementById('statToday').textContent = today;
document.getElementById('statWeek').textContent = week;
document.getElementById('statMonth').textContent = month;
// Count insights
const insightsRes = await fetch('/echo/api/files?path=kb/insights');
if (insightsRes.ok) {
const insightsData = await insightsRes.json();
document.getElementById('statInsights').textContent = insightsData.files ? insightsData.files.length : 0;
}
} catch (e) {
console.log('Stats load error:', e);
}
}
function renderActivity() {
const body = document.getElementById('activityBody');
@@ -1607,6 +1474,7 @@
const typeLabels = {
'cron': '⏰ Cron Jobs',
'git': '📦 Git Commits',
'git-file': '🔸 Git Changes',
'file': '📄 Fișiere',
'task': '✅ Task-uri'
};
@@ -1617,13 +1485,22 @@
<i data-lucide="activity"></i>
Ultimele 24h
</div>
${activityData.map(item => `
<div class="activity-item" ${item.path ? `onclick="window.open('files.html#${item.path}', '_blank')" style="cursor:pointer"` : ''}>
${activityData.map(item => {
let clickAttr = '';
if (item.type === 'git-file' && item.path) {
clickAttr = `onclick="window.open('files.html#${item.path}', '_blank')" style="cursor:pointer"`;
} else if (item.path) {
clickAttr = `onclick="window.open('files.html#${item.path}', '_blank')" style="cursor:pointer"`;
} else if (item.type === 'git' && item.commitHash) {
clickAttr = `onclick="window.open('https://gitea.romfast.ro/romfast/clawd/commit/${item.commitHash}', '_blank')" style="cursor:pointer"`;
}
return `
<div class="activity-item" ${clickAttr}>
<div class="activity-icon ${item.type}">
<i data-lucide="${item.icon || 'activity'}"></i>
</div>
<div class="activity-content">
<div class="activity-text">${item.text}</div>
<div class="activity-text">${item.type === 'git' && item.commitHash ? `<code style="font-size:10px;margin-right:4px">${item.commitHash}</code>` : ''}${item.text}</div>
<div class="activity-meta">
<span class="activity-type">${typeLabels[item.type] || item.type}</span>
<span class="activity-agent">${item.agent}</span>
@@ -1631,7 +1508,7 @@
</div>
</div>
</div>
`).join('')}
`}).join('')}
</div>
`;
lucide.createIcons();
@@ -1867,7 +1744,6 @@
loadStatus();
loadIssues();
loadActivity();
loadStats();
</script>
</body>
</html>