Update ashboard, dashboard (~3)
This commit is contained in:
@@ -28,9 +28,43 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
self.handle_files_post()
|
||||
elif self.path == '/api/refresh-index':
|
||||
self.handle_refresh_index()
|
||||
elif self.path == '/api/git-commit':
|
||||
self.handle_git_commit()
|
||||
else:
|
||||
self.send_error(404)
|
||||
|
||||
def handle_git_commit(self):
|
||||
"""Run git commit and push."""
|
||||
try:
|
||||
script = TOOLS_DIR / 'git_commit.py'
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(script), '--push'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
cwd=str(BASE_DIR)
|
||||
)
|
||||
|
||||
output = result.stdout + result.stderr
|
||||
|
||||
# Parse files count
|
||||
files_match = re.search(r'Files changed: (\d+)', output)
|
||||
files = int(files_match.group(1)) if files_match else 0
|
||||
|
||||
if result.returncode == 0 or 'Pushing...' in output:
|
||||
self.send_json({
|
||||
'success': True,
|
||||
'files': files,
|
||||
'output': output
|
||||
})
|
||||
else:
|
||||
self.send_json({
|
||||
'success': False,
|
||||
'error': output or 'Unknown error'
|
||||
})
|
||||
except Exception as e:
|
||||
self.send_json({'success': False, 'error': str(e)}, 500)
|
||||
|
||||
def handle_refresh_index(self):
|
||||
"""Regenerate memory/kb/index.json"""
|
||||
try:
|
||||
|
||||
@@ -725,12 +725,13 @@
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
padding: 10px 12px;
|
||||
background: #1f2937;
|
||||
background: #111827;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 6px;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid #1f2937;
|
||||
}
|
||||
.todo-item:hover { background: #374151; }
|
||||
.todo-item:hover { background: #1f2937; }
|
||||
.todo-item.done { opacity: 0.6; }
|
||||
.todo-item.done .todo-text { text-decoration: line-through; }
|
||||
.todo-checkbox {
|
||||
@@ -754,6 +755,7 @@
|
||||
.todo-checkbox.checked svg { display: block; }
|
||||
.todo-content { flex: 1; min-width: 0; }
|
||||
.todo-text { font-size: 14px; color: #f3f4f6; margin-bottom: 4px; }
|
||||
.todo-context { font-size: 13px; color: #9ca3af; margin-bottom: 6px; font-style: italic; }
|
||||
.todo-meta { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
||||
.todo-domain {
|
||||
font-size: 11px;
|
||||
@@ -771,6 +773,26 @@
|
||||
}
|
||||
.todo-due.overdue { color: #ef4444; font-weight: 500; }
|
||||
.todo-source { font-size: 11px; color: #6b7280; }
|
||||
|
||||
/* Button icon only */
|
||||
.btn-icon {
|
||||
padding: 6px;
|
||||
background: transparent;
|
||||
border: 1px solid #374151;
|
||||
border-radius: 6px;
|
||||
color: #9ca3af;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-icon:hover {
|
||||
background: #374151;
|
||||
color: #f3f4f6;
|
||||
border-color: #4b5563;
|
||||
}
|
||||
.btn-icon svg { width: 16px; height: 16px; }
|
||||
.issue-owner.clawdbot { color: #8b5cf6; }
|
||||
|
||||
.issue-date {
|
||||
@@ -931,7 +953,6 @@
|
||||
<main class="main">
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">Dashboard</h1>
|
||||
<p class="page-subtitle">Echo Work · Productivitate și proiecte</p>
|
||||
</div>
|
||||
|
||||
<!-- Status Bar -->
|
||||
@@ -943,7 +964,10 @@
|
||||
</div>
|
||||
<div class="status-summary" id="statusSummary">Se încarcă...</div>
|
||||
<div class="status-actions" onclick="event.stopPropagation()">
|
||||
<button class="btn btn-secondary btn-sm" onclick="refreshStatus()" title="Refresh">
|
||||
<button class="btn btn-icon" onclick="gitCommit()" title="Git Commit">
|
||||
<i data-lucide="git-commit"></i>
|
||||
</button>
|
||||
<button class="btn btn-icon" onclick="refreshStatus()" title="Refresh">
|
||||
<i data-lucide="refresh-cw"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -1017,24 +1041,29 @@
|
||||
</div>
|
||||
|
||||
<div class="dashboard-grid">
|
||||
<!-- Activity Panel -->
|
||||
<div class="panel activity-panel" id="activityPanel">
|
||||
<div class="panel-header" onclick="toggleSection('activityPanel')">
|
||||
<!-- Issues Panel -->
|
||||
<div class="panel issues-panel" id="issuesPanel">
|
||||
<div class="panel-header" onclick="toggleSection('issuesPanel')">
|
||||
<div class="panel-header-left">
|
||||
<i data-lucide="chevron-down" class="panel-toggle"></i>
|
||||
<div class="panel-title">
|
||||
<i data-lucide="bot"></i>
|
||||
<span>Activity</span>
|
||||
<span>Issues</span>
|
||||
</div>
|
||||
<span class="panel-count" id="activityCount">0</span>
|
||||
<span class="panel-count" id="issuesCount">0</span>
|
||||
</div>
|
||||
<div class="panel-actions" onclick="event.stopPropagation()">
|
||||
<button class="btn btn-secondary btn-sm" onclick="refreshActivity()" title="Refresh">
|
||||
<i data-lucide="refresh-cw"></i>
|
||||
<button class="btn btn-icon" onclick="showAddModal()" title="Adaugă issue">
|
||||
<i data-lucide="plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" id="activityBody">
|
||||
<div class="issues-filters" id="issuesFilters">
|
||||
<button class="filter-btn active" data-filter="all">Toate</button>
|
||||
<button class="filter-btn" data-filter="marius">👤 Marius</button>
|
||||
<button class="filter-btn" data-filter="robert">👷 Robert</button>
|
||||
<button class="filter-btn" data-filter="clawdbot">🤖 Clawdbot</button>
|
||||
</div>
|
||||
<div class="panel-body" id="issuesBody">
|
||||
<div class="empty-state">
|
||||
<i data-lucide="loader"></i>
|
||||
<p>Se încarcă...</p>
|
||||
@@ -1042,22 +1071,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Issues Panel -->
|
||||
<!-- Todo's Panel -->
|
||||
<div class="panel todos-panel" id="todosPanel">
|
||||
<div class="panel-header" onclick="toggleSection('todosPanel')">
|
||||
<div class="panel-header-left">
|
||||
<i data-lucide="chevron-down" class="panel-toggle"></i>
|
||||
<div class="panel-title">
|
||||
<i data-lucide="list-todo"></i>
|
||||
<span>Todo's</span>
|
||||
</div>
|
||||
<span class="panel-count" id="todosCount">0</span>
|
||||
</div>
|
||||
<div class="panel-actions" onclick="event.stopPropagation()">
|
||||
<button class="btn btn-primary btn-sm" onclick="showAddTodoModal()">
|
||||
<button class="btn btn-icon" onclick="showAddTodoModal()" title="Adaugă todo">
|
||||
<i data-lucide="plus"></i>
|
||||
<span>Nou</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1069,30 +1095,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel issues-panel" id="issuesPanel">
|
||||
<div class="panel-header" onclick="toggleSection('issuesPanel')">
|
||||
<!-- Activity Panel -->
|
||||
<div class="panel activity-panel" id="activityPanel">
|
||||
<div class="panel-header" onclick="toggleSection('activityPanel')">
|
||||
<div class="panel-header-left">
|
||||
<i data-lucide="chevron-down" class="panel-toggle"></i>
|
||||
<div class="panel-title">
|
||||
<i data-lucide="check-square"></i>
|
||||
<span>Issues</span>
|
||||
<span>Activity</span>
|
||||
</div>
|
||||
<span class="panel-count" id="issuesCount">0</span>
|
||||
<span class="panel-count" id="activityCount">0</span>
|
||||
</div>
|
||||
<div class="panel-actions" onclick="event.stopPropagation()">
|
||||
<button class="btn btn-primary btn-sm" onclick="showAddModal()">
|
||||
<i data-lucide="plus"></i>
|
||||
<span>Nou</span>
|
||||
<button class="btn btn-icon" onclick="refreshActivity()" title="Refresh">
|
||||
<i data-lucide="refresh-cw"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="issues-filters" id="issuesFilters">
|
||||
<button class="filter-btn active" data-filter="all">Toate</button>
|
||||
<button class="filter-btn" data-filter="marius">👤 Marius</button>
|
||||
<button class="filter-btn" data-filter="robert">👷 Robert</button>
|
||||
<button class="filter-btn" data-filter="clawdbot">🤖 Clawdbot</button>
|
||||
</div>
|
||||
<div class="panel-body" id="issuesBody">
|
||||
<div class="panel-body" id="activityBody">
|
||||
<div class="empty-state">
|
||||
<i data-lucide="loader"></i>
|
||||
<p>Se încarcă...</p>
|
||||
@@ -1279,6 +1298,23 @@
|
||||
updateStatusSummary();
|
||||
}
|
||||
|
||||
async function gitCommit() {
|
||||
if (!confirm('Fac commit și push la toate modificările?')) return;
|
||||
showToast('Se execută commit...', 'info');
|
||||
try {
|
||||
const response = await fetch('/echo/api/git-commit', { method: 'POST' });
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
showToast('Commit reușit: ' + (result.files || 0) + ' fișiere', 'success');
|
||||
setTimeout(refreshStatus, 1000);
|
||||
} else {
|
||||
showToast('Eroare: ' + (result.error || 'necunoscută'), 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
showToast('Eroare la commit: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshStatus() {
|
||||
showToast('Se reîmprospătează...');
|
||||
await loadStatus();
|
||||
@@ -1551,6 +1587,7 @@
|
||||
</div>
|
||||
<div class="todo-content">
|
||||
<div class="todo-text">${todo.text}</div>
|
||||
${todo.context ? `<div class="todo-context">${todo.context}</div>` : ''}
|
||||
<div class="todo-meta">
|
||||
<span class="todo-domain ${todo.domain}">@${todo.domain}</span>
|
||||
${todo.dueDate ? `<span class="todo-due ${isOverdue ? 'overdue' : ''}">${formatDate(todo.dueDate)}</span>` : ''}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
{
|
||||
"lastUpdated": "2026-02-02T10:45:00Z",
|
||||
"lastUpdated": "2026-02-02T10:52:00Z",
|
||||
"items": [
|
||||
{
|
||||
"id": "prov-2026-02-02",
|
||||
"text": "Provocare: Observă când apare vocea critică și dă-i un nume ridicol",
|
||||
"text": "Provocare: Alege UN lucru și scrie pe hârtie ce EFORT necesită. Întreabă-te: Îmi asum ASTA?",
|
||||
"context": "Dacă da → fă-l. Dacă nu → ajustează sau renunță fără vinovăție.",
|
||||
"domain": "self",
|
||||
"dueDate": "2026-02-02",
|
||||
"done": false,
|
||||
"doneAt": null,
|
||||
"source": "morning-coaching",
|
||||
"source": "Zoltan Vereș - Motivația Intrinsecă",
|
||||
"createdAt": "2026-02-02T09:00:00Z"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user