- Added wimtools to offline packages and playbook verification - Webapp startnet.cmd editor: extract, view, edit, save back to boot.wim - Uses wimextract/wimupdate for in-place WIM modification - Dark-themed code editor with tab support and common command reference Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
204 lines
6.3 KiB
HTML
204 lines
6.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-bs-theme="light">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{% block title %}PXE Server Manager{% endblock %}</title>
|
|
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
|
rel="stylesheet"
|
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YcnS49cn91B2HOwP4cMpe1bBMnos9GBsYl7a"
|
|
crossorigin="anonymous">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
|
|
rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--sidebar-width: 280px;
|
|
}
|
|
body {
|
|
min-height: 100vh;
|
|
}
|
|
.sidebar {
|
|
width: var(--sidebar-width);
|
|
min-height: 100vh;
|
|
background-color: #1a1d21;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 100;
|
|
overflow-y: auto;
|
|
}
|
|
.sidebar .nav-link {
|
|
color: #adb5bd;
|
|
padding: 0.6rem 1.25rem;
|
|
font-size: 0.9rem;
|
|
border-radius: 0;
|
|
}
|
|
.sidebar .nav-link:hover,
|
|
.sidebar .nav-link.active {
|
|
color: #fff;
|
|
background-color: rgba(255,255,255,0.08);
|
|
}
|
|
.sidebar .nav-link .bi {
|
|
margin-right: 0.5rem;
|
|
font-size: 1rem;
|
|
}
|
|
.sidebar-heading {
|
|
font-size: 0.7rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
color: #6c757d;
|
|
padding: 1rem 1.25rem 0.4rem;
|
|
font-weight: 600;
|
|
}
|
|
.sidebar .brand {
|
|
padding: 1.2rem 1.25rem;
|
|
font-size: 1.1rem;
|
|
font-weight: 700;
|
|
color: #fff;
|
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.sidebar .brand .bi {
|
|
font-size: 1.3rem;
|
|
color: #0d6efd;
|
|
}
|
|
.main-content {
|
|
margin-left: var(--sidebar-width);
|
|
padding: 2rem;
|
|
}
|
|
.status-dot {
|
|
display: inline-block;
|
|
width: 10px;
|
|
height: 10px;
|
|
border-radius: 50%;
|
|
}
|
|
.status-dot.active {
|
|
background-color: #198754;
|
|
}
|
|
.status-dot.inactive {
|
|
background-color: #dc3545;
|
|
}
|
|
.status-dot.unknown {
|
|
background-color: #ffc107;
|
|
}
|
|
.card {
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
.card-header {
|
|
font-weight: 600;
|
|
}
|
|
.table th {
|
|
font-weight: 600;
|
|
}
|
|
.btn-row-action {
|
|
padding: 0.2rem 0.5rem;
|
|
font-size: 0.8rem;
|
|
}
|
|
.drag-handle {
|
|
cursor: grab;
|
|
color: #6c757d;
|
|
}
|
|
.drag-handle:active {
|
|
cursor: grabbing;
|
|
}
|
|
.nav-section-divider {
|
|
border-top: 1px solid rgba(255,255,255,0.06);
|
|
margin-top: 0.5rem;
|
|
}
|
|
</style>
|
|
{% block extra_head %}{% endblock %}
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Sidebar -->
|
|
<nav class="sidebar d-flex flex-column">
|
|
<div class="brand">
|
|
<img src="{{ url_for('static', filename='ge-aerospace-logo.svg') }}" alt="GE Aerospace" style="height: 28px; filter: brightness(0) invert(1);">
|
|
PXE Manager
|
|
</div>
|
|
<ul class="nav flex-column mt-2">
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'dashboard' %}active{% endif %}"
|
|
href="{{ url_for('dashboard') }}">
|
|
<i class="bi bi-speedometer2"></i> Dashboard
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'images_import' %}active{% endif %}"
|
|
href="{{ url_for('images_import') }}">
|
|
<i class="bi bi-download"></i> Image Import
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="nav-section-divider"></div>
|
|
<div class="sidebar-heading">Tools</div>
|
|
<ul class="nav flex-column">
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'startnet_editor' %}active{% endif %}"
|
|
href="{{ url_for('startnet_editor') }}">
|
|
<i class="bi bi-terminal"></i> startnet.cmd
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'clonezilla_backups' %}active{% endif %}"
|
|
href="{{ url_for('clonezilla_backups') }}">
|
|
<i class="bi bi-archive"></i> Clonezilla Backups
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="nav-section-divider"></div>
|
|
<div class="sidebar-heading">GE Aerospace Images</div>
|
|
<ul class="nav flex-column">
|
|
{% for it in ['gea-standard', 'gea-engineer', 'gea-shopfloor'] %}
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'unattend_editor' and image_type is defined and image_type == it %}active{% endif %}"
|
|
href="{{ url_for('unattend_editor', image_type=it) }}">
|
|
<i class="bi bi-file-earmark-code"></i> {{ all_friendly_names[it] }}
|
|
</a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
|
|
<div class="nav-section-divider"></div>
|
|
<div class="sidebar-heading">GE Legacy Images</div>
|
|
<ul class="nav flex-column">
|
|
{% for it in ['ge-standard', 'ge-engineer', 'ge-shopfloor-lockdown', 'ge-shopfloor-mce'] %}
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'unattend_editor' and image_type is defined and image_type == it %}active{% endif %}"
|
|
href="{{ url_for('unattend_editor', image_type=it) }}">
|
|
<i class="bi bi-file-earmark-code"></i> {{ all_friendly_names[it] }}
|
|
</a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- Main content -->
|
|
<div class="main-content">
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
{% for category, message in messages %}
|
|
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
{% block content %}{% endblock %}
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
|
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
|
crossorigin="anonymous"></script>
|
|
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
|
{% block extra_scripts %}{% endblock %}
|
|
</body>
|
|
</html>
|