Network devices: manage buttons where every other asset keeps them
Machines, PCs, printers and measuring tools all carry Print Label / Edit / Retire / Back to List in a page header. A network device had no header at all: Edit was tucked inside the hero title row, and Print Label and Delete sat in a bar at the very bottom of the page, past every card. Managing one meant looking somewhere different from every other asset type. They move to the standard header. The bottom bar is removed rather than left as a second copy, and the two delete handlers collapse into one - the route is a soft delete, so it is called Retire here as it is everywhere else, and the confirm says what is kept.
This commit is contained in:
@@ -1,5 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="detail-page" v-if="device">
|
<div class="detail-page" v-if="device">
|
||||||
|
<!--
|
||||||
|
The same page-header + header-actions block every other asset detail page
|
||||||
|
uses. This page had no header at all: Edit was tucked inside the hero
|
||||||
|
title row and there was no Print Label, no Retire and no way back to the
|
||||||
|
list, so managing a network device meant looking somewhere different from
|
||||||
|
every other asset type.
|
||||||
|
-->
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>Network Device Details</h2>
|
||||||
|
<div class="header-actions">
|
||||||
|
<router-link :to="`/print/asset-label/network_device/${deviceId}`"
|
||||||
|
class="btn btn-secondary" target="_blank">Print Label</router-link>
|
||||||
|
<router-link v-if="authStore.isAuthenticated" :to="`/network/${deviceId}/edit`"
|
||||||
|
class="btn btn-primary">Edit</router-link>
|
||||||
|
<button v-if="authStore.isAuthenticated" @click="confirmRetire"
|
||||||
|
class="btn btn-danger">Retire</button>
|
||||||
|
<router-link to="/network" class="btn btn-secondary">Back to List</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="hero-card">
|
<div class="hero-card">
|
||||||
<div class="hero-image">
|
<div class="hero-image">
|
||||||
<img v-if="device.networkdevice?.imageurl" :src="withBase(device.networkdevice.imageurl)" alt="Model photo" />
|
<img v-if="device.networkdevice?.imageurl" :src="withBase(device.networkdevice.imageurl)" alt="Model photo" />
|
||||||
@@ -10,13 +30,6 @@
|
|||||||
<div class="hero-content">
|
<div class="hero-content">
|
||||||
<div class="hero-title-row">
|
<div class="hero-title-row">
|
||||||
<h1 class="hero-title">{{ device.networkdevice?.hostname || device.name || device.assetnumber }}</h1>
|
<h1 class="hero-title">{{ device.networkdevice?.hostname || device.name || device.assetnumber }}</h1>
|
||||||
<router-link
|
|
||||||
v-if="authStore.isAuthenticated"
|
|
||||||
:to="`/network/${deviceId}/edit`"
|
|
||||||
class="btn btn-secondary"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="hero-meta">
|
<div class="hero-meta">
|
||||||
<span class="badge" :style="colorStyle(device.statuscolor)">
|
<span class="badge" :style="colorStyle(device.statuscolor)">
|
||||||
@@ -184,18 +197,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Actions -->
|
<!-- The manage actions live in the page header, where every other asset
|
||||||
<div class="action-bar" v-if="authStore.isAuthenticated">
|
detail page puts them. They used to sit down here instead, which is
|
||||||
<router-link :to="`/print/asset-label/network_device/${deviceId}`" class="btn btn-secondary" target="_blank">
|
why finding them on a network device meant looking somewhere else. -->
|
||||||
Print Label
|
|
||||||
</router-link>
|
|
||||||
<router-link :to="`/network/${deviceId}/edit`" class="btn btn-primary">
|
|
||||||
Edit Device
|
|
||||||
</router-link>
|
|
||||||
<button @click="confirmDelete" class="btn btn-danger">
|
|
||||||
Delete Device
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Audit Footer -->
|
<!-- Audit Footer -->
|
||||||
<div class="audit-footer">
|
<div class="audit-footer">
|
||||||
@@ -228,6 +232,7 @@ import PluginAssetPanels from '@/components/PluginAssetPanels.vue'
|
|||||||
import { useWarrantyBadge } from '@/composables/warrantyBadge'
|
import { useWarrantyBadge } from '@/composables/warrantyBadge'
|
||||||
import { useIdentifierFlags } from '@/composables/identifierSettings'
|
import { useIdentifierFlags } from '@/composables/identifierSettings'
|
||||||
import { useToast } from '@/composables/toast'
|
import { useToast } from '@/composables/toast'
|
||||||
|
import { apiError } from '@/utils/apiError'
|
||||||
import { setRecordTitle } from '@/composables/pageTitle'
|
import { setRecordTitle } from '@/composables/pageTitle'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
@@ -293,17 +298,24 @@ function formatDate(dateStr) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function confirmDelete() {
|
// Soft delete, like every other asset type: the record leaves the lists while
|
||||||
if (confirm(`Are you sure you want to delete ${device.value.networkdevice?.hostname || device.value.assetnumber}?`)) {
|
// its history and relationships stay put, and it can be restored by setting
|
||||||
try {
|
// isactive back. Called Retire rather than Delete for exactly that reason.
|
||||||
await networkApi.delete(deviceId)
|
async function confirmRetire () {
|
||||||
router.push('/network')
|
const label = device.value?.networkdevice?.hostname
|
||||||
} catch (error) {
|
|| device.value?.name || device.value?.assetnumber || 'this device'
|
||||||
console.error('Error deleting device:', error)
|
if (!confirm(`Retire ${label}?\n\nIt will no longer appear in ShopDB. `
|
||||||
toast.error('Failed to delete device')
|
+ `History and relationships are kept, and it can be restored.`)) return
|
||||||
}
|
try {
|
||||||
|
await networkApi.delete(deviceId)
|
||||||
|
toast.success(`Retired ${label}`)
|
||||||
|
router.push('/network')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error retiring network device:', error)
|
||||||
|
toast.error(apiError(error, 'Failed to retire network device'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user