<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Torc Dashboard</title>
<link rel="stylesheet" href="/static/css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"
integrity="sha384-J7Q85oZE4GJ/e7+n2aOQsLXfDwwfnA8S2nZAL5BpFsfpCF84zQD7LroZ/dMnLgex"
crossorigin="anonymous"></script>
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"
integrity="sha384-Hl48Kq2HifOWdXEjMsKo6qxqvRLTYqIGbvlENBmkHAxZKIGCXv43H6W1jA671RzC"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"
integrity="sha384-2IH3T69EIKYC4c+RXZifZRvaH5SRUdacJW7j6HtE5rQbvLhKKdawxq6vpIzJ7j9M"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre@2.5.0/cytoscape-dagre.min.js"
integrity="sha384-drxU/AikJCPfvw6zqWesCn7xREkWv1Y91CVTxrMRTwdttj6lHh27yDR9Ap7zABYr"
crossorigin="anonymous"></script>
</head>
<body>
<div class="app-container">
<nav class="sidebar">
<div class="sidebar-header">
<h1>Torc</h1>
<span class="version">Dashboard</span>
</div>
<ul class="nav-menu">
<li class="nav-item active" data-tab="workflows">
<span class="nav-icon">▢</span>
Workflows
</li>
<li class="nav-item" data-tab="details">
<span class="nav-icon">☰</span>
Details
</li>
<li class="nav-item" data-tab="dag">
<span class="nav-icon">◆</span>
DAG View
</li>
<li class="nav-item" data-tab="events">
<span class="nav-icon">◉</span>
Events
<span class="badge" id="event-badge" style="display:none">0</span>
</li>
<li class="nav-item" data-tab="settings">
<span class="nav-icon">⚙</span>
Settings
</li>
</ul>
<div class="sidebar-footer">
<div class="connection-status" id="connection-status">
<span class="status-dot disconnected"></span>
<span class="status-text">Disconnected</span>
</div>
</div>
</nav>
<main class="main-content">
<div class="tab-content active" id="tab-workflows">
<div class="tab-header">
<h2>Workflows</h2>
<div class="header-actions">
<button class="btn btn-primary" id="btn-refresh-workflows">
Refresh
</button>
<button class="btn btn-secondary" id="btn-create-workflow">
Create Workflow
</button>
</div>
</div>
<div class="table-container">
<table class="data-table" id="workflows-table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Owner</th>
<th>Status</th>
<th>Jobs</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="workflows-body">
<tr>
<td colspan="7" class="loading">Loading workflows...</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="tab-content" id="tab-details">
<div class="tab-header">
<h2>Workflow Details</h2>
<div class="header-actions">
<select id="workflow-selector" class="select-input">
<option value="">Select a workflow...</option>
</select>
</div>
</div>
<div class="details-container" id="details-container">
<div class="placeholder-message">
Select a workflow to view details
</div>
</div>
<div class="sub-tabs" id="details-sub-tabs" style="display:none">
<button class="sub-tab active" data-subtab="jobs">Jobs</button>
<button class="sub-tab" data-subtab="files">Files</button>
<button class="sub-tab" data-subtab="user-data">User Data</button>
<button class="sub-tab" data-subtab="results">Results</button>
</div>
<div class="sub-tab-content" id="details-content"></div>
</div>
<div class="tab-content" id="tab-dag">
<div class="tab-header">
<h2>DAG Visualization</h2>
<div class="header-actions">
<select id="dag-workflow-selector" class="select-input">
<option value="">Select a workflow...</option>
</select>
<select id="dag-type-selector" class="select-input">
<option value="jobs">Job Dependencies</option>
<option value="files">Job-File Relations</option>
<option value="userdata">Job-UserData Relations</option>
</select>
<button class="btn btn-secondary" id="btn-fit-dag">Fit to View</button>
</div>
</div>
<div class="dag-container" id="dag-container">
<div class="placeholder-message">
Select a workflow to view its DAG
</div>
</div>
<div class="dag-legend" id="dag-legend" style="display:none">
<div class="legend-item"><span class="legend-color" style="background:#6c757d"></span> Uninitialized</div>
<div class="legend-item"><span class="legend-color" style="background:#ffc107"></span> Blocked</div>
<div class="legend-item"><span class="legend-color" style="background:#17a2b8"></span> Ready</div>
<div class="legend-item"><span class="legend-color" style="background:#fd7e14"></span> Pending</div>
<div class="legend-item"><span class="legend-color" style="background:#007bff"></span> Running</div>
<div class="legend-item"><span class="legend-color" style="background:#28a745"></span> Completed</div>
<div class="legend-item"><span class="legend-color" style="background:#dc3545"></span> Failed</div>
<div class="legend-item"><span class="legend-color" style="background:#6f42c1"></span> Canceled</div>
</div>
</div>
<div class="tab-content" id="tab-events">
<div class="tab-header">
<h2>Events</h2>
<div class="header-actions">
<select id="events-workflow-selector" class="select-input">
<option value="">All Workflows</option>
</select>
<button class="btn btn-secondary" id="btn-clear-events">Clear</button>
<label class="toggle-label">
<input type="checkbox" id="auto-refresh-events" checked>
Auto-refresh
</label>
</div>
</div>
<div class="events-container" id="events-container">
<div class="events-list" id="events-list">
<div class="placeholder-message">No events yet</div>
</div>
</div>
</div>
<div class="tab-content" id="tab-settings">
<div class="tab-header">
<h2>Settings</h2>
</div>
<div class="settings-container">
<div class="settings-section">
<h3>API Configuration</h3>
<div class="form-group">
<label for="api-url">API URL</label>
<input type="text" id="api-url" class="text-input"
placeholder="http://localhost:8080/torc-service/v1">
<small>The base URL for the Torc API</small>
</div>
<button class="btn btn-primary" id="btn-save-settings">Save Settings</button>
<button class="btn btn-secondary" id="btn-test-connection">Test Connection</button>
</div>
<div class="settings-section">
<h3>Display Options</h3>
<div class="form-group">
<label for="refresh-interval">Auto-refresh interval (seconds)</label>
<input type="number" id="refresh-interval" class="text-input"
value="30" min="5" max="300">
</div>
<div class="form-group">
<label>
<input type="checkbox" id="dark-mode">
Dark Mode
</label>
</div>
</div>
<div class="settings-section">
<h3>Server Info</h3>
<div id="server-info" class="info-box">
<p>Click "Test Connection" to fetch server information</p>
</div>
</div>
</div>
</div>
</main>
</div>
<div class="modal" id="create-workflow-modal">
<div class="modal-content">
<div class="modal-header">
<h3>Create Workflow</h3>
<button class="modal-close" id="modal-close">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="workflow-name">Workflow Name *</label>
<input type="text" id="workflow-name" class="text-input"
placeholder="Enter workflow name...">
</div>
<div class="form-group">
<label for="workflow-description">Description</label>
<textarea id="workflow-description" class="text-input" rows="3"
placeholder="Optional description..."></textarea>
</div>
<div class="form-group">
<small style="color: var(--text-secondary);">
Note: This creates an empty workflow. To create a workflow with jobs from a spec file, use the CLI:<br>
<code>torc workflows create <spec.yaml></code>
</small>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-cancel-create">Cancel</button>
<button class="btn btn-primary" id="btn-submit-workflow">Create</button>
</div>
</div>
</div>
<div class="toast-container" id="toast-container"></div>
<script src="/static/js/api.js"></script>
<script src="/static/js/dag.js"></script>
<script src="/static/js/app.js"></script>
</body>
</html>