<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Torc Workflow Manager</title>
<link rel="icon" type="image/png" sizes="32x32" href="/static/images/torc_icon_32.png">
<link rel="apple-touch-icon" sizes="180x180" href="/static/images/apple-touch-icon.png">
<link rel="stylesheet" href="/static/css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"></script>
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre@2.5.0/cytoscape-dagre.min.js"></script>
</head>
<body>
<div class="app-container">
<nav class="sidebar">
<div class="sidebar-header">
<h1><img src="/static/images/torc_icon.png" alt="Torc" class="header-icon"> Torc</h1>
<span class="version">Workflow Manager</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="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="debugging">
<span class="nav-icon">🔎</span>
Debugging
</li>
<li class="nav-item" data-tab="resource-plots">
<span class="nav-icon">📈</span>
Resource Plots
</li>
<li class="nav-item" data-tab="chat">
<span class="nav-icon">💬</span>
AI Chat
</li>
<li class="nav-item" data-tab="config">
<span class="nav-icon">⚙</span>
Configuration
</li>
</ul>
<div class="sidebar-footer">
<div class="sidebar-status-row">
<div class="connection-status" id="connection-status">
<span class="status-dot disconnected"></span>
<span class="status-text">Disconnected</span>
</div>
<div class="user-display" id="user-display" title="Current user">
<span class="user-icon">👤</span>
<span class="user-text">-</span>
</div>
<div class="version-display" id="version-display" title="Torc version">
<span class="version-text">v-.-.-</span>
</div>
</div>
<div class="sidebar-dark-toggle" id="sidebar-dark-toggle" title="Toggle dark mode (D)">
<span class="dark-toggle-icon" id="dark-toggle-icon">☾</span>
<span class="dark-toggle-label" id="dark-toggle-label">Dark Mode</span>
</div>
<div class="keyboard-hint" id="keyboard-hint" title="Show keyboard shortcuts">
Press <kbd>?</kbd> for shortcuts
</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-success btn-create-prominent" id="btn-create-workflow">
+ Create Workflow
</button>
<button class="btn btn-primary" id="btn-import-workflow">Import Workflow</button>
<input type="text" id="workflow-filter" class="text-input" placeholder="Filter workflows..." style="width: 200px;">
<label class="toggle-label" title="Show workflows from all users">
<input type="checkbox" id="show-all-users">
All users
</label>
<button class="btn btn-secondary" id="btn-refresh-workflows">
Refresh
</button>
</div>
</div>
<div class="bulk-action-bar" id="workflows-bulk-actions" style="display: none;">
<span class="bulk-selection-count"><span id="workflows-selection-count">0</span> selected</span>
<button class="btn btn-danger btn-sm" id="btn-bulk-delete">Delete Selected</button>
<button class="btn btn-secondary btn-sm" id="btn-clear-selection">Clear Selection</button>
</div>
<div class="table-container">
<table class="data-table" id="workflows-table">
<thead>
<tr>
<th class="checkbox-column"><input type="checkbox" id="workflows-select-all" title="Select all"></th>
<th>ID</th>
<th>Name</th>
<th>Timestamp</th>
<th>User</th>
<th>Project</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="workflows-body">
<tr>
<td colspan="8" 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>
<button class="btn btn-secondary" id="btn-refresh-details">Refresh</button>
</div>
</div>
<div class="details-container" id="details-container">
<div class="placeholder-message">
Select a workflow to view details
</div>
</div>
<div class="workflow-actions-panel" id="workflow-actions-panel" style="display:none">
<div class="action-group">
<h4>Management</h4>
<button class="btn btn-primary" id="btn-init-workflow" title="Initialize a workflow, including all job statuses">Initialize</button>
<button class="btn btn-warning" id="btn-reinit-workflow" title="Reinitialize a workflow. This will reinitialize all jobs with a status of canceled, submitting, pending, or terminated. Jobs with a status of done will also be reinitialized if an input_file or user_data record has changed.">Re-initialize</button>
<button class="btn btn-danger" id="btn-reset-workflow" title="Reset workflow and job status">Reset</button>
<button class="btn btn-secondary" id="btn-export-workflow" title="Export workflow to a JSON file on the server for backup or migration">Export</button>
</div>
<div class="action-group">
<h4>Execution</h4>
<button class="btn btn-success" id="btn-run-workflow-detail" title="Run workflow locally on this machine">Run Locally</button>
<button class="btn btn-success" id="btn-submit-workflow-detail" title="Submit workflow to the HPC scheduler (e.g., Slurm)">Submit to HPC</button>
</div>
<div class="action-group">
<h4>Recovery</h4>
<button class="btn btn-warning" id="btn-recover-workflow" title="Analyze and recover failed jobs (adjust resources, reset, and resubmit)">Recover Failed Jobs</button>
<button class="btn btn-info" id="btn-sync-status" title="Detect orphaned running jobs whose Slurm allocations have ended. Marks them as failed so the workflow can be recovered.">Sync Status</button>
<button class="btn btn-danger" id="btn-cancel-workflow" title="Cancel workflow and terminate all running Slurm jobs">Cancel Workflow</button>
</div>
<div class="action-group">
<h4>Visualization</h4>
<button class="btn btn-secondary" id="btn-show-dag" title="View the directed acyclic graph of job dependencies">View DAG</button>
<button class="btn btn-secondary" id="btn-show-plan" title="View the execution plan showing job stages">Execution Plan</button>
</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="results">Results</button>
<button class="sub-tab" data-subtab="events">Events</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="resources">Resource Requirements</button>
<button class="sub-tab" data-subtab="schedulers">Schedulers</button>
<button class="sub-tab" data-subtab="compute-nodes">Compute Nodes</button>
<button class="sub-tab" data-subtab="scheduled-nodes">Scheduled Nodes</button>
<button class="sub-tab" data-subtab="slurm-stats">Slurm Stats</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">
<button class="btn btn-secondary" id="btn-dag-back" style="display:none" title="Go back to previous view">← Back</button>
<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>
<span id="events-status" class="status-disconnected">â—‹ Disconnected</span>
</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-debugging">
<div class="tab-header">
<h2>Job Debugging</h2>
<div class="header-actions">
<select id="debug-workflow-selector" class="select-input">
<option value="">Select a workflow...</option>
</select>
</div>
</div>
<div class="debugging-container">
<div class="settings-section">
<h3>Job Results Report</h3>
<div class="form-group">
<label for="debug-output-dir">Output Directory</label>
<input type="text" id="debug-output-dir" class="text-input" value="torc_output" placeholder="torc_output">
<small>Directory where job logs are stored</small>
</div>
<div class="form-group">
<label>Options</label>
<label class="toggle-label">
<input type="checkbox" id="debug-all-runs">
Include all runs (not just latest)
</label>
<label class="toggle-label">
<input type="checkbox" id="debug-failed-only" checked>
Show only failed jobs
</label>
</div>
<button class="btn btn-primary" id="btn-generate-report">Generate Report</button>
</div>
<div class="settings-section">
<h3>Job Results <span id="debug-job-count"></span></h3>
<div id="debug-jobs-table-container">
<div class="placeholder-message">Generate a report to view job results</div>
</div>
</div>
<div class="settings-section">
<h3>Log File Viewer</h3>
<div id="debug-selected-job-info" class="placeholder-message">
Select a job from the table above to view its logs
</div>
<div class="log-tabs" id="log-tabs" style="display:none">
<button class="sub-tab active" data-logtab="stdout">stdout</button>
<button class="sub-tab" data-logtab="stderr">stderr</button>
</div>
<div id="log-viewer" class="log-viewer" style="display:none">
<div class="log-path" id="log-path"></div>
<pre id="log-content" class="log-content"></pre>
</div>
</div>
<div class="settings-section">
<h3>Slurm Log Analysis</h3>
<p class="section-description">Parse Slurm log files for known error patterns (OOM, time limits, node failures, etc.)</p>
<div class="form-group">
<label>Options</label>
<label class="toggle-label">
<input type="checkbox" id="slurm-errors-only">
Show only errors (hide warnings)
</label>
</div>
<button class="btn btn-primary" id="btn-slurm-parse-logs">Analyze Slurm Logs</button>
<div id="slurm-logs-results" style="margin-top: 15px;">
<div class="placeholder-message">Click "Analyze Slurm Logs" to scan for issues</div>
</div>
</div>
<div class="settings-section">
<h3>Slurm Accounting Data</h3>
<p class="section-description">Collect sacct data for all Slurm jobs in this workflow</p>
<button class="btn btn-primary" id="btn-slurm-sacct">Collect sacct Data</button>
<div id="slurm-sacct-results" style="margin-top: 15px;">
<div class="placeholder-message">Click "Collect sacct Data" to retrieve job accounting information</div>
</div>
</div>
</div>
</div>
<div class="tab-content" id="tab-resource-plots">
<div class="tab-header">
<h2>Resource Plots</h2>
</div>
<div class="resource-plots-container">
<div class="settings-section">
<h3>Resource Database Selection</h3>
<div class="form-group">
<label for="resource-db-dir">Database Directory</label>
<div style="display: flex; gap: 10px;">
<input type="text" id="resource-db-dir" class="text-input"
value="torc_output/resource_utilization"
placeholder="torc_output/resource_utilization">
<button class="btn btn-secondary" id="btn-scan-dbs">Scan</button>
</div>
<small>Directory containing resource monitoring database files (.db)</small>
</div>
<div class="form-group">
<label>Available Databases</label>
<div id="resource-db-list" class="resource-db-list">
<div class="placeholder-message">Click "Scan" to discover database files</div>
</div>
</div>
<button class="btn btn-primary" id="btn-generate-plots" disabled>Generate Plots</button>
</div>
<div class="settings-section" id="plots-section" style="display: none;">
<h3>Resource Utilization Plots</h3>
<div class="plot-tabs" id="plot-tabs">
</div>
<div class="plot-container" id="plot-container">
<div class="placeholder-message">Select a plot to view</div>
</div>
</div>
</div>
</div>
<div class="tab-content" id="tab-config">
<div class="tab-header">
<h2>Configuration</h2>
</div>
<div class="settings-container">
<div class="settings-section">
<h3>Server Management</h3>
<div class="server-status-panel" id="server-status-panel">
<div class="server-status-indicator">
<span class="status-dot" id="server-status-dot"></span>
<span id="server-status-text">Checking...</span>
</div>
</div>
<div class="form-group">
<label for="server-port">Server Port</label>
<input type="number" id="server-port" class="text-input"
value="0" min="0" max="65535">
<small>Port for torc-server to listen on (0 = auto-detect free port)</small>
</div>
<div class="form-group">
<label for="server-database">Database Path</label>
<input type="text" id="server-database" class="text-input"
placeholder="db/sqlite/dev.db">
<small>Path to SQLite database file (leave empty for default)</small>
</div>
<div class="form-group">
<label for="server-completion-interval">Completion Check Interval (seconds)</label>
<input type="number" id="server-completion-interval" class="text-input"
value="5" min="1" max="300">
<small>How often to check for job completions and unblock dependent jobs</small>
</div>
<div class="form-group">
<label for="server-log-level">Log Level</label>
<select id="server-log-level" class="select-input">
<option value="error">Error</option>
<option value="warn">Warn</option>
<option value="info" selected>Info</option>
<option value="debug">Debug</option>
<option value="trace">Trace</option>
</select>
</div>
<div class="server-actions">
<button class="btn btn-success" id="btn-start-server">Start Server</button>
<button class="btn btn-danger" id="btn-stop-server" disabled>Stop Server</button>
</div>
<div id="server-output" class="server-output" style="display: none;">
<h4>Server Output</h4>
<pre id="server-output-content"></pre>
</div>
</div>
<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 class="form-group" id="theme-selector-group" style="display: none;">
<label for="theme-selector">Dark Theme</label>
<select id="theme-selector" class="select-input">
<optgroup label="Subtle">
<option value="warm">Warm Gray (Slack)</option>
<option value="neutral">Neutral (GitHub dark)</option>
<option value="dimmed">Dimmed (GitHub dimmed)</option>
<option value="nord">Nord</option>
<option value="dracula">Dracula</option>
<option value="midnight">Midnight Blue</option>
</optgroup>
<optgroup label="More Contrast">
<option value="high-contrast">High Contrast</option>
<option value="monokai">Monokai (warm olive)</option>
</optgroup>
</select>
<small>Choose a color scheme for dark mode</small>
</div>
</div>
<div class="settings-section">
<h3>Connection Info</h3>
<div id="server-info" class="info-box">
<p>Click "Test Connection" to fetch server information</p>
</div>
</div>
</div>
</div>
<div class="tab-content" id="tab-chat">
<div class="chat-container">
<div class="chat-header">
<h2>AI Chat <span class="badge-experimental">Experimental</span></h2>
<div class="header-actions">
<a class="btn btn-secondary btn-sm" href="https://natlabrockies.github.io/torc/v0.20.4/core/monitoring/dashboard.html#ai-chat-tab" target="_blank" rel="noopener" title="AI Chat documentation">?</a>
<button class="btn btn-secondary btn-sm" id="chat-clear-btn">Clear</button>
</div>
</div>
<div class="chat-messages" id="chat-messages">
<div class="chat-welcome">
<p><strong>Torc AI Assistant</strong></p>
<p>Ask questions about your workflows, job status, logs, and more.</p>
<p class="chat-examples">Try: "Help me create a workflow" or "Show me the failed jobs"</p>
</div>
</div>
<div class="chat-setup" id="chat-setup" style="display:none">
<div class="chat-setup-content">
<div class="chat-setup-icon">💬</div>
<h3>Set up AI Chat</h3>
<p>AI Chat uses Claude to answer questions about your workflows, job status, and more.</p>
<div class="chat-setup-provider">
<label for="chat-provider-select">Provider</label>
<select id="chat-provider-select" class="chat-setup-select">
<option value="anthropic">Anthropic (Direct API)</option>
<option value="foundry">Azure AI Foundry</option>
<option value="custom">Custom Endpoint</option>
</select>
</div>
<div class="chat-setup-field">
<label for="chat-api-key-input">API Key</label>
<input type="password" id="chat-api-key-input" class="chat-input" placeholder="sk-ant-..." aria-label="API key">
</div>
<div class="chat-setup-field" id="chat-foundry-field" style="display:none">
<label for="chat-foundry-resource">Foundry Resource Name</label>
<input type="text" id="chat-foundry-resource" class="chat-input" placeholder="my-resource" aria-label="Azure AI Foundry resource name">
<small>URL: https://{resource}.services.ai.azure.com/anthropic/v1</small>
</div>
<div class="chat-setup-field" id="chat-custom-url-field" style="display:none">
<label for="chat-custom-base-url">Base URL</label>
<input type="text" id="chat-custom-base-url" class="chat-input" placeholder="https://my-proxy.example.com/v1" aria-label="Custom base URL">
</div>
<div class="chat-setup-field" id="chat-custom-header-field" style="display:none">
<label for="chat-custom-auth-header">Auth Header <small>(optional, default: x-api-key)</small></label>
<input type="text" id="chat-custom-auth-header" class="chat-input" placeholder="x-api-key" aria-label="Custom auth header name">
</div>
<div class="chat-setup-actions">
<button class="btn btn-primary" id="chat-api-key-submit">Connect</button>
</div>
<p id="chat-setup-error" class="chat-setup-error" style="display:none"></p>
<p class="chat-setup-note">Credentials are stored in memory only for this session. For persistent configuration, use CLI flags or environment variables.</p>
<p class="chat-setup-docs"><a href="https://natlabrockies.github.io/torc/v0.20.4/core/monitoring/dashboard.html#ai-chat-tab" target="_blank" rel="noopener">View documentation →</a></p>
</div>
</div>
<div class="chat-input-area">
<textarea id="chat-input" class="chat-input" placeholder="Ask about your workflows..." aria-label="Chat message input" rows="1"></textarea>
<button class="btn btn-primary" id="chat-send-btn">Send</button>
<button class="btn btn-danger" id="chat-stop-btn" style="display:none">Stop</button>
</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="sub-tabs" id="create-source-tabs">
<button class="sub-tab active" data-createtab="upload">Upload File</button>
<button class="sub-tab" data-createtab="path">File Path</button>
<button class="sub-tab" data-createtab="inline">Inline Spec</button>
<button class="sub-tab" data-createtab="wizard">Wizard</button>
</div>
<div class="create-panel active" id="create-panel-upload">
<div class="form-group">
<label>Upload Workflow Spec File</label>
<div class="file-upload-zone" id="file-upload-zone">
<div class="upload-content">
<div class="upload-icon">📁</div>
<p>Drag and drop a file here, or click to select</p>
<p class="upload-hint">Supports YAML, JSON, JSON5, KDL</p>
</div>
<input type="file" id="spec-file-input" accept=".yaml,.yml,.json,.json5,.kdl" style="display:none">
</div>
<div id="upload-status"></div>
</div>
</div>
<div class="create-panel" id="create-panel-path">
<div class="form-group">
<label for="workflow-spec-path">Spec File Path</label>
<input type="text" id="workflow-spec-path" class="text-input"
placeholder="/path/to/workflow.yaml or workflow.json">
<small>Enter the path to a workflow spec file on the server</small>
</div>
</div>
<div class="create-panel" id="create-panel-inline">
<div class="form-group">
<label for="workflow-spec-text">Inline Spec (JSON/YAML)</label>
<textarea id="workflow-spec-text" class="text-input" rows="12"
placeholder="Paste your workflow specification here..."></textarea>
</div>
</div>
<div class="create-panel" id="create-panel-wizard">
<div class="wizard-steps">
<div class="wizard-step active" data-step="1">
<span class="step-number">1</span>
<span class="step-label">Basics</span>
</div>
<div class="wizard-step" data-step="2">
<span class="step-number">2</span>
<span class="step-label">Jobs</span>
</div>
<div class="wizard-step" data-step="3">
<span class="step-number">3</span>
<span class="step-label">Schedulers</span>
</div>
<div class="wizard-step" data-step="4">
<span class="step-number">4</span>
<span class="step-label">Actions</span>
</div>
<div class="wizard-step" data-step="5">
<span class="step-number">5</span>
<span class="step-label">Monitoring</span>
</div>
<div class="wizard-step" data-step="6">
<span class="step-number">6</span>
<span class="step-label">Review</span>
</div>
</div>
<div class="wizard-content active" id="wizard-step-1">
<div class="form-group">
<label for="wizard-name">Workflow Name *</label>
<input type="text" id="wizard-name" class="text-input"
placeholder="my-data-pipeline">
</div>
<div class="form-group">
<label for="wizard-description">Description</label>
<input type="text" id="wizard-description" class="text-input"
placeholder="Optional description of what this workflow does">
</div>
<div class="form-group">
<label for="wizard-parallelization-strategy">Parallelization Strategy</label>
<select id="wizard-parallelization-strategy" class="select-input">
<option value="resource_aware" selected>Resource-Aware (recommended)</option>
<option value="queue_depth">Queue-Depth (--max-parallel-jobs)</option>
</select>
<small class="strategy-help">
<strong>Resource-Aware:</strong> Define per-job CPU/memory/GPU requirements. The runner intelligently allocates jobs based on available resources.<br>
<strong>Queue-Depth:</strong> Simply control the number of concurrent jobs with <code>--max-parallel-jobs</code>. Best for homogeneous jobs.
<a href="https://nrel.github.io/torc/explanation/parallelization.html" target="_blank">Learn more</a>
</small>
</div>
</div>
<div class="wizard-content" id="wizard-step-2">
<div class="wizard-jobs-header">
<h4>Jobs</h4>
<button type="button" class="btn btn-sm btn-success" id="wizard-add-job">+ Add Job</button>
</div>
<p class="wizard-help-text">
Need file-based dependencies or complex data pipelines? <a href="https://nrel.github.io/torc/how-to/creating-workflows.html" target="_blank">Create from a spec file</a> instead.
</p>
<div id="wizard-jobs-list" class="wizard-jobs-list">
</div>
</div>
<div class="wizard-content" id="wizard-step-3">
<div class="wizard-schedulers-header">
<h4>Slurm Schedulers</h4>
<button type="button" class="btn btn-sm btn-success" id="wizard-add-scheduler">+ Add Scheduler</button>
</div>
<p class="wizard-help-text">Configure Slurm schedulers to allocate compute nodes for your workflow jobs.</p>
<div id="wizard-schedulers-list" class="wizard-schedulers-list">
</div>
</div>
<div class="wizard-content" id="wizard-step-4">
<div class="wizard-actions-header">
<h4>Workflow Actions</h4>
<button type="button" class="btn btn-sm btn-success" id="wizard-add-action">+ Add Action</button>
</div>
<p class="wizard-help-text">Actions automatically schedule Slurm nodes when certain events occur (workflow starts, jobs become ready, or jobs complete).</p>
<div id="wizard-actions-list" class="wizard-actions-list">
</div>
</div>
<div class="wizard-content" id="wizard-step-5">
<div class="wizard-monitoring-header">
<h4>Resource Monitoring</h4>
</div>
<p class="wizard-help-text">Configure resource monitoring to track CPU, memory, and process usage during job execution.</p>
<div class="form-group">
<label class="toggle-label">
<input type="checkbox" id="wizard-monitoring-enabled" checked>
Enable resource monitoring
</label>
<small>When enabled, resource utilization will be tracked for all jobs</small>
</div>
<div id="wizard-monitoring-options" class="wizard-monitoring-options">
<div class="form-group">
<label for="wizard-monitoring-granularity">Granularity</label>
<select id="wizard-monitoring-granularity" class="select-input">
<option value="summary">Summary (peak and average values only)</option>
<option value="time_series">Time Series (detailed samples at regular intervals)</option>
</select>
<small>Time series provides more detailed data but uses more storage</small>
</div>
<div class="form-group">
<label for="wizard-monitoring-interval">Sample Interval (seconds)</label>
<input type="number" id="wizard-monitoring-interval" class="text-input"
value="5" min="1" max="300">
<small>How often to sample resource usage (1-300 seconds)</small>
</div>
</div>
</div>
<div class="wizard-content" id="wizard-step-6">
<div class="form-group">
<label>Generated Workflow Spec</label>
<pre id="wizard-preview" class="wizard-preview"></pre>
<div id="wizard-preview-slurm-note" class="wizard-slurm-note" style="display: none;"></div>
</div>
</div>
<div class="wizard-nav">
<button type="button" class="btn btn-secondary" id="wizard-prev" disabled>Back</button>
<button type="button" class="btn btn-primary" id="wizard-next">Next</button>
</div>
</div>
<div class="form-group" style="margin-top: 16px;">
<label>Options</label>
<label class="toggle-label">
<input type="checkbox" id="create-option-initialize" checked>
Initialize workflow after creation
</label>
</div>
<div class="form-group" id="slurm-options-group" style="margin-top: 16px; display: none;">
<label>Slurm Options</label>
<label class="toggle-label" id="slurm-checkbox-label">
<input type="checkbox" id="create-option-slurm" disabled>
Generate Slurm schedulers
<span id="slurm-profile-badge" class="badge badge-info" style="margin-left: 8px; display: none;"></span>
</label>
<small id="slurm-disabled-hint" style="color: var(--text-secondary); display: block; margin-top: 4px;">
No HPC profile detected. Slurm scheduler generation is not available.
</small>
<div id="slurm-account-section" style="margin-top: 12px; display: none;">
<label for="create-slurm-account">Slurm Account *</label>
<input type="text" id="create-slurm-account" class="text-input"
placeholder="e.g., myproject" style="max-width: 300px;">
<small>The Slurm account to use for job submissions</small>
</div>
</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="modal" id="execution-plan-modal">
<div class="modal-content" style="max-width: 800px;">
<div class="modal-header">
<h3>Execution Plan</h3>
<button class="modal-close" id="plan-modal-close">×</button>
</div>
<div class="modal-body">
<div id="execution-plan-content">
<div class="placeholder-message">Loading execution plan...</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-close-plan">Close</button>
</div>
</div>
</div>
<div class="modal" id="init-confirm-modal">
<div class="modal-content" style="max-width: 600px;">
<div class="modal-header">
<h3>Existing Output Files Detected</h3>
<button class="modal-close" id="init-confirm-modal-close">×</button>
</div>
<div class="modal-body">
<div id="init-confirm-content">
<div class="placeholder-message">Loading...</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-cancel-init">Cancel</button>
<button class="btn btn-danger" id="btn-confirm-init">Delete Files and Initialize</button>
</div>
</div>
</div>
<div class="modal" id="reinit-confirm-modal">
<div class="modal-content" style="max-width: 600px;">
<div class="modal-header">
<h3>Existing Output Files Detected</h3>
<button class="modal-close" id="reinit-confirm-modal-close">×</button>
</div>
<div class="modal-body">
<div id="reinit-confirm-content">
<div class="placeholder-message">Loading...</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-cancel-reinit">Cancel</button>
<button class="btn btn-danger" id="btn-confirm-reinit">Delete Files and Reinitialize</button>
</div>
</div>
</div>
<div class="modal" id="recover-modal">
<div class="modal-content" style="max-width: 800px; max-height: 85vh;">
<div class="modal-header">
<h3>Recovery Analysis</h3>
<button class="modal-close" id="recover-modal-close">×</button>
</div>
<div class="modal-body" style="overflow-y: auto;">
<div id="recover-content">
<div class="placeholder-message">Analyzing workflow...</div>
</div>
</div>
<div class="modal-footer" id="recover-modal-footer">
<button class="btn btn-secondary" id="btn-cancel-recover">Cancel</button>
<button class="btn btn-success" id="btn-confirm-recover">Apply Recovery</button>
</div>
</div>
</div>
<div class="modal" id="sync-status-modal">
<div class="modal-content" style="max-width: 800px; max-height: 85vh;">
<div class="modal-header">
<h3>Sync Status Analysis</h3>
<button class="modal-close" id="sync-status-modal-close">×</button>
</div>
<div class="modal-body" style="overflow-y: auto;">
<div id="sync-status-content">
<div class="placeholder-message">Checking Slurm job statuses...</div>
</div>
</div>
<div class="modal-footer" id="sync-status-modal-footer">
<button class="btn btn-secondary" id="btn-cancel-sync-status">Close</button>
<button class="btn btn-warning" id="btn-confirm-sync-status" style="display:none">Apply Sync</button>
</div>
</div>
</div>
<div class="modal" id="file-viewer-modal">
<div class="modal-content" style="max-width: 900px; max-height: 80vh;">
<div class="modal-header">
<h3 id="file-viewer-title">File Contents</h3>
<button class="modal-close" id="file-viewer-modal-close">×</button>
</div>
<div class="modal-body" style="padding: 0;">
<div id="file-viewer-path" class="file-viewer-path"></div>
<div id="file-viewer-content-wrapper" class="file-viewer-content-wrapper">
<pre id="file-viewer-content" class="file-viewer-content"></pre>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-close-file-viewer">Close</button>
</div>
</div>
</div>
<div class="modal" id="slurm-logs-modal">
<div class="modal-content" style="max-width: 900px; max-height: 85vh;">
<div class="modal-header">
<h3 id="slurm-logs-title">Slurm Job Logs</h3>
<button class="modal-close" id="slurm-logs-modal-close">×</button>
</div>
<div class="modal-body" style="padding: 0; display: flex; flex-direction: column;">
<div class="slurm-logs-info" id="slurm-logs-info"></div>
<div class="log-tabs" id="slurm-log-tabs">
<button class="sub-tab active" data-slurm-logtab="stdout">stdout</button>
<button class="sub-tab" data-slurm-logtab="stderr">stderr</button>
</div>
<div class="slurm-log-viewer">
<div class="log-path" id="slurm-log-path"></div>
<pre id="slurm-log-content" class="log-content"></pre>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-close-slurm-logs">Close</button>
</div>
</div>
</div>
<div class="modal" id="job-details-modal">
<div class="modal-content" style="max-width: 900px; max-height: 85vh;">
<div class="modal-header">
<h3 id="job-details-title">Job Details</h3>
<button class="modal-close" id="job-details-modal-close">×</button>
</div>
<div class="modal-body" style="padding: 0; display: flex; flex-direction: column; max-height: calc(85vh - 130px);">
<div id="job-details-summary" class="job-details-summary"></div>
<div class="sub-tabs job-details-tabs" id="job-details-tabs">
<button class="sub-tab active" data-jobdetailtab="results">Results</button>
<button class="sub-tab" data-jobdetailtab="logs">Logs</button>
<button class="sub-tab" data-jobdetailtab="input-files">Input Files</button>
<button class="sub-tab" data-jobdetailtab="output-files">Output Files</button>
<button class="sub-tab" data-jobdetailtab="input-user-data">Input User Data</button>
<button class="sub-tab" data-jobdetailtab="output-user-data">Output User Data</button>
<button class="sub-tab" data-jobdetailtab="resource-req">Resource Req</button>
<button class="sub-tab" data-jobdetailtab="dependencies">Dependencies</button>
</div>
<div id="job-details-content" class="job-details-content"></div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-close-job-details">Close</button>
</div>
</div>
</div>
<div class="modal" id="export-workflow-modal">
<div class="modal-content" style="max-width: 500px;">
<div class="modal-header">
<h3>Export Workflow</h3>
<button class="modal-close" id="export-modal-close">×</button>
</div>
<div class="modal-body">
<p>Save the workflow to a JSON file on the server.</p>
<div class="form-group">
<label for="export-output-path">Output file path</label>
<input type="text" id="export-output-path" class="text-input" style="width: 100%;">
</div>
<div class="form-group">
<label class="toggle-label">
<input type="checkbox" id="export-include-results">
Include results (job execution metrics)
</label>
</div>
<div class="form-group">
<label class="toggle-label">
<input type="checkbox" id="export-include-events">
Include events (workflow history)
</label>
</div>
<div id="export-status"></div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-cancel-export">Cancel</button>
<button class="btn btn-primary" id="btn-confirm-export">Export</button>
</div>
</div>
</div>
<div class="modal" id="import-workflow-modal">
<div class="modal-content" style="max-width: 550px;">
<div class="modal-header">
<h3>Import Workflow</h3>
<button class="modal-close" id="import-modal-close">×</button>
</div>
<div class="modal-body">
<p>Import a previously exported workflow JSON file.</p>
<div class="sub-tabs" style="margin-bottom: 12px;">
<button class="sub-tab active" data-importtab="path">File Path</button>
<button class="sub-tab" data-importtab="upload">Upload</button>
</div>
<div id="import-panel-path" class="import-panel">
<div class="form-group">
<label for="import-file-path">Path to exported JSON file on the server</label>
<input type="text" id="import-file-path" class="text-input" placeholder="/path/to/workflow_export.json" style="width: 100%;">
</div>
</div>
<div id="import-panel-upload" class="import-panel" style="display: none;">
<div class="file-upload-zone" id="import-file-upload-zone">
<p>Drop an exported workflow JSON file here or click to select</p>
<input type="file" id="import-file-input" accept=".json" style="display:none">
</div>
<div id="import-upload-status"></div>
</div>
<div class="form-group" style="margin-top: 12px;">
<label for="import-name-override">Name override (optional)</label>
<input type="text" id="import-name-override" class="text-input" placeholder="Leave empty to use original name" style="width: 100%;">
</div>
<div class="form-group">
<label class="toggle-label">
<input type="checkbox" id="import-skip-results">
Skip results (ignore job execution metrics)
</label>
</div>
<div class="form-group">
<label class="toggle-label">
<input type="checkbox" id="import-skip-events">
Skip events (ignore workflow history)
</label>
</div>
<div id="import-status"></div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" id="btn-cancel-import">Cancel</button>
<button class="btn btn-primary" id="btn-confirm-import">Import</button>
</div>
</div>
</div>
<div class="execution-output-panel" id="execution-output-panel" style="display:none">
<div class="execution-output-header">
<span>Execution Output</span>
<button class="btn btn-danger btn-sm" id="btn-cancel-execution">Cancel</button>
<button class="btn btn-secondary btn-sm" id="btn-close-output">Close</button>
</div>
<pre id="execution-output" class="execution-output"></pre>
</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>
<script src="/static/js/app-utils.js"></script>
<script src="/static/js/app-core.js"></script>
<script src="/static/js/app-workflows.js"></script>
<script src="/static/js/app-details.js"></script>
<script src="/static/js/app-tables.js"></script>
<script src="/static/js/app-events.js"></script>
<script src="/static/js/app-dag-tab.js"></script>
<script src="/static/js/app-debugging.js"></script>
<script src="/static/js/app-resources.js"></script>
<script src="/static/js/app-config.js"></script>
<script src="/static/js/marked.min.js"></script>
<script src="/static/js/app-chat.js"></script>
<script src="/static/js/app-modals.js"></script>
<script src="/static/js/app-job-details.js"></script>
<script src="/static/js/app-wizard.js"></script>
<script src="/static/js/app-keyboard.js"></script>
</body>
</html>