@seamapi/react 4.4.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/elements.js +3902 -3846
- package/dist/elements.js.map +1 -1
- package/lib/seam/components/AccessCodeDetails/AccessCodeDetails.js +8 -3
- package/lib/seam/components/AccessCodeDetails/AccessCodeDetails.js.map +1 -1
- package/lib/seam/components/AccessCodeDetails/AccessCodeDevice.js +26 -7
- package/lib/seam/components/AccessCodeDetails/AccessCodeDevice.js.map +1 -1
- package/lib/seam/components/DeviceDetails/LockDeviceDetails.js +24 -5
- package/lib/seam/components/DeviceDetails/LockDeviceDetails.js.map +1 -1
- package/lib/seam/locks/use-toggle-lock.d.ts +5 -2
- package/lib/seam/locks/use-toggle-lock.js +5 -1
- package/lib/seam/locks/use-toggle-lock.js.map +1 -1
- package/lib/ui/Snackbar/Snackbar.d.ts +2 -3
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx +50 -34
- package/src/lib/seam/components/AccessCodeDetails/AccessCodeDevice.tsx +58 -24
- package/src/lib/seam/components/DeviceDetails/LockDeviceDetails.tsx +105 -71
- package/src/lib/seam/locks/use-toggle-lock.ts +13 -3
- package/src/lib/ui/Snackbar/Snackbar.tsx +2 -2
- package/src/lib/version.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import classNames from 'classnames'
|
|
2
|
+
import { useState } from 'react'
|
|
2
3
|
|
|
3
4
|
import { ChevronRightIcon } from 'lib/icons/ChevronRight.js'
|
|
4
5
|
import { useAccessCodes } from 'lib/seam/access-codes/use-access-codes.js'
|
|
@@ -16,6 +17,7 @@ import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
|
|
|
16
17
|
import { EditableDeviceName } from 'lib/ui/device/EditableDeviceName.js'
|
|
17
18
|
import { OnlineStatus } from 'lib/ui/device/OnlineStatus.js'
|
|
18
19
|
import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
|
|
20
|
+
import { Snackbar, type SnackbarVariant } from 'lib/ui/Snackbar/Snackbar.js'
|
|
19
21
|
import { useToggle } from 'lib/ui/use-toggle.js'
|
|
20
22
|
|
|
21
23
|
interface LockDeviceDetailsProps extends NestedSpecificDeviceDetailsProps {
|
|
@@ -38,11 +40,25 @@ export function LockDeviceDetails({
|
|
|
38
40
|
onEditName,
|
|
39
41
|
}: LockDeviceDetailsProps): JSX.Element | null {
|
|
40
42
|
const [accessCodesOpen, toggleAccessCodesOpen] = useToggle()
|
|
41
|
-
const toggleLock = useToggleLock()
|
|
42
43
|
const { accessCodes } = useAccessCodes({
|
|
43
44
|
device_id: device.device_id,
|
|
44
45
|
})
|
|
45
46
|
|
|
47
|
+
const [snackbarVisible, setSnackbarVisible] = useState(false)
|
|
48
|
+
const [snackbarVariant, setSnackbarVariant] =
|
|
49
|
+
useState<SnackbarVariant>('success')
|
|
50
|
+
|
|
51
|
+
const toggleLock = useToggleLock({
|
|
52
|
+
onSuccess: () => {
|
|
53
|
+
setSnackbarVisible(true)
|
|
54
|
+
setSnackbarVariant('success')
|
|
55
|
+
},
|
|
56
|
+
onError: () => {
|
|
57
|
+
setSnackbarVisible(true)
|
|
58
|
+
setSnackbarVariant('error')
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
46
62
|
const lockStatus = device.properties.locked ? t.locked : t.unlocked
|
|
47
63
|
const toggleLockLabel = device.properties.locked ? t.unlock : t.lock
|
|
48
64
|
|
|
@@ -88,87 +104,103 @@ export function LockDeviceDetails({
|
|
|
88
104
|
]
|
|
89
105
|
|
|
90
106
|
return (
|
|
91
|
-
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
<
|
|
107
|
+
<>
|
|
108
|
+
<Snackbar
|
|
109
|
+
variant={snackbarVariant}
|
|
110
|
+
visible={snackbarVisible}
|
|
111
|
+
onClose={() => {
|
|
112
|
+
setSnackbarVisible(false)
|
|
113
|
+
}}
|
|
114
|
+
message={
|
|
115
|
+
snackbarVariant === 'success'
|
|
116
|
+
? t.successfullyUpdated
|
|
117
|
+
: t.failedToUpdate
|
|
118
|
+
}
|
|
119
|
+
autoDismiss
|
|
120
|
+
/>
|
|
121
|
+
|
|
122
|
+
<div className={classNames('seam-device-details', className)}>
|
|
123
|
+
<ContentHeader title='Device' onBack={onBack} />
|
|
124
|
+
<div className='seam-body'>
|
|
125
|
+
<div className='seam-summary'>
|
|
126
|
+
<div className='seam-content'>
|
|
127
|
+
<div className='seam-image'>
|
|
128
|
+
<DeviceImage device={device} />
|
|
129
|
+
</div>
|
|
130
|
+
<div className='seam-info'>
|
|
131
|
+
<span className='seam-label'>{t.device}</span>
|
|
132
|
+
<EditableDeviceName
|
|
133
|
+
tagName='h4'
|
|
134
|
+
value={device.properties.name}
|
|
135
|
+
className='seam-device-name'
|
|
136
|
+
onEdit={onEditName}
|
|
137
|
+
/>
|
|
138
|
+
<div className='seam-properties'>
|
|
139
|
+
<span className='seam-label'>{t.status}:</span>{' '}
|
|
140
|
+
<OnlineStatus device={device} />
|
|
141
|
+
{device.properties.online && (
|
|
142
|
+
<>
|
|
143
|
+
<span className='seam-label'>{t.power}:</span>{' '}
|
|
144
|
+
<BatteryStatusIndicator device={device} />
|
|
145
|
+
</>
|
|
146
|
+
)}
|
|
147
|
+
<DeviceModel device={device} />
|
|
148
|
+
</div>
|
|
117
149
|
</div>
|
|
118
150
|
</div>
|
|
151
|
+
<Alerts alerts={alerts} className='seam-alerts-space-top' />
|
|
119
152
|
</div>
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
</
|
|
130
|
-
<ChevronRightIcon />
|
|
153
|
+
<div className='seam-box'>
|
|
154
|
+
<div
|
|
155
|
+
className='seam-content seam-access-codes'
|
|
156
|
+
onClick={toggleAccessCodesOpen}
|
|
157
|
+
>
|
|
158
|
+
<span className='seam-value'>
|
|
159
|
+
{accessCodeCount} {t.accessCodes}
|
|
160
|
+
</span>
|
|
161
|
+
<ChevronRightIcon />
|
|
162
|
+
</div>
|
|
131
163
|
</div>
|
|
132
|
-
</div>
|
|
133
164
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
165
|
+
<div className='seam-box'>
|
|
166
|
+
{device.properties.locked && device.properties.online && (
|
|
167
|
+
<div className='seam-content seam-lock-status'>
|
|
168
|
+
<div>
|
|
169
|
+
<span className='seam-label'>{t.lockStatus}</span>
|
|
170
|
+
<span className='seam-value'>{lockStatus}</span>
|
|
171
|
+
</div>
|
|
172
|
+
<div className='seam-right'>
|
|
173
|
+
{!disableLockUnlock &&
|
|
174
|
+
device.capabilities_supported.includes('lock') && (
|
|
175
|
+
<Button
|
|
176
|
+
size='small'
|
|
177
|
+
onClick={() => {
|
|
178
|
+
toggleLock.mutate(device)
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
{toggleLockLabel}
|
|
182
|
+
</Button>
|
|
183
|
+
)}
|
|
184
|
+
</div>
|
|
153
185
|
</div>
|
|
154
|
-
|
|
155
|
-
)}
|
|
186
|
+
)}
|
|
156
187
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
188
|
+
<AccessCodeLength
|
|
189
|
+
supportedCodeLengths={
|
|
190
|
+
device.properties?.supported_code_lengths ?? []
|
|
191
|
+
}
|
|
192
|
+
/>
|
|
193
|
+
</div>
|
|
194
|
+
<DeviceInfo
|
|
195
|
+
device={device}
|
|
196
|
+
disableConnectedAccountInformation={
|
|
197
|
+
disableConnectedAccountInformation
|
|
160
198
|
}
|
|
199
|
+
disableResourceIds={disableResourceIds}
|
|
161
200
|
/>
|
|
162
201
|
</div>
|
|
163
|
-
<DeviceInfo
|
|
164
|
-
device={device}
|
|
165
|
-
disableConnectedAccountInformation={
|
|
166
|
-
disableConnectedAccountInformation
|
|
167
|
-
}
|
|
168
|
-
disableResourceIds={disableResourceIds}
|
|
169
|
-
/>
|
|
170
202
|
</div>
|
|
171
|
-
|
|
203
|
+
</>
|
|
172
204
|
)
|
|
173
205
|
}
|
|
174
206
|
|
|
@@ -208,4 +240,6 @@ const t = {
|
|
|
208
240
|
lockStatus: 'Lock status',
|
|
209
241
|
status: 'Status',
|
|
210
242
|
power: 'Power',
|
|
243
|
+
successfullyUpdated: 'Lock status has been successfully updated',
|
|
244
|
+
failedToUpdate: 'Failed to update lock status',
|
|
211
245
|
}
|
|
@@ -12,8 +12,6 @@ import {
|
|
|
12
12
|
|
|
13
13
|
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
14
|
|
|
15
|
-
export type UseToggleLockParams = never
|
|
16
|
-
|
|
17
15
|
export type UseToggleLockData = undefined
|
|
18
16
|
|
|
19
17
|
export type UseToggleLockMutationVariables = Pick<Device, 'device_id'> & {
|
|
@@ -29,7 +27,14 @@ type MutationError =
|
|
|
29
27
|
| SeamActionAttemptFailedError<ToggleLockActionAttempt>
|
|
30
28
|
| SeamActionAttemptTimeoutError<ToggleLockActionAttempt>
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
interface UseToggleLockParams {
|
|
31
|
+
onError?: () => void
|
|
32
|
+
onSuccess?: () => void
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function useToggleLock(
|
|
36
|
+
params: UseToggleLockParams = {}
|
|
37
|
+
): UseMutationResult<
|
|
33
38
|
UseToggleLockData,
|
|
34
39
|
MutationError,
|
|
35
40
|
UseToggleLockMutationVariables
|
|
@@ -92,6 +97,8 @@ export function useToggleLock(): UseMutationResult<
|
|
|
92
97
|
)
|
|
93
98
|
},
|
|
94
99
|
onError: async (_error, variables) => {
|
|
100
|
+
params.onError?.()
|
|
101
|
+
|
|
95
102
|
await queryClient.invalidateQueries({
|
|
96
103
|
queryKey: ['devices', 'list'],
|
|
97
104
|
})
|
|
@@ -99,5 +106,8 @@ export function useToggleLock(): UseMutationResult<
|
|
|
99
106
|
queryKey: ['devices', 'get', { device_id: variables.device_id }],
|
|
100
107
|
})
|
|
101
108
|
},
|
|
109
|
+
onSuccess() {
|
|
110
|
+
params.onSuccess?.()
|
|
111
|
+
},
|
|
102
112
|
})
|
|
103
113
|
}
|
|
@@ -5,9 +5,9 @@ import { CheckGreenIcon } from 'lib/icons/CheckGreen.js'
|
|
|
5
5
|
import { CloseWhiteIcon } from 'lib/icons/CloseWhite.js'
|
|
6
6
|
import { ExclamationCircleIcon } from 'lib/icons/ExclamationCircle.js'
|
|
7
7
|
|
|
8
|
-
type SnackbarVariant = 'success' | 'error'
|
|
8
|
+
export type SnackbarVariant = 'success' | 'error'
|
|
9
9
|
|
|
10
|
-
interface SnackbarProps {
|
|
10
|
+
export interface SnackbarProps {
|
|
11
11
|
message: string
|
|
12
12
|
variant: SnackbarVariant
|
|
13
13
|
visible: boolean
|
package/src/lib/version.ts
CHANGED