-
Preinstall flags (preinstall phase only):
+
+ Preinstall flags (only take effect at imaging):
@@ -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; }