add branch validation to queue
This commit is contained in:
@@ -54,7 +54,8 @@
|
||||
|
||||
<script>
|
||||
let validatedBranch = null;
|
||||
let availableScenarios = [];
|
||||
let organizedData = {};
|
||||
let scenarioMap = {};
|
||||
|
||||
document.getElementById('branchForm').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
@@ -101,7 +102,8 @@ function validateBranch() {
|
||||
nextBtn.style.display = 'inline-block';
|
||||
|
||||
validatedBranch = branchName;
|
||||
availableScenarios = data.scenarios;
|
||||
organizedData = data.organized_data || {};
|
||||
scenarioMap = data.scenario_map || {};
|
||||
|
||||
// Log debug info
|
||||
if (data.debug) {
|
||||
@@ -118,7 +120,8 @@ function validateBranch() {
|
||||
nextBtn.style.display = 'none';
|
||||
|
||||
validatedBranch = null;
|
||||
availableScenarios = [];
|
||||
organizedData = {};
|
||||
scenarioMap = {};
|
||||
|
||||
// Log debug info for troubleshooting
|
||||
console.error('Branch validation failed:', data.error);
|
||||
@@ -143,7 +146,7 @@ function validateBranch() {
|
||||
}
|
||||
|
||||
function proceedToStep2() {
|
||||
if (!validatedBranch || !availableScenarios.length) {
|
||||
if (!validatedBranch || Object.keys(organizedData).length === 0) {
|
||||
alert('Please validate the branch first');
|
||||
return;
|
||||
}
|
||||
@@ -159,11 +162,17 @@ function proceedToStep2() {
|
||||
branchInput.value = validatedBranch;
|
||||
form.appendChild(branchInput);
|
||||
|
||||
const scenariosInput = document.createElement('input');
|
||||
scenariosInput.type = 'hidden';
|
||||
scenariosInput.name = 'scenarios';
|
||||
scenariosInput.value = JSON.stringify(availableScenarios);
|
||||
form.appendChild(scenariosInput);
|
||||
const organizedDataInput = document.createElement('input');
|
||||
organizedDataInput.type = 'hidden';
|
||||
organizedDataInput.name = 'organized_data';
|
||||
organizedDataInput.value = JSON.stringify(organizedData);
|
||||
form.appendChild(organizedDataInput);
|
||||
|
||||
const scenarioMapInput = document.createElement('input');
|
||||
scenarioMapInput.type = 'hidden';
|
||||
scenarioMapInput.name = 'scenario_map';
|
||||
scenarioMapInput.value = JSON.stringify(scenarioMap);
|
||||
form.appendChild(scenarioMapInput);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
@@ -181,7 +190,8 @@ document.getElementById('branch_name').addEventListener('input', function() {
|
||||
nextBtn.style.display = 'none';
|
||||
|
||||
validatedBranch = null;
|
||||
availableScenarios = [];
|
||||
organizedData = {};
|
||||
scenarioMap = {};
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -33,36 +33,210 @@
|
||||
<strong>Branch:</strong> {{ branch_name }}
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ url_for('jobs.submit_step2') }}">
|
||||
<form method="POST" action="{{ url_for('jobs.submit_step2') }}" id="scenarioForm">
|
||||
<input type="hidden" name="branch_name" value="{{ branch_name }}">
|
||||
<input type="hidden" name="scenario_map" value="{{ scenario_map|tojson }}">
|
||||
<input type="hidden" name="selected_scenarios" id="selectedScenariosInput">
|
||||
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="selectAll" onclick="toggleAll(this)">
|
||||
Select All Scenarios
|
||||
</label>
|
||||
<div class="scenario-controls">
|
||||
<button type="button" class="btn btn-sm" onclick="selectAll()" style="background: var(--success); color: white; margin-right: 10px;">Select All</button>
|
||||
<button type="button" class="btn btn-sm" onclick="deselectAll()" style="background: var(--danger); color: white;">Deselect All</button>
|
||||
<span id="selectionCount" style="margin-left: 20px; font-weight: 600;">0 scenarios selected</span>
|
||||
</div>
|
||||
|
||||
<div class="checkbox-group">
|
||||
{% for scenario in scenarios %}
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" name="scenarios" value="{{ scenario }}" id="scenario_{{ loop.index }}">
|
||||
<label for="scenario_{{ loop.index }}">{{ scenario }}</label>
|
||||
<div class="scenario-tree">
|
||||
{% for layer_name, layer_data in organized_data.items() %}
|
||||
<div class="tree-layer">
|
||||
<div class="tree-node layer-node" onclick="toggleLayer('{{ layer_name }}')">
|
||||
<span class="tree-toggle" id="toggle-{{ layer_name }}">▶</span>
|
||||
<input type="checkbox" class="layer-checkbox" id="layer-{{ layer_name }}" onchange="toggleLayerSelection('{{ layer_name }}')">
|
||||
<label for="layer-{{ layer_name }}" class="tree-label layer-label">{{ layer_name.replace('_', ' ').title() }}</label>
|
||||
</div>
|
||||
|
||||
<div class="tree-children" id="children-{{ layer_name }}" style="display: none;">
|
||||
{% for stack_name, scenarios in layer_data.items() %}
|
||||
<div class="tree-stack">
|
||||
<div class="tree-node stack-node" onclick="toggleStack('{{ layer_name }}', '{{ stack_name }}')">
|
||||
<span class="tree-toggle" id="toggle-{{ layer_name }}-{{ stack_name }}">▶</span>
|
||||
<input type="checkbox" class="stack-checkbox" id="stack-{{ layer_name }}-{{ stack_name }}" onchange="toggleStackSelection('{{ layer_name }}', '{{ stack_name }}')">
|
||||
<label for="stack-{{ layer_name }}-{{ stack_name }}" class="tree-label stack-label">{{ stack_name.replace('_', ' ').title() }}</label>
|
||||
</div>
|
||||
|
||||
<div class="tree-children" id="children-{{ layer_name }}-{{ stack_name }}" style="display: none;">
|
||||
{% for scenario in scenarios %}
|
||||
<div class="tree-scenario">
|
||||
<div class="tree-node scenario-node">
|
||||
<span class="tree-spacer"></span>
|
||||
<input type="checkbox" class="scenario-checkbox" id="scenario-{{ scenario }}" value="{{ scenario }}" onchange="updateSelectionCount()" data-layer="{{ layer_name }}" data-stack="{{ stack_name }}">
|
||||
<label for="scenario-{{ scenario }}" class="tree-label scenario-label">{{ scenario }}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="{{ url_for('jobs.submit') }}" class="btn" style="background: #6b7280; color: white;">Back</a>
|
||||
<button type="submit" class="btn btn-primary">Next</button>
|
||||
<button type="submit" class="btn btn-primary" id="nextBtn" disabled>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleAll(checkbox) {
|
||||
const checkboxes = document.querySelectorAll('input[name="scenarios"]');
|
||||
checkboxes.forEach(cb => cb.checked = checkbox.checked);
|
||||
let selectedScenarios = new Set();
|
||||
|
||||
function toggleLayer(layerName) {
|
||||
const children = document.getElementById(`children-${layerName}`);
|
||||
const toggle = document.getElementById(`toggle-${layerName}`);
|
||||
|
||||
if (children.style.display === 'none') {
|
||||
children.style.display = 'block';
|
||||
toggle.textContent = '▼';
|
||||
} else {
|
||||
children.style.display = 'none';
|
||||
toggle.textContent = '▶';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleStack(layerName, stackName) {
|
||||
const children = document.getElementById(`children-${layerName}-${stackName}`);
|
||||
const toggle = document.getElementById(`toggle-${layerName}-${stackName}`);
|
||||
|
||||
if (children.style.display === 'none') {
|
||||
children.style.display = 'block';
|
||||
toggle.textContent = '▼';
|
||||
} else {
|
||||
children.style.display = 'none';
|
||||
toggle.textContent = '▶';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleLayerSelection(layerName) {
|
||||
const layerCheckbox = document.getElementById(`layer-${layerName}`);
|
||||
const stackCheckboxes = document.querySelectorAll(`input[id^="stack-${layerName}-"]`);
|
||||
const scenarioCheckboxes = document.querySelectorAll(`input[data-layer="${layerName}"]`);
|
||||
|
||||
// Update all stacks and scenarios in this layer
|
||||
stackCheckboxes.forEach(checkbox => {
|
||||
checkbox.checked = layerCheckbox.checked;
|
||||
checkbox.indeterminate = false;
|
||||
});
|
||||
|
||||
scenarioCheckboxes.forEach(checkbox => {
|
||||
checkbox.checked = layerCheckbox.checked;
|
||||
if (layerCheckbox.checked) {
|
||||
selectedScenarios.add(checkbox.value);
|
||||
} else {
|
||||
selectedScenarios.delete(checkbox.value);
|
||||
}
|
||||
});
|
||||
|
||||
updateSelectionCount();
|
||||
}
|
||||
|
||||
function toggleStackSelection(layerName, stackName) {
|
||||
const stackCheckbox = document.getElementById(`stack-${layerName}-${stackName}`);
|
||||
const scenarioCheckboxes = document.querySelectorAll(`input[data-layer="${layerName}"][data-stack="${stackName}"]`);
|
||||
|
||||
// Update all scenarios in this stack
|
||||
scenarioCheckboxes.forEach(checkbox => {
|
||||
checkbox.checked = stackCheckbox.checked;
|
||||
if (stackCheckbox.checked) {
|
||||
selectedScenarios.add(checkbox.value);
|
||||
} else {
|
||||
selectedScenarios.delete(checkbox.value);
|
||||
}
|
||||
});
|
||||
|
||||
updateLayerState(layerName);
|
||||
updateSelectionCount();
|
||||
}
|
||||
|
||||
function updateLayerState(layerName) {
|
||||
const layerCheckbox = document.getElementById(`layer-${layerName}`);
|
||||
const stackCheckboxes = document.querySelectorAll(`input[id^="stack-${layerName}-"]`);
|
||||
const scenarioCheckboxes = document.querySelectorAll(`input[data-layer="${layerName}"]`);
|
||||
|
||||
// Update stack states
|
||||
stackCheckboxes.forEach(stackCheckbox => {
|
||||
const stackName = stackCheckbox.id.replace(`stack-${layerName}-`, '');
|
||||
const stackScenarios = document.querySelectorAll(`input[data-layer="${layerName}"][data-stack="${stackName}"]`);
|
||||
const checkedCount = Array.from(stackScenarios).filter(cb => cb.checked).length;
|
||||
|
||||
if (checkedCount === 0) {
|
||||
stackCheckbox.checked = false;
|
||||
stackCheckbox.indeterminate = false;
|
||||
} else if (checkedCount === stackScenarios.length) {
|
||||
stackCheckbox.checked = true;
|
||||
stackCheckbox.indeterminate = false;
|
||||
} else {
|
||||
stackCheckbox.checked = false;
|
||||
stackCheckbox.indeterminate = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Update layer state
|
||||
const checkedScenarios = Array.from(scenarioCheckboxes).filter(cb => cb.checked).length;
|
||||
if (checkedScenarios === 0) {
|
||||
layerCheckbox.checked = false;
|
||||
layerCheckbox.indeterminate = false;
|
||||
} else if (checkedScenarios === scenarioCheckboxes.length) {
|
||||
layerCheckbox.checked = true;
|
||||
layerCheckbox.indeterminate = false;
|
||||
} else {
|
||||
layerCheckbox.checked = false;
|
||||
layerCheckbox.indeterminate = true;
|
||||
}
|
||||
}
|
||||
|
||||
function updateSelectionCount() {
|
||||
// Update selected scenarios set
|
||||
selectedScenarios.clear();
|
||||
document.querySelectorAll('.scenario-checkbox:checked').forEach(checkbox => {
|
||||
selectedScenarios.add(checkbox.value);
|
||||
});
|
||||
|
||||
// Update all layer states
|
||||
const layers = new Set();
|
||||
document.querySelectorAll('.scenario-checkbox').forEach(checkbox => {
|
||||
layers.add(checkbox.dataset.layer);
|
||||
});
|
||||
layers.forEach(layer => updateLayerState(layer));
|
||||
|
||||
// Update UI
|
||||
const count = selectedScenarios.size;
|
||||
document.getElementById('selectionCount').textContent = `${count} scenario${count !== 1 ? 's' : ''} selected`;
|
||||
document.getElementById('nextBtn').disabled = count === 0;
|
||||
|
||||
// Update hidden input
|
||||
document.getElementById('selectedScenariosInput').value = JSON.stringify(Array.from(selectedScenarios));
|
||||
}
|
||||
|
||||
function selectAll() {
|
||||
document.querySelectorAll('.scenario-checkbox').forEach(checkbox => {
|
||||
checkbox.checked = true;
|
||||
selectedScenarios.add(checkbox.value);
|
||||
});
|
||||
updateSelectionCount();
|
||||
}
|
||||
|
||||
function deselectAll() {
|
||||
document.querySelectorAll('.scenario-checkbox, .stack-checkbox, .layer-checkbox').forEach(checkbox => {
|
||||
checkbox.checked = false;
|
||||
checkbox.indeterminate = false;
|
||||
});
|
||||
selectedScenarios.clear();
|
||||
updateSelectionCount();
|
||||
}
|
||||
|
||||
// Initialize
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
updateSelectionCount();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user