List rows click through to the item; drop the redundant VLANs tab
Some checks failed
CI / backend (push) Successful in 1m39s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Has been cancelled

Row-click: the whole table row now navigates to the item detail (machines, PCs,
printers, network devices, measuring tools, applications), matching the Networks
list. The actions cell is @click.stop so View/Edit/Delete still work
independently; a shared .clickable-row style gives the cursor + hover.

Network hub: drop the VLANs tab - a subnet belongs to a VLAN (each Networks row
already shows its VLAN) so a sibling tab was redundant; VLAN naming stays in
Settings. Hub is now Devices | Networks.

Verified: row-click navigates on machines/pcs/network; hub shows two tabs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-13 14:21:34 -04:00
parent 8528617037
commit 58af5afda2
8 changed files with 785 additions and 779 deletions

View File

@@ -1742,3 +1742,9 @@ td.actions {
color: var(--text-light); color: var(--text-light);
cursor: pointer; cursor: pointer;
} }
/* Clickable list rows: the whole row navigates to the item detail; interactive
cells (the actions column, in-row links) stop propagation so they still work
independently. */
.clickable-row { cursor: pointer; }
.clickable-row:hover td { background: var(--bg); }

View File

@@ -39,7 +39,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="app in applications" :key="app.appid"> <tr v-for="app in applications" :key="app.appid" class="clickable-row" @click="$router.push(`/applications/${app.appid}`)">
<td class="icon-cell"> <td class="icon-cell">
<a v-if="app.installpath" :href="app.installpath" target="_blank" title="Download Installation Files" class="icon-download"> <a v-if="app.installpath" :href="app.installpath" target="_blank" title="Download Installation Files" class="icon-download">
&#x2B07; &#x2B07;
@@ -66,7 +66,7 @@
<td class="description">{{ app.appdescription || '-' }}</td> <td class="description">{{ app.appdescription || '-' }}</td>
<td>{{ app.supportteamname || '-' }}</td> <td>{{ app.supportteamname || '-' }}</td>
<td>{{ app.contacts && app.contacts.length ? app.contacts.map(c => c.name).join(', ') : '-' }}</td> <td>{{ app.contacts && app.contacts.length ? app.contacts.map(c => c.name).join(', ') : '-' }}</td>
<td class="actions"> <td class="actions" @click.stop>
<router-link <router-link
:to="`/applications/${app.appid}`" :to="`/applications/${app.appid}`"
class="btn btn-secondary btn-sm" class="btn btn-secondary btn-sm"

View File

@@ -36,7 +36,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="item in machines" :key="item.assetid"> <tr v-for="item in machines" :key="item.assetid" class="clickable-row" @click="$router.push(`/machines/${item.machine?.machineid || item.assetid}`)">
<td> <td>
{{ item.assetnumber }}<template v-if="item.dualpathpartner"> / {{ item.dualpathpartner.assetnumber }}</template> {{ item.assetnumber }}<template v-if="item.dualpathpartner"> / {{ item.dualpathpartner.assetnumber }}</template>
</td> </td>
@@ -50,7 +50,7 @@
</span> </span>
</td> </td>
<td>{{ item.locationname || '-' }}</td> <td>{{ item.locationname || '-' }}</td>
<td class="actions"> <td class="actions" @click.stop>
<router-link <router-link
:to="`/machines/${item.machine?.machineid || item.assetid}`" :to="`/machines/${item.machine?.machineid || item.assetid}`"
class="btn btn-secondary btn-sm" class="btn btn-secondary btn-sm"

View File

@@ -49,7 +49,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="item in tools" :key="item.assetid"> <tr v-for="item in tools" :key="item.assetid" class="clickable-row" @click="$router.push(`/measuringtools/${item.measuringtool?.measuringtoolid || item.assetid}`)">
<td>{{ item.assetnumber }}</td> <td>{{ item.assetnumber }}</td>
<td>{{ item.name || '-' }}</td> <td>{{ item.name || '-' }}</td>
<td class="mono">{{ item.serialnumber || '-' }}</td> <td class="mono">{{ item.serialnumber || '-' }}</td>
@@ -61,7 +61,7 @@
</span> </span>
</td> </td>
<td>{{ item.locationname || '-' }}</td> <td>{{ item.locationname || '-' }}</td>
<td class="actions"> <td class="actions" @click.stop>
<router-link <router-link
:to="`/measuringtools/${item.measuringtool?.measuringtoolid || item.assetid}`" :to="`/measuringtools/${item.measuringtool?.measuringtoolid || item.assetid}`"
class="btn btn-secondary btn-sm" class="btn btn-secondary btn-sm"

