diff --git a/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx b/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx index e1725bdc2..24e9ffeb1 100644 --- a/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx +++ b/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx @@ -217,7 +217,7 @@ export function AccessCodeDetails({ {(!disableEditAccessCode || !disableDeleteAccessCode) && (
- {!disableEditAccessCode && ( + {!disableEditAccessCode && !accessCode.is_offline_access_code && (
- {!disableLockUnlock && ( + {!disableLockUnlock && device.properties.online && ( - )} + {device.properties.locked && device.properties.online && ( +
+
+ {t.lockStatus} + {lockStatus} +
+
+ {!disableLockUnlock && + device.capabilities_supported.includes('lock') && ( + + )} +
- + )} + ('DeviceTable', async (ctx) => { +test('DeviceTable renders devices', async (ctx) => { render(, ctx) await screen.findByText('Fake August Lock 1') }) + +test('DeviceTable renders generic lock device', async (ctx) => { + const existingDevice = ctx.database.devices[0] + + ctx.database.addDevice({ + device_id: 'august_generic_lock_device', + device_type: 'august_lock', + name: 'Generic August Device', + display_name: 'Generic August Device', + connected_account_id: existingDevice?.connected_account_id, + can_remotely_unlock: false, + can_remotely_lock: false, + can_program_online_access_codes: true, + properties: { + online: false, + manufacturer: 'august', + name: 'Generic August Device', + }, + workspace_id: existingDevice?.workspace_id ?? '', + errors: [], + warnings: [], + custom_metadata: {}, + }) + + render(, ctx) + await screen.findByText('Generic August Device') +}) diff --git a/src/lib/seam/locks/lock-device.ts b/src/lib/seam/locks/lock-device.ts index 8acab2a90..e7b12198b 100644 --- a/src/lib/seam/locks/lock-device.ts +++ b/src/lib/seam/locks/lock-device.ts @@ -5,5 +5,14 @@ export type LockDevice = Omit & { NonNullable>> } -export const isLockDevice = (device: Device): device is LockDevice => - 'locked' in device.properties +export const isLockDevice = (device: Device): device is LockDevice => { + return ( + 'locked' in device.properties || + 'can_remotely_lock' in device || + 'can_remotely_unlock' in device || + 'can_program_online_access_code' in device || + 'can_program_offline_access_code' in device || + device.properties.online_access_codes_enabled === true || + device.properties.offline_access_codes_enabled === true + ) +} diff --git a/src/lib/ui/device/LockStatus.tsx b/src/lib/ui/device/LockStatus.tsx index cea83c2b0..703457eee 100644 --- a/src/lib/ui/device/LockStatus.tsx +++ b/src/lib/ui/device/LockStatus.tsx @@ -19,6 +19,10 @@ export function LockStatus(props: LockStatusProps): JSX.Element | null { }, } = props + if (locked === null) { + return null + } + return (
diff --git a/test/fixtures/api.ts b/test/fixtures/api.ts index 94570fee2..8889c88f0 100644 --- a/test/fixtures/api.ts +++ b/test/fixtures/api.ts @@ -2,12 +2,18 @@ import { createFake as createFakeDevicedb, type Fake as FakeDevicedb, } from '@seamapi/fake-devicedb' -import { createFake, type Fake, type Seed } from '@seamapi/fake-seam-connect' +import { + createFake, + type Database, + type Fake, + type Seed, +} from '@seamapi/fake-seam-connect' import { beforeEach } from 'vitest' export interface ApiTestContext { endpoint: string seed: Seed + database: Database } beforeEach(async (ctx) => { @@ -22,6 +28,7 @@ beforeEach(async (ctx) => { ctx.endpoint = endpoint ctx.seed = seed + ctx.database = fake.database return () => { fake.server?.close()