<template>
<GnTable
:columns="columns"
:rows="devices"
:caption="caption"
>
<template #cell-device="{ row }">
<router-link
:to="{ name: 'device-detail', params: { id: String(row.id) } }"
class="device-link"
>
<div class="device-cell">
<div class="device-icon" v-html="typeIcon(row.device_type)" />
<div class="device-info">
<strong>{{ row.name || row.alias || `Device #${row.id}` }}</strong>
<small>{{ row.alias }} — {{ row.device_ip || '—' }}</small>
</div>
</div>
</router-link>
</template>
<template #cell-connect="{ row }">
<DeviceConnectionBadge :status="row.connection_status || 'unknown'" />
</template>
<template #cell-state="{ row }">
<DeviceStateCell :state="stateFor(row)" />
</template>
<template v-if="showActions" #cell-actions="{ row }">
<GnButton
variant="warning"
icon="ph-arrow-clockwise"
size="sm"
:loading="devicesStore.isRebooting(row.id)"
@click="reboot(row.id)"
>
Reboot
</GnButton>
</template>
</GnTable>
</template>
<script setup>
import { computed } from "vue";
import { useDevicesStore } from "../../stores/devices";
import { GnTable, GnButton } from "gnexus-ui-kit/vue";
import DeviceConnectionBadge from "../../features/devices/components/DeviceConnectionBadge.vue";
import DeviceStateCell from "../../features/devices/components/DeviceStateCell.vue";
const props = defineProps({
devices: { type: Array, required: true },
showActions: { type: Boolean, default: true },
caption: { type: String, default: "Devices" },
});
const devicesStore = useDevicesStore();
const TYPE_ICONS = {
relay: '<i class="ph ph-toggle-left"></i>',
button: '<i class="ph ph-hand-tap"></i>',
sensor: '<i class="ph ph-thermometer"></i>',
};
const columns = computed(() => {
const cols = [
{ key: "device", label: "Device" },
{ key: "connect", label: "Connect" },
{ key: "state", label: "State" },
];
if (props.showActions) {
cols.push({ key: "actions", label: "Actions" });
}
return cols;
});
function typeIcon(type) {
return TYPE_ICONS[type] || TYPE_ICONS.relay;
}
function stateFor(device) {
return (
devicesStore.stateByDeviceId[String(device.id)] || {
status: "idle",
message: "Not loaded",
connectionStatus: device.connection_status || "unknown",
}
);
}
function reboot(id) {
devicesStore.rebootDevice(id);
}
</script>
<style scoped>
.device-cell {
display: flex;
align-items: center;
gap: 10px;
}
.device-icon {
font-size: 20px;
color: var(--color-primary);
}
.device-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.device-info small {
color: var(--color-muted);
font-size: 12px;
}
.device-link {
color: inherit;
text-decoration: none;
}
.device-link:hover strong {
color: var(--color-primary);
}
</style>