Files
shopdb-flask/plugins/network/frontend/views/NetworkHub.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

73 lines
1.8 KiB
Vue

<template>
<div>
<div class="page-header">
<h1>Network</h1>
</div>
<div class="hub-tabs">
<button
v-for="tab in tabs"
:key="tab.key"
class="hub-tab"
:class="{ active: active === tab.key }"
@click="setTab(tab.key)"
>{{ tab.label }}</button>
</div>
<component :is="current" />
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import NetworkDevicesList from './NetworkDevicesList.vue'
import SubnetsBrowse from './SubnetsBrowse.vue'
const route = useRoute()
const router = useRouter()
// VLANs are a layer under a subnet (each Networks row shows its VLAN); VLAN
// naming lives in Settings, so the hub is just Devices + Networks.
const tabs = [
{ key: 'devices', label: 'Devices', comp: NetworkDevicesList },
{ key: 'networks', label: 'Networks', comp: SubnetsBrowse },
]
const active = ref(tabs.some(t => t.key === route.query.tab) ? route.query.tab : 'devices')
const current = computed(() => (tabs.find(t => t.key === active.value) || tabs[0]).comp)
function setTab(key) {
active.value = key
router.replace({ query: { ...route.query, tab: key } })
}
watch(() => route.query.tab, (value) => {
if (value && value !== active.value && tabs.some(t => t.key === value)) {
active.value = value
}
})
</script>
<style scoped>
.hub-tabs {
display: flex;
gap: 0.25rem;
border-bottom: 1px solid var(--border);
margin-bottom: 1.25rem;
}
.hub-tab {
background: none;
border: none;
border-bottom: 2px solid transparent;
padding: 0.6rem 1rem;
cursor: pointer;
color: var(--text-light);
font-size: 0.95rem;
font-weight: 500;
}
.hub-tab:hover { color: var(--text); }
.hub-tab.active {
color: var(--primary);
border-bottom-color: var(--primary);
}
</style>