diff --git a/packages/api/routes/devices.ts b/packages/api/routes/devices.ts index a8c7fec..feba7a8 100644 --- a/packages/api/routes/devices.ts +++ b/packages/api/routes/devices.ts @@ -5,18 +5,28 @@ import express, { Request, Response, Router } from "express"; import { Zigbee2MqttService } from "../zigbee2mqttService"; import { ApiError } from "./api"; import { range } from "../utils"; -import { Scene } from "@starlight/types"; +import { type Device, Scene } from "@starlight/types"; const router = express.Router(); +const deviceSort = (a: Device, b: Device) => { + const x: number = parseInt(a.friendly_name[0]); + const y: number = parseInt(b.friendly_name[0]); + + return ( + +isFinite(x) - +isFinite(y) || + a.friendly_name.localeCompare(b.friendly_name, undefined, { numeric: true }) + ); +}; + export function deviceRouter(zigbee2mqttService: Zigbee2MqttService): Router { // get data about all existing devices router.get("/", async (req: Request, res: Response) => { const devices = await zigbee2mqttService.getDevices(); const deviceQuery = req.query.parameter?.toString(); - const filteredDevices = devices.filter( - (device) => device.device.type !== "Coordinator", - ); + const cleanedDevices = devices + .filter((device) => device.device.type !== "Coordinator") + .sort((a, b) => deviceSort(a.device, b.device)); if (deviceQuery !== undefined) { const queriedData = devices.map((device) => device.device[deviceQuery]); @@ -26,7 +36,7 @@ export function deviceRouter(zigbee2mqttService: Zigbee2MqttService): Router { } return res.status(200).json({ - data: filteredDevices, + data: cleanedDevices, }); }); diff --git a/packages/ui/src/components/DeviceCard/DeviceCard.tsx b/packages/ui/src/components/DeviceCard/DeviceCard.tsx index 39886d6..0cc61bd 100644 --- a/packages/ui/src/components/DeviceCard/DeviceCard.tsx +++ b/packages/ui/src/components/DeviceCard/DeviceCard.tsx @@ -7,12 +7,13 @@ import { StyledText, StyledHeader } from "../../utils/theme"; import { type Device } from "@starlight/types"; const emojiLookup = { - light: "💡", - switch: "🔌", - fan: "🌡️", + numeric: "📶", + climate: "❄️️", cover: "🪟", + fan: "🌡️", + light: "💡", lock: "🔒", - climate: "❄️️", + switch: "🔌", }; const Card = styled.div` @@ -21,6 +22,8 @@ const Card = styled.div` cursor: pointer; border-radius: 2rem; + opacity: ${(props) => (props.dimmed ? 1 : 0.5)}; + &:hover { background-color: ${({ theme }) => theme.hover}; } @@ -35,7 +38,7 @@ function DeviceCard(props: { device: Device; onClick: Function }) { } return ( - + {deviceEmoji} {props.device.friendly_name} diff --git a/packages/ui/src/components/DeviceList/DeviceList.tsx b/packages/ui/src/components/DeviceList/DeviceList.tsx index 8fbee2d..777b74c 100644 --- a/packages/ui/src/components/DeviceList/DeviceList.tsx +++ b/packages/ui/src/components/DeviceList/DeviceList.tsx @@ -5,14 +5,10 @@ import { Link } from "wouter"; import DeviceCard from "../DeviceCard/DeviceCard"; import { type Device } from "@starlight/types"; -const deviceSort = (a: Device, b: Device) => - +isFinite(a.friendly_name[0]) - +isFinite(b.friendly_name[0]) || - a.friendly_name.localeCompare(b.friendly_name, undefined, { numeric: true }); - function DeviceList(props: { devices: Device[]; onClick: Function }) { return (
- {props.devices.sort(deviceSort).map((device: Device) => ( + {props.devices.map((device: Device) => (