@seamapi/react 2.4.0 → 2.5.1
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 +3759 -3725
- package/dist/elements.js.map +1 -1
- package/dist/index.css +39 -11
- 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/AccessCodeTable/AccessCodeMainIcon.d.ts +6 -0
- package/lib/seam/components/AccessCodeTable/AccessCodeMainIcon.js +27 -0
- package/lib/seam/components/AccessCodeTable/AccessCodeMainIcon.js.map +1 -0
- package/lib/seam/components/AccessCodeTable/AccessCodeRow.js +2 -2
- package/lib/seam/components/AccessCodeTable/AccessCodeRow.js.map +1 -1
- package/lib/seam/components/AccessCodeTable/CodeDetails.js +1 -1
- package/lib/seam/components/AccessCodeTable/CodeDetails.js.map +1 -1
- package/lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js +24 -18
- package/lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js +0 -5
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js.map +1 -1
- package/lib/seam/thermostats/use-cool-thermostat.d.ts +6 -0
- package/lib/seam/thermostats/use-cool-thermostat.js +50 -0
- package/lib/seam/thermostats/use-cool-thermostat.js.map +1 -0
- package/lib/seam/thermostats/use-heat-cool-thermostat.d.ts +6 -0
- package/lib/seam/thermostats/use-heat-cool-thermostat.js +45 -0
- package/lib/seam/thermostats/use-heat-cool-thermostat.js.map +1 -0
- package/lib/seam/thermostats/use-heat-thermostat.d.ts +6 -0
- package/lib/seam/thermostats/use-heat-thermostat.js +50 -0
- package/lib/seam/thermostats/use-heat-thermostat.js.map +1 -0
- package/lib/seam/thermostats/use-set-thermostat-off.d.ts +6 -0
- package/lib/seam/thermostats/use-set-thermostat-off.js +48 -0
- package/lib/seam/thermostats/use-set-thermostat-off.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +2 -2
- package/src/lib/seam/components/AccessCodeTable/AccessCodeMainIcon.tsx +65 -0
- package/src/lib/seam/components/AccessCodeTable/AccessCodeRow.tsx +10 -6
- package/src/lib/seam/components/AccessCodeTable/CodeDetails.tsx +2 -1
- package/src/lib/seam/components/DeviceDetails/ThermostatDeviceDetails.tsx +56 -44
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx +0 -16
- package/src/lib/seam/thermostats/use-cool-thermostat.ts +90 -0
- package/src/lib/seam/thermostats/use-heat-cool-thermostat.ts +83 -0
- package/src/lib/seam/thermostats/use-heat-thermostat.ts +90 -0
- package/src/lib/seam/thermostats/use-set-thermostat-off.ts +83 -0
- package/src/lib/version.ts +1 -1
- package/src/styles/_main.scss +2 -0
- package/src/styles/_seam-table.scss +18 -3
- package/src/styles/_supported-device-table.scss +0 -12
- package/src/styles/_visibility.scss +25 -0
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.d.ts +0 -8
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.js +0 -10
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.js.map +0 -1
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.tsx +0 -47
|
@@ -44,18 +44,6 @@ export function ThermostatDeviceDetails({
|
|
|
44
44
|
device_id: device.device_id,
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
-
const {
|
|
48
|
-
mutate: updateFanMode,
|
|
49
|
-
isError: isFanModeError,
|
|
50
|
-
isSuccess: isFanModeSuccess,
|
|
51
|
-
} = useUpdateFanMode()
|
|
52
|
-
|
|
53
|
-
const {
|
|
54
|
-
mutate: updateThermostat,
|
|
55
|
-
isSuccess: isThermostatUpdateSuccess,
|
|
56
|
-
isError: isThermostatUpdateError,
|
|
57
|
-
} = useUpdateThermostat()
|
|
58
|
-
|
|
59
47
|
if (climateSettingsOpen) {
|
|
60
48
|
return (
|
|
61
49
|
<NestedClimateSettingScheduleTable
|
|
@@ -123,17 +111,7 @@ export function ThermostatDeviceDetails({
|
|
|
123
111
|
temperatureUnit='fahrenheit'
|
|
124
112
|
/>
|
|
125
113
|
</DetailRow>
|
|
126
|
-
<
|
|
127
|
-
<FanModeMenu
|
|
128
|
-
mode={device.properties.fan_mode_setting}
|
|
129
|
-
onChange={(fanMode) => {
|
|
130
|
-
updateFanMode({
|
|
131
|
-
device_id: device.device_id,
|
|
132
|
-
fan_mode_setting: fanMode,
|
|
133
|
-
})
|
|
134
|
-
}}
|
|
135
|
-
/>
|
|
136
|
-
</DetailRow>
|
|
114
|
+
<FanModeRow device={device} />
|
|
137
115
|
</DetailSection>
|
|
138
116
|
|
|
139
117
|
<DetailSection
|
|
@@ -150,22 +128,8 @@ export function ThermostatDeviceDetails({
|
|
|
150
128
|
<p>{t.none}</p>
|
|
151
129
|
)}
|
|
152
130
|
</DetailRow>
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
checked={
|
|
156
|
-
device.properties.default_climate_setting
|
|
157
|
-
?.manual_override_allowed ?? true
|
|
158
|
-
}
|
|
159
|
-
onChange={(checked) => {
|
|
160
|
-
updateThermostat({
|
|
161
|
-
device_id: device.device_id,
|
|
162
|
-
default_climate_setting: {
|
|
163
|
-
manual_override_allowed: checked,
|
|
164
|
-
},
|
|
165
|
-
})
|
|
166
|
-
}}
|
|
167
|
-
/>
|
|
168
|
-
</DetailRow>
|
|
131
|
+
|
|
132
|
+
<ManualOverrideRow device={device} />
|
|
169
133
|
</DetailSection>
|
|
170
134
|
|
|
171
135
|
<DetailSection label={t.deviceDetails}>
|
|
@@ -189,25 +153,73 @@ export function ThermostatDeviceDetails({
|
|
|
189
153
|
</DetailSectionGroup>
|
|
190
154
|
</div>
|
|
191
155
|
</div>
|
|
156
|
+
</div>
|
|
157
|
+
)
|
|
158
|
+
}
|
|
192
159
|
|
|
160
|
+
function ManualOverrideRow({
|
|
161
|
+
device,
|
|
162
|
+
}: {
|
|
163
|
+
device: ThermostatDevice
|
|
164
|
+
}): JSX.Element {
|
|
165
|
+
const { mutate, isSuccess, isError } = useUpdateThermostat()
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<>
|
|
169
|
+
<DetailRow label={t.allowManualOverride}>
|
|
170
|
+
<Switch
|
|
171
|
+
checked={
|
|
172
|
+
device.properties.default_climate_setting
|
|
173
|
+
?.manual_override_allowed ?? true
|
|
174
|
+
}
|
|
175
|
+
onChange={(checked) => {
|
|
176
|
+
mutate({
|
|
177
|
+
device_id: device.device_id,
|
|
178
|
+
default_climate_setting: {
|
|
179
|
+
manual_override_allowed: checked,
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
184
|
+
</DetailRow>
|
|
193
185
|
<Snackbar
|
|
194
186
|
message={t.manualOverrideSuccess}
|
|
195
187
|
variant='success'
|
|
196
|
-
visible={
|
|
188
|
+
visible={isSuccess}
|
|
197
189
|
automaticVisibility
|
|
198
190
|
/>
|
|
199
191
|
|
|
200
192
|
<Snackbar
|
|
201
193
|
message={t.manualOverrideError}
|
|
202
194
|
variant='error'
|
|
203
|
-
visible={
|
|
195
|
+
visible={isError}
|
|
204
196
|
automaticVisibility
|
|
205
197
|
/>
|
|
198
|
+
</>
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function FanModeRow({ device }: { device: ThermostatDevice }): JSX.Element {
|
|
203
|
+
const { mutate, isSuccess, isError } = useUpdateFanMode()
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<>
|
|
207
|
+
<DetailRow label={t.fanMode}>
|
|
208
|
+
<FanModeMenu
|
|
209
|
+
mode={device.properties.fan_mode_setting}
|
|
210
|
+
onChange={(fanMode) => {
|
|
211
|
+
mutate({
|
|
212
|
+
device_id: device.device_id,
|
|
213
|
+
fan_mode_setting: fanMode,
|
|
214
|
+
})
|
|
215
|
+
}}
|
|
216
|
+
/>
|
|
217
|
+
</DetailRow>
|
|
206
218
|
|
|
207
219
|
<Snackbar
|
|
208
220
|
message={t.fanModeSuccess}
|
|
209
221
|
variant='success'
|
|
210
|
-
visible={
|
|
222
|
+
visible={isSuccess}
|
|
211
223
|
automaticVisibility
|
|
212
224
|
autoDismiss
|
|
213
225
|
/>
|
|
@@ -215,10 +227,10 @@ export function ThermostatDeviceDetails({
|
|
|
215
227
|
<Snackbar
|
|
216
228
|
message={t.fanModeError}
|
|
217
229
|
variant='error'
|
|
218
|
-
visible={
|
|
230
|
+
visible={isError}
|
|
219
231
|
automaticVisibility
|
|
220
232
|
/>
|
|
221
|
-
|
|
233
|
+
</>
|
|
222
234
|
)
|
|
223
235
|
}
|
|
224
236
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { DeviceModelV1 } from '@seamapi/types/devicedb'
|
|
2
2
|
import { useMemo } from 'react'
|
|
3
3
|
|
|
4
|
-
import { SupportedDeviceFilterResultRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.js'
|
|
5
4
|
import { SupportedDeviceManufacturerSection } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js'
|
|
6
5
|
import type { UseDeviceModelsData } from 'lib/seam/components/SupportedDeviceTable/use-device-models.js'
|
|
7
6
|
import {
|
|
@@ -80,21 +79,6 @@ export function SupportedDeviceContent({
|
|
|
80
79
|
)
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
const hasFilters = filterValue.trim() !== '' || filters.manufacturer !== null
|
|
84
|
-
|
|
85
|
-
if (hasFilters) {
|
|
86
|
-
return (
|
|
87
|
-
<div className='seam-supported-device-table-content'>
|
|
88
|
-
{deviceModels.map((deviceModel) => (
|
|
89
|
-
<SupportedDeviceFilterResultRow
|
|
90
|
-
key={deviceModel.device_model_id}
|
|
91
|
-
deviceModel={deviceModel}
|
|
92
|
-
/>
|
|
93
|
-
))}
|
|
94
|
-
</div>
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
82
|
return (
|
|
99
83
|
<>
|
|
100
84
|
{Object.entries(groupedDeviceModels)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMutation,
|
|
3
|
+
type UseMutationResult,
|
|
4
|
+
useQueryClient,
|
|
5
|
+
} from '@tanstack/react-query'
|
|
6
|
+
import type {
|
|
7
|
+
SeamError,
|
|
8
|
+
ThermostatCoolRequest,
|
|
9
|
+
ThermostatDevice,
|
|
10
|
+
ThermostatsListResponse,
|
|
11
|
+
} from 'seamapi'
|
|
12
|
+
|
|
13
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
|
+
|
|
15
|
+
// UPSTREAM: Missing ThermostatCoolResponse in seamapi.
|
|
16
|
+
type UseCoolThermostatData = Record<string, unknown>
|
|
17
|
+
type UseCoolThermostatMutationParams = ThermostatCoolRequest
|
|
18
|
+
|
|
19
|
+
export function useCoolThermostat(): UseMutationResult<
|
|
20
|
+
UseCoolThermostatData,
|
|
21
|
+
SeamError,
|
|
22
|
+
UseCoolThermostatMutationParams
|
|
23
|
+
> {
|
|
24
|
+
const { client } = useSeamClient()
|
|
25
|
+
const queryClient = useQueryClient()
|
|
26
|
+
|
|
27
|
+
return useMutation<
|
|
28
|
+
UseCoolThermostatData,
|
|
29
|
+
SeamError,
|
|
30
|
+
UseCoolThermostatMutationParams
|
|
31
|
+
>({
|
|
32
|
+
mutationFn: async (mutationParams: UseCoolThermostatMutationParams) => {
|
|
33
|
+
if (client === null) throw new NullSeamClientError()
|
|
34
|
+
|
|
35
|
+
return await client.thermostats.cool(mutationParams)
|
|
36
|
+
},
|
|
37
|
+
onSuccess: (_data, variables) => {
|
|
38
|
+
queryClient.setQueryData<ThermostatDevice | null>(
|
|
39
|
+
['devices', 'get', { device_id: variables.device_id }],
|
|
40
|
+
(thermostat) => {
|
|
41
|
+
if (thermostat == null) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return getUpdatedThermostat(thermostat, variables)
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
queryClient.setQueryData<ThermostatsListResponse['thermostats']>(
|
|
50
|
+
['devices', 'list', { device_id: variables.device_id }],
|
|
51
|
+
(thermostats): ThermostatDevice[] => {
|
|
52
|
+
if (thermostats == null) {
|
|
53
|
+
return []
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return thermostats.map((thermostat) => {
|
|
57
|
+
if (thermostat.device_id === variables.device_id) {
|
|
58
|
+
return getUpdatedThermostat(thermostat, variables)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return thermostat
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getUpdatedThermostat(
|
|
70
|
+
thermostat: ThermostatDevice,
|
|
71
|
+
variables: UseCoolThermostatMutationParams
|
|
72
|
+
): ThermostatDevice {
|
|
73
|
+
return {
|
|
74
|
+
...thermostat,
|
|
75
|
+
properties: {
|
|
76
|
+
...thermostat.properties,
|
|
77
|
+
current_climate_setting: {
|
|
78
|
+
...thermostat.properties.current_climate_setting,
|
|
79
|
+
cooling_set_point_fahrenheit:
|
|
80
|
+
variables.cooling_set_point_fahrenheit ??
|
|
81
|
+
thermostat.properties.current_climate_setting
|
|
82
|
+
.cooling_set_point_fahrenheit,
|
|
83
|
+
cooling_set_point_celsius:
|
|
84
|
+
variables.cooling_set_point_celsius ??
|
|
85
|
+
thermostat.properties.current_climate_setting
|
|
86
|
+
.cooling_set_point_celsius,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMutation,
|
|
3
|
+
type UseMutationResult,
|
|
4
|
+
useQueryClient,
|
|
5
|
+
} from '@tanstack/react-query'
|
|
6
|
+
import type {
|
|
7
|
+
SeamError,
|
|
8
|
+
ThermostatDevice,
|
|
9
|
+
ThermostatHeatCoolRequest,
|
|
10
|
+
ThermostatsListResponse,
|
|
11
|
+
} from 'seamapi'
|
|
12
|
+
|
|
13
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
|
+
|
|
15
|
+
// UPSTREAM: Missing ThermostatHeatCoolResponse in seamapi.
|
|
16
|
+
type UseHeatCoolThermostatData = Record<string, unknown>
|
|
17
|
+
type UseHeatCoolThermostatMutationParams = ThermostatHeatCoolRequest
|
|
18
|
+
|
|
19
|
+
export function useHeatCoolThermostat(): UseMutationResult<
|
|
20
|
+
UseHeatCoolThermostatData,
|
|
21
|
+
SeamError,
|
|
22
|
+
UseHeatCoolThermostatMutationParams
|
|
23
|
+
> {
|
|
24
|
+
const { client } = useSeamClient()
|
|
25
|
+
const queryClient = useQueryClient()
|
|
26
|
+
|
|
27
|
+
return useMutation<
|
|
28
|
+
UseHeatCoolThermostatData,
|
|
29
|
+
SeamError,
|
|
30
|
+
UseHeatCoolThermostatMutationParams
|
|
31
|
+
>({
|
|
32
|
+
mutationFn: async (mutationParams: UseHeatCoolThermostatMutationParams) => {
|
|
33
|
+
if (client === null) throw new NullSeamClientError()
|
|
34
|
+
|
|
35
|
+
return await client.thermostats.heatCool(mutationParams)
|
|
36
|
+
},
|
|
37
|
+
onSuccess: (_data, variables) => {
|
|
38
|
+
queryClient.setQueryData<ThermostatDevice | null>(
|
|
39
|
+
['devices', 'get', { device_id: variables.device_id }],
|
|
40
|
+
(thermostat) => {
|
|
41
|
+
if (thermostat == null) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return getUpdatedThermostat(thermostat, variables)
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
queryClient.setQueryData<ThermostatsListResponse['thermostats']>(
|
|
50
|
+
['devices', 'list', { device_id: variables.device_id }],
|
|
51
|
+
(thermostats): ThermostatDevice[] => {
|
|
52
|
+
if (thermostats == null) {
|
|
53
|
+
return []
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return thermostats.map((thermostat) => {
|
|
57
|
+
if (thermostat.device_id === variables.device_id) {
|
|
58
|
+
return getUpdatedThermostat(thermostat, variables)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return thermostat
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getUpdatedThermostat(
|
|
70
|
+
thermostat: ThermostatDevice,
|
|
71
|
+
variables: UseHeatCoolThermostatMutationParams
|
|
72
|
+
): ThermostatDevice {
|
|
73
|
+
return {
|
|
74
|
+
...thermostat,
|
|
75
|
+
properties: {
|
|
76
|
+
...thermostat.properties,
|
|
77
|
+
current_climate_setting: {
|
|
78
|
+
...thermostat.properties.current_climate_setting,
|
|
79
|
+
...variables,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMutation,
|
|
3
|
+
type UseMutationResult,
|
|
4
|
+
useQueryClient,
|
|
5
|
+
} from '@tanstack/react-query'
|
|
6
|
+
import type {
|
|
7
|
+
SeamError,
|
|
8
|
+
ThermostatDevice,
|
|
9
|
+
ThermostatHeatRequest,
|
|
10
|
+
ThermostatsListResponse,
|
|
11
|
+
} from 'seamapi'
|
|
12
|
+
|
|
13
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
|
+
|
|
15
|
+
// UPSTREAM: Missing ThermostatHeatResponse in seamapi.
|
|
16
|
+
type UseHeatThermostatData = Record<string, unknown>
|
|
17
|
+
type UseHeatThermostatMutationParams = ThermostatHeatRequest
|
|
18
|
+
|
|
19
|
+
export function useHeatThermostat(): UseMutationResult<
|
|
20
|
+
UseHeatThermostatData,
|
|
21
|
+
SeamError,
|
|
22
|
+
UseHeatThermostatMutationParams
|
|
23
|
+
> {
|
|
24
|
+
const { client } = useSeamClient()
|
|
25
|
+
const queryClient = useQueryClient()
|
|
26
|
+
|
|
27
|
+
return useMutation<
|
|
28
|
+
UseHeatThermostatData,
|
|
29
|
+
SeamError,
|
|
30
|
+
UseHeatThermostatMutationParams
|
|
31
|
+
>({
|
|
32
|
+
mutationFn: async (mutationParams: UseHeatThermostatMutationParams) => {
|
|
33
|
+
if (client === null) throw new NullSeamClientError()
|
|
34
|
+
|
|
35
|
+
return await client.thermostats.heat(mutationParams)
|
|
36
|
+
},
|
|
37
|
+
onSuccess: (_data, variables) => {
|
|
38
|
+
queryClient.setQueryData<ThermostatDevice | null>(
|
|
39
|
+
['devices', 'get', { device_id: variables.device_id }],
|
|
40
|
+
(thermostat) => {
|
|
41
|
+
if (thermostat == null) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return getUpdatedThermostat(thermostat, variables)
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
queryClient.setQueryData<ThermostatsListResponse['thermostats']>(
|
|
50
|
+
['devices', 'list', { device_id: variables.device_id }],
|
|
51
|
+
(thermostats): ThermostatDevice[] => {
|
|
52
|
+
if (thermostats == null) {
|
|
53
|
+
return []
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return thermostats.map((thermostat) => {
|
|
57
|
+
if (thermostat.device_id === variables.device_id) {
|
|
58
|
+
return getUpdatedThermostat(thermostat, variables)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return thermostat
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getUpdatedThermostat(
|
|
70
|
+
thermostat: ThermostatDevice,
|
|
71
|
+
variables: UseHeatThermostatMutationParams
|
|
72
|
+
): ThermostatDevice {
|
|
73
|
+
return {
|
|
74
|
+
...thermostat,
|
|
75
|
+
properties: {
|
|
76
|
+
...thermostat.properties,
|
|
77
|
+
current_climate_setting: {
|
|
78
|
+
...thermostat.properties.current_climate_setting,
|
|
79
|
+
heating_set_point_fahrenheit:
|
|
80
|
+
variables.heating_set_point_fahrenheit ??
|
|
81
|
+
thermostat.properties.current_climate_setting
|
|
82
|
+
.heating_set_point_fahrenheit,
|
|
83
|
+
heating_set_point_celsius:
|
|
84
|
+
variables.heating_set_point_celsius ??
|
|
85
|
+
thermostat.properties.current_climate_setting
|
|
86
|
+
.heating_set_point_celsius,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMutation,
|
|
3
|
+
type UseMutationResult,
|
|
4
|
+
useQueryClient,
|
|
5
|
+
} from '@tanstack/react-query'
|
|
6
|
+
import type {
|
|
7
|
+
SeamError,
|
|
8
|
+
ThermostatDevice,
|
|
9
|
+
ThermostatOffRequest,
|
|
10
|
+
ThermostatsListResponse,
|
|
11
|
+
} from 'seamapi'
|
|
12
|
+
|
|
13
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
|
+
|
|
15
|
+
// UPSTREAM: Missing ThermostatOffResponse in seamapi.
|
|
16
|
+
type UseSetThermostatOffData = Record<string, unknown>
|
|
17
|
+
type UseSetThermostatOffMutationParams = ThermostatOffRequest
|
|
18
|
+
|
|
19
|
+
export function useSetThermostatOff(): UseMutationResult<
|
|
20
|
+
UseSetThermostatOffData,
|
|
21
|
+
SeamError,
|
|
22
|
+
UseSetThermostatOffMutationParams
|
|
23
|
+
> {
|
|
24
|
+
const { client } = useSeamClient()
|
|
25
|
+
const queryClient = useQueryClient()
|
|
26
|
+
|
|
27
|
+
return useMutation<
|
|
28
|
+
UseSetThermostatOffData,
|
|
29
|
+
SeamError,
|
|
30
|
+
UseSetThermostatOffMutationParams
|
|
31
|
+
>({
|
|
32
|
+
mutationFn: async (mutationParams: UseSetThermostatOffMutationParams) => {
|
|
33
|
+
if (client === null) throw new NullSeamClientError()
|
|
34
|
+
|
|
35
|
+
return await client.thermostats.off(mutationParams)
|
|
36
|
+
},
|
|
37
|
+
onSuccess: (_data, variables) => {
|
|
38
|
+
queryClient.setQueryData<ThermostatDevice | null>(
|
|
39
|
+
['devices', 'get', { device_id: variables.device_id }],
|
|
40
|
+
(thermostat) => {
|
|
41
|
+
if (thermostat == null) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return getUpdatedThermostat(thermostat)
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
queryClient.setQueryData<ThermostatsListResponse['thermostats']>(
|
|
50
|
+
['devices', 'list', { device_id: variables.device_id }],
|
|
51
|
+
(thermostats): ThermostatDevice[] => {
|
|
52
|
+
if (thermostats == null) {
|
|
53
|
+
return []
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return thermostats.map((thermostat) => {
|
|
57
|
+
if (thermostat.device_id === variables.device_id) {
|
|
58
|
+
return getUpdatedThermostat(thermostat)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return thermostat
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getUpdatedThermostat(thermostat: ThermostatDevice): ThermostatDevice {
|
|
70
|
+
return {
|
|
71
|
+
...thermostat,
|
|
72
|
+
properties: {
|
|
73
|
+
...thermostat.properties,
|
|
74
|
+
is_fan_running: false,
|
|
75
|
+
current_climate_setting: {
|
|
76
|
+
...thermostat.properties.current_climate_setting,
|
|
77
|
+
automatic_cooling_enabled: false,
|
|
78
|
+
automatic_heating_enabled: false,
|
|
79
|
+
hvac_mode_setting: 'off',
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
}
|
package/src/lib/version.ts
CHANGED
package/src/styles/_main.scss
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
@use './alert';
|
|
6
6
|
@use './buttons';
|
|
7
7
|
@use './layout';
|
|
8
|
+
@use './visibility';
|
|
8
9
|
@use './loading_toast';
|
|
9
10
|
@use './colors';
|
|
10
11
|
@use './icons';
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
@include form-field.all;
|
|
42
43
|
@include buttons.all;
|
|
43
44
|
@include layout.all;
|
|
45
|
+
@include visibility.all;
|
|
44
46
|
@include loading_toast.all;
|
|
45
47
|
@include icons.all;
|
|
46
48
|
@include menus.all;
|
|
@@ -27,11 +27,17 @@
|
|
|
27
27
|
justify-content: center;
|
|
28
28
|
|
|
29
29
|
> div {
|
|
30
|
-
width:
|
|
30
|
+
width: 32px;
|
|
31
31
|
height: 40px;
|
|
32
32
|
display: flex;
|
|
33
33
|
align-items: center;
|
|
34
34
|
justify-content: center;
|
|
35
|
+
margin-right: 4px;
|
|
36
|
+
|
|
37
|
+
@media only screen and (width >= 768px) {
|
|
38
|
+
width: 40px;
|
|
39
|
+
margin-right: 4px;
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -48,10 +54,15 @@
|
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
.seam-details {
|
|
51
|
-
font-size:
|
|
57
|
+
font-size: 12px;
|
|
52
58
|
line-height: 134%;
|
|
53
59
|
color: colors.$text-gray-1;
|
|
54
60
|
display: flex;
|
|
61
|
+
flex-wrap: wrap;
|
|
62
|
+
|
|
63
|
+
@media only screen and (width >= 768px) {
|
|
64
|
+
font-size: 14px;
|
|
65
|
+
}
|
|
55
66
|
|
|
56
67
|
.seam-device-name {
|
|
57
68
|
max-width: 190px;
|
|
@@ -66,10 +77,14 @@
|
|
|
66
77
|
}
|
|
67
78
|
|
|
68
79
|
.seam-action-cell {
|
|
69
|
-
margin-right:
|
|
80
|
+
margin-right: 8px;
|
|
70
81
|
display: flex;
|
|
71
82
|
align-items: center;
|
|
72
83
|
justify-content: center;
|
|
84
|
+
|
|
85
|
+
@media only screen and (width >= 768px) {
|
|
86
|
+
margin-right: 12px;
|
|
87
|
+
}
|
|
73
88
|
}
|
|
74
89
|
|
|
75
90
|
.seam-issue-icon-wrap {
|
|
@@ -248,18 +248,6 @@ $row-padding: 8px;
|
|
|
248
248
|
display: flex;
|
|
249
249
|
padding: 8px;
|
|
250
250
|
}
|
|
251
|
-
|
|
252
|
-
&.filter-result-row {
|
|
253
|
-
.seam-model-name {
|
|
254
|
-
display: flex;
|
|
255
|
-
align-items: center;
|
|
256
|
-
|
|
257
|
-
.seam-manufacturer-image {
|
|
258
|
-
width: 32px;
|
|
259
|
-
margin-right: 4px;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
251
|
}
|
|
264
252
|
|
|
265
253
|
.seam-status-pill {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
@use './colors';
|
|
2
|
+
|
|
3
|
+
@mixin all {
|
|
4
|
+
.seam-invisible {
|
|
5
|
+
display: none !important;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.seam-md-flex {
|
|
9
|
+
@media only screen and (width >= 768px) {
|
|
10
|
+
display: flex !important;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.seam-md-block {
|
|
15
|
+
@media only screen and (width >= 768px) {
|
|
16
|
+
display: block !important;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.seam-md-invisible {
|
|
21
|
+
@media only screen and (width >= 768px) {
|
|
22
|
+
display: none !important;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
-
import type { DeviceModelV1 } from '@seamapi/types/devicedb';
|
|
3
|
-
interface SupportedDeviceFilterResultRowProps {
|
|
4
|
-
deviceModel: DeviceModelV1;
|
|
5
|
-
}
|
|
6
|
-
export declare function SupportedDeviceFilterResultRow({ deviceModel, }: SupportedDeviceFilterResultRowProps): JSX.Element;
|
|
7
|
-
export declare function ModelColumn({ deviceModel, }: SupportedDeviceFilterResultRowProps): JSX.Element;
|
|
8
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ImageColumn, StatusColumn, } from '../../../../lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js';
|
|
3
|
-
import { DotDivider } from '../../../../lib/ui/layout/DotDivider.js';
|
|
4
|
-
export function SupportedDeviceFilterResultRow({ deviceModel, }) {
|
|
5
|
-
return (_jsxs("div", { className: 'seam-row filter-result-row', children: [_jsx(ImageColumn, { deviceModel: deviceModel }), _jsx(ModelColumn, { deviceModel: deviceModel }), _jsx(StatusColumn, { deviceModel: deviceModel })] }));
|
|
6
|
-
}
|
|
7
|
-
export function ModelColumn({ deviceModel, }) {
|
|
8
|
-
return (_jsxs("div", { className: 'seam-col seam-model-col', children: [_jsxs("div", { className: 'seam-model-name', children: [_jsx("img", { src: deviceModel.manufacturer.logo?.url, alt: deviceModel.manufacturer.display_name, className: 'seam-manufacturer-image' }), ' ', _jsx("div", { className: 'seam-truncated-text', children: deviceModel.display_name })] }), _jsx("div", { className: 'seam-model-id', children: _jsxs("div", { className: 'seam-truncated-text', children: [deviceModel.device_model_id, _jsx(DotDivider, {}), deviceModel.main_connection_type] }) })] }));
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=SupportedDeviceFilterResultRow.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SupportedDeviceFilterResultRow.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.tsx"],"names":[],"mappings":";AAEA,OAAO,EACL,WAAW,EACX,YAAY,GACb,MAAM,gEAAgE,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAMxD,MAAM,UAAU,8BAA8B,CAAC,EAC7C,WAAW,GACyB;IACpC,OAAO,CACL,eAAK,SAAS,EAAC,4BAA4B,aACzC,KAAC,WAAW,IAAC,WAAW,EAAE,WAAW,GAAI,EACzC,KAAC,WAAW,IAAC,WAAW,EAAE,WAAW,GAAI,EACzC,KAAC,YAAY,IAAC,WAAW,EAAE,WAAW,GAAI,IACtC,CACP,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,WAAW,GACyB;IACpC,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAK,SAAS,EAAC,iBAAiB,aAC9B,cACE,GAAG,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,EACvC,GAAG,EAAE,WAAW,CAAC,YAAY,CAAC,YAAY,EAC1C,SAAS,EAAC,yBAAyB,GACnC,EAAC,GAAG,EACN,cAAK,SAAS,EAAC,qBAAqB,YAAE,WAAW,CAAC,YAAY,GAAO,IACjE,EACN,cAAK,SAAS,EAAC,eAAe,YAC5B,eAAK,SAAS,EAAC,qBAAqB,aACjC,WAAW,CAAC,eAAe,EAC5B,KAAC,UAAU,KAAG,EACb,WAAW,CAAC,oBAAoB,IAC7B,GACF,IACF,CACP,CAAA;AACH,CAAC"}
|