98 lines
3.2 KiB
HTML
98 lines
3.2 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
|
|
<!-- Step 1: Start New Session -->
|
|
<div class="panel" id="step1">
|
|
<h2>New Conversion Session</h2>
|
|
|
|
<form id="session-form" onsubmit="startSession(event)">
|
|
<div class="form-group">
|
|
<label for="vmid">VM ID *</label>
|
|
<input type="number" id="vmid" name="vmid" required
|
|
placeholder="e.g. 10010" min="100" max="999999">
|
|
<span class="hint">Must be unique on the Proxmox host</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="source-type">Source Type</label>
|
|
<select id="source-type" onchange="toggleSourceInput(event)">
|
|
<option value="upload">File Upload</option>
|
|
<option value="url">Download from URL</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group" id="upload-group">
|
|
<label for="source-file">Source File (.vmdk / .7z / .zip / .tar.gz)</label>
|
|
<input type="file" id="source-file" name="source_file"
|
|
accept=".vmdk,.vhd,.vhdx,.7z,.zip,.tar.gz,.tgz,.tar,.gz">
|
|
</div>
|
|
|
|
<div class="form-group hidden" id="url-group">
|
|
<label for="source-url">Download URL</label>
|
|
<input type="url" id="source-url" name="source_url"
|
|
placeholder="https://example.com/image.7z">
|
|
</div>
|
|
|
|
<button type="submit" id="start-btn">Analyse Source Image</button>
|
|
</form>
|
|
|
|
<div id="session-status" class="hidden" style="margin-top:1rem;"></div>
|
|
</div>
|
|
|
|
<!-- Step 2: Analysis Result (populated by JavaScript) -->
|
|
<div id="analysis-section"></div>
|
|
|
|
<script>
|
|
function toggleSourceInput(e) {
|
|
const type = e.target.value;
|
|
document.getElementById('upload-group').classList.toggle('hidden', type !== 'upload');
|
|
document.getElementById('url-group').classList.toggle('hidden', type !== 'url');
|
|
}
|
|
|
|
async function startSession(e) {
|
|
e.preventDefault();
|
|
const btn = document.getElementById('start-btn');
|
|
const status = document.getElementById('session-status');
|
|
btn.disabled = true;
|
|
status.classList.remove('hidden');
|
|
status.innerHTML = '<div class="spinner"></div> Analysing source image...';
|
|
|
|
const formData = new FormData();
|
|
formData.append('vmid', document.getElementById('vmid').value);
|
|
|
|
const sourceType = document.getElementById('source-type').value;
|
|
formData.append('source_type', sourceType);
|
|
|
|
if (sourceType === 'upload') {
|
|
const fileInput = document.getElementById('source-file');
|
|
if (fileInput.files.length > 0) {
|
|
formData.append('source_file', fileInput.files[0]);
|
|
} else {
|
|
status.innerHTML = '<div class="error">Please select a file.</div>';
|
|
btn.disabled = false;
|
|
return;
|
|
}
|
|
} else {
|
|
const url = document.getElementById('source-url').value.trim();
|
|
if (!url) {
|
|
status.innerHTML = '<div class="error">Please enter a URL.</div>';
|
|
btn.disabled = false;
|
|
return;
|
|
}
|
|
formData.append('source_url', url);
|
|
}
|
|
|
|
try {
|
|
const resp = await fetch('/session/start', { method: 'POST', body: formData });
|
|
const html = await resp.text();
|
|
document.getElementById('analysis-section').innerHTML = html;
|
|
status.classList.add('hidden');
|
|
} catch (err) {
|
|
status.innerHTML = `<div class="error">Failed: ${err.message}</div>`;
|
|
} finally {
|
|
btn.disabled = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
{% endblock %}
|