feat: colour device-inventory role badge by node-type accent
The role/type badge on each inventory tile was always flat grey (bg-[#21262d] text-muted-foreground), which read as disabled and gave no visual cue about the device kind. Colour it with the same per-type accent the node uses on the canvas — resolved through the active theme / style section via resolveNodeColors — so a zigbee_coordinator, zwave_router, etc. gets its style-section colour (translucent background + solid text). Applies to every source (IP, zigbee, zwave) since all node types carry an accent in the theme. Test: role badge renders with the node-type accent colour, not the grey muted class. ha-relevant: yes
This commit is contained in:
@@ -7,6 +7,8 @@ import { Dialog, DialogClose, DialogContent, DialogHeader, DialogTitle } from '@
|
||||
import { scanApi } from '@/api/client'
|
||||
import { useCanvasStore } from '@/stores/canvasStore'
|
||||
import { useDesignStore } from '@/stores/designStore'
|
||||
import { useThemeStore } from '@/stores/themeStore'
|
||||
import { resolveNodeColors } from '@/utils/nodeColors'
|
||||
import { toast } from 'sonner'
|
||||
import { PendingDeviceModal, type PendingDevice } from '@/components/modals/PendingDeviceModal'
|
||||
import type { NodeType, ServiceInfo } from '@/types'
|
||||
@@ -657,7 +659,12 @@ interface DeviceCardProps {
|
||||
|
||||
function DeviceCard({ device, selected, selectMode, highlighted, onClick, cardRef }: DeviceCardProps) {
|
||||
const source = inferSource(device)
|
||||
const Icon = TYPE_ICONS[device.suggested_type ?? 'generic'] ?? Circle
|
||||
const roleType = (device.suggested_type ?? 'generic') as NodeType
|
||||
const Icon = TYPE_ICONS[roleType] ?? Circle
|
||||
const activeTheme = useThemeStore((s) => s.activeTheme)
|
||||
// Colour the role badge with the same accent the node uses on the canvas
|
||||
// (from the active theme / style section), instead of a flat grey.
|
||||
const roleColor = resolveNodeColors({ type: roleType, custom_colors: undefined }, activeTheme).border
|
||||
const label = deviceLabel(device)
|
||||
const sourceColor = source === 'zigbee' ? '#00d4ff' : source === 'zwave' ? '#ff6e00' : '#a855f7'
|
||||
const sourceLabel =
|
||||
@@ -734,7 +741,10 @@ function DeviceCard({ device, selected, selectMode, highlighted, onClick, cardRe
|
||||
{sourceLabel}
|
||||
</span>
|
||||
{device.suggested_type && (
|
||||
<span className="text-[9px] font-mono px-1.5 py-0.5 rounded uppercase tracking-wider bg-[#21262d] text-muted-foreground">
|
||||
<span
|
||||
className="text-[9px] font-mono px-1.5 py-0.5 rounded uppercase tracking-wider"
|
||||
style={{ background: `${roleColor}22`, color: roleColor }}
|
||||
>
|
||||
{device.suggested_type}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -153,6 +153,18 @@ describe('PendingDevicesModal', () => {
|
||||
expect(screen.getByText('Z-WAVE')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('colours the role badge with the node-type accent, not flat grey', async () => {
|
||||
mockPending.mockResolvedValue({ data: [DEVICE_ZWAVE] })
|
||||
render(<PendingDevicesModal {...baseProps} />)
|
||||
const card = await waitFor(() => screen.getByTestId('pending-card-dev-c'))
|
||||
// zwave_router accent from the default theme = #e3b341 (amber), applied to
|
||||
// both the text colour and a translucent background.
|
||||
const badge = within(card).getByText('zwave_router')
|
||||
// #e3b341 → rgb(227, 179, 65) once jsdom normalises the inline colour.
|
||||
expect(badge).toHaveStyle({ color: 'rgb(227, 179, 65)' })
|
||||
expect(badge.className).not.toContain('text-muted-foreground')
|
||||
})
|
||||
|
||||
it('filters by source (zwave only)', async () => {
|
||||
mockPending.mockResolvedValue({ data: [DEVICE_IP, DEVICE_ZWAVE] })
|
||||
render(<PendingDevicesModal {...baseProps} />)
|
||||
|
||||
Reference in New Issue
Block a user