Newer
Older
smart-home-server / webclient-vue / src / features / devices / pages / DevicesListPage.vue
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 25 Apr 3 KB Add Vue devices list page
<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>