Rename the equipment domain to machines; retype the models catalog (ADR-011)
The equipment plugin is now the machines plugin, ending the UI-vs-code vocabulary split while the contract is pre-1.0 and nothing external depends on the old names. - plugins/equipment -> plugins/machines: manifest, class, /api/machines, machines.* permissions, registry key (with an auto-migrating load shim for existing installs). - Tables: equipment -> machines (equipmentid -> machineid) and equipmenttypes -> machinetypes, renamed in the plugin's own migration chain (machines0002rename), idempotent for both upgrading and fresh installs. - The legacy core machinetypes lookup actually types the vendor MODELS catalog, so it is renamed losslessly to modeltypes (models.modeltypeid, /api/modeltypes, Model Types settings page) rather than collapsed, freeing the machinetypes name. Core migration 7d17_machines_rename also flips data in place: assettypes row equipment -> machine, auditlog entitytype, identifier_/search_ settings keys, permission rows, and renames alembic_version_equipment. - Frontend: machinesApi/modeltypesApi, item.machine response shape, assettype value compares 'equipment' -> 'machine' (map, search, custom fields, relationships), routes machines.js with plugin gating retagged, /print/machine-badge, Machine Types (subtypes) and Model Types (catalog) settings pages, machines-by-type report id. - Docs swept; ADRs left as history per the authoring rule. Upgrade: flask db upgrade then flask plugin upgrade-all. Verified: dev DB flipped live (262 machines, 35 modeltypes, 95 models retyped, zero equipment tables remain); fresh scratch-MySQL install produces the new names; 341 tests green; naming/style green; frontend builds; live E2E on machines list/detail, PC relationships, map, reports, and both settings pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,14 +27,14 @@
|
||||
:key="rel.relationshipid"
|
||||
class="relationship-item"
|
||||
>
|
||||
<div class="rel-icon"><component :is="getAssetIcon(rel.targetasset?.assettype)" :size="16" /></div>
|
||||
<div class="rel-icon"><component :is="getAssetIcon(rel.targetasset?.assettypename || rel.targetasset?.assettype)" :size="16" /></div>
|
||||
<div class="rel-content">
|
||||
<router-link :to="getAssetRoute(rel.targetasset)" class="rel-name">
|
||||
{{ rel.targetasset?.name || rel.targetasset?.assetnumber || 'Unknown' }}
|
||||
</router-link>
|
||||
<div class="rel-meta">
|
||||
<span class="badge" :style="colorStyle(colorForType(rel.relationshiptypename))">{{ rel.relationshiptypename }}</span>
|
||||
<span class="rel-type-badge">{{ rel.targetasset?.assettype }}</span>
|
||||
<span class="rel-type-badge">{{ rel.targetasset?.assettypename || rel.targetasset?.assettype }}</span>
|
||||
</div>
|
||||
<div v-if="rel.notes" class="rel-notes">{{ rel.notes }}</div>
|
||||
</div>
|
||||
@@ -59,14 +59,14 @@
|
||||
:key="rel.relationshipid"
|
||||
class="relationship-item"
|
||||
>
|
||||
<div class="rel-icon"><component :is="getAssetIcon(rel.sourceasset?.assettype)" :size="16" /></div>
|
||||
<div class="rel-icon"><component :is="getAssetIcon(rel.sourceasset?.assettypename || rel.sourceasset?.assettype)" :size="16" /></div>
|
||||
<div class="rel-content">
|
||||
<router-link :to="getAssetRoute(rel.sourceasset)" class="rel-name">
|
||||
{{ rel.sourceasset?.name || rel.sourceasset?.assetnumber || 'Unknown' }}
|
||||
</router-link>
|
||||
<div class="rel-meta">
|
||||
<span class="badge" :style="colorStyle(colorForType(rel.relationshiptypename))">{{ rel.relationshiptypename }}</span>
|
||||
<span class="rel-type-badge">{{ rel.sourceasset?.assettype }}</span>
|
||||
<span class="rel-type-badge">{{ rel.sourceasset?.assettypename || rel.sourceasset?.assettype }}</span>
|
||||
</div>
|
||||
<div v-if="rel.notes" class="rel-notes">{{ rel.notes }}</div>
|
||||
</div>
|
||||
@@ -173,7 +173,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { Cog, Monitor, Printer, Globe, Package } from 'lucide-vue-next'
|
||||
import { Cog, Monitor, Printer, Globe, Package, Ruler } from 'lucide-vue-next'
|
||||
import { assetsApi, relationshipTypesApi } from '../api'
|
||||
import { colorStyle } from '@/utils/colorStyle'
|
||||
import { useAuthStore } from '../stores/auth'
|
||||
@@ -384,10 +384,11 @@ function closeModal() {
|
||||
|
||||
function getAssetIcon(assettype) {
|
||||
const icons = {
|
||||
'equipment': Cog,
|
||||
'machine': Cog,
|
||||
'computer': Monitor,
|
||||
'printer': Printer,
|
||||
'network_device': Globe
|
||||
'network_device': Globe,
|
||||
'measuring_tool': Ruler
|
||||
}
|
||||
return icons[assettype] || Package
|
||||
}
|
||||
@@ -396,21 +397,22 @@ function getAssetRoute(asset) {
|
||||
if (!asset) return '#'
|
||||
|
||||
const routeMap = {
|
||||
'equipment': '/machines',
|
||||
'machine': '/machines',
|
||||
'computer': '/pcs',
|
||||
'printer': '/printers',
|
||||
'network_device': '/network'
|
||||
'network_device': '/network',
|
||||
'measuring_tool': '/measuringtools'
|
||||
}
|
||||
|
||||
const basePath = routeMap[asset.assettype] || '/assets'
|
||||
// serializer sends assettypename; old shape used assettype
|
||||
const typename = asset.assettypename || asset.assettype
|
||||
const basePath = routeMap[typename] || '/assets'
|
||||
|
||||
// Use typedata ID if available
|
||||
if (asset.assettype === 'network_device' && asset.typedata?.networkdeviceid) {
|
||||
return `/network/${asset.typedata.networkdeviceid}`
|
||||
}
|
||||
|
||||
// For equipment/computer/printer, use machineid from typedata or assetid
|
||||
const id = asset.typedata?.machineid || asset.assetid
|
||||
// pluginid is the extension-table id the detail routes key on
|
||||
const id = asset.pluginid
|
||||
|| asset.typedata?.networkdeviceid
|
||||
|| asset.typedata?.machineid
|
||||
|| asset.assetid
|
||||
return `${basePath}/${id}`
|
||||
}
|
||||
</script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user