1
0
This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Timmy-time-dashboard/src/dashboard/templates/upgrade_queue.html
Alexander Whitestone 622a6a9204 polish: extract inline CSS, add connection status, panel macro, favicon, ollama cache, toast system (#164)
Major:
- Extract all inline <style> blocks from 22 Jinja2 templates into
  static/css/mission-control.css — single cacheable stylesheet
- Add tox lint check that fails on inline <style> in templates

Minor:
1. Connection status indicator in topbar (green/amber/red dot) reflecting
   WebSocket + Ollama reachability, with auto-reconnect
2. Jinja2 {% macro panel(title) %} in macros.html — eliminates repeated
   .card.mc-panel markup; index.html converted as example
3. SVG favicon (purple T + orange dot)
4. 30-second TTL cache on _check_ollama() to avoid blocking the event loop
   on every health poll (asyncio.to_thread was already in place)
5. Toast notification system (McToast.show) for transient status messages —
   wired into connection status for Ollama/WebSocket state changes

Enforcement:
- CLAUDE.md updated with conventions 11-14 (no inline CSS, use panel macro,
  use toasts, never block the event loop)
- tox lint + pre-push environments now fail on inline <style> blocks

https://claude.ai/code/session_014FQ785MQdyJQ4BAXrRSo9w

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-11 09:52:57 -04:00

186 lines
5.7 KiB
HTML

{% extends "base.html" %}
{% block title %}Upgrade Queue{% endblock %}
{% block content %}
<div class="mc-panel">
<div class="mc-panel-header">
<h1 class="page-title">Upgrade Queue</h1>
<p class="mc-text-secondary">Review and approve self-modification proposals</p>
</div>
<!-- Pending Upgrades -->
<div class="mc-section">
<h2 class="mc-section-title">
Pending Upgrades
{% if pending_count > 0 %}
<span class="mc-badge mc-badge-warning">{{ pending_count }}</span>
{% endif %}
</h2>
{% if pending %}
<div class="upgrades-list">
{% for upgrade in pending %}
<div class="upgrade-card upgrade-pending" data-id="{{ upgrade.id }}">
<div class="upgrade-header">
<h3>{{ upgrade.description }}</h3>
<span class="mc-badge mc-badge-warning">PENDING</span>
</div>
<div class="upgrade-meta">
<span class="upgrade-branch">Branch: {{ upgrade.branch_name }}</span>
<span class="upgrade-time">Proposed: {{ upgrade.proposed_at[11:16] }}</span>
</div>
<div class="upgrade-files">
Files: {{ upgrade.files_changed|join(', ') }}
</div>
<div class="upgrade-test-status">
{% if upgrade.test_passed %}
<span class="test-passed">✓ Tests passed</span>
{% else %}
<span class="test-failed">✗ Tests failed</span>
{% endif %}
</div>
<div class="upgrade-actions">
<button class="mc-btn mc-btn-primary" onclick="approveUpgrade('{{ upgrade.id }}')">
Approve
</button>
<button class="mc-btn" onclick="rejectUpgrade('{{ upgrade.id }}')">
Reject
</button>
<a href="/self-modify/queue/{{ upgrade.id }}/diff" class="mc-btn mc-btn-secondary">
View Diff
</a>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="mc-empty-state" style="padding:2rem; text-align:center;">
<p>No pending upgrades.</p>
<p class="mc-text-secondary" style="margin-bottom:1rem;">Upgrades are proposed by the self-modification system when the system identifies improvements. You can also trigger them via work orders or the task queue.</p>
<div style="display:flex; gap:0.75rem; justify-content:center; flex-wrap:wrap;">
<a href="/work-orders/queue" class="mc-btn mc-btn-secondary" style="text-decoration:none;">View Work Orders</a>
<a href="/tasks" class="mc-btn mc-btn-secondary" style="text-decoration:none;">View Task Queue</a>
</div>
</div>
{% endif %}
</div>
<!-- Approved (Waiting to Apply) -->
{% if approved %}
<div class="mc-section">
<h2 class="mc-section-title">Approved (Ready to Apply)</h2>
<div class="upgrades-list">
{% for upgrade in approved %}
<div class="upgrade-card upgrade-approved">
<div class="upgrade-header">
<h3>{{ upgrade.description }}</h3>
<span class="mc-badge mc-badge-success">APPROVED</span>
</div>
<div class="upgrade-actions">
<button class="mc-btn mc-btn-primary" onclick="applyUpgrade('{{ upgrade.id }}')">
Apply Now
</button>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<!-- History -->
<div class="mc-section">
<h2 class="mc-section-title">History</h2>
{% if applied %}
<h4>Applied</h4>
<div class="upgrades-list upgrades-history">
{% for upgrade in applied %}
<div class="upgrade-card upgrade-applied">
<span class="upgrade-desc">{{ upgrade.description }}</span>
<span class="mc-badge mc-badge-success">APPLIED</span>
<span class="upgrade-time">{{ upgrade.applied_at[11:16] if upgrade.applied_at else '' }}</span>
</div>
{% endfor %}
</div>
{% endif %}
{% if rejected %}
<h4>Rejected</h4>
<div class="upgrades-list upgrades-history">
{% for upgrade in rejected %}
<div class="upgrade-card upgrade-rejected">
<span class="upgrade-desc">{{ upgrade.description }}</span>
<span class="mc-badge mc-badge-secondary">REJECTED</span>
</div>
{% endfor %}
</div>
{% endif %}
{% if failed %}
<h4>Failed</h4>
<div class="upgrades-list upgrades-history">
{% for upgrade in failed %}
<div class="upgrade-card upgrade-failed">
<span class="upgrade-desc">{{ upgrade.description }}</span>
<span class="mc-badge mc-badge-danger">FAILED</span>
<span class="upgrade-error" title="{{ upgrade.error_message }}">⚠️</span>
</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<script>
async function approveUpgrade(id) {
if (!confirm('Approve this upgrade?')) return;
const response = await fetch(`/self-modify/queue/${id}/approve`, {
method: 'POST',
});
if (response.ok) {
window.location.reload();
} else {
alert('Failed to approve: ' + await response.text());
}
}
async function rejectUpgrade(id) {
if (!confirm('Reject this upgrade? The branch will be deleted.')) return;
const response = await fetch(`/self-modify/queue/${id}/reject`, {
method: 'POST',
});
if (response.ok) {
window.location.reload();
} else {
alert('Failed to reject: ' + await response.text());
}
}
async function applyUpgrade(id) {
if (!confirm('Apply this upgrade? This will merge to main.')) return;
const response = await fetch(`/self-modify/queue/${id}/apply`, {
method: 'POST',
});
if (response.ok) {
alert('Upgrade applied successfully!');
window.location.reload();
} else {
const error = await response.text();
alert('Failed to apply: ' + error);
}
}
</script>
{% endblock %}