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>
146 lines
5.7 KiB
HTML
146 lines
5.7 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Work Orders — Timmy Time{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid" style="max-width: 1200px; padding: 24px;">
|
|
|
|
<!-- Header -->
|
|
<div class="d-flex justify-content-between align-items-center" style="margin-bottom: 24px;">
|
|
<div>
|
|
<h2 style="margin: 0; font-size: 1.5rem;">WORK ORDERS</h2>
|
|
<div style="font-size: 0.75rem; color: var(--text-muted); letter-spacing: 0.1em; margin-top: 4px;">
|
|
SUBMIT · REVIEW · EXECUTE
|
|
</div>
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<span class="badge" style="background: var(--amber); color: #000; font-size: 0.75rem;">
|
|
{{ pending_count }} PENDING
|
|
</span>
|
|
<button class="btn mc-btn-send" style="font-size: 0.75rem; padding: 6px 16px;"
|
|
onclick="document.getElementById('submit-form').style.display = document.getElementById('submit-form').style.display === 'none' ? 'block' : 'none'">
|
|
+ NEW
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Submit Form (hidden by default) -->
|
|
<div id="submit-form" class="card" style="display: none; margin-bottom: 24px; padding: 20px;">
|
|
<h3 style="font-size: 0.875rem; margin-bottom: 16px; letter-spacing: 0.1em;">SUBMIT WORK ORDER</h3>
|
|
<form hx-post="/work-orders/submit"
|
|
hx-target="#submit-result"
|
|
hx-swap="innerHTML"
|
|
hx-on::after-request="if(event.detail.successful){this.reset(); setTimeout(()=>htmx.trigger('#pending-section','load'),500);}"
|
|
class="d-flex flex-column gap-3">
|
|
|
|
<div>
|
|
<label style="font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.15em;">TITLE</label>
|
|
<input type="text" name="title" class="form-control mc-input" placeholder="Brief title for this work order" required />
|
|
</div>
|
|
|
|
<div>
|
|
<label style="font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.15em;">DESCRIPTION</label>
|
|
<textarea name="description" class="form-control mc-input" rows="3" placeholder="Detailed description..."></textarea>
|
|
</div>
|
|
|
|
<div class="d-flex gap-3">
|
|
<div style="flex: 1;">
|
|
<label style="font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.15em;">PRIORITY</label>
|
|
<select name="priority" class="form-control mc-input">
|
|
{% for p in priorities %}
|
|
<option value="{{ p }}" {{ "selected" if p == "medium" else "" }}>{{ p | upper }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div style="flex: 1;">
|
|
<label style="font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.15em;">CATEGORY</label>
|
|
<select name="category" class="form-control mc-input">
|
|
{% for c in categories %}
|
|
<option value="{{ c }}" {{ "selected" if c == "suggestion" else "" }}>{{ c | upper }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div style="flex: 1;">
|
|
<label style="font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.15em;">SUBMITTER</label>
|
|
<input type="text" name="submitter" class="form-control mc-input" value="dashboard" />
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label style="font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.15em;">RELATED FILES (comma-separated)</label>
|
|
<input type="text" name="related_files" class="form-control mc-input" placeholder="src/timmy/agent.py, src/config.py" />
|
|
</div>
|
|
|
|
<input type="hidden" name="submitter_type" value="user" />
|
|
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div id="submit-result" style="font-size: 0.75rem;"></div>
|
|
<button type="submit" class="btn mc-btn-send" style="padding: 8px 24px;">SUBMIT</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Pending Queue -->
|
|
<div class="card" style="margin-bottom: 24px; padding: 20px;">
|
|
<h3 style="font-size: 0.875rem; margin-bottom: 16px; letter-spacing: 0.1em;">
|
|
INCOMING QUEUE
|
|
</h3>
|
|
<div id="pending-section"
|
|
hx-get="/work-orders/queue/pending"
|
|
hx-trigger="load, every 30s"
|
|
hx-swap="innerHTML">
|
|
{% if pending %}
|
|
{% for wo in pending %}
|
|
{% include "partials/work_order_card.html" %}
|
|
{% endfor %}
|
|
{% else %}
|
|
<div style="color: var(--text-muted); font-size: 0.8rem; padding: 12px 0;">
|
|
No pending work orders. Use the + NEW button or the API to submit one.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Active Work -->
|
|
<div class="card" style="margin-bottom: 24px; padding: 20px;">
|
|
<h3 style="font-size: 0.875rem; margin-bottom: 16px; letter-spacing: 0.1em;">
|
|
ACTIVE WORK
|
|
</h3>
|
|
<div id="active-section"
|
|
hx-get="/work-orders/queue/active"
|
|
hx-trigger="load, every 15s"
|
|
hx-swap="innerHTML">
|
|
{% if active %}
|
|
{% for wo in active %}
|
|
{% include "partials/work_order_card.html" %}
|
|
{% endfor %}
|
|
{% else %}
|
|
<div style="color: var(--text-muted); font-size: 0.8rem; padding: 12px 0;">
|
|
No work orders currently in progress.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- History -->
|
|
<div class="card" style="padding: 20px;">
|
|
<h3 style="font-size: 0.875rem; margin-bottom: 16px; letter-spacing: 0.1em;">
|
|
HISTORY
|
|
</h3>
|
|
{% if completed or rejected %}
|
|
{% for wo in completed %}
|
|
{% include "partials/work_order_card.html" %}
|
|
{% endfor %}
|
|
{% for wo in rejected %}
|
|
{% include "partials/work_order_card.html" %}
|
|
{% endfor %}
|
|
{% else %}
|
|
<div style="color: var(--text-muted); font-size: 0.8rem; padding: 12px 0;">
|
|
No completed or rejected work orders yet.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
</div>
|
|
{% endblock %}
|