Webapp redesign phase 3: Drivers tab
- One line per entry: position, model tokens, pack, OS, size and status chips; family, friendly name, osId, folder, zip state, Dell hint and the verbatim lint findings are in the row body. - Status chips compare the staged map with the saved one: New, Edited, Moved from #n, Removing, the worst current finding, and 'Clears on save' / 'Clears n' when the staged changes resolve this entry's findings. The toolbar and a sticky save bar show lint now and after. - Removing an entry is staged with Undo remove instead of deleting the row; Undo edit puts an edited entry back. - Reordering moved into the row menu (Move up / down / to position). The Move dialog shows the order after the move and re-lints the staged map with the move applied, listing any new errors before staging it. - An edit that changes the tokens but keeps the old friendly name is flagged in the row and in the review step. - Filters: Win11/Win10 with counts, 'Findings or unsaved', 'Zip problems' (missing, trap and case); a status key explains the chips. - _image_header.html: new header and underline tabs for every image tab; the shared review modal and diff use the design tokens.
This commit is contained in:
@@ -53,51 +53,41 @@
|
|||||||
{% set _tab = active_tab if active_tab is defined and active_tab else image_tab_for_endpoint(request.endpoint) %}
|
{% set _tab = active_tab if active_tab is defined and active_tab else image_tab_for_endpoint(request.endpoint) %}
|
||||||
{% set _hdr = image_header_info(image_type) %}
|
{% set _hdr = image_header_info(image_type) %}
|
||||||
<style>
|
<style>
|
||||||
.image-head { margin-bottom: 1.25rem; }
|
.image-head { margin-bottom: 20px; }
|
||||||
.image-head-top {
|
.image-head-top { display: flex; flex-wrap: wrap; gap: 12px 16px; justify-content: space-between; align-items: flex-end; margin-bottom: 14px; }
|
||||||
display: flex; flex-wrap: wrap; gap: 0.75rem 1rem;
|
|
||||||
justify-content: space-between; align-items: flex-end;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
}
|
|
||||||
.image-head-title { flex: 1 1 20rem; min-width: 0; }
|
.image-head-title { flex: 1 1 20rem; min-width: 0; }
|
||||||
.image-head h1 { font-size: 20px; font-weight: 500; line-height: 1.3; margin: 0.15rem 0 0.2rem; }
|
.image-head h1 { font-size: 28px; font-weight: 600; line-height: 1.25; margin: 2px 0 4px; letter-spacing: 0; }
|
||||||
.image-head-meta { font-size: 13px; color: var(--text-light); display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; align-items: center; }
|
.image-head .eyebrow-t { font-size: 13px; color: var(--muted); }
|
||||||
|
.image-head-meta { font-size: 12px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: center; }
|
||||||
.image-head-meta .sep { opacity: 0.5; }
|
.image-head-meta .sep { opacity: 0.5; }
|
||||||
.image-head .header-actions { flex-wrap: wrap; align-items: center; }
|
.image-head .header-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||||
.image-tabs.nav-tabs { flex-wrap: wrap; }
|
.image-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line-2); overflow-x: auto; scrollbar-width: none; margin: 0; padding: 0; list-style: none; }
|
||||||
.image-tabs .nav-link { font-size: 12px; padding: 0.65rem 1rem; display: flex; align-items: center; gap: 0.4rem; }
|
.image-tabs a { flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 42px; padding: 0 14px; font-size: 14px;
|
||||||
.image-tabs .nav-link .bi { font-size: 14px; }
|
color: var(--text-2); text-decoration: none; white-space: nowrap; border-bottom: 3px solid transparent; margin-bottom: -1px; }
|
||||||
.image-tabs .tab-count {
|
.image-tabs a:hover { color: var(--text); }
|
||||||
font-size: 10px; font-weight: 600; letter-spacing: 0; line-height: 1;
|
.image-tabs a[aria-current] { color: var(--text); font-weight: 600; border-bottom-color: var(--text); }
|
||||||
padding: 2px 7px; border-radius: 999px;
|
.image-tabs .tab-count { font-family: var(--font-mono); font-size: 12px; color: var(--muted); font-weight: 400; }
|
||||||
background: var(--bg); border: 1px solid var(--border); color: var(--text-light);
|
|
||||||
}
|
|
||||||
.image-tabs .nav-link.active .tab-count { color: var(--primary); border-color: var(--primary); }
|
|
||||||
|
|
||||||
/* Unified diff (review step of every save) */
|
/* Unified diff (review step of every save) */
|
||||||
.diff-file { border: 1px solid var(--border); border-radius: 0.25rem; margin-bottom: 1rem; overflow: hidden; }
|
.diff-file { border: 1px solid var(--line-2); border-radius: 10px; margin-bottom: 1rem; overflow: hidden; }
|
||||||
.diff-file-head { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); font-weight: 600; font-size: 13px; }
|
.diff-file-head { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; padding: 8px 12px; border-bottom: 1px solid var(--line-2);
|
||||||
.diff-view {
|
background: var(--surface-2); font-weight: 600; font-size: 13px; }
|
||||||
margin: 0; max-height: 55vh; overflow: auto; font-size: 12px; line-height: 1.45;
|
.diff-view { margin: 0; max-height: 55vh; overflow: auto; font-size: 12px; line-height: 1.45; font-family: var(--font-mono); background: var(--surface); }
|
||||||
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; background: var(--bg-card-solid);
|
.diff-view span { display: block; padding: 0 12px; white-space: pre-wrap; word-break: break-all; }
|
||||||
}
|
.diff-view .d-add { background: var(--add-bg); color: var(--add-text); }
|
||||||
.diff-view span { display: block; padding: 0 0.75rem; white-space: pre-wrap; word-break: break-all; }
|
.diff-view .d-del { background: var(--del-bg); color: var(--del-text); }
|
||||||
.diff-view .d-add { background: rgba(10, 214, 79, 0.16); }
|
.diff-view .d-hunk { color: var(--accent); background: var(--surface-2); }
|
||||||
.diff-view .d-del { background: rgba(220, 53, 69, 0.14); }
|
.diff-view .d-meta { color: var(--muted); }
|
||||||
.diff-view .d-hunk { color: var(--primary); background: rgba(65, 129, 255, 0.08); }
|
|
||||||
.diff-view .d-meta { color: var(--text-light); }
|
|
||||||
[data-theme="dark"] .diff-view .d-add { background: rgba(10, 214, 79, 0.18); }
|
|
||||||
[data-theme="dark"] .diff-view .d-del { background: rgba(245, 54, 92, 0.2); }
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="image-head">
|
<div class="image-head">
|
||||||
<div class="image-head-top">
|
<div class="image-head-top">
|
||||||
<div class="image-head-title">
|
<div class="image-head-title">
|
||||||
<div class="eyebrow">GE Aerospace image</div>
|
<div class="eyebrow-t">Image</div>
|
||||||
<h1>{{ _hdr.friendly_name }}</h1>
|
<h1>{{ _hdr.friendly_name | replace('GE Aerospace ', '') }}</h1>
|
||||||
<div class="image-head-meta">
|
<div class="image-head-meta">
|
||||||
<span class="mono">{{ image_type }}</span>
|
<span class="mono">{{ image_type }}</span>
|
||||||
{% if _hdr.os_label %}<span class="sep">|</span><span><i class="bi bi-windows"></i> {{ _hdr.os_label }}</span>{% endif %}
|
{% if _hdr.os_label %}<span class="sep">|</span><span>{{ _hdr.os_label }}</span>{% endif %}
|
||||||
{% if header_subtitle is defined and header_subtitle %}<span class="sep">|</span><span class="mono">{{ header_subtitle }}</span>{% endif %}
|
{% if header_subtitle is defined and header_subtitle %}<span class="sep">|</span><span class="mono">{{ header_subtitle }}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -106,20 +96,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="nav nav-tabs image-tabs" role="tablist">
|
<nav aria-label="Image sections"><ul class="image-tabs">
|
||||||
{% for t in image_tabs %}
|
{% for t in image_tabs %}
|
||||||
<li class="nav-item">
|
<li><a href="{{ image_tab_url(image_type, t.id) }}"{% if t.id == _tab %} aria-current="page"{% endif %}>
|
||||||
<a class="nav-link {% if t.id == _tab %}active{% endif %}"
|
{{ t.label }}
|
||||||
{% if t.id == _tab %}aria-current="page"{% endif %}
|
|
||||||
href="{{ image_tab_url(image_type, t.id) }}">
|
|
||||||
<i class="bi {{ t.icon }}"></i> {{ t.label }}
|
|
||||||
{% if t.id == 'drivers' %}<span class="tab-count" title="Entries in HardwareDriver.json">{{ _hdr.driver_count }}</span>
|
{% if t.id == 'drivers' %}<span class="tab-count" title="Entries in HardwareDriver.json">{{ _hdr.driver_count }}</span>
|
||||||
{% elif t.id == 'os' and _hdr.package_count %}<span class="tab-count" title="Entries in packages.json">{{ _hdr.package_count }}</span>
|
{% elif t.id == 'os' and _hdr.package_count %}<span class="tab-count" title="Entries in packages.json">{{ _hdr.package_count }}</span>
|
||||||
{% elif t.id == 'unattend' and not _hdr.has_unattend %}<span class="tab-count" title="FlatUnattendW10.xml is missing">missing</span>{% endif %}
|
{% elif t.id == 'unattend' and not _hdr.has_unattend %}<span class="chip c-warn" style="font-size: 11px; padding: 1px 6px">missing</span>{% endif %}
|
||||||
</a>
|
</a></li>
|
||||||
</li>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul></nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Shared review step: filled by PxeImage.reviewAndSave (static/image-pages.js) #}
|
{# Shared review step: filled by PxeImage.reviewAndSave (static/image-pages.js) #}
|
||||||
@@ -139,10 +125,8 @@
|
|||||||
<div class="alert alert-danger d-none mb-0" id="imageReviewError"></div>
|
<div class="alert alert-danger d-none mb-0" id="imageReviewError"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
<button type="button" class="ui-btn" data-bs-dismiss="modal">Back to editing</button>
|
||||||
<button type="button" class="btn btn-success" id="imageReviewConfirm" disabled>
|
<button type="button" class="ui-btn pri" id="imageReviewConfirm" disabled>Save and back up</button>
|
||||||
<i class="bi bi-check-lg"></i> Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user