Sudo-JHare ca8668e5e5 V2.0 release.
Hapi Config Page.
retrieve bundles from server
split bundles to resources.
new upload page, and Package Registry CACHE
2025-05-04 22:55:36 +10:00

145 lines
8.7 KiB
HTML

{% extends "base.html" %}
{% from "_form_helpers.html" import render_field %}
{% block content %}
<div class="px-4 py-5 my-5 text-center">
<img class="d-block mx-auto mb-4" src="{{ url_for('static', filename='FHIRFLARE.png') }}" alt="FHIRFLARE IG Toolkit" width="192" height="192">
<h1 class="display-5 fw-bold text-body-emphasis">Import FHIR Implementation Guides</h1>
<div class="col-lg-6 mx-auto">
<p class="lead mb-4">
Import new FHIR Implementation Guides to the system for viewing.
</p>
</div>
</div>
<div id="fire-loading-overlay" class="fire-loading-overlay d-none">
<div class="campfire">
<div class="campfire-scaler">
<div class="sparks">
<div class="spark"></div> <div class="spark"></div> <div class="spark"></div> <div class="spark"></div>
<div class="spark"></div> <div class="spark"></div> <div class="spark"></div> <div class="spark"></div>
</div>
<div class="logs">
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
<div class="log"><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div><div class="streak"></div></div>
</div>
<div class="sticks">
<div class="stick"></div><div class="stick"></div><div class="stick"></div><div class="stick"></div>
</div>
<div class="fire">
<div class="fire__red"><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div></div>
<div class="fire__orange"><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div></div>
<div class="fire__yellow"><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div></div>
<div class="fire__white"><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div><div class="flame"></div></div>
</div>
</div> </div> <div class="loading-text text-center">
<p class="text-white mt-3">Importing Implementation Guide... Please wait.</p>
<p id="log-display" class="text-white mb-0"></p>
</div>
</div>
<div class="container mt-4">
<h2><i class="bi bi-download me-2"></i>Import a New IG</h2>
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<form id="import-ig-form" method="POST" class="form">
{{ form.hidden_tag() }}
{{ render_field(form.package_name) }}
{{ render_field(form.package_version) }}
{{ render_field(form.dependency_mode) }}
<div class="d-grid gap-2 d-sm-flex">
{{ form.submit(class="btn btn-success", id="submit-btn") }}
<a href="{{ url_for('index') }}" class="btn btn-secondary">Back</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
// Your existing JS here (exactly as provided before)
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('import-ig-form');
const submitBtn = document.getElementById('submit-btn');
const loadingOverlay = document.getElementById('fire-loading-overlay');
const logDisplay = document.getElementById('log-display');
if (form && submitBtn && loadingOverlay && logDisplay) {
form.addEventListener('submit', async function(event) {
event.preventDefault();
submitBtn.disabled = true;
logDisplay.textContent = 'Starting import...';
loadingOverlay.classList.remove('d-none'); // Show the overlay
let eventSource;
try {
eventSource = new EventSource('{{ url_for('stream_import_logs') }}');
eventSource.onmessage = function(event) {
if (event.data === '[DONE]') {
eventSource.close();
return;
}
logDisplay.textContent = event.data;
};
eventSource.onerror = function() {
console.error('SSE connection error');
if(eventSource) eventSource.close();
logDisplay.textContent = 'Log streaming interrupted.';
};
} catch (e) {
console.error('Failed to initialize SSE:', e);
logDisplay.textContent = 'Unable to stream logs: ' + e.message;
}
const formData = new FormData(form);
try {
const response = await fetch('{{ url_for('import_ig') }}', {
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
body: formData
});
if (eventSource && eventSource.readyState !== EventSource.CLOSED) {
eventSource.close();
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({ message: `HTTP error: ${response.status}` }));
throw new Error(errorData.message || `HTTP error: ${response.status}`);
}
const data = await response.json();
if (data.redirect) {
window.location.href = data.redirect;
} else {
// Optional: display success message
}
} catch (error) {
console.error('Import error:', error);
if (eventSource && eventSource.readyState !== EventSource.CLOSED) {
eventSource.close();
}
const alertDiv = document.createElement('div');
alertDiv.className = 'alert alert-danger mt-3';
alertDiv.textContent = `Import failed: ${error.message}`;
form.closest('.card-body').appendChild(alertDiv);
} finally {
loadingOverlay.classList.add('d-none'); // Hide overlay when done
submitBtn.disabled = false;
}
});
} else {
console.error('Required elements missing for import script.');
}
});
</script>
{% endblock %}