@@ -7,7 +7,6 @@ import { useAuthStore } from "@/stores/auth";
const route = useRoute ( ) ;
const auth = useAuthStore ( ) ;
const rack = ref < Rack | null > ( null ) ;
const side = ref ( "front" ) ;
const showAddDevice = ref ( false ) ;
const showAddNonnet = ref ( false ) ;
const addForm = ref ( { device _id : 0 , position _u : 1 , side : "front" } ) ;
@@ -24,11 +23,11 @@ onMounted(load);
const siteDevices = ( ) => rack . value ? . site _devices || [ ] ;
const slots = ( r : Rack ) => {
const slotsForSide = ( r : Rack , rackSide : string ) => {
const h = r . height _u ;
const map : Record < number , typeof r.devices > = { } ;
for ( const d of r . devices || [ ] ) {
if ( d . side === side . value ) ( map [ d . position _u ] ? ? = [ ] ) . push ( d ) ;
if ( d . side === rackSide ) ( map [ d . position _u ] ? ? = [ ] ) . push ( d ) ;
}
return Array . from ( { length : h } , ( _ , i ) => ( { u : h - i , devices : map [ h - i ] || [ ] } ) ) ;
} ;
@@ -81,23 +80,24 @@ async function removeDevice(rackDeviceId: number) {
< a v-if = "auth.can('export_rack_csv')" :href="`/api/v2/racks/${rack.id}/export`" class="btn-secondary text-sm" > Export CSV < / a >
< / div >
< div class = "mt-4 flex flex-wrap gap-2" >
< button class = "rounded-lg px-3 py-1 text-sm" : class = "side === 'front' ? 'bg-accent text-slate-950' : 'bg-surface-overlay'" @click ="side = 'front'" > Front < / button >
< button class = "rounded-lg px-3 py-1 text-sm" : class = "side === 'back' ? 'bg-accent text-slate-950' : 'bg-surface-overlay'" @click ="side = 'back'" > Back < / button >
< button v-if = "auth.can('add_device_to_rack')" class="btn-secondary text-sm" @click="showAddDevice = true; err = ''" > Add device < / button >
< button v-if = "auth.can('add_nonnet_device_to_rack')" class="btn-secondary text-sm" @click="showAddNonnet = true; err = ''" > Add non -networked < / button >
< / div >
< div class = "card mt-6 max-w-md font-mono text-sm " >
< div v-for = "row in slots(rack) " :key="row.u " class="flex border-b border-slate-200 py-2 dark:border-slate-700 " >
< span class = "w-10 shrink-0 text-slate-5 00" > U { { row . u } } < / span >
< span class = "flex flex-1 flex-col gap-1 " >
< span v-for = "d in row.devices" :key="d.id" class="flex items-center gap-2" >
< RouterLink v-if = "d.device_id" :to="`/devices/${d.device_id}`" class="text-accent hover:underline" > {{ d.device_name }} < / RouterLink >
< span v-else > {{ d.nonnet_device_name }} < / span >
< button v-if = "auth.can('remove_device_from_rack') " class="text-red-500 hover:underline" @click="removeDevice(d.id)" > × < / button >
< div class = "mt-6 grid gap-6 lg:grid-cols-2 " >
< div v-for = "rackSide in ['front', 'back'] as const " :key="rackSide " class="card font-mono text-sm " >
< h2 class = "mb-3 border-b border-slate-200 pb-2 text-base font-semibold capitalize dark:border-slate-7 00" > { { rackSide } } < / h2 >
< div v-for = "row in slotsForSide(rack, rackSide)" :key="row.u" class="flex border-b border-slate-200 py-2 dark:border-slate-700 " >
< span class = "w-10 shrink-0 text-slate-500" > U { { row . u } } < / span >
< span class = "flex flex-1 flex-col gap-1" >
< span v-for = "d in row.devices" :key="d.id" class="flex items-center gap-2" >
< RouterLink v-if = "d.device_id" :to="`/devices/${d.device_id}` " class="text-accent hover:underline" > {{ d.device_name }} < / RouterLink >
< span v-else > {{ d.nonnet_device_name }} < / span >
< button v-if = "auth.can('remove_device_from_rack')" class="text-red-500 hover:underline" @click="removeDevice(d.id)" > × < / button >
< / span >
< span v-if = "!row.devices.length" class="text-slate-500" > — < / span >
< / span >
< span v-if = "!row.devices.length" class="text-slate-500" > — < / span >
< / span >
< / div >
< / div >
< / div >