- Shopfloor PC type menu (CMM, WaxAndTrace, Keyence, Genspect, Display, Standard) - Baseline scripts: OpenText CSF, Start Menu shortcuts, network/WinRM, power/display - Standard type: eDNC + MarkZebra with 64-bit path mirroring - CMM type: Hexagon CLM Tools, PC-DMIS 2016/2019 R2 - Display sub-type: Lobby vs Dashboard - Webapp: enrollment management, image config editor, UI refresh - Upload-Image.ps1: robocopy MCL cache to PXE server - Download-Drivers.ps1: Dell driver download pipeline - Slim Blancco GRUB EFI (10MB -> 660KB) for old hardware compat - Shopfloor display imaging guide docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
221 lines
6.9 KiB
HTML
221 lines
6.9 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">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
<title>{% block title %}PXE Server Manager{% endblock %}</title>
|
|
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
|
|
<link href="{{ url_for('static', filename='bootstrap.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-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;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 0.3rem;
|
|
}
|
|
.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') }}">
|
|
Dashboard
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'images_import' %}active{% endif %}"
|
|
href="{{ url_for('images_import') }}">
|
|
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') }}">
|
|
startnet.cmd
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'clonezilla_backups' %}active{% endif %}"
|
|
href="{{ url_for('clonezilla_backups') }}">
|
|
Clonezilla Backups
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'blancco_reports' %}active{% endif %}"
|
|
href="{{ url_for('blancco_reports') }}">
|
|
Blancco Reports
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'enrollment' %}active{% endif %}"
|
|
href="{{ url_for('enrollment') }}">
|
|
Enrollment
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'audit_log' %}active{% endif %}"
|
|
href="{{ url_for('audit_log') }}">
|
|
Audit Log
|
|
</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 all_image_types if it.startswith('gea-') %}
|
|
<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) }}">
|
|
{{ all_friendly_names[it] }}
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'image_config' and image_type is defined and image_type == it %}active{% endif %}"
|
|
href="{{ url_for('image_config', image_type=it) }}" style="padding-left: 2.5rem; font-size: 0.82rem;">
|
|
Configuration
|
|
</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 all_image_types if it.startswith('ge-') and not it.startswith('gea-') %}
|
|
<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) }}">
|
|
{{ all_friendly_names[it] }}
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'image_config' and image_type is defined and image_type == it %}active{% endif %}"
|
|
href="{{ url_for('image_config', image_type=it) }}" style="padding-left: 2.5rem; font-size: 0.82rem;">
|
|
Configuration
|
|
</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="{{ url_for('static', filename='bootstrap.bundle.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
|
{% block extra_scripts %}{% endblock %}
|
|
</body>
|
|
</html>
|