Skip to content

Commit dd438a7

Browse files
authored
Merge pull request #146 from NatLabRockies/fix/dash
Fix Dash bugs
2 parents 8835c7b + 2eb46b2 commit dd438a7

File tree

18 files changed

+137
-55
lines changed

18 files changed

+137
-55
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ members = [
55
resolver = "2"
66

77
[workspace.package]
8-
version = "0.15.1"
8+
version = "0.15.2"
99
authors = ["Daniel Thom", "Joseph McKinsey"]
1010
license = "BSD-3-Clause"
1111
edition = "2024"
@@ -14,7 +14,7 @@ description = "Workflow management system"
1414

1515
[workspace.dependencies]
1616
# Self-reference for sub-crates (version only specified here)
17-
torc = { version = "0.15.1", path = "." }
17+
torc = { version = "0.15.2", path = "." }
1818

1919
# Shared dependencies
2020
serde = { version = "1.0", features = ["derive"] }

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Usage:
22
# # Download and extract release binaries
3-
# VERSION=0.15.1
3+
# VERSION=0.15.2
44
# mkdir -p artifact
55
# curl -fsSL "https://github.com/NatLabRockies/torc/releases/download/v${VERSION}/torc-x86_64-unknown-linux-musl.tar.gz" \
66
# | tar xz -C artifact/

docs/src/getting-started/installation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ listed below.
5353

5454
```
5555
/scratch/dthom/torc/
56-
├── 0.15.1/
56+
├── 0.15.2/
5757
├── ...
58-
└── latest -> 0.15.1 (symlink to current version)
58+
└── latest -> 0.15.2 (symlink to current version)
5959
```
6060

6161
> **Recommended**: Use the `latest` directory. Torc maintains backwards compatibility, so you'll
@@ -104,7 +104,7 @@ docker pull ghcr.io/natlabrockies/torc:latest
104104
```
105105

106106
> **Recommended**: Use the `latest` tag to automatically receive updates and bug fixes. Torc
107-
> maintains backwards compatibility across releases. Pinned version tags (e.g., `0.14.2`) are also
107+
> maintains backwards compatibility across releases. Pinned version tags (e.g., `0.15.2`) are also
108108
> available.
109109
110110
### Running the Server

python_client/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
66
name = "torc-client"
77
# Note: Do not update manually. Use cargo-release from the repo root, such as
88
# $ cargo release minor --execute
9-
version = "0.15.1"
9+
version = "0.15.2"
1010
description = "Workflow management system"
1111
requires-python = ">=3.11,<3.14"
1212
license = "BSD-3-Clause"

src/bin/torc-dash.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,18 @@ async fn proxy_handler(
524524

525525
// ============== CLI Command Handlers ==============
526526

527-
/// Extract workflow ID from CLI output like "Created workflow 123" or "ID: 123"
527+
/// Extract workflow ID from CLI output.
528+
/// Tries JSON first ({"workflow_id": 123}), then falls back to text patterns
529+
/// like "Created workflow 123" or "ID: 123".
528530
fn extract_workflow_id(stdout: &str) -> Option<String> {
531+
// Try JSON parsing first
532+
if let Ok(json) = serde_json::from_str::<serde_json::Value>(stdout)
533+
&& let Some(id) = json.get("workflow_id")
534+
{
535+
return Some(id.to_string().trim_matches('"').to_string());
536+
}
537+
538+
// Fall back to text pattern matching
529539
for line in stdout.lines() {
530540
if line.contains("Created workflow") {
531541
// Extract the number after "Created workflow"
@@ -703,7 +713,7 @@ async fn cli_create_handler(
703713
// Spec is a file path
704714
run_torc_command(
705715
&state.torc_bin,
706-
&["workflows", "create", &req.spec],
716+
&["-f", "json", "workflows", "create", &req.spec],
707717
&state.api_url,
708718
)
709719
.await
@@ -722,7 +732,7 @@ async fn cli_create_handler(
722732

723733
let result = run_torc_command(
724734
&state.torc_bin,
725-
&["workflows", "create", &temp_path],
735+
&["-f", "json", "workflows", "create", &temp_path],
726736
&state.api_url,
727737
)
728738
.await;
@@ -815,7 +825,14 @@ async fn cli_create_slurm_handler(
815825

816826
let result = if req.is_file {
817827
// Spec is a file path
818-
let mut args = vec!["workflows", "create-slurm", "--account", &req.account];
828+
let mut args = vec![
829+
"-f",
830+
"json",
831+
"workflows",
832+
"create-slurm",
833+
"--account",
834+
&req.account,
835+
];
819836
if let Some(ref profile) = req.profile {
820837
args.push("--hpc-profile");
821838
args.push(profile);
@@ -835,7 +852,14 @@ async fn cli_create_slurm_handler(
835852
});
836853
}
837854

838-
let mut args = vec!["workflows", "create-slurm", "--account", &req.account];
855+
let mut args = vec![
856+
"-f",
857+
"json",
858+
"workflows",
859+
"create-slurm",
860+
"--account",
861+
&req.account,
862+
];
839863
if let Some(ref profile) = req.profile {
840864
args.push("--hpc-profile");
841865
args.push(profile);

torc-dash/static/css/style.css

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,26 @@ body {
217217
gap: 8px;
218218
}
219219

220+
.sidebar-dark-toggle {
221+
display: flex;
222+
align-items: center;
223+
gap: 8px;
224+
padding: 6px 0;
225+
margin-top: 8px;
226+
font-size: 12px;
227+
color: rgba(255, 255, 255, 0.5);
228+
cursor: pointer;
229+
transition: color 0.2s;
230+
}
231+
232+
.sidebar-dark-toggle:hover {
233+
color: rgba(255, 255, 255, 0.8);
234+
}
235+
236+
.dark-toggle-icon {
237+
font-size: 14px;
238+
}
239+
220240
.connection-status {
221241
display: flex;
222242
align-items: center;
@@ -1829,14 +1849,16 @@ textarea.text-input {
18291849
padding: 8px 16px;
18301850
border: 1px solid var(--border-color);
18311851
border-radius: var(--border-radius);
1832-
background: var(--bg-secondary);
1852+
background: var(--bg-tertiary);
1853+
color: var(--text-primary);
18331854
cursor: pointer;
18341855
font-size: 13px;
1856+
font-weight: 500;
18351857
transition: var(--transition);
18361858
}
18371859

18381860
.plot-tab:hover {
1839-
background: var(--bg-tertiary);
1861+
background: var(--border-color);
18401862
}
18411863

18421864
.plot-tab.active {
@@ -2077,16 +2099,18 @@ textarea.text-input {
20772099
.resource-preset-btn {
20782100
padding: 6px 12px;
20792101
font-size: 12px;
2102+
font-weight: 500;
20802103
border: 1px solid var(--border-color);
20812104
border-radius: var(--border-radius);
2082-
background: var(--bg-primary);
2105+
background: var(--bg-tertiary);
2106+
color: var(--text-primary);
20832107
cursor: pointer;
20842108
transition: var(--transition);
20852109
}
20862110

20872111
.resource-preset-btn:hover {
20882112
border-color: var(--primary-color);
2089-
background: rgba(0, 123, 255, 0.05);
2113+
background: var(--border-color);
20902114
}
20912115

20922116
.resource-preset-btn.selected {

torc-dash/static/index.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ <h1><img src="/static/images/torc_icon.png" alt="Torc" class="header-icon"> Torc
6464
<span class="version-text">v-.-.-</span>
6565
</div>
6666
</div>
67+
<div class="sidebar-dark-toggle" id="sidebar-dark-toggle" title="Toggle dark mode (D)">
68+
<span class="dark-toggle-icon" id="dark-toggle-icon">&#9790;</span>
69+
<span class="dark-toggle-label" id="dark-toggle-label">Dark Mode</span>
70+
</div>
6771
<div class="keyboard-hint" id="keyboard-hint" title="Show keyboard shortcuts">
6872
Press <kbd>?</kbd> for shortcuts
6973
</div>
@@ -244,7 +248,7 @@ <h2>Job Debugging</h2>
244248
<h3>Job Results Report</h3>
245249
<div class="form-group">
246250
<label for="debug-output-dir">Output Directory</label>
247-
<input type="text" id="debug-output-dir" class="text-input" value="output" placeholder="output">
251+
<input type="text" id="debug-output-dir" class="text-input" value="torc_output" placeholder="torc_output">
248252
<small>Directory where job logs are stored</small>
249253
</div>
250254
<div class="form-group">
@@ -327,8 +331,8 @@ <h3>Resource Database Selection</h3>
327331
<label for="resource-db-dir">Database Directory</label>
328332
<div style="display: flex; gap: 10px;">
329333
<input type="text" id="resource-db-dir" class="text-input"
330-
value="output/resource_utilization"
331-
placeholder="output/resource_utilization">
334+
value="torc_output/resource_utilization"
335+
placeholder="torc_output/resource_utilization">
332336
<button class="btn btn-secondary" id="btn-scan-dbs">Scan</button>
333337
</div>
334338
<small>Directory containing resource monitoring database files (.db)</small>
@@ -669,10 +673,6 @@ <h4>Resource Monitoring</h4>
669673
<input type="checkbox" id="create-option-initialize" checked>
670674
Initialize workflow after creation
671675
</label>
672-
<label class="toggle-label">
673-
<input type="checkbox" id="create-option-run">
674-
Run workflow immediately
675-
</label>
676676
</div>
677677

678678
<!-- Slurm Options -->

torc-dash/static/js/app-core.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Object.assign(TorcDashboard.prototype, {
2323
if (themeSelector) themeSelector.value = theme;
2424
if (themeSelectorGroup) themeSelectorGroup.style.display = darkMode ? 'block' : 'none';
2525

26+
// Sync sidebar dark mode toggle
27+
this.updateSidebarDarkToggle(darkMode);
28+
2629
const refreshInterval = localStorage.getItem('torc-refresh-interval') || '30';
2730
const intervalInput = document.getElementById('refresh-interval');
2831
if (intervalInput) intervalInput.value = refreshInterval;
@@ -51,13 +54,26 @@ Object.assign(TorcDashboard.prototype, {
5154
} else {
5255
this.removeAllThemes();
5356
}
57+
this.updateSidebarDarkToggle(e.target.checked);
5458
});
5559

5660
// Apply theme immediately when selector changes
5761
themeSelector?.addEventListener('change', (e) => {
5862
this.applyTheme(e.target.value);
5963
localStorage.setItem('torc-theme', e.target.value);
6064
});
65+
66+
// Sidebar dark mode toggle
67+
document.getElementById('sidebar-dark-toggle')?.addEventListener('click', () => {
68+
this.toggleDarkMode();
69+
});
70+
},
71+
72+
updateSidebarDarkToggle(isDark) {
73+
const icon = document.getElementById('dark-toggle-icon');
74+
const label = document.getElementById('dark-toggle-label');
75+
if (icon) icon.innerHTML = isDark ? '&#9788;' : '&#9790;';
76+
if (label) label.textContent = isDark ? 'Light Mode' : 'Dark Mode';
6177
},
6278

6379
applyTheme(theme) {
@@ -119,6 +135,7 @@ Object.assign(TorcDashboard.prototype, {
119135
if (selector) selector.value = nextTheme.id;
120136
const selectorGroup = document.getElementById('theme-selector-group');
121137
if (selectorGroup) selectorGroup.style.display = 'block';
138+
this.updateSidebarDarkToggle(true);
122139
} else {
123140
document.body.classList.remove('dark-mode');
124141
this.removeAllThemes();
@@ -129,6 +146,7 @@ Object.assign(TorcDashboard.prototype, {
129146
if (checkbox) checkbox.checked = false;
130147
const selectorGroup = document.getElementById('theme-selector-group');
131148
if (selectorGroup) selectorGroup.style.display = 'none';
149+
this.updateSidebarDarkToggle(false);
132150
}
133151

134152
this.showToast(`Theme: ${nextTheme.name}`, 'info');
@@ -152,6 +170,7 @@ Object.assign(TorcDashboard.prototype, {
152170
document.body.classList.remove('dark-mode');
153171
this.removeAllThemes();
154172
}
173+
this.updateSidebarDarkToggle(darkMode);
155174

156175
this.showToast('Settings saved', 'success');
157176

@@ -198,15 +217,19 @@ Object.assign(TorcDashboard.prototype, {
198217
dagVisualizer.loadJobDependencies(this.selectedWorkflowId);
199218
}
200219

201-
// Sync events workflow selector with selected workflow and clear badge
220+
// Sync events workflow selector with selected workflow and start SSE stream
202221
if (tabName === 'events') {
203222
const badge = document.getElementById('event-badge');
204223
if (badge) badge.style.display = 'none';
205224
if (this.selectedWorkflowId) {
206225
const eventsSelector = document.getElementById('events-workflow-selector');
207-
if (eventsSelector) {
226+
if (eventsSelector && eventsSelector.value !== this.selectedWorkflowId) {
208227
eventsSelector.value = this.selectedWorkflowId;
209228
}
229+
// Start SSE stream if not already connected for this workflow
230+
if (this._lastEventsWorkflowId !== this.selectedWorkflowId) {
231+
this.startEventStream(this.selectedWorkflowId);
232+
}
210233
}
211234
}
212235

torc-dash/static/js/app-debugging.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Object.assign(TorcDashboard.prototype, {
4141
}
4242

4343
// Get output directory from the input field
44-
this.debugOutputDir = document.getElementById('debug-output-dir')?.value || 'output';
44+
this.debugOutputDir = document.getElementById('debug-output-dir')?.value || 'torc_output';
4545

4646
try {
4747
// Get jobs and results for the workflow
@@ -220,7 +220,7 @@ Object.assign(TorcDashboard.prototype, {
220220
return;
221221
}
222222

223-
const outputDir = document.getElementById('debug-output-dir')?.value || 'output';
223+
const outputDir = document.getElementById('debug-output-dir')?.value || 'torc_output';
224224
const errorsOnly = document.getElementById('slurm-errors-only')?.checked || false;
225225
const resultsContainer = document.getElementById('slurm-logs-results');
226226

@@ -339,7 +339,7 @@ Object.assign(TorcDashboard.prototype, {
339339
return;
340340
}
341341

342-
const outputDir = document.getElementById('debug-output-dir')?.value || 'output';
342+
const outputDir = document.getElementById('debug-output-dir')?.value || 'torc_output';
343343
const resultsContainer = document.getElementById('slurm-sacct-results');
344344

345345
resultsContainer.innerHTML = '<div class="loading-indicator">Collecting sacct data...</div>';

0 commit comments

Comments
 (0)