Files
testarena/app/templates/jobs/submit_step2.html
2025-12-27 01:14:47 +01:00

269 lines
12 KiB
HTML

{% extends "base.html" %}
{% block title %}Select Scenarios - ASF TestArena{% endblock %}
{% block content %}
<div class="submit-container">
<h2 style="margin-bottom: 30px; color: var(--dark);">Select Test Scenarios</h2>
<div class="step-indicator">
<div class="step completed">
<div class="step-number"></div>
<div class="step-label">Branch</div>
</div>
<div class="step active">
<div class="step-number">2</div>
<div class="step-label">Scenarios</div>
</div>
<div class="step">
<div class="step-number">3</div>
<div class="step-label">Environment</div>
</div>
<div class="step">
<div class="step-number">4</div>
<div class="step-label">Test Mode</div>
</div>
<div class="step">
<div class="step-number">5</div>
<div class="step-label">Review</div>
</div>
</div>
<div style="background: #eff6ff; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
<strong>Branch:</strong> {{ branch_name }}
</div>
<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="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="scenario-tree">
{% if organized_data %}
{% 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;">
{% if layer_data %}
{% 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;">
{% if scenarios %}
{% 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 %}
{% else %}
<div class="tree-scenario">
<div class="tree-node scenario-node">
<span class="tree-spacer"></span>
<span class="tree-label scenario-label" style="color: #9ca3af;">No scenarios found</span>
</div>
</div>
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<div class="tree-stack">
<div class="tree-node stack-node">
<span class="tree-spacer"></span>
<span class="tree-label stack-label" style="color: #9ca3af;">No stacks found</span>
</div>
</div>
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<div class="tree-layer">
<div class="tree-node layer-node">
<span class="tree-label layer-label" style="color: #9ca3af;">No scenarios available</span>
</div>
</div>
{% endif %}
</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" id="nextBtn" disabled>Next</button>
</div>
</form>
</div>
<script>
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 %}