@seamapi/react 1.60.1 → 1.60.3
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 +1 -1
- package/dist/elements.js +18524 -34069
- package/dist/elements.js.map +1 -1
- package/dist/index.css +6 -0
- package/dist/index.css.map +1 -1
- package/dist/index.min.css +1 -1
- package/dist/index.min.css.map +1 -1
- package/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.d.ts +7 -0
- package/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.js +35 -13
- package/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.js.map +1 -1
- package/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.js +8 -15
- package/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.js.map +1 -1
- package/lib/ui/AccessCodeForm/AccessCodeForm.d.ts +5 -1
- package/lib/ui/AccessCodeForm/AccessCodeForm.js +4 -4
- package/lib/ui/AccessCodeForm/AccessCodeForm.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/lib/icons/AccessCodeKey.tsx +1 -1
- package/src/lib/icons/Add.tsx +1 -1
- package/src/lib/icons/ArrowBack.tsx +1 -1
- package/src/lib/icons/ArrowRestart.tsx +1 -1
- package/src/lib/icons/ArrowRight.tsx +1 -1
- package/src/lib/icons/BatteryLevelCritical.tsx +1 -1
- package/src/lib/icons/BatteryLevelFull.tsx +1 -1
- package/src/lib/icons/BatteryLevelHigh.tsx +1 -1
- package/src/lib/icons/BatteryLevelLow.tsx +1 -1
- package/src/lib/icons/BatteryLevelWired.tsx +1 -1
- package/src/lib/icons/Bee.tsx +1 -1
- package/src/lib/icons/Check.tsx +1 -1
- package/src/lib/icons/CheckBlack.tsx +1 -1
- package/src/lib/icons/CheckboxBlank.tsx +1 -1
- package/src/lib/icons/CheckboxFilled.tsx +1 -1
- package/src/lib/icons/ChevronDown.tsx +1 -1
- package/src/lib/icons/ChevronRight.tsx +1 -1
- package/src/lib/icons/ChevronWide.tsx +1 -1
- package/src/lib/icons/ClimateSettingSchedule.tsx +1 -1
- package/src/lib/icons/Close.tsx +1 -1
- package/src/lib/icons/Copy.tsx +1 -1
- package/src/lib/icons/DotsEllipsisMore.tsx +1 -1
- package/src/lib/icons/Edit.tsx +1 -1
- package/src/lib/icons/ExclamationCircle.tsx +1 -1
- package/src/lib/icons/ExclamationCircleOutline.tsx +1 -1
- package/src/lib/icons/Fan.tsx +1 -1
- package/src/lib/icons/FanOutline.tsx +1 -1
- package/src/lib/icons/Info.tsx +1 -1
- package/src/lib/icons/InfoDark.tsx +1 -1
- package/src/lib/icons/LockLocked.tsx +1 -1
- package/src/lib/icons/LockUnlocked.tsx +1 -1
- package/src/lib/icons/Off.tsx +1 -1
- package/src/lib/icons/OnlineStatusAccountOffline.tsx +1 -1
- package/src/lib/icons/OnlineStatusDeviceOffline.tsx +1 -1
- package/src/lib/icons/OnlineStatusOnline.tsx +1 -1
- package/src/lib/icons/RadioChecked.tsx +1 -1
- package/src/lib/icons/RadioUnchecked.tsx +1 -1
- package/src/lib/icons/Seam.tsx +1 -1
- package/src/lib/icons/Search.tsx +1 -1
- package/src/lib/icons/TemperatureAdd.tsx +1 -1
- package/src/lib/icons/TemperatureSubtract.tsx +1 -1
- package/src/lib/icons/ThermostatCool.tsx +1 -1
- package/src/lib/icons/ThermostatCoolLarge.tsx +1 -1
- package/src/lib/icons/ThermostatHeat.tsx +1 -1
- package/src/lib/icons/ThermostatHeatCool.tsx +1 -1
- package/src/lib/icons/ThermostatHeatLarge.tsx +1 -1
- package/src/lib/icons/ThermostatOff.tsx +1 -1
- package/src/lib/icons/TriangleWarning.tsx +1 -1
- package/src/lib/icons/TriangleWarningOutline.tsx +1 -1
- package/src/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.tsx +53 -15
- package/src/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.tsx +11 -19
- package/src/lib/ui/AccessCodeForm/AccessCodeForm.tsx +12 -4
- package/src/lib/version.ts +1 -1
- package/src/styles/_access-code-form.scss +7 -0
|
@@ -14,6 +14,7 @@ import { getValidationError } from 'lib/seam/error-handlers.js'
|
|
|
14
14
|
import {
|
|
15
15
|
AccessCodeForm,
|
|
16
16
|
type AccessCodeFormSubmitData,
|
|
17
|
+
type ResponseErrors,
|
|
17
18
|
} from 'lib/ui/AccessCodeForm/AccessCodeForm.js'
|
|
18
19
|
|
|
19
20
|
export interface CreateAccessCodeFormProps extends CommonProps {
|
|
@@ -48,7 +49,7 @@ function Content({
|
|
|
48
49
|
}: Omit<CreateAccessCodeFormProps, 'deviceId'> & {
|
|
49
50
|
device: NonNullable<UseDeviceData>
|
|
50
51
|
}): JSX.Element {
|
|
51
|
-
const { submit, isSubmitting,
|
|
52
|
+
const { submit, isSubmitting, responseErrors } = useSubmitCreateAccessCode({
|
|
52
53
|
onSuccess: () => {
|
|
53
54
|
if (onBack != null) {
|
|
54
55
|
onBack()
|
|
@@ -63,29 +64,23 @@ function Content({
|
|
|
63
64
|
onBack={onBack}
|
|
64
65
|
onSubmit={submit}
|
|
65
66
|
isSubmitting={isSubmitting}
|
|
66
|
-
|
|
67
|
+
responseErrors={responseErrors}
|
|
67
68
|
/>
|
|
68
69
|
)
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
function useSubmitCreateAccessCode(params: { onSuccess: () => void }): {
|
|
72
|
-
codeError: string | null
|
|
73
73
|
submit: (data: AccessCodeFormSubmitData) => void
|
|
74
74
|
isSubmitting: boolean
|
|
75
|
+
responseErrors: ResponseErrors | null
|
|
75
76
|
} {
|
|
76
77
|
const { onSuccess } = params
|
|
77
78
|
const { mutate, isLoading: isSubmitting } = useCreateAccessCode()
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const handleError = (error: SeamError): void => {
|
|
81
|
-
const codeError = getValidationError({ error, property: 'code' })
|
|
82
|
-
if (codeError != null) {
|
|
83
|
-
setCodeError(codeError)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
79
|
+
const { responseErrors, handleResponseError, resetResponseErrors } =
|
|
80
|
+
useResponseErrors()
|
|
86
81
|
|
|
87
82
|
const submit = (data: AccessCodeFormSubmitData): void => {
|
|
88
|
-
|
|
83
|
+
resetResponseErrors()
|
|
89
84
|
|
|
90
85
|
const { name, code, type, device, startDate, endDate, timezone } = data
|
|
91
86
|
if (name === '') {
|
|
@@ -107,7 +102,7 @@ function useSubmitCreateAccessCode(params: { onSuccess: () => void }): {
|
|
|
107
102
|
},
|
|
108
103
|
{
|
|
109
104
|
onSuccess,
|
|
110
|
-
onError:
|
|
105
|
+
onError: handleResponseError,
|
|
111
106
|
}
|
|
112
107
|
)
|
|
113
108
|
|
|
@@ -122,10 +117,53 @@ function useSubmitCreateAccessCode(params: { onSuccess: () => void }): {
|
|
|
122
117
|
},
|
|
123
118
|
{
|
|
124
119
|
onSuccess,
|
|
125
|
-
onError:
|
|
120
|
+
onError: handleResponseError,
|
|
126
121
|
}
|
|
127
122
|
)
|
|
128
123
|
}
|
|
129
124
|
|
|
130
|
-
return { submit, isSubmitting,
|
|
125
|
+
return { submit, isSubmitting, responseErrors }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function useResponseErrors(): {
|
|
129
|
+
responseErrors: ResponseErrors | null
|
|
130
|
+
handleResponseError: (error: SeamError) => void
|
|
131
|
+
resetResponseErrors: () => void
|
|
132
|
+
} {
|
|
133
|
+
const [responseErrors, setResponseErrors] = useState<Record<
|
|
134
|
+
string,
|
|
135
|
+
string | undefined
|
|
136
|
+
> | null>(null)
|
|
137
|
+
|
|
138
|
+
const handleResponseError = (error: SeamError): void => {
|
|
139
|
+
const code = getValidationError({ error, property: 'code' })
|
|
140
|
+
const name = getValidationError({ error, property: 'name' })
|
|
141
|
+
|
|
142
|
+
if (code != null || name != null) {
|
|
143
|
+
setResponseErrors({
|
|
144
|
+
code,
|
|
145
|
+
name,
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
setResponseErrors({
|
|
152
|
+
unknown: t.genericResponseError,
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const resetResponseErrors = (): void => {
|
|
157
|
+
setResponseErrors(null)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
responseErrors,
|
|
162
|
+
handleResponseError,
|
|
163
|
+
resetResponseErrors,
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const t = {
|
|
168
|
+
genericResponseError: 'The code could not be saved. Please try again.',
|
|
131
169
|
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
2
|
-
import type { SeamError } from 'seamapi'
|
|
3
|
-
|
|
4
1
|
import { useComponentTelemetry } from 'lib/telemetry/index.js'
|
|
5
2
|
|
|
6
3
|
import { createIsoDate } from 'lib/dates.js'
|
|
@@ -13,11 +10,12 @@ import {
|
|
|
13
10
|
type CommonProps,
|
|
14
11
|
withRequiredCommonProps,
|
|
15
12
|
} from 'lib/seam/components/common-props.js'
|
|
13
|
+
import { useResponseErrors } from 'lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.js'
|
|
16
14
|
import { useDevice } from 'lib/seam/devices/use-device.js'
|
|
17
|
-
import { getValidationError } from 'lib/seam/error-handlers.js'
|
|
18
15
|
import {
|
|
19
16
|
AccessCodeForm,
|
|
20
17
|
type AccessCodeFormSubmitData,
|
|
18
|
+
type ResponseErrors,
|
|
21
19
|
} from 'lib/ui/AccessCodeForm/AccessCodeForm.js'
|
|
22
20
|
|
|
23
21
|
export interface EditAccessCodeFormProps extends CommonProps {
|
|
@@ -58,7 +56,7 @@ function Content({
|
|
|
58
56
|
device_id: accessCode.device_id,
|
|
59
57
|
})
|
|
60
58
|
|
|
61
|
-
const { submit, isSubmitting,
|
|
59
|
+
const { submit, isSubmitting, responseErrors } = useSubmitEditAccessCode(
|
|
62
60
|
accessCode,
|
|
63
61
|
onBack
|
|
64
62
|
)
|
|
@@ -75,7 +73,7 @@ function Content({
|
|
|
75
73
|
device={device}
|
|
76
74
|
onSubmit={submit}
|
|
77
75
|
isSubmitting={isSubmitting}
|
|
78
|
-
|
|
76
|
+
responseErrors={responseErrors}
|
|
79
77
|
/>
|
|
80
78
|
)
|
|
81
79
|
}
|
|
@@ -86,20 +84,14 @@ function useSubmitEditAccessCode(
|
|
|
86
84
|
): {
|
|
87
85
|
submit: (data: AccessCodeFormSubmitData) => void
|
|
88
86
|
isSubmitting: boolean
|
|
89
|
-
|
|
87
|
+
responseErrors: ResponseErrors | null
|
|
90
88
|
} {
|
|
91
89
|
const { mutate, isLoading: isSubmitting } = useUpdateAccessCode()
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
const handleError = (error: SeamError): void => {
|
|
95
|
-
const codeError = getValidationError({ error, property: 'code' })
|
|
96
|
-
if (codeError != null) {
|
|
97
|
-
setCodeError(codeError)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
90
|
+
const { responseErrors, handleResponseError, resetResponseErrors } =
|
|
91
|
+
useResponseErrors()
|
|
100
92
|
|
|
101
93
|
const submit = (data: AccessCodeFormSubmitData): void => {
|
|
102
|
-
|
|
94
|
+
resetResponseErrors()
|
|
103
95
|
|
|
104
96
|
const { name, code, type, device, startDate, endDate, timezone } = data
|
|
105
97
|
if (name === '') {
|
|
@@ -123,7 +115,7 @@ function useSubmitEditAccessCode(
|
|
|
123
115
|
},
|
|
124
116
|
{
|
|
125
117
|
onSuccess,
|
|
126
|
-
onError:
|
|
118
|
+
onError: handleResponseError,
|
|
127
119
|
}
|
|
128
120
|
)
|
|
129
121
|
|
|
@@ -139,10 +131,10 @@ function useSubmitEditAccessCode(
|
|
|
139
131
|
},
|
|
140
132
|
{
|
|
141
133
|
onSuccess,
|
|
142
|
-
onError:
|
|
134
|
+
onError: handleResponseError,
|
|
143
135
|
}
|
|
144
136
|
)
|
|
145
137
|
}
|
|
146
138
|
|
|
147
|
-
return { submit, isSubmitting,
|
|
139
|
+
return { submit, isSubmitting, responseErrors }
|
|
148
140
|
}
|
|
@@ -33,12 +33,17 @@ export interface AccessCodeFormSubmitData {
|
|
|
33
33
|
timezone: string
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export interface ResponseErrors {
|
|
37
|
+
unknown?: string | undefined
|
|
38
|
+
code?: string | undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
export interface AccessCodeFormProps {
|
|
37
42
|
accessCode?: NonNullable<UseAccessCodeData>
|
|
38
43
|
device: NonNullable<UseDeviceData>
|
|
39
44
|
isSubmitting: boolean
|
|
40
45
|
onSubmit: (data: AccessCodeFormSubmitData) => void
|
|
41
|
-
|
|
46
|
+
responseErrors: ResponseErrors | null
|
|
42
47
|
onBack: (() => void) | undefined
|
|
43
48
|
className: string | undefined
|
|
44
49
|
}
|
|
@@ -60,7 +65,7 @@ function Content({
|
|
|
60
65
|
device,
|
|
61
66
|
onSubmit,
|
|
62
67
|
isSubmitting,
|
|
63
|
-
|
|
68
|
+
responseErrors,
|
|
64
69
|
}: Omit<AccessCodeFormProps, 'className'>): JSX.Element {
|
|
65
70
|
const [type, setType] = useState<AccessCode['type']>(
|
|
66
71
|
accessCode?.type ?? 'ongoing'
|
|
@@ -171,7 +176,7 @@ function Content({
|
|
|
171
176
|
)
|
|
172
177
|
}
|
|
173
178
|
|
|
174
|
-
const hasCodeError = errors.code != null ||
|
|
179
|
+
const hasCodeError = errors.code != null || responseErrors?.code != null
|
|
175
180
|
|
|
176
181
|
const codeLengthRequirement = getCodeLengthRequirement(device)
|
|
177
182
|
|
|
@@ -217,7 +222,7 @@ function Content({
|
|
|
217
222
|
size='large'
|
|
218
223
|
clearable
|
|
219
224
|
hasError={hasCodeError}
|
|
220
|
-
helperText={
|
|
225
|
+
helperText={responseErrors?.code ?? errors.code?.message}
|
|
221
226
|
inputProps={{
|
|
222
227
|
...register('code', {
|
|
223
228
|
required: t.codeRequiredError,
|
|
@@ -281,6 +286,9 @@ function Content({
|
|
|
281
286
|
)}
|
|
282
287
|
</>
|
|
283
288
|
</FormField>
|
|
289
|
+
{responseErrors?.unknown != null && (
|
|
290
|
+
<div className='seam-unknown-error'>{responseErrors?.unknown}</div>
|
|
291
|
+
)}
|
|
284
292
|
<div className='seam-actions'>
|
|
285
293
|
<Button onClick={onBack}>{t.cancel}</Button>
|
|
286
294
|
<Button
|
package/src/lib/version.ts
CHANGED