Files
pulse/views/pages/executions.ejs
T
jaredandClaude Fable 5.1 68d0a906a6 feat(ui): TDS migration stage 2 — six page views and page modules
- Dashboard, Workers, Workflows, Executions, Quick Command, Scheduler pages on the
  shared layout, all behaviour via Pulse delegated actions (no inline handlers)
- Executions: server-driven Manual/Automated views, compare mode, detail modal with all
  log types, ?open= deep link, cross-page re-run via sessionStorage
- Workflows: run modal (dry-run available for every workflow), create modal pre-filled
  with the example definition
- Fix EJS comment in page-header partial that broke rendering

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamVMDrA8RqhyxmUHgiqRp
2026-09-08 21:57:33 -04:00

119 lines
5.7 KiB
Plaintext

<%#
Executions page (WP-E).
Owns DOM id prefix `ex-` and action namespace `ex:*`.
All behaviour lives in /assets/pages/executions.js (auto-loaded by the layout);
styling additions in /assets/pages/executions.css (auto-linked).
The page-header is written out inline rather than through the shared partial
because the Clear Completed button is admin-only and the partial takes its
actions as a pre-rendered string.
%>
<div class="lt-page-header">
<div>
<h1 class="lt-page-title">Executions</h1>
<p class="lt-page-subtitle">Workflow and quick-command run history</p>
</div>
<div class="lt-page-actions">
<div class="lt-btn-group">
<button type="button" class="lt-btn lt-btn-secondary lt-btn-sm" data-action="ex:refresh">&#x21bb; Refresh</button>
<button type="button" class="lt-btn lt-btn-secondary lt-btn-sm" id="ex-compare-toggle"
data-action="ex:compare-toggle" aria-pressed="false">&#x25a4; Compare Mode</button>
<button type="button" class="lt-btn lt-btn-primary lt-btn-sm is-hidden" id="ex-compare-run"
data-action="ex:compare-run">&#x2696; Compare Selected</button>
<% if (user && user.isAdmin) { %>
<button type="button" class="lt-btn lt-btn-danger lt-btn-sm" data-action="ex:clear-completed">&#x2716; Clear Completed</button>
<% } %>
</div>
</div>
</div>
<div class="lt-frame">
<span class="lt-frame-bl"></span><span class="lt-frame-br"></span>
<!-- Manual / Automated sub-tabs. base.js initTabs wires the click/keyboard
behaviour and persists lt_activeTab_/executions; the ex:view-tab action
keeps pulse_executionView (the authoritative store) in sync. -->
<div class="lt-tab-bar" role="tablist" aria-label="Execution view">
<button type="button" class="lt-tab active" role="tab" id="ex-tabbtn-manual"
aria-selected="true" aria-controls="ex-tab-manual"
data-tab="ex-tab-manual" data-action="ex:view-tab" data-view="manual">
&#x1f464; Manual Runs <span class="lt-badge lt-badge-sm" id="ex-count-manual"></span>
</button>
<button type="button" class="lt-tab" role="tab" id="ex-tabbtn-automated"
aria-selected="false" aria-controls="ex-tab-automated"
data-tab="ex-tab-automated" data-action="ex:view-tab" data-view="automated">
&#x1f916; Automated <span class="lt-badge lt-badge-sm" id="ex-count-automated"></span>
</button>
</div>
<div class="lt-alert lt-alert--warning is-hidden" id="ex-compare-hint">
<span class="lt-alert-icon">&#x25a4;</span>
<div class="lt-alert-body">
<div class="lt-alert-title">Compare mode</div>
<div class="lt-alert-msg">Select 2&ndash;5 executions to compare their outputs. Click a row to toggle selection.</div>
</div>
</div>
<div class="lt-toolbar">
<div class="lt-toolbar-left">
<div class="lt-search">
<input type="search" id="ex-search" class="lt-input lt-search-input"
placeholder="Search by command, execution ID, or workflow name…"
autocomplete="off" aria-label="Search executions"
data-input-action="ex:search">
</div>
<select id="ex-status" class="lt-select" aria-label="Status filter" data-change-action="ex:filter-status">
<option value="">All Statuses</option>
<option value="running">Running</option>
<option value="completed">Completed</option>
<option value="failed">Failed</option>
<option value="waiting">Waiting</option>
</select>
<button type="button" class="lt-btn lt-btn-ghost lt-btn-sm" data-action="ex:clear-filters">Clear Filters</button>
</div>
<div class="lt-toolbar-right">
<span id="ex-filter-stats" class="pulse-meta"></span>
</div>
</div>
<div class="lt-tab-panels">
<div class="lt-tab-panel active" id="ex-tab-manual" role="tabpanel" aria-labelledby="ex-tabbtn-manual" tabindex="-1">
<div id="ex-list-manual" class="ex-list">
<div class="lt-empty-state lt-empty-state--sm"><div class="lt-empty-state-title">Loading&hellip;</div></div>
</div>
</div>
<div class="lt-tab-panel" id="ex-tab-automated" role="tabpanel" aria-labelledby="ex-tabbtn-automated" tabindex="-1">
<div id="ex-list-automated" class="ex-list">
<div class="lt-empty-state lt-empty-state--sm"><div class="lt-empty-state-title">Loading&hellip;</div></div>
</div>
</div>
</div>
</div>
<!-- ===================== EXECUTION DETAIL MODAL ===================== -->
<div class="lt-modal-overlay" id="ex-detail-modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="ex-detail-title">
<div class="lt-modal lt-modal-lg">
<div class="lt-modal-header">
<span class="lt-modal-title" id="ex-detail-title">Execution Details</span>
<button type="button" class="lt-modal-close" data-modal-close aria-label="Close">&#x2715;</button>
</div>
<div class="lt-modal-body" id="ex-detail-body"></div>
<div class="lt-modal-footer" id="ex-detail-footer"></div>
</div>
</div>
<!-- ===================== EXECUTION COMPARE MODAL ==================== -->
<div class="lt-modal-overlay" id="ex-compare-modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="ex-compare-title">
<div class="lt-modal lt-modal-lg">
<div class="lt-modal-header">
<span class="lt-modal-title" id="ex-compare-title">&#x2696; Execution Comparison</span>
<button type="button" class="lt-modal-close" data-modal-close aria-label="Close">&#x2715;</button>
</div>
<div class="lt-modal-body" id="ex-compare-body"></div>
<div class="lt-modal-footer">
<button type="button" class="lt-btn lt-btn-secondary lt-btn-sm" data-modal-close>Close</button>
</div>
</div>
</div>