View File

@@ -67,7 +67,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="device in devices" :key="device.networkdevice?.networkdeviceid || device.assetid"> <tr v-for="device in devices" :key="device.networkdevice?.networkdeviceid || device.assetid" class="clickable-row" @click="$router.push(`/network/${device.networkdevice?.networkdeviceid || device.assetid}`)">
<td>{{ device.assetnumber }}</td> <td>{{ device.assetnumber }}</td>
<td class="mono">{{ device.networkdevice?.hostname || '-' }}</td> <td class="mono">{{ device.networkdevice?.hostname || '-' }}</td>
<td class="mono">{{ device.serialnumber || '-' }}</td> <td class="mono">{{ device.serialnumber || '-' }}</td>
@@ -85,7 +85,7 @@
</span> </span>
</td> </td>
<td>{{ device.locationname || '-' }}</td> <td>{{ device.locationname || '-' }}</td>
<td class="actions"> <td class="actions" @click.stop>
<router-link <router-link
:to="`/network/${device.networkdevice?.networkdeviceid}`" :to="`/network/${device.networkdevice?.networkdeviceid}`"
class="btn btn-secondary btn-sm" class="btn btn-secondary btn-sm"

View File

@@ -21,15 +21,15 @@ import { ref, computed, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import NetworkDevicesList from './NetworkDevicesList.vue' import NetworkDevicesList from './NetworkDevicesList.vue'
import SubnetsBrowse from './SubnetsBrowse.vue' import SubnetsBrowse from './SubnetsBrowse.vue'
import VLANsList from '../settings/VLANsList.vue'
const route = useRoute() const route = useRoute()
const router = useRouter() 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 = [ const tabs = [
{ key: 'devices', label: 'Devices', comp: NetworkDevicesList }, { key: 'devices', label: 'Devices', comp: NetworkDevicesList },
{ key: 'networks', label: 'Networks', comp: SubnetsBrowse }, { key: 'networks', label: 'Networks', comp: SubnetsBrowse },
{ key: 'vlans', label: 'VLANs', comp: VLANsList },
] ]
const active = ref(tabs.some(t => t.key === route.query.tab) ? route.query.tab : 'devices') const active = ref(tabs.some(t => t.key === route.query.tab) ? route.query.tab : 'devices')

View File

@@ -36,7 +36,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="item in computers" :key="item.assetid"> <tr v-for="item in computers" :key="item.assetid" class="clickable-row" @click="$router.push(`/pcs/${item.computer?.computerid || item.assetid}`)">
<td>{{ item.assetnumber }}</td> <td>{{ item.assetnumber }}</td>
<td>{{ item.computer?.hostname || '-' }}</td> <td>{{ item.computer?.hostname || '-' }}</td>
<td class="mono">{{ item.serialnumber || '-' }}</td> <td class="mono">{{ item.serialnumber || '-' }}</td>
@@ -54,7 +54,7 @@
</span> </span>
</td> </td>
<td>{{ item.locationname || '-' }}</td> <td>{{ item.locationname || '-' }}</td>
<td class="actions"> <td class="actions" @click.stop>
<router-link <router-link
:to="`/pcs/${item.computer?.computerid || item.assetid}`" :to="`/pcs/${item.computer?.computerid || item.assetid}`"
class="btn btn-secondary btn-sm" class="btn btn-secondary btn-sm"

View File

@@ -44,7 +44,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="printer in printers" :key="printer.printer?.printerid || printer.assetid"> <tr v-for="printer in printers" :key="printer.printer?.printerid || printer.assetid" class="clickable-row" @click="$router.push(`/printers/${printer.printer?.printerid || printer.assetid}`)">
<td>{{ printer.assetnumber }}</td> <td>{{ printer.assetnumber }}</td>
<td>{{ printer.name && printer.name.toUpperCase() !== 'NONE' ? printer.name : (printer.printer?.hostname || '-') }}</td> <td>{{ printer.name && printer.name.toUpperCase() !== 'NONE' ? printer.name : (printer.printer?.hostname || '-') }}</td>
<td>{{ printer.businessunitname || '-' }}</td> <td>{{ printer.businessunitname || '-' }}</td>
@@ -55,7 +55,7 @@
{{ printer.statusname || 'Active' }} {{ printer.statusname || 'Active' }}
</span> </span>
</td> </td>
<td class="actions"> <td class="actions" @click.stop>
<router-link <router-link
:to="`/printers/${printer.printer?.printerid || printer.assetid}`" :to="`/printers/${printer.printer?.printerid || printer.assetid}`"
class="btn btn-secondary btn-sm" class="btn btn-secondary btn-sm"