@seamapi/react 2.0.1 → 2.1.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 +1 -1
- package/dist/elements.js +2580 -2532
- package/dist/elements.js.map +1 -1
- package/dist/index.css +40 -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/SupportedDeviceTable/SupportedDeviceFilterArea.js +10 -2
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js +2 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.d.ts +6 -0
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js +21 -0
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js.map +1 -0
- package/lib/seam/components/index.d.ts +1 -0
- package/lib/seam/components/index.js +1 -0
- package/lib/seam/components/index.js.map +1 -1
- package/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.d.ts +6 -1
- package/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js +12 -1
- package/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js.map +1 -1
- package/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.d.ts +15 -0
- package/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js +42 -0
- package/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js.map +1 -0
- package/lib/ui/thermostat/ClimateSettingControlGroup.d.ts +9 -0
- package/lib/ui/thermostat/ClimateSettingControlGroup.js +8 -0
- package/lib/ui/thermostat/ClimateSettingControlGroup.js.map +1 -0
- package/lib/ui/thermostat/TemperatureControlGroup.d.ts +1 -2
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx +12 -6
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx +3 -2
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts +9 -0
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx +65 -0
- package/src/lib/seam/components/elements.ts +1 -0
- package/src/lib/seam/components/index.ts +1 -0
- package/src/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.tsx +30 -2
- package/src/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.tsx +149 -0
- package/src/lib/ui/thermostat/ClimateSettingControlGroup.tsx +32 -0
- package/src/lib/ui/thermostat/TemperatureControlGroup.tsx +1 -1
- package/src/lib/version.ts +1 -1
- package/src/styles/_climate-setting-schedule-form.scss +24 -0
- package/src/styles/_main.scss +2 -0
- package/src/styles/_supported-device-table-manufacturer-keys.scss +19 -0
- package/src/styles/_thermostat.scss +15 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { useComponentTelemetry } from '../../../../lib/telemetry/index.js';
|
|
4
|
+
import { CopyIcon } from '../../../../lib/icons/Copy.js';
|
|
5
|
+
import { withRequiredCommonProps, } from '../../../../lib/seam/components/common-props.js';
|
|
6
|
+
import { copyToClipboard } from '../../../../lib/ui/clipboard.js';
|
|
7
|
+
import { MenuItem } from '../../../../lib/ui/Menu/MenuItem.js';
|
|
8
|
+
import { useManufacturers } from './use-manufacturers.js';
|
|
9
|
+
export const NestedSupportedDeviceTableManufacturerKeys = withRequiredCommonProps(SupportedDeviceTableManufacturerKeys);
|
|
10
|
+
export function SupportedDeviceTableManufacturerKeys({ className, } = {}) {
|
|
11
|
+
useComponentTelemetry('SupportedDeviceTableManufacturerKeys');
|
|
12
|
+
const { manufacturers } = useManufacturers();
|
|
13
|
+
return (_jsx("div", { className: classNames('supported-device-table-manufacturer-keys', className), children: manufacturers?.map((manufacturer) => (_jsx(ManufacturerKey, { manufacturer: manufacturer }, manufacturer.manufacturer_id))) }));
|
|
14
|
+
}
|
|
15
|
+
function ManufacturerKey({ manufacturer, }) {
|
|
16
|
+
const key = manufacturer.display_name;
|
|
17
|
+
return (_jsxs("div", { className: 'seam-manufacturer-key', children: [_jsx("div", { className: 'seam-manufacturer-key-value', children: key }), _jsx(MenuItem, { className: 'seam-copy-button', onClick: () => {
|
|
18
|
+
void copyToClipboard(key);
|
|
19
|
+
}, children: _jsx(CopyIcon, {}) })] }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=SupportedDeviceTableManufacturerKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SupportedDeviceTableManufacturerKeys.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx"],"names":[],"mappings":";AACA,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAEL,uBAAuB,GACxB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAKzD,MAAM,CAAC,MAAM,0CAA0C,GACrD,uBAAuB,CAAC,oCAAoC,CAAC,CAAA;AAE/D,MAAM,UAAU,oCAAoC,CAAC,EACnD,SAAS,MACoC,EAAE;IAC/C,qBAAqB,CAAC,sCAAsC,CAAC,CAAA;IAE7D,MAAM,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE,CAAA;IAE5C,OAAO,CACL,cACE,SAAS,EAAE,UAAU,CACnB,0CAA0C,EAC1C,SAAS,CACV,YAEA,aAAa,EAAE,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CACpC,KAAC,eAAe,IAEd,YAAY,EAAE,YAAY,IADrB,YAAY,CAAC,eAAe,CAEjC,CACH,CAAC,GACE,CACP,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EACvB,YAAY,GAGb;IACC,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAA;IACrC,OAAO,CACL,eAAK,SAAS,EAAC,uBAAuB,aACpC,cAAK,SAAS,EAAC,6BAA6B,YAAE,GAAG,GAAO,EACxD,KAAC,QAAQ,IACP,SAAS,EAAC,kBAAkB,EAC5B,OAAO,EAAE,GAAG,EAAE;oBACZ,KAAK,eAAe,CAAC,GAAG,CAAC,CAAA;gBAC3B,CAAC,YAED,KAAC,QAAQ,KAAG,GACH,IACP,CACP,CAAA;AACH,CAAC"}
|
|
@@ -9,3 +9,4 @@ export * from './DeviceDetails/DeviceDetails.js';
|
|
|
9
9
|
export * from './DeviceTable/DeviceTable.js';
|
|
10
10
|
export * from './EditAccessCodeForm/EditAccessCodeForm.js';
|
|
11
11
|
export * from './SupportedDeviceTable/SupportedDeviceTable.js';
|
|
12
|
+
export * from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js';
|
|
@@ -9,4 +9,5 @@ export * from './DeviceDetails/DeviceDetails.js';
|
|
|
9
9
|
export * from './DeviceTable/DeviceTable.js';
|
|
10
10
|
export * from './EditAccessCodeForm/EditAccessCodeForm.js';
|
|
11
11
|
export * from './SupportedDeviceTable/SupportedDeviceTable.js';
|
|
12
|
+
export * from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js';
|
|
12
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/seam/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,0CAA0C,CAAA;AACxD,cAAc,sCAAsC,CAAA;AACpD,cAAc,kEAAkE,CAAA;AAChF,cAAc,8DAA8D,CAAA;AAC5E,cAAc,mBAAmB,CAAA;AACjC,cAAc,gDAAgD,CAAA;AAC9D,cAAc,gDAAgD,CAAA;AAC9D,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,4CAA4C,CAAA;AAC1D,cAAc,gDAAgD,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/seam/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,0CAA0C,CAAA;AACxD,cAAc,sCAAsC,CAAA;AACpD,cAAc,kEAAkE,CAAA;AAChF,cAAc,8DAA8D,CAAA;AAC5E,cAAc,mBAAmB,CAAA;AACjC,cAAc,gDAAgD,CAAA;AAC9D,cAAc,gDAAgD,CAAA;AAC9D,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,4CAA4C,CAAA;AAC1D,cAAc,gDAAgD,CAAA;AAC9D,cAAc,gEAAgE,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
-
import type { ClimateSetting } from 'seamapi';
|
|
2
|
+
import type { ClimateSetting, HvacModeSetting } from 'seamapi';
|
|
3
3
|
export interface ClimateSettingScheduleFormSubmitData {
|
|
4
4
|
name: string;
|
|
5
5
|
deviceId: string;
|
|
@@ -20,6 +20,11 @@ export interface ClimateSettingScheduleFormFields {
|
|
|
20
20
|
startDate: string;
|
|
21
21
|
endDate: string;
|
|
22
22
|
timeZone: string;
|
|
23
|
+
hvacModeSetting: HvacModeSetting;
|
|
24
|
+
setPoints: {
|
|
25
|
+
heatingSetPoint: number;
|
|
26
|
+
coolingSetPoint: number;
|
|
27
|
+
};
|
|
23
28
|
}
|
|
24
29
|
export declare function ClimateSettingScheduleForm({ className, ...props }: ClimateSettingScheduleFormProps): JSX.Element | null;
|
|
25
30
|
export declare const t: {
|
|
@@ -3,6 +3,7 @@ import classNames from 'classnames';
|
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { useForm } from 'react-hook-form';
|
|
5
5
|
import { getSystemTimeZone } from '../../../lib/dates.js';
|
|
6
|
+
import { ClimateSettingScheduleFormClimateSetting } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js';
|
|
6
7
|
import { ClimateSettingScheduleFormDeviceSelect } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormDeviceSelect.js';
|
|
7
8
|
import { ClimateSettingScheduleFormNameAndSchedule } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormNameAndSchedule.js';
|
|
8
9
|
import { ClimateSettingScheduleFormTimeZonePicker } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormTimeZonePicker.js';
|
|
@@ -10,13 +11,18 @@ export function ClimateSettingScheduleForm({ className, ...props }) {
|
|
|
10
11
|
return (_jsx("div", { className: classNames('seam-climate-setting-schedule-form', className), children: _jsx(Content, { ...props }) }));
|
|
11
12
|
}
|
|
12
13
|
function Content({ onBack, }) {
|
|
13
|
-
const { control, watch } = useForm({
|
|
14
|
+
const { control, watch, resetField } = useForm({
|
|
14
15
|
defaultValues: {
|
|
15
16
|
deviceId: '',
|
|
16
17
|
name: '',
|
|
17
18
|
startDate: '',
|
|
18
19
|
endDate: '',
|
|
19
20
|
timeZone: getSystemTimeZone(),
|
|
21
|
+
hvacModeSetting: 'heat_cool',
|
|
22
|
+
setPoints: {
|
|
23
|
+
heatingSetPoint: 70,
|
|
24
|
+
coolingSetPoint: 75,
|
|
25
|
+
},
|
|
20
26
|
},
|
|
21
27
|
});
|
|
22
28
|
const deviceId = watch('deviceId');
|
|
@@ -41,6 +47,11 @@ function Content({ onBack, }) {
|
|
|
41
47
|
setPage('name_and_schedule');
|
|
42
48
|
} }));
|
|
43
49
|
}
|
|
50
|
+
if (page === 'climate_setting') {
|
|
51
|
+
return (_jsx(ClimateSettingScheduleFormClimateSetting, { title: t.addNewClimateSettingSchedule, control: control, watch: watch, resetField: resetField, deviceId: deviceId, onBack: () => {
|
|
52
|
+
setPage('name_and_schedule');
|
|
53
|
+
}, onCancel: onBack, onSave: () => { } }));
|
|
54
|
+
}
|
|
44
55
|
return _jsx(_Fragment, {});
|
|
45
56
|
}
|
|
46
57
|
export const t = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClimateSettingScheduleForm.js","sourceRoot":"","sources":["../../../src/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,sCAAsC,EAAE,MAAM,qEAAqE,CAAA;AAC5H,OAAO,EAAE,yCAAyC,EAAE,MAAM,wEAAwE,CAAA;AAClI,OAAO,EAAE,wCAAwC,EAAE,MAAM,uEAAuE,CAAA;
|
|
1
|
+
{"version":3,"file":"ClimateSettingScheduleForm.js","sourceRoot":"","sources":["../../../src/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import { type Control, type UseFormResetField, type UseFormWatch } from 'react-hook-form';
|
|
3
|
+
import type { ClimateSettingScheduleFormFields } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js';
|
|
4
|
+
interface ClimateSettingScheduleFormClimateSettingProps {
|
|
5
|
+
title: string;
|
|
6
|
+
control: Control<ClimateSettingScheduleFormFields>;
|
|
7
|
+
watch: UseFormWatch<ClimateSettingScheduleFormFields>;
|
|
8
|
+
resetField: UseFormResetField<ClimateSettingScheduleFormFields>;
|
|
9
|
+
deviceId: string;
|
|
10
|
+
onBack: () => void;
|
|
11
|
+
onCancel: (() => void) | undefined;
|
|
12
|
+
onSave: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function ClimateSettingScheduleFormClimateSetting({ title, control, watch, resetField, deviceId, onBack, onCancel, onSave, }: ClimateSettingScheduleFormClimateSettingProps): JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Controller, } from 'react-hook-form';
|
|
3
|
+
import { useDevice } from '../../../lib/seam/devices/use-device.js';
|
|
4
|
+
import { Button } from '../../../lib/ui/Button.js';
|
|
5
|
+
import { FormField } from '../../../lib/ui/FormField.js';
|
|
6
|
+
import { InputLabel } from '../../../lib/ui/InputLabel.js';
|
|
7
|
+
import { ContentHeader } from '../../../lib/ui/layout/ContentHeader.js';
|
|
8
|
+
import { ClimateModeMenu } from '../../../lib/ui/thermostat/ClimateModeMenu.js';
|
|
9
|
+
import { TemperatureControlGroup } from '../../../lib/ui/thermostat/TemperatureControlGroup.js';
|
|
10
|
+
export function ClimateSettingScheduleFormClimateSetting({ title, control, watch, resetField, deviceId, onBack, onCancel, onSave, }) {
|
|
11
|
+
const { device } = useDevice({
|
|
12
|
+
device_id: deviceId,
|
|
13
|
+
});
|
|
14
|
+
const hvacModeSetting = watch('hvacModeSetting');
|
|
15
|
+
return (_jsxs(_Fragment, { children: [_jsx(ContentHeader, { title: title, onBack: onBack, subheading: device?.properties.name }), _jsxs("div", { className: 'seam-main', children: [_jsx("div", { className: 'seam-climate-setting-schedule-form-climate-setting', children: _jsxs("div", { className: 'seam-content', children: [_jsxs("div", { children: [_jsx(InputLabel, { children: t.climateSetting }), _jsx("span", { className: 'seam-label', children: t.climateSettingSubHeading })] }), _jsx(FormContent, { control: control, resetField: resetField, hvacModeSetting: hvacModeSetting })] }) }), _jsxs("div", { className: 'seam-actions', children: [_jsx(Button, { onClick: onCancel, children: t.cancel }), _jsx(Button, { variant: 'solid', onClick: onSave, children: t.save })] })] })] }));
|
|
16
|
+
}
|
|
17
|
+
function FormContent({ control, resetField, hvacModeSetting, }) {
|
|
18
|
+
return (_jsxs(_Fragment, { children: [_jsx(FormField, { children: _jsx(Controller, { name: 'hvacModeSetting', control: control, render: ({ field: { value, onChange } }) => {
|
|
19
|
+
return (_jsx(ClimateModeMenu, { mode: value, onChange: (mode) => {
|
|
20
|
+
resetField('setPoints');
|
|
21
|
+
onChange(mode);
|
|
22
|
+
} }));
|
|
23
|
+
} }) }), hvacModeSetting !== 'off' && (_jsx(FormField, { className: 'seam-climate-setting-slider-container', children: _jsx(Controller, { name: 'setPoints', control: control, render: ({ field: { value, onChange } }) => (_jsx(TemperatureControlGroup, { coolValue: value.coolingSetPoint, heatValue: value.heatingSetPoint, delta: 5, maxCool: 90, maxHeat: 100, minCool: 50, minHeat: 70, mode: hvacModeSetting, onCoolValueChange: (coolingSetPoint) => {
|
|
24
|
+
onChange({
|
|
25
|
+
...value,
|
|
26
|
+
coolingSetPoint,
|
|
27
|
+
});
|
|
28
|
+
}, onHeatValueChange: (heatingSetPoint) => {
|
|
29
|
+
onChange({
|
|
30
|
+
...value,
|
|
31
|
+
heatingSetPoint,
|
|
32
|
+
});
|
|
33
|
+
} })) }) }))] }));
|
|
34
|
+
}
|
|
35
|
+
const t = {
|
|
36
|
+
climateSetting: 'Climate setting',
|
|
37
|
+
climateSettingSubHeading: 'Choose mode and adjust the climate',
|
|
38
|
+
cancel: 'Cancel',
|
|
39
|
+
save: 'Save',
|
|
40
|
+
next: 'Next',
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=ClimateSettingScheduleFormClimateSetting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClimateSettingScheduleFormClimateSetting.js","sourceRoot":"","sources":["../../../src/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import type { HvacModeSetting } from 'seamapi';
|
|
3
|
+
import { type TemperatureControlGroupProps } from '../../../lib/ui/thermostat/TemperatureControlGroup.js';
|
|
4
|
+
type ClimateSettingControlGroupProps = Omit<TemperatureControlGroupProps, 'mode'> & {
|
|
5
|
+
mode: HvacModeSetting;
|
|
6
|
+
onModeChange: (mode: HvacModeSetting) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function ClimateSettingControlGroup(props: ClimateSettingControlGroupProps): JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ClimateModeMenu } from '../../../lib/ui/thermostat/ClimateModeMenu.js';
|
|
3
|
+
import { TemperatureControlGroup, } from '../../../lib/ui/thermostat/TemperatureControlGroup.js';
|
|
4
|
+
export function ClimateSettingControlGroup(props) {
|
|
5
|
+
const { mode, onModeChange, ...rest } = props;
|
|
6
|
+
return (_jsxs("div", { className: 'seam-climate-setting-control-group', children: [_jsx(ClimateModeMenu, { mode: mode, onChange: onModeChange }), mode !== 'off' && (_jsx("div", { className: 'seam-climate-setting-slider-container', children: _jsx(TemperatureControlGroup, { mode: mode, ...rest }) }))] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ClimateSettingControlGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClimateSettingControlGroup.js","sourceRoot":"","sources":["../../../src/lib/ui/thermostat/ClimateSettingControlGroup.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAA;AACtE,OAAO,EACL,uBAAuB,GAExB,MAAM,8CAA8C,CAAA;AAUrD,MAAM,UAAU,0BAA0B,CACxC,KAAsC;IAEtC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;IAC7C,OAAO,CACL,eAAK,SAAS,EAAC,oCAAoC,aACjD,KAAC,eAAe,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,GAAI,EAEtD,IAAI,KAAK,KAAK,IAAI,CACjB,cAAK,SAAS,EAAC,uCAAuC,YACpD,KAAC,uBAAuB,IAAC,IAAI,EAAE,IAAI,KAAM,IAAI,GAAI,GAC7C,CACP,IACG,CACP,CAAA;AACH,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" resolution-mode="require"/>
|
|
2
2
|
import type { HvacModeSetting } from 'seamapi';
|
|
3
|
-
interface TemperatureControlGroupProps {
|
|
3
|
+
export interface TemperatureControlGroupProps {
|
|
4
4
|
mode: Exclude<HvacModeSetting, 'off'>;
|
|
5
5
|
heatValue: number;
|
|
6
6
|
onHeatValueChange: (temperature: number) => void;
|
|
@@ -13,4 +13,3 @@ interface TemperatureControlGroupProps {
|
|
|
13
13
|
maxCool: number;
|
|
14
14
|
}
|
|
15
15
|
export declare function TemperatureControlGroup({ mode, heatValue, onHeatValueChange, coolValue, onCoolValueChange, delta, minHeat, maxHeat, minCool, maxCool, }: TemperatureControlGroupProps): JSX.Element;
|
|
16
|
-
export {};
|
package/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const seamapiReactVersion = "2.0
|
|
1
|
+
declare const seamapiReactVersion = "2.1.0";
|
|
2
2
|
export default seamapiReactVersion;
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@ export function SupportedDeviceFilterArea({
|
|
|
27
27
|
}: SupportedDeviceFilterAreaProps): JSX.Element {
|
|
28
28
|
const appliedFiltersCount = getAppliedFilterCount(filters)
|
|
29
29
|
|
|
30
|
-
const { manufacturers:
|
|
30
|
+
const { manufacturers: manufacturersData } = useFilteredManufacturers({
|
|
31
31
|
manufacturers,
|
|
32
32
|
excludedManufacturers,
|
|
33
33
|
})
|
|
@@ -44,6 +44,16 @@ export function SupportedDeviceFilterArea({
|
|
|
44
44
|
|
|
45
45
|
const allLabel = t.all
|
|
46
46
|
|
|
47
|
+
const options =
|
|
48
|
+
manufacturersData
|
|
49
|
+
?.filter((manufacturer) => {
|
|
50
|
+
if (filters.supportedOnly) {
|
|
51
|
+
return ['stable', 'beta'].includes(manufacturer.integration)
|
|
52
|
+
}
|
|
53
|
+
return true
|
|
54
|
+
})
|
|
55
|
+
?.map((manufacturer) => manufacturer.display_name) ?? []
|
|
56
|
+
|
|
47
57
|
return (
|
|
48
58
|
<div className='seam-supported-device-table-filter-area'>
|
|
49
59
|
<div className='seam-deliberate-block' />
|
|
@@ -69,11 +79,7 @@ export function SupportedDeviceFilterArea({
|
|
|
69
79
|
<FilterCategoryMenu
|
|
70
80
|
label={t.manufacturer}
|
|
71
81
|
allLabel={allLabel}
|
|
72
|
-
options={
|
|
73
|
-
availableManufacturers?.map(
|
|
74
|
-
(manufacturer) => manufacturer.display_name
|
|
75
|
-
) ?? []
|
|
76
|
-
}
|
|
82
|
+
options={options}
|
|
77
83
|
onSelect={(manufacturer: string) => {
|
|
78
84
|
setFilters((filters) => ({
|
|
79
85
|
...filters,
|
|
@@ -38,6 +38,7 @@ export function ImageColumn({
|
|
|
38
38
|
export function ModelColumn({
|
|
39
39
|
deviceModel,
|
|
40
40
|
}: SupportedDeviceRowProps): JSX.Element {
|
|
41
|
+
const sku = deviceModel.aesthetic_variants[0]?.manufacturer_sku
|
|
41
42
|
return (
|
|
42
43
|
<div className='seam-col seam-model-col'>
|
|
43
44
|
<div className='seam-model-name'>
|
|
@@ -45,8 +46,8 @@ export function ModelColumn({
|
|
|
45
46
|
</div>
|
|
46
47
|
<div className='seam-model-id'>
|
|
47
48
|
<div className='seam-truncated-text'>
|
|
48
|
-
{
|
|
49
|
-
<DotDivider />
|
|
49
|
+
{sku}
|
|
50
|
+
{sku != null && <DotDivider />}
|
|
50
51
|
{deviceModel.main_connection_type}
|
|
51
52
|
</div>
|
|
52
53
|
</div>
|
package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ElementProps } from 'lib/element.js'
|
|
2
|
+
|
|
3
|
+
import type { SupportedDeviceTableManufacturerKeysProps } from './SupportedDeviceTableManufacturerKeys.js'
|
|
4
|
+
|
|
5
|
+
export const name = 'seam-supported-device-table-manufacturer-keys'
|
|
6
|
+
|
|
7
|
+
export const props: ElementProps<SupportedDeviceTableManufacturerKeysProps> = {}
|
|
8
|
+
|
|
9
|
+
export { SupportedDeviceTableManufacturerKeys as Component } from './SupportedDeviceTableManufacturerKeys.js'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Manufacturer } from '@seamapi/types/devicedb'
|
|
2
|
+
import classNames from 'classnames'
|
|
3
|
+
|
|
4
|
+
import { useComponentTelemetry } from 'lib/telemetry/index.js'
|
|
5
|
+
|
|
6
|
+
import { CopyIcon } from 'lib/icons/Copy.js'
|
|
7
|
+
import {
|
|
8
|
+
type CommonProps,
|
|
9
|
+
withRequiredCommonProps,
|
|
10
|
+
} from 'lib/seam/components/common-props.js'
|
|
11
|
+
import { copyToClipboard } from 'lib/ui/clipboard.js'
|
|
12
|
+
import { MenuItem } from 'lib/ui/Menu/MenuItem.js'
|
|
13
|
+
|
|
14
|
+
import { useManufacturers } from './use-manufacturers.js'
|
|
15
|
+
|
|
16
|
+
export interface SupportedDeviceTableManufacturerKeysProps
|
|
17
|
+
extends CommonProps {}
|
|
18
|
+
|
|
19
|
+
export const NestedSupportedDeviceTableManufacturerKeys =
|
|
20
|
+
withRequiredCommonProps(SupportedDeviceTableManufacturerKeys)
|
|
21
|
+
|
|
22
|
+
export function SupportedDeviceTableManufacturerKeys({
|
|
23
|
+
className,
|
|
24
|
+
}: SupportedDeviceTableManufacturerKeysProps = {}): JSX.Element {
|
|
25
|
+
useComponentTelemetry('SupportedDeviceTableManufacturerKeys')
|
|
26
|
+
|
|
27
|
+
const { manufacturers } = useManufacturers()
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div
|
|
31
|
+
className={classNames(
|
|
32
|
+
'supported-device-table-manufacturer-keys',
|
|
33
|
+
className
|
|
34
|
+
)}
|
|
35
|
+
>
|
|
36
|
+
{manufacturers?.map((manufacturer) => (
|
|
37
|
+
<ManufacturerKey
|
|
38
|
+
key={manufacturer.manufacturer_id}
|
|
39
|
+
manufacturer={manufacturer}
|
|
40
|
+
/>
|
|
41
|
+
))}
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function ManufacturerKey({
|
|
47
|
+
manufacturer,
|
|
48
|
+
}: {
|
|
49
|
+
manufacturer: Manufacturer
|
|
50
|
+
}): JSX.Element {
|
|
51
|
+
const key = manufacturer.display_name
|
|
52
|
+
return (
|
|
53
|
+
<div className='seam-manufacturer-key'>
|
|
54
|
+
<div className='seam-manufacturer-key-value'>{key}</div>
|
|
55
|
+
<MenuItem
|
|
56
|
+
className='seam-copy-button'
|
|
57
|
+
onClick={() => {
|
|
58
|
+
void copyToClipboard(key)
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<CopyIcon />
|
|
62
|
+
</MenuItem>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
@@ -8,3 +8,4 @@ export * as DeviceDetails from './DeviceDetails/DeviceDetails.element.js'
|
|
|
8
8
|
export * as DeviceTable from './DeviceTable/DeviceTable.element.js'
|
|
9
9
|
export * as EditAccessCodeForm from './EditAccessCodeForm/EditAccessCodeForm.element.js'
|
|
10
10
|
export * as SupportedDeviceTable from './SupportedDeviceTable/SupportedDeviceTable.element.js'
|
|
11
|
+
export * as SupportedDeviceTableManufacturerKeys from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.js'
|
|
@@ -9,3 +9,4 @@ export * from './DeviceDetails/DeviceDetails.js'
|
|
|
9
9
|
export * from './DeviceTable/DeviceTable.js'
|
|
10
10
|
export * from './EditAccessCodeForm/EditAccessCodeForm.js'
|
|
11
11
|
export * from './SupportedDeviceTable/SupportedDeviceTable.js'
|
|
12
|
+
export * from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js'
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import classNames from 'classnames'
|
|
2
2
|
import { useState } from 'react'
|
|
3
3
|
import { useForm } from 'react-hook-form'
|
|
4
|
-
import type { ClimateSetting } from 'seamapi'
|
|
4
|
+
import type { ClimateSetting, HvacModeSetting } from 'seamapi'
|
|
5
5
|
|
|
6
6
|
import { getSystemTimeZone } from 'lib/dates.js'
|
|
7
|
+
import { ClimateSettingScheduleFormClimateSetting } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js'
|
|
7
8
|
import { ClimateSettingScheduleFormDeviceSelect } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormDeviceSelect.js'
|
|
8
9
|
import { ClimateSettingScheduleFormNameAndSchedule } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormNameAndSchedule.js'
|
|
9
10
|
import { ClimateSettingScheduleFormTimeZonePicker } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormTimeZonePicker.js'
|
|
@@ -30,6 +31,11 @@ export interface ClimateSettingScheduleFormFields {
|
|
|
30
31
|
startDate: string
|
|
31
32
|
endDate: string
|
|
32
33
|
timeZone: string
|
|
34
|
+
hvacModeSetting: HvacModeSetting
|
|
35
|
+
setPoints: {
|
|
36
|
+
heatingSetPoint: number
|
|
37
|
+
coolingSetPoint: number
|
|
38
|
+
}
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
export function ClimateSettingScheduleForm({
|
|
@@ -48,13 +54,18 @@ export function ClimateSettingScheduleForm({
|
|
|
48
54
|
function Content({
|
|
49
55
|
onBack,
|
|
50
56
|
}: Omit<ClimateSettingScheduleFormProps, 'className'>): JSX.Element {
|
|
51
|
-
const { control, watch } = useForm({
|
|
57
|
+
const { control, watch, resetField } = useForm({
|
|
52
58
|
defaultValues: {
|
|
53
59
|
deviceId: '',
|
|
54
60
|
name: '',
|
|
55
61
|
startDate: '',
|
|
56
62
|
endDate: '',
|
|
57
63
|
timeZone: getSystemTimeZone(),
|
|
64
|
+
hvacModeSetting: 'heat_cool' as HvacModeSetting,
|
|
65
|
+
setPoints: {
|
|
66
|
+
heatingSetPoint: 70,
|
|
67
|
+
coolingSetPoint: 75,
|
|
68
|
+
},
|
|
58
69
|
},
|
|
59
70
|
})
|
|
60
71
|
|
|
@@ -114,6 +125,23 @@ function Content({
|
|
|
114
125
|
)
|
|
115
126
|
}
|
|
116
127
|
|
|
128
|
+
if (page === 'climate_setting') {
|
|
129
|
+
return (
|
|
130
|
+
<ClimateSettingScheduleFormClimateSetting
|
|
131
|
+
title={t.addNewClimateSettingSchedule}
|
|
132
|
+
control={control}
|
|
133
|
+
watch={watch}
|
|
134
|
+
resetField={resetField}
|
|
135
|
+
deviceId={deviceId}
|
|
136
|
+
onBack={() => {
|
|
137
|
+
setPage('name_and_schedule')
|
|
138
|
+
}}
|
|
139
|
+
onCancel={onBack}
|
|
140
|
+
onSave={() => {}}
|
|
141
|
+
/>
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
117
145
|
return <></>
|
|
118
146
|
}
|
|
119
147
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Control,
|
|
3
|
+
Controller,
|
|
4
|
+
type UseFormResetField,
|
|
5
|
+
type UseFormWatch,
|
|
6
|
+
} from 'react-hook-form'
|
|
7
|
+
import type { HvacModeSetting } from 'seamapi'
|
|
8
|
+
|
|
9
|
+
import { useDevice } from 'lib/seam/devices/use-device.js'
|
|
10
|
+
import { Button } from 'lib/ui/Button.js'
|
|
11
|
+
import type { ClimateSettingScheduleFormFields } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js'
|
|
12
|
+
import { FormField } from 'lib/ui/FormField.js'
|
|
13
|
+
import { InputLabel } from 'lib/ui/InputLabel.js'
|
|
14
|
+
import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
|
|
15
|
+
import { ClimateModeMenu } from 'lib/ui/thermostat/ClimateModeMenu.js'
|
|
16
|
+
import { TemperatureControlGroup } from 'lib/ui/thermostat/TemperatureControlGroup.js'
|
|
17
|
+
|
|
18
|
+
interface ClimateSettingScheduleFormClimateSettingProps {
|
|
19
|
+
title: string
|
|
20
|
+
control: Control<ClimateSettingScheduleFormFields>
|
|
21
|
+
watch: UseFormWatch<ClimateSettingScheduleFormFields>
|
|
22
|
+
resetField: UseFormResetField<ClimateSettingScheduleFormFields>
|
|
23
|
+
deviceId: string
|
|
24
|
+
onBack: () => void
|
|
25
|
+
onCancel: (() => void) | undefined
|
|
26
|
+
onSave: () => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function ClimateSettingScheduleFormClimateSetting({
|
|
30
|
+
title,
|
|
31
|
+
control,
|
|
32
|
+
watch,
|
|
33
|
+
resetField,
|
|
34
|
+
deviceId,
|
|
35
|
+
onBack,
|
|
36
|
+
onCancel,
|
|
37
|
+
onSave,
|
|
38
|
+
}: ClimateSettingScheduleFormClimateSettingProps): JSX.Element {
|
|
39
|
+
const { device } = useDevice({
|
|
40
|
+
device_id: deviceId,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const hvacModeSetting = watch('hvacModeSetting')
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<>
|
|
47
|
+
<ContentHeader
|
|
48
|
+
title={title}
|
|
49
|
+
onBack={onBack}
|
|
50
|
+
subheading={device?.properties.name}
|
|
51
|
+
/>
|
|
52
|
+
<div className='seam-main'>
|
|
53
|
+
<div className='seam-climate-setting-schedule-form-climate-setting'>
|
|
54
|
+
<div className='seam-content'>
|
|
55
|
+
<div>
|
|
56
|
+
<InputLabel>{t.climateSetting}</InputLabel>
|
|
57
|
+
<span className='seam-label'>{t.climateSettingSubHeading}</span>
|
|
58
|
+
</div>
|
|
59
|
+
<FormContent
|
|
60
|
+
control={control}
|
|
61
|
+
resetField={resetField}
|
|
62
|
+
hvacModeSetting={hvacModeSetting}
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<div className='seam-actions'>
|
|
67
|
+
<Button onClick={onCancel}>{t.cancel}</Button>
|
|
68
|
+
<Button variant='solid' onClick={onSave}>
|
|
69
|
+
{t.save}
|
|
70
|
+
</Button>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface FormContentProps {
|
|
78
|
+
control: Control<ClimateSettingScheduleFormFields>
|
|
79
|
+
resetField: UseFormResetField<ClimateSettingScheduleFormFields>
|
|
80
|
+
hvacModeSetting: HvacModeSetting
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function FormContent({
|
|
84
|
+
control,
|
|
85
|
+
resetField,
|
|
86
|
+
hvacModeSetting,
|
|
87
|
+
}: FormContentProps): JSX.Element {
|
|
88
|
+
return (
|
|
89
|
+
<>
|
|
90
|
+
<FormField>
|
|
91
|
+
<Controller
|
|
92
|
+
name='hvacModeSetting'
|
|
93
|
+
control={control}
|
|
94
|
+
render={({ field: { value, onChange } }) => {
|
|
95
|
+
return (
|
|
96
|
+
<ClimateModeMenu
|
|
97
|
+
mode={value}
|
|
98
|
+
onChange={(mode) => {
|
|
99
|
+
resetField('setPoints')
|
|
100
|
+
onChange(mode)
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
)
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
</FormField>
|
|
107
|
+
{hvacModeSetting !== 'off' && (
|
|
108
|
+
<FormField className='seam-climate-setting-slider-container'>
|
|
109
|
+
<Controller
|
|
110
|
+
name='setPoints'
|
|
111
|
+
control={control}
|
|
112
|
+
render={({ field: { value, onChange } }) => (
|
|
113
|
+
<TemperatureControlGroup
|
|
114
|
+
coolValue={value.coolingSetPoint}
|
|
115
|
+
heatValue={value.heatingSetPoint}
|
|
116
|
+
delta={5}
|
|
117
|
+
maxCool={90}
|
|
118
|
+
maxHeat={100}
|
|
119
|
+
minCool={50}
|
|
120
|
+
minHeat={70}
|
|
121
|
+
mode={hvacModeSetting}
|
|
122
|
+
onCoolValueChange={(coolingSetPoint) => {
|
|
123
|
+
onChange({
|
|
124
|
+
...value,
|
|
125
|
+
coolingSetPoint,
|
|
126
|
+
})
|
|
127
|
+
}}
|
|
128
|
+
onHeatValueChange={(heatingSetPoint) => {
|
|
129
|
+
onChange({
|
|
130
|
+
...value,
|
|
131
|
+
heatingSetPoint,
|
|
132
|
+
})
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
)}
|
|
136
|
+
/>
|
|
137
|
+
</FormField>
|
|
138
|
+
)}
|
|
139
|
+
</>
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const t = {
|
|
144
|
+
climateSetting: 'Climate setting',
|
|
145
|
+
climateSettingSubHeading: 'Choose mode and adjust the climate',
|
|
146
|
+
cancel: 'Cancel',
|
|
147
|
+
save: 'Save',
|
|
148
|
+
next: 'Next',
|
|
149
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { HvacModeSetting } from 'seamapi'
|
|
2
|
+
|
|
3
|
+
import { ClimateModeMenu } from 'lib/ui/thermostat/ClimateModeMenu.js'
|
|
4
|
+
import {
|
|
5
|
+
TemperatureControlGroup,
|
|
6
|
+
type TemperatureControlGroupProps,
|
|
7
|
+
} from 'lib/ui/thermostat/TemperatureControlGroup.js'
|
|
8
|
+
|
|
9
|
+
type ClimateSettingControlGroupProps = Omit<
|
|
10
|
+
TemperatureControlGroupProps,
|
|
11
|
+
'mode'
|
|
12
|
+
> & {
|
|
13
|
+
mode: HvacModeSetting
|
|
14
|
+
onModeChange: (mode: HvacModeSetting) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ClimateSettingControlGroup(
|
|
18
|
+
props: ClimateSettingControlGroupProps
|
|
19
|
+
): JSX.Element {
|
|
20
|
+
const { mode, onModeChange, ...rest } = props
|
|
21
|
+
return (
|
|
22
|
+
<div className='seam-climate-setting-control-group'>
|
|
23
|
+
<ClimateModeMenu mode={mode} onChange={onModeChange} />
|
|
24
|
+
|
|
25
|
+
{mode !== 'off' && (
|
|
26
|
+
<div className='seam-climate-setting-slider-container'>
|
|
27
|
+
<TemperatureControlGroup mode={mode} {...rest} />
|
|
28
|
+
</div>
|
|
29
|
+
)}
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|