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/ledger.html
Alexander Payne 5f9bbb8435 feat: add task queue with human-in-the-loop approval + work orders + UI bug fixes
Task Queue system:
- New /tasks page with three-column layout (Pending/Active/Completed)
- Full CRUD API at /api/tasks with approve/veto/modify/pause/cancel/retry
- SQLite persistence in task_queue table
- WebSocket live updates via ws_manager
- Create task modal with agent assignment and priority
- Auto-approve rules for low-risk tasks
- HTMX polling for real-time column updates
- HOME TASK buttons now link to task queue with agent pre-selected
- MARKET HIRE buttons link to task queue with agent pre-selected

Work Order system:
- External submission API for agents/users (POST /work-orders/submit)
- Risk scoring and configurable auto-execution thresholds
- Dashboard at /work-orders/queue with approve/reject/execute flow
- Integration with swarm task system for execution

UI & Dashboard bug fixes:
- EVENTS: add startup event so page is never empty
- LEDGER: fix empty filter params in URL
- MISSION CONTROL: LLM backend and model now read from /health
- MISSION CONTROL: agent count fallback to /swarm/agents
- SWARM: HTMX fallback loads initial data if WebSocket is slow
- MEMORY: add edit/delete buttons for personal facts
- UPGRADES: add empty state guidance with links
- BRIEFING: add regenerate button and POST /briefing/regenerate endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 10:27:08 -05:00

146 lines
5.0 KiB
HTML

{% extends "base.html" %}
{% block title %}Lightning Ledger - Timmy Time{% endblock %}
{% block content %}
<div class="mc-panel">
<div class="mc-panel-header">
<h1 class="page-title">Lightning Ledger</h1>
<p class="mc-text-secondary">Bitcoin Lightning Network transaction history</p>
</div>
<!-- Balance Cards -->
<div class="mc-stats-row balance-row">
<div class="mc-stat-card sats-balance">
<div class="mc-stat-label">Available Balance</div>
<div class="mc-stat-value">{{ balance.available_sats }} <small>sats</small></div>
</div>
<div class="mc-stat-card">
<div class="mc-stat-label">Total Received</div>
<div class="mc-stat-value">{{ balance.incoming_total_sats }} <small>sats</small></div>
</div>
<div class="mc-stat-card">
<div class="mc-stat-label">Total Sent</div>
<div class="mc-stat-value">{{ balance.outgoing_total_sats }} <small>sats</small></div>
</div>
<div class="mc-stat-card">
<div class="mc-stat-label">Fees Paid</div>
<div class="mc-stat-value">{{ balance.fees_paid_sats }} <small>sats</small></div>
</div>
<div class="mc-stat-card net-balance">
<div class="mc-stat-label">Net</div>
<div class="mc-stat-value {% if balance.net_sats >= 0 %}positive{% else %}negative{% endif %}">
{{ balance.net_sats }} <small>sats</small>
</div>
</div>
</div>
<!-- Pending Summary -->
{% if balance.pending_incoming_sats > 0 or balance.pending_outgoing_sats > 0 %}
<div class="mc-pending-row">
{% if balance.pending_incoming_sats > 0 %}
<span class="mc-pending-badge incoming">
Pending incoming: {{ balance.pending_incoming_sats }} sats
</span>
{% endif %}
{% if balance.pending_outgoing_sats > 0 %}
<span class="mc-pending-badge outgoing">
Pending outgoing: {{ balance.pending_outgoing_sats }} sats
</span>
{% endif %}
</div>
{% endif %}
<!-- Filters -->
<div class="mc-filters">
<form id="ledger-filter-form" class="mc-filter-form">
<select name="tx_type" class="mc-select" onchange="submitLedgerFilter()">
<option value="">All Types</option>
{% for t in tx_types %}
<option value="{{ t }}" {% if filter_type == t %}selected{% endif %}>{{ t }}</option>
{% endfor %}
</select>
<select name="status" class="mc-select" onchange="submitLedgerFilter()">
<option value="">All Statuses</option>
{% for s in tx_statuses %}
<option value="{{ s }}" {% if filter_status == s %}selected{% endif %}>{{ s }}</option>
{% endfor %}
</select>
</form>
</div>
<script>
function submitLedgerFilter() {
var form = document.getElementById('ledger-filter-form');
var params = new URLSearchParams();
var txType = form.querySelector('[name="tx_type"]').value;
var status = form.querySelector('[name="status"]').value;
if (txType) params.append('tx_type', txType);
if (status) params.append('status', status);
var qs = params.toString();
window.location.href = '/lightning/ledger' + (qs ? '?' + qs : '');
}
</script>
<!-- Transactions Table -->
<div class="mc-table-container">
{% if transactions %}
<table class="mc-table transactions-table">
<thead>
<tr>
<th>Time</th>
<th>Type</th>
<th>Status</th>
<th>Amount</th>
<th>Hash</th>
<th>Memo</th>
</tr>
</thead>
<tbody>
{% for tx in transactions %}
<tr class="transaction-row" data-type="{{ tx.tx_type.value }}" data-status="{{ tx.status.value }}">
<td>{{ tx.created_at[11:19] }}</td>
<td>
<span class="mc-badge mc-badge-{{ tx.tx_type.value }}">
{{ tx.tx_type.value }}
</span>
</td>
<td>
<span class="mc-status mc-status-{{ tx.status.value }}">
{{ tx.status.value }}
</span>
</td>
<td class="amount {% if tx.tx_type.value == 'incoming' %}positive{% else %}negative{% endif %}">
{% if tx.tx_type.value == 'incoming' %}+{% endif %}{{ tx.amount_sats }} sats
</td>
<td class="mono">{{ tx.payment_hash[:16] }}...</td>
<td>{{ tx.memo }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="mc-empty-state">
<p>No transactions yet.</p>
<p class="mc-text-secondary">Invoices and payments will appear here.</p>
</div>
{% endif %}
</div>
<!-- Weekly Stats -->
{% if stats %}
<div class="mc-stats-section">
<h3>Activity (Last 7 Days)</h3>
<div class="mc-mini-chart">
{% for date, day_stats in stats.items() %}
<div class="mc-chart-bar" title="{{ date }}">
<div class="bar incoming" style="height: {{ day_stats.incoming.count * 10 }}px"></div>
<div class="bar outgoing" style="height: {{ day_stats.outgoing.count * 10 }}px"></div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endblock %}