Files
shopdb-flask/plugins/network/frontend/views/SubnetDetail.vue
cproudlock ebca0b00b0 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.
2026-07-18 23:56:07 -04:00

89 lines
3.3 KiB
Vue

<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>