Frontend naming + CSS-variable cleanups (review low)
Naming convention (LOCKED): rename the ManifestEditor simulate state sim -> simulateInputs / simResult -> simulateResult (+ .sim-result CSS class) - 'sim' was banned standalone shorthand. Rename AssetRelationships props assetId -> assetid and machineNumber -> machinenumber so a prop holding a DB field value mirrors it verbatim; updated the five detail-page call sites (:assetid=). CSS variables: SearchResults per-domain badge palette moved into CSS variables on the container; the duplicated prefers-color-scheme dark block collapses to a single set of variable overrides instead of restating all ten selectors. frontend build green; vitest 49 pass; naming green; search badges + detail relationships verified rendering with no console errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -196,12 +196,12 @@ import { apiError } from '../utils/apiError'
|
|||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
assetId: {
|
assetid: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
// Alternative: lookup by machine/asset number
|
// Alternative: lookup by machine/asset number
|
||||||
machineNumber: {
|
machinenumber: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
}
|
}
|
||||||
@@ -315,14 +315,14 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.assetId, async () => {
|
watch(() => props.assetid, async () => {
|
||||||
await resolveAssetId()
|
await resolveAssetId()
|
||||||
if (resolvedAssetId.value) {
|
if (resolvedAssetId.value) {
|
||||||
await loadRelationships()
|
await loadRelationships()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.machineNumber, async () => {
|
watch(() => props.machinenumber, async () => {
|
||||||
await resolveAssetId()
|
await resolveAssetId()
|
||||||
if (resolvedAssetId.value) {
|
if (resolvedAssetId.value) {
|
||||||
await loadRelationships()
|
await loadRelationships()
|
||||||
@@ -330,17 +330,17 @@ watch(() => props.machineNumber, async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function resolveAssetId() {
|
async function resolveAssetId() {
|
||||||
// If assetId is provided directly, use it
|
// If assetid is provided directly, use it
|
||||||
if (props.assetId) {
|
if (props.assetid) {
|
||||||
resolvedAssetId.value = props.assetId
|
resolvedAssetId.value = props.assetid
|
||||||
lookupFailed.value = false
|
lookupFailed.value = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, try to look up by machine number
|
// Otherwise, try to look up by machine number
|
||||||
if (props.machineNumber) {
|
if (props.machinenumber) {
|
||||||
try {
|
try {
|
||||||
const response = await assetsApi.lookup(props.machineNumber)
|
const response = await assetsApi.lookup(props.machinenumber)
|
||||||
resolvedAssetId.value = response.data.data?.assetid
|
resolvedAssetId.value = response.data.data?.assetid
|
||||||
lookupFailed.value = !resolvedAssetId.value
|
lookupFailed.value = !resolvedAssetId.value
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="search-results">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Search Results</h2>
|
<h2>Search Results</h2>
|
||||||
<span v-if="results.length" class="results-count">
|
<span v-if="results.length" class="results-count">
|
||||||
@@ -385,56 +385,33 @@ watch(results, () => {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-type.machine {
|
/* Per-domain badge palette. Values live in CSS variables on the container so
|
||||||
background: #e3f2fd;
|
the dark theme overrides them in one place (below) instead of restating
|
||||||
color: #1565c0;
|
every selector. Each badge rule just references its pair. */
|
||||||
|
.search-results {
|
||||||
|
--rt-machine-bg: #e3f2fd; --rt-machine-fg: #1565c0;
|
||||||
|
--rt-computer-bg: #e8f5e9; --rt-computer-fg: #2e7d32;
|
||||||
|
--rt-application-bg: #fff3e0; --rt-application-fg: #e65100;
|
||||||
|
--rt-knowledgebase-bg: #f3e5f5; --rt-knowledgebase-fg: #7b1fa2;
|
||||||
|
--rt-printer-bg: #fce4ec; --rt-printer-fg: #c2185b;
|
||||||
|
--rt-network-bg: #fff8e1; --rt-network-fg: #f57f17;
|
||||||
|
--rt-measuring-bg: #e0f7fa; --rt-measuring-fg: #00838f;
|
||||||
|
--rt-employee-bg: #e0f2f1; --rt-employee-fg: #00695c;
|
||||||
|
--rt-notification-bg: #e8eaf6; --rt-notification-fg: #283593;
|
||||||
|
--rt-subnet-bg: #fbe9e7; --rt-subnet-fg: #bf360c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result-type.machine { background: var(--rt-machine-bg); color: var(--rt-machine-fg); }
|
||||||
.result-type.pc,
|
.result-type.pc,
|
||||||
.result-type.computer {
|
.result-type.computer { background: var(--rt-computer-bg); color: var(--rt-computer-fg); }
|
||||||
background: #e8f5e9;
|
.result-type.application { background: var(--rt-application-bg); color: var(--rt-application-fg); }
|
||||||
color: #2e7d32;
|
.result-type.knowledgebase { background: var(--rt-knowledgebase-bg); color: var(--rt-knowledgebase-fg); }
|
||||||
}
|
.result-type.printer { background: var(--rt-printer-bg); color: var(--rt-printer-fg); }
|
||||||
|
.result-type.network_device { background: var(--rt-network-bg); color: var(--rt-network-fg); }
|
||||||
.result-type.application {
|
.result-type.measuring_tool { background: var(--rt-measuring-bg); color: var(--rt-measuring-fg); }
|
||||||
background: #fff3e0;
|
.result-type.employee { background: var(--rt-employee-bg); color: var(--rt-employee-fg); }
|
||||||
color: #e65100;
|
.result-type.notification { background: var(--rt-notification-bg); color: var(--rt-notification-fg); }
|
||||||
}
|
.result-type.subnet { background: var(--rt-subnet-bg); color: var(--rt-subnet-fg); }
|
||||||
|
|
||||||
.result-type.knowledgebase {
|
|
||||||
background: #f3e5f5;
|
|
||||||
color: #7b1fa2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.printer {
|
|
||||||
background: #fce4ec;
|
|
||||||
color: #c2185b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.network_device {
|
|
||||||
background: #fff8e1;
|
|
||||||
color: #f57f17;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.measuring_tool {
|
|
||||||
background: #e0f7fa;
|
|
||||||
color: #00838f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.employee {
|
|
||||||
background: #e0f2f1;
|
|
||||||
color: #00695c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.notification {
|
|
||||||
background: #e8eaf6;
|
|
||||||
color: #283593;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.subnet {
|
|
||||||
background: #fbe9e7;
|
|
||||||
color: #bf360c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-content {
|
.result-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -486,55 +463,17 @@ watch(results, () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.result-type.machine {
|
.search-results {
|
||||||
background: rgba(21, 101, 192, 0.2);
|
--rt-machine-bg: rgba(21, 101, 192, 0.2); --rt-machine-fg: #64b5f6;
|
||||||
color: #64b5f6;
|
--rt-computer-bg: rgba(46, 125, 50, 0.2); --rt-computer-fg: #81c784;
|
||||||
}
|
--rt-application-bg: rgba(230, 81, 0, 0.2); --rt-application-fg: #ffb74d;
|
||||||
|
--rt-knowledgebase-bg: rgba(123, 31, 162, 0.2); --rt-knowledgebase-fg: #ce93d8;
|
||||||
.result-type.pc,
|
--rt-printer-bg: rgba(194, 24, 91, 0.2); --rt-printer-fg: #f48fb1;
|
||||||
.result-type.computer {
|
--rt-network-bg: rgba(245, 127, 23, 0.2); --rt-network-fg: #ffd54f;
|
||||||
background: rgba(46, 125, 50, 0.2);
|
--rt-measuring-bg: rgba(0, 131, 143, 0.2); --rt-measuring-fg: #80deea;
|
||||||
color: #81c784;
|
--rt-employee-bg: rgba(0, 105, 92, 0.2); --rt-employee-fg: #80cbc4;
|
||||||
}
|
--rt-notification-bg: rgba(40, 53, 147, 0.2); --rt-notification-fg: #9fa8da;
|
||||||
|
--rt-subnet-bg: rgba(191, 54, 12, 0.2); --rt-subnet-fg: #ffab91;
|
||||||
.result-type.application {
|
|
||||||
background: rgba(230, 81, 0, 0.2);
|
|
||||||
color: #ffb74d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.knowledgebase {
|
|
||||||
background: rgba(123, 31, 162, 0.2);
|
|
||||||
color: #ce93d8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.printer {
|
|
||||||
background: rgba(194, 24, 91, 0.2);
|
|
||||||
color: #f48fb1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.network_device {
|
|
||||||
background: rgba(245, 127, 23, 0.2);
|
|
||||||
color: #ffd54f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.measuring_tool {
|
|
||||||
background: rgba(0, 131, 143, 0.2);
|
|
||||||
color: #80deea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.employee {
|
|
||||||
background: rgba(0, 105, 92, 0.2);
|
|
||||||
color: #80cbc4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.notification {
|
|
||||||
background: rgba(40, 53, 147, 0.2);
|
|
||||||
color: #9fa8da;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-type.subnet {
|
|
||||||
background: rgba(191, 54, 12, 0.2);
|
|
||||||
color: #ffab91;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -192,27 +192,27 @@
|
|||||||
<h3 class="section-title">Simulate: what would a PC get?</h3>
|
<h3 class="section-title">Simulate: what would a PC get?</h3>
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="setting-row">
|
<div class="setting-row">
|
||||||
<label><span>Subtype</span><input v-model="sim.subtype" placeholder="subtype" /></label>
|
<label><span>Subtype</span><input v-model="simulateInputs.subtype" placeholder="subtype" /></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-row">
|
<div class="setting-row">
|
||||||
<label><span>Hostname</span><input v-model="sim.hostname" placeholder="hostname" /></label>
|
<label><span>Hostname</span><input v-model="simulateInputs.hostname" placeholder="hostname" /></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-row">
|
<div class="setting-row">
|
||||||
<label><span>Machine #</span><input v-model="sim.machinenumber" placeholder="machine #" /></label>
|
<label><span>Machine #</span><input v-model="simulateInputs.machinenumber" placeholder="machine #" /></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-row">
|
<div class="setting-row">
|
||||||
<label><span>CMM version</span><input v-model="sim.cmmversion" placeholder="CMM version" /></label>
|
<label><span>CMM version</span><input v-model="simulateInputs.cmmversion" placeholder="CMM version" /></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary" @click="runSimulate">Run</button>
|
<button class="btn btn-primary" @click="runSimulate">Run</button>
|
||||||
<div v-if="simResult" class="sim-result">
|
<div v-if="simulateResult" class="simulate-result">
|
||||||
<div>
|
<div>
|
||||||
<strong>Applies ({{ simResult.applied.length }}):</strong>
|
<strong>Applies ({{ simulateResult.applied.length }}):</strong>
|
||||||
{{ simResult.applied.join(', ') || 'none' }}
|
{{ simulateResult.applied.join(', ') || 'none' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="muted">
|
<div class="muted">
|
||||||
<strong>Filtered:</strong>
|
<strong>Filtered:</strong>
|
||||||
<span v-for="filtered in simResult.filtered" :key="filtered.name">
|
<span v-for="filtered in simulateResult.filtered" :key="filtered.name">
|
||||||
{{ filtered.name }} ({{ filtered.filteredby.join(',') }});
|
{{ filtered.name }} ({{ filtered.filteredby.join(',') }});
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -618,8 +618,8 @@ const versions = ref([])
|
|||||||
const showPreview = ref(false)
|
const showPreview = ref(false)
|
||||||
const previewText = ref('')
|
const previewText = ref('')
|
||||||
|
|
||||||
const sim = ref({ subtype: '', hostname: '', machinenumber: '', cmmversion: '' })
|
const simulateInputs = ref({ subtype: '', hostname: '', machinenumber: '', cmmversion: '' })
|
||||||
const simResult = ref(null)
|
const simulateResult = ref(null)
|
||||||
|
|
||||||
const compliance = ref(null)
|
const compliance = ref(null)
|
||||||
const complianceRows = computed(() => compliance.value?.rows || [])
|
const complianceRows = computed(() => compliance.value?.rows || [])
|
||||||
@@ -655,7 +655,7 @@ async function exportShare() {
|
|||||||
async function selectScope(id) {
|
async function selectScope(id) {
|
||||||
selectedId.value = id
|
selectedId.value = id
|
||||||
showVersions.value = false
|
showVersions.value = false
|
||||||
simResult.value = null
|
simulateResult.value = null
|
||||||
compliance.value = null
|
compliance.value = null
|
||||||
try {
|
try {
|
||||||
detail.value = payload(await api.get(`/geenforce/scopes/${id}`))
|
detail.value = payload(await api.get(`/geenforce/scopes/${id}`))
|
||||||
@@ -821,8 +821,8 @@ async function rollback(versionnumber) {
|
|||||||
// -- simulate / preview --
|
// -- simulate / preview --
|
||||||
async function runSimulate() {
|
async function runSimulate() {
|
||||||
try {
|
try {
|
||||||
const params = { ...sim.value }
|
const params = { ...simulateInputs.value }
|
||||||
simResult.value = payload(await api.get(
|
simulateResult.value = payload(await api.get(
|
||||||
`/geenforce/scopes/${detail.value.scopeid}/simulate`, { params }))
|
`/geenforce/scopes/${detail.value.scopeid}/simulate`, { params }))
|
||||||
} catch (e) { error.value = 'Simulate failed' }
|
} catch (e) { error.value = 'Simulate failed' }
|
||||||
}
|
}
|
||||||
@@ -929,7 +929,7 @@ loadApplications()
|
|||||||
.muted { color: var(--text-light); }
|
.muted { color: var(--text-light); }
|
||||||
|
|
||||||
/* Simulator result */
|
/* Simulator result */
|
||||||
.sim-result {
|
.simulate-result {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -208,7 +208,7 @@
|
|||||||
<WarrantyPanel :assetid="machine.assetid" :items="warranties" />
|
<WarrantyPanel :assetid="machine.assetid" :items="warranties" />
|
||||||
|
|
||||||
<!-- All relationships (dualpath, controls, ...) -->
|
<!-- All relationships (dualpath, controls, ...) -->
|
||||||
<AssetRelationships v-if="machine.assetid" :assetId="machine.assetid" />
|
<AssetRelationships v-if="machine.assetid" :assetid="machine.assetid" />
|
||||||
|
|
||||||
<!-- Notes -->
|
<!-- Notes -->
|
||||||
<div class="section-card" v-if="machine.notes">
|
<div class="section-card" v-if="machine.notes">
|
||||||
|
|||||||
@@ -140,7 +140,7 @@
|
|||||||
<WarrantyPanel :assetid="tool.assetid" :items="warranties" />
|
<WarrantyPanel :assetid="tool.assetid" :items="warranties" />
|
||||||
|
|
||||||
<!-- All relationships (partof, connectedto, ...) -->
|
<!-- All relationships (partof, connectedto, ...) -->
|
||||||
<AssetRelationships v-if="tool.assetid" :assetId="tool.assetid" />
|
<AssetRelationships v-if="tool.assetid" :assetid="tool.assetid" />
|
||||||
|
|
||||||
<!-- Notes -->
|
<!-- Notes -->
|
||||||
<div class="section-card" v-if="tool.notes">
|
<div class="section-card" v-if="tool.notes">
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
<!-- Relationships -->
|
<!-- Relationships -->
|
||||||
<AssetRelationships
|
<AssetRelationships
|
||||||
v-if="device.assetid"
|
v-if="device.assetid"
|
||||||
:assetId="device.assetid"
|
:assetid="device.assetid"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Notes -->
|
<!-- Notes -->
|
||||||
|
|||||||
@@ -213,7 +213,7 @@
|
|||||||
<WarrantyPanel :assetid="computer.assetid" :items="warranties" />
|
<WarrantyPanel :assetid="computer.assetid" :items="warranties" />
|
||||||
|
|
||||||
<!-- All relationships (controls, defaultprinter, ...) -->
|
<!-- All relationships (controls, defaultprinter, ...) -->
|
||||||
<AssetRelationships v-if="computer.assetid" :assetId="computer.assetid" />
|
<AssetRelationships v-if="computer.assetid" :assetid="computer.assetid" />
|
||||||
|
|
||||||
<!-- Notes -->
|
<!-- Notes -->
|
||||||
<div class="section-card" v-if="computer.notes">
|
<div class="section-card" v-if="computer.notes">
|
||||||
|
|||||||
@@ -179,7 +179,7 @@
|
|||||||
<WarrantyPanel :assetid="printer.assetid" :items="warranties" />
|
<WarrantyPanel :assetid="printer.assetid" :items="warranties" />
|
||||||
|
|
||||||
<!-- All relationships (defaultprinter, connectedto, ...) -->
|
<!-- All relationships (defaultprinter, connectedto, ...) -->
|
||||||
<AssetRelationships v-if="printer.assetid" :assetId="printer.assetid" />
|
<AssetRelationships v-if="printer.assetid" :assetid="printer.assetid" />
|
||||||
|
|
||||||
<!-- Notes -->
|
<!-- Notes -->
|
||||||
<div class="section-card" v-if="printer.notes">
|
<div class="section-card" v-if="printer.notes">
|
||||||
|
|||||||
Reference in New Issue
Block a user