Feat v0.9.6 stage mode collapse (#80)
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-frontend (push) Successful in 6s
CI/CD / test-go-pg (push) Successful in 2m49s
CI/CD / test-sqlite (push) Successful in 3m4s
CI/CD / build-and-deploy (push) Successful in 1m15s
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-frontend (push) Successful in 6s
CI/CD / test-go-pg (push) Successful in 2m49s
CI/CD / test-sqlite (push) Successful in 3m4s
CI/CD / build-and-deploy (push) Successful in 1m15s
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #80.
This commit is contained in:
@@ -178,7 +178,7 @@
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<!-- Stage surface: form, review, delegated (custom surface), or automated -->
|
||||
<!-- Stage surface: form, delegated (custom surface), or automated -->
|
||||
|
||||
{{if .Data.AudienceMismatch}}
|
||||
<div class="wf-submitted">
|
||||
@@ -195,11 +195,6 @@
|
||||
<div id="customSurfaceMount" style="flex:1;overflow-y:auto"></div>
|
||||
{{else if eq .Data.StageMode "form"}}
|
||||
<div class="wf-form" id="formArea"></div>
|
||||
{{else if eq .Data.StageMode "review"}}
|
||||
<div id="reviewArea" style="flex:1;overflow-y:auto;display:flex">
|
||||
<div id="reviewDataPanel" style="flex:1;overflow-y:auto;border-right:1px solid var(--border)"></div>
|
||||
<div id="reviewActionPanel" style="flex:1;overflow-y:auto;display:flex;flex-direction:column"></div>
|
||||
</div>
|
||||
{{else if eq .Data.Status "completed"}}
|
||||
<div class="wf-form-success" style="flex:1;display:flex;flex-direction:column;justify-content:center">
|
||||
<h3>Completed</h3>
|
||||
@@ -212,7 +207,7 @@
|
||||
{{end}}
|
||||
|
||||
<div class="wf-session-info">
|
||||
{{if .Data.SurfacePkgID}}Session:{{else if eq .Data.StageMode "form"}}Submitting as{{else if eq .Data.StageMode "review"}}Reviewing as{{else}}Session:{{end}} <strong>{{.Data.SessionName}}</strong>
|
||||
{{if .Data.SurfacePkgID}}Session:{{else if eq .Data.StageMode "form"}}Submitting as{{else}}Session:{{end}} <strong>{{.Data.SessionName}}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -542,116 +537,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
// ── Review surface (structured review with side-by-side + comments) ──
|
||||
if (STAGE_MODE === 'review') {
|
||||
var dataPanel = document.getElementById('reviewDataPanel');
|
||||
var actionPanel = document.getElementById('reviewActionPanel');
|
||||
if (dataPanel && actionPanel) {
|
||||
loadReviewSurface(dataPanel, actionPanel);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadReviewSurface(dataPanel, actionPanel) {
|
||||
dataPanel.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-3)">Loading\u2026</div>';
|
||||
|
||||
// Left panel: structured data card
|
||||
var html = '<div style="padding:24px">';
|
||||
html += '<h3 style="margin-bottom:16px">Collected Data</h3>';
|
||||
|
||||
try {
|
||||
var resp = await fetch(BASE + '/api/v1/public/workflows/resume/' + API_ID, {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
if (resp.ok) {
|
||||
var status = await resp.json();
|
||||
if (status.stage_data && typeof status.stage_data === 'object') {
|
||||
html += '<table style="width:100%;border-collapse:collapse">';
|
||||
for (var key in status.stage_data) {
|
||||
if (!status.stage_data.hasOwnProperty(key) || key.startsWith('_')) continue;
|
||||
html += '<tr style="border-bottom:1px solid var(--border)">';
|
||||
html += '<td style="padding:8px;font-weight:600;font-size:13px;width:30%;vertical-align:top">' + escHtml(key) + '</td>';
|
||||
var val = status.stage_data[key];
|
||||
var display = typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val);
|
||||
html += '<td style="padding:8px;font-size:13px;white-space:pre-wrap">' + escHtml(display) + '</td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
} else {
|
||||
html += '<p style="color:var(--text-3)">No data collected yet.</p>';
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
html += '<p style="color:var(--danger)">Failed to load review data.</p>';
|
||||
}
|
||||
html += '</div>';
|
||||
dataPanel.innerHTML = html;
|
||||
|
||||
// Right panel: comment input + approve/reject buttons
|
||||
var actHtml = '<div style="padding:24px;flex:1;display:flex;flex-direction:column">';
|
||||
actHtml += '<h3 style="margin-bottom:16px">Review Actions</h3>';
|
||||
actHtml += '<div style="margin-bottom:16px">';
|
||||
actHtml += '<label style="font-size:13px;font-weight:600;display:block;margin-bottom:4px">Add Comment</label>';
|
||||
actHtml += '<textarea id="reviewComment" rows="3" style="width:100%;padding:8px;font-size:14px;border:1px solid var(--border);border-radius:6px;background:var(--input-bg);color:var(--text);font-family:var(--font);resize:vertical" placeholder="Optional comment\u2026"></textarea>';
|
||||
actHtml += '</div>';
|
||||
actHtml += '<div style="display:flex;gap:8px">';
|
||||
actHtml += '<button id="reviewAdvanceBtn" style="background:var(--accent);color:#fff;border:none;border-radius:8px;padding:10px 24px;font-weight:600;cursor:pointer;font-size:14px">Approve & Advance</button>';
|
||||
actHtml += '<button id="reviewRejectBtn" style="background:var(--danger,#e74c3c);color:#fff;border:none;border-radius:8px;padding:10px 24px;font-weight:600;cursor:pointer;font-size:14px">Reject</button>';
|
||||
actHtml += '</div>';
|
||||
actHtml += '<div style="font-size:12px;color:var(--text-3);margin-top:8px">Ctrl+Enter: Approve · Ctrl+Shift+Enter: Reject</div>';
|
||||
actHtml += '</div>';
|
||||
actionPanel.innerHTML = actHtml;
|
||||
|
||||
// Keyboard shortcuts
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.ctrlKey && e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (e.shiftKey) {
|
||||
document.getElementById('reviewRejectBtn').click();
|
||||
} else {
|
||||
document.getElementById('reviewAdvanceBtn').click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('reviewAdvanceBtn').addEventListener('click', async function() {
|
||||
this.disabled = true;
|
||||
try {
|
||||
var r = await fetch(BASE + '/api/v1/public/workflows/advance/' + API_ID, {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ data: {} }),
|
||||
});
|
||||
if (r.ok) {
|
||||
actionPanel.innerHTML = '<div style="padding:40px;text-align:center"><h3>Approved</h3><p style="color:var(--text-2)">Stage advanced.</p></div>';
|
||||
setTimeout(function() { window.location.reload(); }, 1500);
|
||||
} else {
|
||||
var err = await r.json().catch(function() { return {}; });
|
||||
alert('Failed: ' + (err.error || 'unknown'));
|
||||
document.getElementById('reviewAdvanceBtn').disabled = false;
|
||||
}
|
||||
} catch(e) { alert('Error: ' + e.message); }
|
||||
});
|
||||
|
||||
document.getElementById('reviewRejectBtn').addEventListener('click', async function() {
|
||||
var comment = document.getElementById('reviewComment').value;
|
||||
var reason = comment || prompt('Rejection reason:');
|
||||
if (!reason) return;
|
||||
this.disabled = true;
|
||||
try {
|
||||
var r = await fetch(BASE + '/api/v1/public/workflows/advance/' + API_ID, {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ data: { _action: 'reject', reason: reason } }),
|
||||
});
|
||||
if (r.ok) {
|
||||
actionPanel.innerHTML = '<div style="padding:40px;text-align:center"><h3>Rejected</h3><p style="color:var(--text-2)">Sent back for revision.</p></div>';
|
||||
setTimeout(function() { window.location.reload(); }, 1500);
|
||||
} else {
|
||||
var err = await r.json().catch(function() { return {}; });
|
||||
alert('Failed: ' + (err.error || 'unknown'));
|
||||
document.getElementById('reviewRejectBtn').disabled = false;
|
||||
}
|
||||
} catch(e) { alert('Error: ' + e.message); }
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user