<template>
<section class="page">
<div class="page-heading">
<div>
<p class="eyebrow">Devices</p>
<h1>Device Matrix</h1>
</div>
<UiButton :loading="devicesStore.isLoading || devicesStore.isLoadingStates" @click="reload">
Refresh
</UiButton>
</div>
<AppLoadingState v-if="devicesStore.isLoading" text="Loading devices" />
<AppErrorState
v-else-if="devicesStore.error"
title="Devices loading failed"
:message="devicesStore.error.message"
:retry="reload"
/>
<AppEmptyState
v-else-if="devicesStore.devices.length === 0"
title="No active devices"
message="No active devices found."
/>
<div v-else class="devices-panel">
<div class="devices-summary">
<UiBadge variant="primary">Total: {{ devicesStore.total }}</UiBadge>
<UiBadge v-if="devicesStore.isLoadingStates" variant="neutral">States loading</UiBadge>
<UiBadge v-else variant="success">States settled</UiBadge>
</div>
<AppErrorState
v-if="devicesStore.stateError"
title="Device states loading failed"
:message="devicesStore.stateError.message"
/>
<div class="devices-table-wrap">
<table class="devices-table">
<thead>
<tr>
<th>Device name</th>
<th>Connect</th>
<th>State</th>
<th>IP</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="device in devicesStore.devices" :key="device.id">
<td>
<strong>{{ device.name || device.alias || `Device #${device.id}` }}</strong>
<small>{{ device.alias }}</small>
</td>
<td>
<DeviceConnectionBadge :status="stateFor(device).connectionStatus" />
</td>
<td>
<DeviceStateCell :state="stateFor(device)" />
</td>
<td>{{ device.ip || "unknown" }}</td>
<td>{{ device.type || "unknown" }}</td>
<td>
<div class="devices-actions">
<UiButton variant="secondary" disabled>Details</UiButton>
<UiButton variant="warning" disabled>Reboot</UiButton>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
</template>
<script setup>
import { onMounted } from "vue";
import { useDevicesStore } from "../../../stores/devices";
import AppEmptyState from "../../../components/feedback/AppEmptyState.vue";
import AppErrorState from "../../../components/feedback/AppErrorState.vue";
import AppLoadingState from "../../../components/feedback/AppLoadingState.vue";
import UiBadge from "../../../components/ui/UiBadge.vue";
import UiButton from "../../../components/ui/UiButton.vue";
import DeviceConnectionBadge from "../components/DeviceConnectionBadge.vue";
import DeviceStateCell from "../components/DeviceStateCell.vue";
const devicesStore = useDevicesStore();
function stateFor(device) {
return devicesStore.stateByDeviceId[String(device.id)] || {
status: "idle",
message: "Not loaded",
connectionStatus: device.connection_status || "unknown",
};
}
async function reload() {
const result = await devicesStore.loadDevices();
if (result.ok) {
await devicesStore.loadDeviceStates();
}
}
onMounted(reload);
</script>