GE-Enforce editor: phase-aware form, scope summary, narrower entries table
- Phase-aware editing: a preinstall scope now only offers MSI/EXE types and
Registry/File detection (the preinstall runner silently skips the rest), and
the preinstall flags show only for a preinstall scope - so an author cannot
pick an option that would do nothing.
- Per-scope summary line ('Installs PC-DMIS 2016, ...; 4 entries; runs after
common') under the scope header.
- Entries table: dropped the redundant Detection + Filters columns (the
plain-English entry line already conveys them), fixed-layout with sized button
columns and stacked Up/Down - no more horizontal scroll.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
<button class="btn btn-sm btn-danger" @click="deleteScope">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="scopeSummary" class="scope-summary muted">{{ scopeSummary }}</p>
|
||||
<div class="settings-grid">
|
||||
<div class="setting-row">
|
||||
<label>
|
||||
@@ -152,13 +153,13 @@
|
||||
Order is execution order. Put config-restore entries after their installer.
|
||||
</p>
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<table class="entries-table">
|
||||
<thead>
|
||||
<tr><th>Order</th><th>Name</th><th>Type</th><th>Detection</th><th>Filters</th><th></th></tr>
|
||||
<tr><th class="col-order">Order</th><th class="col-type">Type</th><th>Entry</th><th class="col-actions"></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(entry, index) in detail.entries" :key="entry.entryid">
|
||||
<td class="actions">
|
||||
<td class="order-cell">
|
||||
<button
|
||||
class="btn btn-sm btn-secondary"
|
||||
:disabled="index === 0"
|
||||
@@ -170,19 +171,17 @@
|
||||
@click="moveEntry(index, 1)"
|
||||
>Down</button>
|
||||
</td>
|
||||
<td><span class="badge badge-info">{{ entry.Type }}</span></td>
|
||||
<td>
|
||||
{{ entry.Name }}
|
||||
<div class="entry-name">{{ entry.Name }}</div>
|
||||
<div class="entry-desc muted">{{ describeEntry(entry) }}</div>
|
||||
</td>
|
||||
<td><span class="badge badge-info">{{ entry.Type }}</span></td>
|
||||
<td class="muted">{{ entry.DetectionMethod || 'always' }}</td>
|
||||
<td class="muted">{{ filterSummary(entry) }}</td>
|
||||
<td class="actions">
|
||||
<td class="row-actions">
|
||||
<button class="btn btn-sm btn-secondary" @click="openEditEntry(entry)">Edit</button>
|
||||
<button class="btn btn-sm btn-danger" @click="deleteEntry(entry)">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="!detail.entries.length"><td colspan="6" class="empty">No entries.</td></tr>
|
||||
<tr v-if="!detail.entries.length"><td colspan="4" class="empty">No entries.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -273,8 +272,9 @@
|
||||
<label>
|
||||
<span>Type</span>
|
||||
<select v-model="entryForm.Type">
|
||||
<option v-for="entryType in ENTRY_TYPES" :key="entryType" :value="entryType">{{ entryType }}</option>
|
||||
<option v-for="entryType in availableEntryTypes" :key="entryType" :value="entryType">{{ entryType }}</option>
|
||||
</select>
|
||||
<small v-if="isPreinstallScope" class="input-hint">Preinstall runs at imaging and supports MSI/EXE only.</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -330,8 +330,9 @@
|
||||
<span>Detection method</span>
|
||||
<select v-model="entryForm.DetectionMethod">
|
||||
<option value="">(none: always installs)</option>
|
||||
<option v-for="method in DETECTION_METHODS" :key="method" :value="method">{{ method }}</option>
|
||||
<option v-for="method in availableDetectionMethods" :key="method" :value="method">{{ method }}</option>
|
||||
</select>
|
||||
<small v-if="isPreinstallScope" class="input-hint">Preinstall supports Registry/File detection only.</small>
|
||||
</label>
|
||||
</div>
|
||||
<div v-if="entryForm.DetectionMethod" class="settings-grid">
|
||||
@@ -430,8 +431,8 @@
|
||||
<button type="button" class="btn btn-sm btn-danger" @click="removeProcess(processIndex)">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preinstall-flags">
|
||||
<span class="flags-label">Preinstall flags (preinstall phase only):</span>
|
||||
<div v-if="isPreinstallScope" class="preinstall-flags">
|
||||
<span class="flags-label">Preinstall flags (only take effect at imaging):</span>
|
||||
<label class="flag-label"><input type="checkbox" v-model="entryForm.PreEnrollment" /> PreEnrollment</label>
|
||||
<label class="flag-label"><input type="checkbox" v-model="entryForm.KillAfterDetection" /> KillAfterDetection</label>
|
||||
<label class="flag-label"><input type="checkbox" v-model="entryForm.PCTypesStrict" /> PCTypesStrict</label>
|
||||
@@ -494,6 +495,38 @@ const error = ref('')
|
||||
const notice = ref('')
|
||||
const shareRoot = ref('')
|
||||
|
||||
// Phase-aware editing: the PREINSTALL runner implements only MSI/EXE types and
|
||||
// Registry/File detection (other types/detections are silently skipped there),
|
||||
// and only preinstall honors the preinstall flags. Restrict the form for a
|
||||
// preinstall scope so an author cannot pick an option that would do nothing.
|
||||
const isPreinstallScope = computed(() => detail.value?.phase === 'preinstall')
|
||||
const availableEntryTypes = computed(() => {
|
||||
if (!isPreinstallScope.value) return ENTRY_TYPES
|
||||
const allowed = ['MSI', 'EXE']
|
||||
// keep the current value visible even if it is out of the allowed set
|
||||
const current = entryForm.value?.Type
|
||||
return current && !allowed.includes(current) ? [...allowed, current] : allowed
|
||||
})
|
||||
const availableDetectionMethods = computed(() => {
|
||||
if (!isPreinstallScope.value) return DETECTION_METHODS
|
||||
const allowed = ['Registry', 'File']
|
||||
const current = entryForm.value?.DetectionMethod
|
||||
return current && !allowed.includes(current) ? [...allowed, current] : allowed
|
||||
})
|
||||
|
||||
// One-line summary of what a scope installs (installer entries only).
|
||||
const scopeSummary = computed(() => {
|
||||
const scope = detail.value
|
||||
if (!scope || !scope.entries || !scope.entries.length) return ''
|
||||
const installers = scope.entries
|
||||
.filter(e => ['MSI', 'EXE', 'CMD', 'BAT'].includes(e.Type))
|
||||
.map(e => e.Name)
|
||||
const shown = installers.slice(0, 6).join(', ')
|
||||
const more = installers.length > 6 ? `, +${installers.length - 6} more` : ''
|
||||
const apps = installers.length ? `Installs ${shown}${more}. ` : ''
|
||||
return `${apps}${scope.entries.length} entries; runs after common.`
|
||||
})
|
||||
|
||||
// Show only the targeting gates a scope actually uses (a per-type manifest
|
||||
// already runs on its own type, so PCTypes is noise there; CMM shows a version
|
||||
// gate; collections shows machine numbers; the common/preinstall manifests use
|
||||
@@ -892,7 +925,18 @@ loadConfig()
|
||||
/* Modals: wider entry/preview, still responsive (global max-width + width:100%). */
|
||||
.modal-entry { max-width: min(1100px, 96vw); }
|
||||
.toggle-all { font-weight: 400; font-size: 0.8rem; }
|
||||
.entry-desc { font-size: 0.78rem; margin-top: 0.15rem; }
|
||||
.entry-name { font-weight: 500; }
|
||||
.entry-desc { font-size: 0.78rem; margin-top: 0.15rem; overflow-wrap: anywhere; }
|
||||
.scope-summary { margin: 0 0 0.75rem 0; font-size: 0.85rem; }
|
||||
/* Fixed layout so the Entry column flexes and the button columns never force
|
||||
a horizontal scroll. */
|
||||
.scope-detail .entries-table { width: 100%; table-layout: fixed; }
|
||||
.entries-table th.col-order, .entries-table td.order-cell { width: 58px; }
|
||||
.entries-table th.col-type { width: 64px; }
|
||||
.entries-table th.col-actions, .entries-table td.row-actions { width: 128px; }
|
||||
.order-cell { display: flex; flex-direction: column; gap: 0.2rem; }
|
||||
.order-cell .btn { padding: 0.1rem 0.3rem; }
|
||||
.row-actions { display: flex; gap: 0.3rem; flex-wrap: wrap; }
|
||||
.help-panel { margin: 0 0 1rem 0; border: 1px solid var(--border);
|
||||
border-radius: 6px; padding: 0.5rem 0.75rem; background: var(--bg-card); }
|
||||
.help-panel summary { cursor: pointer; font-weight: 600; font-size: 0.9rem; }
|
||||
|
||||
Reference in New Issue
Block a user