@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.
Files changed (72) hide show
  1. package/README.md +1 -1
  2. package/dist/elements.js +18524 -34069
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +6 -0
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.min.css +1 -1
  7. package/dist/index.min.css.map +1 -1
  8. package/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.d.ts +7 -0
  9. package/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.js +35 -13
  10. package/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.js.map +1 -1
  11. package/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.js +8 -15
  12. package/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.js.map +1 -1
  13. package/lib/ui/AccessCodeForm/AccessCodeForm.d.ts +5 -1
  14. package/lib/ui/AccessCodeForm/AccessCodeForm.js +4 -4
  15. package/lib/ui/AccessCodeForm/AccessCodeForm.js.map +1 -1
  16. package/lib/version.d.ts +1 -1
  17. package/lib/version.js +1 -1
  18. package/package.json +1 -1
  19. package/src/lib/icons/AccessCodeKey.tsx +1 -1
  20. package/src/lib/icons/Add.tsx +1 -1
  21. package/src/lib/icons/ArrowBack.tsx +1 -1
  22. package/src/lib/icons/ArrowRestart.tsx +1 -1
  23. package/src/lib/icons/ArrowRight.tsx +1 -1
  24. package/src/lib/icons/BatteryLevelCritical.tsx +1 -1
  25. package/src/lib/icons/BatteryLevelFull.tsx +1 -1
  26. package/src/lib/icons/BatteryLevelHigh.tsx +1 -1
  27. package/src/lib/icons/BatteryLevelLow.tsx +1 -1
  28. package/src/lib/icons/BatteryLevelWired.tsx +1 -1
  29. package/src/lib/icons/Bee.tsx +1 -1
  30. package/src/lib/icons/Check.tsx +1 -1
  31. package/src/lib/icons/CheckBlack.tsx +1 -1
  32. package/src/lib/icons/CheckboxBlank.tsx +1 -1
  33. package/src/lib/icons/CheckboxFilled.tsx +1 -1
  34. package/src/lib/icons/ChevronDown.tsx +1 -1
  35. package/src/lib/icons/ChevronRight.tsx +1 -1
  36. package/src/lib/icons/ChevronWide.tsx +1 -1
  37. package/src/lib/icons/ClimateSettingSchedule.tsx +1 -1
  38. package/src/lib/icons/Close.tsx +1 -1
  39. package/src/lib/icons/Copy.tsx +1 -1
  40. package/src/lib/icons/DotsEllipsisMore.tsx +1 -1
  41. package/src/lib/icons/Edit.tsx +1 -1
  42. package/src/lib/icons/ExclamationCircle.tsx +1 -1
  43. package/src/lib/icons/ExclamationCircleOutline.tsx +1 -1
  44. package/src/lib/icons/Fan.tsx +1 -1
  45. package/src/lib/icons/FanOutline.tsx +1 -1
  46. package/src/lib/icons/Info.tsx +1 -1
  47. package/src/lib/icons/InfoDark.tsx +1 -1
  48. package/src/lib/icons/LockLocked.tsx +1 -1
  49. package/src/lib/icons/LockUnlocked.tsx +1 -1
  50. package/src/lib/icons/Off.tsx +1 -1
  51. package/src/lib/icons/OnlineStatusAccountOffline.tsx +1 -1
  52. package/src/lib/icons/OnlineStatusDeviceOffline.tsx +1 -1
  53. package/src/lib/icons/OnlineStatusOnline.tsx +1 -1
  54. package/src/lib/icons/RadioChecked.tsx +1 -1
  55. package/src/lib/icons/RadioUnchecked.tsx +1 -1
  56. package/src/lib/icons/Seam.tsx +1 -1
  57. package/src/lib/icons/Search.tsx +1 -1
  58. package/src/lib/icons/TemperatureAdd.tsx +1 -1
  59. package/src/lib/icons/TemperatureSubtract.tsx +1 -1
  60. package/src/lib/icons/ThermostatCool.tsx +1 -1
  61. package/src/lib/icons/ThermostatCoolLarge.tsx +1 -1
  62. package/src/lib/icons/ThermostatHeat.tsx +1 -1
  63. package/src/lib/icons/ThermostatHeatCool.tsx +1 -1
  64. package/src/lib/icons/ThermostatHeatLarge.tsx +1 -1
  65. package/src/lib/icons/ThermostatOff.tsx +1 -1
  66. package/src/lib/icons/TriangleWarning.tsx +1 -1
  67. package/src/lib/icons/TriangleWarningOutline.tsx +1 -1
  68. package/src/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.tsx +53 -15
  69. package/src/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.tsx +11 -19
  70. package/src/lib/ui/AccessCodeForm/AccessCodeForm.tsx +12 -4
  71. package/src/lib/version.ts +1 -1
  72. 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, codeError } = useSubmitCreateAccessCode({
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
- codeError={codeError}
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 [codeError, setCodeError] = useState<string | null>(null)
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
- setCodeError(null)
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: handleError,
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: handleError,
120
+ onError: handleResponseError,
126
121
  }
127
122
  )
128
123
  }
129
124
 
130
- return { submit, isSubmitting, codeError }
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, codeError } = useSubmitEditAccessCode(
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
- codeError={codeError}
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
- codeError: string | null
87
+ responseErrors: ResponseErrors | null
90
88
  } {
91
89
  const { mutate, isLoading: isSubmitting } = useUpdateAccessCode()
92
- const [codeError, setCodeError] = useState<string | null>(null)
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
- setCodeError(null)
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: handleError,
118
+ onError: handleResponseError,
127
119
  }
128
120
  )
129
121
 
@@ -139,10 +131,10 @@ function useSubmitEditAccessCode(
139
131
  },
140
132
  {
141
133
  onSuccess,
142
- onError: handleError,
134
+ onError: handleResponseError,
143
135
  }
144
136
  )
145
137
  }
146
138
 
147
- return { submit, isSubmitting, codeError }
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
- codeError: string | null
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
- codeError,
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 || codeError != 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={codeError ?? errors.code?.message}
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
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '1.60.1'
1
+ const seamapiReactVersion = '1.60.3'
2
2
 
3
3
  export default seamapiReactVersion
@@ -72,6 +72,13 @@
72
72
  }
73
73
  }
74
74
 
75
+ .seam-unknown-error {
76
+ text-align: center;
77
+ margin-bottom: 16px;
78
+ line-height: 134%;
79
+ color: colors.$status-red;
80
+ }
81
+
75
82
  .seam-actions {
76
83
  display: flex;
77
84
  gap: 8px;