torc 0.21.0

Workflow management system
<!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">
    <!-- Cytoscape.js for DAG visualization -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"
            integrity="sha384-J7Q85oZE4GJ/e7+n2aOQsLXfDwwfnA8S2nZAL5BpFsfpCF84zQD7LroZ/dMnLgex"
            crossorigin="anonymous"></script>
    <!-- Plotly.js for charts -->
    <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"
            integrity="sha384-Hl48Kq2HifOWdXEjMsKo6qxqvRLTYqIGbvlENBmkHAxZKIGCXv43H6W1jA671RzC"
            crossorigin="anonymous"></script>
    <!-- Dagre layout for Cytoscape -->
    <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">
        <!-- Sidebar -->
        <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">&#9634;</span>
                    Workflows
                </li>
                <li class="nav-item" data-tab="details">
                    <span class="nav-icon">&#9776;</span>
                    Details
                </li>
                <li class="nav-item" data-tab="dag">
                    <span class="nav-icon">&#9670;</span>
                    DAG View
                </li>
                <li class="nav-item" data-tab="events">
                    <span class="nav-icon">&#9673;</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">&#9881;</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 Content -->
        <main class="main-content">
            <!-- Workflows Tab -->
            <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>

            <!-- Details Tab -->
            <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>
                <!-- Sub-tabs for jobs, files, etc. -->
                <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>

            <!-- DAG Tab -->
            <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>

            <!-- Events Tab -->
            <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>

            <!-- Settings Tab -->
            <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>

    <!-- Modal for workflow creation -->
    <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">&times;</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 &lt;spec.yaml&gt;</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>

    <!-- Toast notifications -->
    <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>