ADR-013 Phase 4: relocate the remaining 9 plugin frontends (all 13 done)
Relocate warranty, measuringtools, network, printers, usb, notifications, computers, and slides into plugins/<name>/frontend/. Each plugin's views are pulled from wherever they lived (own dir, plus the shared views/settings/, views/reports/, views/print/ dirs, and top-level views) into the plugin's frontend/views/, and its route file becomes the self-contained routes.js. Handled the messy cases: - computers: name mismatch (its views live in views/pcs/) - moved by following the route file's own imports, so the dir name did not matter. Its OS/access- protocol/PC-type settings views move with it (only computers.js routed them). - network: NetworkHub's sibling sub-views (NetworkDevicesList, SubnetsBrowse, not directly routed) moved too so its `./` imports resolve. - printers: the qrLogo helper is SHARED with core AssetLabel, so it stays in views/print/ and PrinterQR imports it via @/views/print/qrLogo. - slides: route file is toplevel-only (TVDashboard); SlideManager stays core (core.js routes /settings/slides). frontend/src/views/ now holds only core views; frontend/src/router/routes/ holds only core.js. All 13 plugins are self-contained under plugins/<name>/frontend/. Verified live: Network (hub + moved sub-views), Computers (name mismatch), GE-Enforce (helper), printedparts all render from their staged frontends. Build + 58 vitest + naming green.
This commit is contained in:
88
plugins/network/frontend/views/SubnetDetail.vue
Normal file
88
plugins/network/frontend/views/SubnetDetail.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="detail-page">
|
||||
<div v-if="loading" class="loading">Loading...</div>
|
||||
<div v-else-if="!subnet" class="empty-state"><p>Network not found.</p></div>
|
||||
<template v-else>
|
||||
<div class="page-header">
|
||||
<h1>{{ subnet.name || subnet.cidr }}</h1>
|
||||
<router-link to="/networks" class="btn btn-secondary">Back to Networks</router-link>
|
||||
</div>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="content-column">
|
||||
<div class="section-card">
|
||||
<h3 class="section-title">Network</h3>
|
||||
<div class="info-list">
|
||||
<div class="info-row"><span class="info-label">CIDR</span><span class="info-value mono">{{ subnet.cidr }}</span></div>
|
||||
<div class="info-row"><span class="info-label">Network Address</span><span class="info-value mono">{{ subnet.networkaddress || '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">Type</span><span class="info-value">{{ subnet.subnettype || '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">VLAN</span><span class="info-value">{{ subnet.vlannumber || subnet.vlanid || '-' }}</span></div>
|
||||
<div class="info-row" v-if="subnet.gatewayip"><span class="info-label">Gateway</span><span class="info-value mono">{{ subnet.gatewayip }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card" v-if="subnet.description">
|
||||
<h3 class="section-title">Notes</h3>
|
||||
<div class="notes-content">{{ subnet.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-column">
|
||||
<div class="section-card">
|
||||
<h3 class="section-title">Devices on this network ({{ devices.length }})</h3>
|
||||
<div v-if="devices.length === 0" class="empty-state"><p>No devices found in this range.</p></div>
|
||||
<div v-else class="table-container">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Device</th><th>IP</th><th>Type</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="dev in devices" :key="dev.assetid">
|
||||
<td>
|
||||
<router-link v-if="dev.url" :to="dev.url">{{ dev.name || dev.assetnumber }}</router-link>
|
||||
<span v-else>{{ dev.name || dev.assetnumber }}</span>
|
||||
</td>
|
||||
<td class="mono">{{ dev.ipaddress }}</td>
|
||||
<td>{{ typeLabel(dev.assettype) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { networkApi } from '@/api'
|
||||
|
||||
const route = useRoute()
|
||||
const subnet = ref(null)
|
||||
const loading = ref(true)
|
||||
|
||||
const devices = computed(() => subnet.value?.devices || [])
|
||||
|
||||
const TYPE_LABELS = {
|
||||
computer: 'PC', network_device: 'Network Device', printer: 'Printer',
|
||||
machine: 'Machine', measuring_tool: 'Measuring Tool',
|
||||
}
|
||||
function typeLabel(type) {
|
||||
return TYPE_LABELS[type] || type || '-'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await networkApi.subnets.get(route.params.id)
|
||||
subnet.value = response.data?.data || response.data
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
Reference in New Issue
Block a user