@seamapi/react 2.14.0 → 2.16.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.
Files changed (46) hide show
  1. package/README.md +2 -2
  2. package/dist/elements.js +22418 -15795
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +49 -1
  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/dates.d.ts +1 -0
  9. package/lib/dates.js +4 -0
  10. package/lib/dates.js.map +1 -1
  11. package/lib/icons/NoiseLevels.d.ts +2 -0
  12. package/lib/icons/NoiseLevels.js +5 -0
  13. package/lib/icons/NoiseLevels.js.map +1 -0
  14. package/lib/seam/components/DeviceDetails/DeviceDetails.js +5 -1
  15. package/lib/seam/components/DeviceDetails/DeviceDetails.js.map +1 -1
  16. package/lib/seam/components/DeviceDetails/DeviceInfo.js +1 -1
  17. package/lib/seam/components/DeviceDetails/DeviceInfo.js.map +1 -1
  18. package/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.d.ts +8 -0
  19. package/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js +15 -0
  20. package/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js.map +1 -0
  21. package/lib/seam/noise-sensors/use-noise-thresholds.d.ts +5 -0
  22. package/lib/seam/noise-sensors/use-noise-thresholds.js +26 -0
  23. package/lib/seam/noise-sensors/use-noise-thresholds.js.map +1 -0
  24. package/lib/ui/layout/DetailRow.d.ts +1 -1
  25. package/lib/ui/layout/DetailSection.d.ts +3 -2
  26. package/lib/ui/layout/DetailSection.js +3 -2
  27. package/lib/ui/layout/DetailSection.js.map +1 -1
  28. package/lib/ui/noise-sensor/NoiseThresholdsList.d.ts +7 -0
  29. package/lib/ui/noise-sensor/NoiseThresholdsList.js +45 -0
  30. package/lib/ui/noise-sensor/NoiseThresholdsList.js.map +1 -0
  31. package/lib/version.d.ts +1 -1
  32. package/lib/version.js +1 -1
  33. package/package.json +3 -2
  34. package/src/lib/dates.ts +5 -0
  35. package/src/lib/icons/NoiseLevels.tsx +31 -0
  36. package/src/lib/seam/components/DeviceDetails/DeviceDetails.tsx +6 -1
  37. package/src/lib/seam/components/DeviceDetails/DeviceInfo.tsx +4 -1
  38. package/src/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.tsx +58 -0
  39. package/src/lib/seam/noise-sensors/use-noise-thresholds.ts +46 -0
  40. package/src/lib/ui/layout/DetailRow.tsx +1 -1
  41. package/src/lib/ui/layout/DetailSection.tsx +5 -2
  42. package/src/lib/ui/noise-sensor/NoiseThresholdsList.tsx +141 -0
  43. package/src/lib/version.ts +1 -1
  44. package/src/styles/_device-details.scss +1 -0
  45. package/src/styles/_layout.scss +55 -0
  46. package/src/styles/_thermostat.scss +1 -1
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function NoiseLevelsIcon(props) {
3
+ return (_jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: 18, height: 19, fill: 'none', ...props, children: [_jsx("path", { fill: '#9DA1A9', fillRule: 'evenodd', d: 'M8.744 5.47q.046-.09.097-.18c.547-.966 1.534-1.77 3.412-1.77 1.016 0 1.76.259 2.302.638.546.381.934.916 1.186 1.537.516 1.273.415 2.81-.006 3.762-.362.816-.915 1.949-1.477 3.1-.464.952-.935 1.916-1.308 2.724-.603 1.303-1.939 1.383-2.55.842-.453-.401-.624-.87-.659-1.273-.018-.206 0-.389.034-.528.03-.127.062-.18.062-.18v.002l-.002.001a.767.767 0 0 0-.88-1.203 9.5 9.5 0 0 1-.745 1.489q-.021.264.002.55a3.43 3.43 0 0 0 1.171 2.291c1.467 1.298 3.974.783 4.96-1.346.338-.732.8-1.68 1.264-2.634.583-1.196 1.171-2.403 1.53-3.213.587-1.324.701-3.294.026-4.96-.343-.848-.901-1.64-1.73-2.22-.831-.58-1.89-.914-3.18-.914-2.106 0-3.509.827-4.378 1.983q.501.708.869 1.502M9.93 6.752c.298-.952 1.163-1.623 2.3-1.592.893.024 1.514.445 1.88.967.333.474.469 1.054.402 1.484a.767.767 0 0 1-1.517-.227v-.003a.5.5 0 0 0-.02-.11.8.8 0 0 0-.12-.263c-.106-.149-.289-.304-.666-.314-.45-.012-.701.219-.795.516-.1.32-.043.834.444 1.337.513.53.69 1.182.638 1.75-.046.5-.304 1.138-.898 1.382a.767.767 0 0 1-.665-1.38.4.4 0 0 0 .034-.14.69.69 0 0 0-.211-.544c-.822-.849-1.098-1.933-.806-2.863m.969 3.572.002-.003z', clipRule: 'evenodd' }), _jsx("path", { fill: '#27AE60', d: 'm1.191 8.702-.816.974.844 1.007a1.312 1.312 0 0 0-.028-1.98M2.173 11.82l1.041 1.242a4.4 4.4 0 0 0 1.577-3.383c0-1.36-.614-2.575-1.58-3.385L2.17 7.536A2.79 2.79 0 0 1 3.17 9.679c0 .86-.387 1.628-.997 2.14' }), _jsx("path", { fill: '#27AE60', d: 'm4.154 14.183 1.042 1.242a7.48 7.48 0 0 0 2.679-5.746 7.48 7.48 0 0 0-2.683-5.748L4.151 5.173a5.87 5.87 0 0 1 2.103 4.506 5.87 5.87 0 0 1-2.1 4.503' })] }));
4
+ }
5
+ //# sourceMappingURL=NoiseLevels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoiseLevels.js","sourceRoot":"","sources":["../../src/lib/icons/NoiseLevels.tsx"],"names":[],"mappings":";AAKA,MAAM,UAAU,eAAe,CAAC,KAA8B;IAC5D,OAAO,CACL,eACE,KAAK,EAAC,4BAA4B,EAClC,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,IAAI,EAAC,MAAM,KACP,KAAK,aAET,eACE,IAAI,EAAC,SAAS,EACd,QAAQ,EAAC,SAAS,EAClB,CAAC,EAAC,gkCAAgkC,EAClkC,QAAQ,EAAC,SAAS,GAClB,EACF,eACE,IAAI,EAAC,SAAS,EACd,CAAC,EAAC,6MAA6M,GAC/M,EACF,eACE,IAAI,EAAC,SAAS,EACd,CAAC,EAAC,qJAAqJ,GACvJ,IACE,CACP,CAAA;AACH,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { isLockDevice, isThermostatDevice } from 'seamapi';
2
+ import { isLockDevice, isNoiseSensorDevice, isThermostatDevice } from 'seamapi';
3
3
  import { withRequiredCommonProps, } from '../../../../lib/seam/components/common-props.js';
4
4
  import { LockDeviceDetails } from '../../../../lib/seam/components/DeviceDetails/LockDeviceDetails.js';
5
+ import { NoiseSensorDeviceDetails } from '../../../../lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js';
5
6
  import { ThermostatDeviceDetails } from '../../../../lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js';
6
7
  import { useDevice } from '../../../../lib/seam/devices/use-device.js';
7
8
  import { useComponentTelemetry } from '../../../../lib/telemetry/index.js';
@@ -33,6 +34,9 @@ export function DeviceDetails({ deviceId, errorFilter = () => true, warningFilte
33
34
  if (isThermostatDevice(device)) {
34
35
  return _jsx(ThermostatDeviceDetails, { device: device, ...props });
35
36
  }
37
+ if (isNoiseSensorDevice(device)) {
38
+ return _jsx(NoiseSensorDeviceDetails, { device: device, ...props });
39
+ }
36
40
  return null;
37
41
  }
38
42
  //# sourceMappingURL=DeviceDetails.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceDetails.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/DeviceDetails/DeviceDetails.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAE1D,OAAO,EAEL,uBAAuB,GACxB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wDAAwD,CAAA;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,8DAA8D,CAAA;AACtG,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAM9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAA;AAQzE,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,EACxB,aAAa,GAAG,GAAG,EAAE,CAAC,IAAI,EAC1B,iBAAiB,GAAG,KAAK,EACzB,uBAAuB,GAAG,KAAK,EAC/B,kBAAkB,GAAG,KAAK,EAC1B,kCAAkC,GAAG,KAAK,EAC1C,uBAAuB,GAAG,KAAK,EAC/B,qBAAqB,GAAG,KAAK,EAC7B,8BAA8B,GAAG,KAAK,EACtC,MAAM,EACN,SAAS,GACU;IACnB,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAEtC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAA;IAEF,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,KAAK,GAAqC;QAC9C,WAAW;QACX,aAAa;QACb,iBAAiB;QACjB,uBAAuB;QACvB,kBAAkB;QAClB,kCAAkC;QAClC,uBAAuB;QACvB,qBAAqB;QACrB,8BAA8B;QAC9B,MAAM;QACN,SAAS;KACV,CAAA;IAED,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,KAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,KAAM,KAAK,GAAI,CAAA;IACzD,CAAC;IAED,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAC,uBAAuB,IAAC,MAAM,EAAE,MAAM,KAAM,KAAK,GAAI,CAAA;IAC/D,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
1
+ {"version":3,"file":"DeviceDetails.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/DeviceDetails/DeviceDetails.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAE/E,OAAO,EAEL,uBAAuB,GACxB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wDAAwD,CAAA;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,+DAA+D,CAAA;AACxG,OAAO,EAAE,uBAAuB,EAAE,MAAM,8DAA8D,CAAA;AACtG,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAM9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAA;AAQzE,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,EACxB,aAAa,GAAG,GAAG,EAAE,CAAC,IAAI,EAC1B,iBAAiB,GAAG,KAAK,EACzB,uBAAuB,GAAG,KAAK,EAC/B,kBAAkB,GAAG,KAAK,EAC1B,kCAAkC,GAAG,KAAK,EAC1C,uBAAuB,GAAG,KAAK,EAC/B,qBAAqB,GAAG,KAAK,EAC7B,8BAA8B,GAAG,KAAK,EACtC,MAAM,EACN,SAAS,GACU;IACnB,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAEtC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAA;IAEF,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,KAAK,GAAqC;QAC9C,WAAW;QACX,aAAa;QACb,iBAAiB;QACjB,uBAAuB;QACvB,kBAAkB;QAClB,kCAAkC;QAClC,uBAAuB;QACvB,qBAAqB;QACrB,8BAA8B;QAC9B,MAAM;QACN,SAAS;KACV,CAAA;IAED,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,KAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,KAAM,KAAK,GAAI,CAAA;IACzD,CAAC;IAED,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAC,uBAAuB,IAAC,MAAM,EAAE,MAAM,KAAM,KAAK,GAAI,CAAA;IAC/D,CAAC;IAED,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,KAAC,wBAAwB,IAAC,MAAM,EAAE,MAAM,KAAM,KAAK,GAAI,CAAA;IAChE,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -5,7 +5,7 @@ import { DetailRow } from '../../../../lib/ui/layout/DetailRow.js';
5
5
  import { DetailSection } from '../../../../lib/ui/layout/DetailSection.js';
6
6
  export function DeviceInfo({ device, disableConnectedAccountInformation, disableResourceIds, }) {
7
7
  const { connectedAccount } = useConnectedAccount(device.connected_account_id);
8
- return (_jsxs(DetailSection, { label: t.deviceInfo, children: [_jsx(DetailRow, { label: t.manufacturer, children: _jsxs("div", { className: 'seam-detail-row-hstack', children: [device.properties.model.manufacturer_display_name, device.properties.manufacturer === 'ecobee' && _jsx(BeeIcon, {})] }) }), !disableConnectedAccountInformation && (_jsx(DetailRow, { label: t.linkedAccount, sublabel: connectedAccount?.user_identifier?.email ??
8
+ return (_jsxs(DetailSection, { label: t.deviceInfo, className: 'seam-device-details-device-info', children: [_jsx(DetailRow, { label: t.manufacturer, children: _jsxs("div", { className: 'seam-detail-row-hstack', children: [device.properties.model.manufacturer_display_name, device.properties.manufacturer === 'ecobee' && _jsx(BeeIcon, {})] }) }), !disableConnectedAccountInformation && (_jsx(DetailRow, { label: t.linkedAccount, sublabel: connectedAccount?.user_identifier?.email ??
9
9
  device.connected_account_id })), !disableResourceIds && (_jsx(DetailRow, { label: t.deviceId, sublabel: device.device_id }))] }));
10
10
  }
11
11
  const t = {
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceInfo.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/DeviceDetails/DeviceInfo.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAY9D,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,kCAAkC,EAClC,kBAAkB,GACF;IAChB,MAAM,EAAE,gBAAgB,EAAE,GAAG,mBAAmB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC7E,OAAO,CACL,MAAC,aAAa,IAAC,KAAK,EAAE,CAAC,CAAC,UAAU,aAChC,KAAC,SAAS,IAAC,KAAK,EAAE,CAAC,CAAC,YAAY,YAC9B,eAAK,SAAS,EAAC,wBAAwB,aACpC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,yBAAyB,EACjD,MAAM,CAAC,UAAU,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAC,OAAO,KAAG,IACvD,GACI,EACX,CAAC,kCAAkC,IAAI,CACtC,KAAC,SAAS,IACR,KAAK,EAAE,CAAC,CAAC,aAAa,EACtB,QAAQ,EACN,gBAAgB,EAAE,eAAe,EAAE,KAAK;oBACxC,MAAM,CAAC,oBAAoB,GAE7B,CACH,EACA,CAAC,kBAAkB,IAAI,CACtB,KAAC,SAAS,IAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,GAAI,CAC7D,IACa,CACjB,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,UAAU,EAAE,aAAa;IACzB,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,gBAAgB;IAC/B,QAAQ,EAAE,WAAW;CACtB,CAAA"}
1
+ {"version":3,"file":"DeviceInfo.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/DeviceDetails/DeviceInfo.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAY9D,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,kCAAkC,EAClC,kBAAkB,GACF;IAChB,MAAM,EAAE,gBAAgB,EAAE,GAAG,mBAAmB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC7E,OAAO,CACL,MAAC,aAAa,IACZ,KAAK,EAAE,CAAC,CAAC,UAAU,EACnB,SAAS,EAAC,iCAAiC,aAE3C,KAAC,SAAS,IAAC,KAAK,EAAE,CAAC,CAAC,YAAY,YAC9B,eAAK,SAAS,EAAC,wBAAwB,aACpC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,yBAAyB,EACjD,MAAM,CAAC,UAAU,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAC,OAAO,KAAG,IACvD,GACI,EACX,CAAC,kCAAkC,IAAI,CACtC,KAAC,SAAS,IACR,KAAK,EAAE,CAAC,CAAC,aAAa,EACtB,QAAQ,EACN,gBAAgB,EAAE,eAAe,EAAE,KAAK;oBACxC,MAAM,CAAC,oBAAoB,GAE7B,CACH,EACA,CAAC,kBAAkB,IAAI,CACtB,KAAC,SAAS,IAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,GAAI,CAC7D,IACa,CACjB,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,UAAU,EAAE,aAAa;IACzB,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,gBAAgB;IAC/B,QAAQ,EAAE,WAAW;CACtB,CAAA"}
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import type { NoiseSensorDevice } from 'seamapi';
3
+ import type { NestedSpecificDeviceDetailsProps } from '../../../../lib/seam/components/DeviceDetails/DeviceDetails.js';
4
+ interface NoiseSensorDeviceDetailsProps extends NestedSpecificDeviceDetailsProps {
5
+ device: NoiseSensorDevice;
6
+ }
7
+ export declare function NoiseSensorDeviceDetails({ device, disableConnectedAccountInformation, disableResourceIds, }: NoiseSensorDeviceDetailsProps): JSX.Element | null;
8
+ export {};
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { DeviceInfo } from '../../../../lib/seam/components/DeviceDetails/DeviceInfo.js';
3
+ import { DeviceModel } from '../../../../lib/seam/components/DeviceDetails/DeviceModel.js';
4
+ import { DeviceImage } from '../../../../lib/ui/device/DeviceImage.js';
5
+ import { OnlineStatus } from '../../../../lib/ui/device/OnlineStatus.js';
6
+ import { NoiseThresholdsList } from '../../../../lib/ui/noise-sensor/NoiseThresholdsList.js';
7
+ export function NoiseSensorDeviceDetails({ device, disableConnectedAccountInformation, disableResourceIds, }) {
8
+ return (_jsx("div", { className: 'seam-device-details', children: _jsxs("div", { className: 'seam-body', children: [_jsx("div", { className: 'seam-summary', children: _jsxs("div", { className: 'seam-content', children: [_jsx("div", { className: 'seam-image', children: _jsx(DeviceImage, { device: device }) }), _jsxs("div", { className: 'seam-info', children: [_jsx("span", { className: 'seam-label', children: t.noiseSensor }), _jsx("h4", { className: 'seam-device-name', children: device.properties.name }), _jsxs("div", { className: 'seam-properties', children: [_jsxs("span", { className: 'seam-label', children: [t.status, ":"] }), ' ', _jsx(OnlineStatus, { device: device }), _jsx(DeviceModel, { device: device })] })] })] }) }), _jsx(NoiseThresholdsList, { device: device }), _jsx(DeviceInfo, { device: device, disableConnectedAccountInformation: disableConnectedAccountInformation, disableResourceIds: disableResourceIds })] }) }));
9
+ }
10
+ const t = {
11
+ noiseSensor: 'Noise Sensor',
12
+ status: 'Status',
13
+ noiseLevel: 'Noise level',
14
+ };
15
+ //# sourceMappingURL=NoiseSensorDeviceDetails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoiseSensorDeviceDetails.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iDAAiD,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,kDAAkD,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAA;AAOhF,MAAM,UAAU,wBAAwB,CAAC,EACvC,MAAM,EACN,kCAAkC,EAClC,kBAAkB,GACY;IAC9B,OAAO,CACL,cAAK,SAAS,EAAC,qBAAqB,YAClC,eAAK,SAAS,EAAC,WAAW,aACxB,cAAK,SAAS,EAAC,cAAc,YAC3B,eAAK,SAAS,EAAC,cAAc,aAC3B,cAAK,SAAS,EAAC,YAAY,YACzB,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,GAAI,GAC3B,EACN,eAAK,SAAS,EAAC,WAAW,aACxB,eAAM,SAAS,EAAC,YAAY,YAAE,CAAC,CAAC,WAAW,GAAQ,EACnD,aAAI,SAAS,EAAC,kBAAkB,YAAE,MAAM,CAAC,UAAU,CAAC,IAAI,GAAM,EAC9D,eAAK,SAAS,EAAC,iBAAiB,aAC9B,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,MAAM,SAAS,EAAC,GAAG,EACnD,KAAC,YAAY,IAAC,MAAM,EAAE,MAAM,GAAI,EAChC,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,GAAI,IAC3B,IACF,IACF,GACF,EAEN,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,GAAI,EAEvC,KAAC,UAAU,IACT,MAAM,EAAE,MAAM,EACd,kCAAkC,EAChC,kCAAkC,EAEpC,kBAAkB,EAAE,kBAAkB,GACtC,IACE,GACF,CACP,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,WAAW,EAAE,cAAc;IAC3B,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,aAAa;CAC1B,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { NoiseThresholds, NoiseThresholdsListRequest } from 'seamapi';
2
+ import type { UseSeamQueryResult } from '../../../lib/seam/use-seam-query-result.js';
3
+ export type UseNoiseThresholdsParams = NoiseThresholdsListRequest;
4
+ export type UseNoiseThresholdsData = NoiseThresholds[];
5
+ export declare function useNoiseThresholds(params: UseNoiseThresholdsParams): UseSeamQueryResult<'noiseThresholds', UseNoiseThresholdsData>;
@@ -0,0 +1,26 @@
1
+ import { useQuery, useQueryClient } from '@tanstack/react-query';
2
+ import { useSeamClient } from '../../../lib/seam/use-seam-client.js';
3
+ export function useNoiseThresholds(params) {
4
+ const { client } = useSeamClient();
5
+ const queryClient = useQueryClient();
6
+ const { data, ...rest } = useQuery({
7
+ enabled: client != null,
8
+ queryKey: ['noise_thresholds', 'list', params],
9
+ queryFn: async () => {
10
+ if (client == null)
11
+ return [];
12
+ return await client.noiseThresholds.list(params);
13
+ },
14
+ onSuccess: (noiseThresholds) => {
15
+ for (const noiseThreshold of noiseThresholds) {
16
+ queryClient.setQueryData([
17
+ 'noise_thresholds',
18
+ 'get',
19
+ { noise_threshold_id: noiseThreshold.noise_threshold_id },
20
+ ], noiseThreshold);
21
+ }
22
+ },
23
+ });
24
+ return { ...rest, noiseThresholds: data };
25
+ }
26
+ //# sourceMappingURL=use-noise-thresholds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-noise-thresholds.js","sourceRoot":"","sources":["../../../src/lib/seam/noise-sensors/use-noise-thresholds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAQhE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAM3D,MAAM,UAAU,kBAAkB,CAChC,MAAgC;IAEhC,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAGhC;QACA,OAAO,EAAE,MAAM,IAAI,IAAI;QACvB,QAAQ,EAAE,CAAC,kBAAkB,EAAE,MAAM,EAAE,MAAM,CAAC;QAC9C,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO,EAAE,CAAA;YAC7B,OAAO,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClD,CAAC;QACD,SAAS,EAAE,CAAC,eAAe,EAAE,EAAE;YAC7B,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE,CAAC;gBAC7C,WAAW,CAAC,YAAY,CACtB;oBACE,kBAAkB;oBAClB,KAAK;oBACL,EAAE,kBAAkB,EAAE,cAAc,CAAC,kBAAkB,EAAE;iBAC1D,EACD,cAAc,CACf,CAAA;YACH,CAAC;QACH,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,GAAG,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAA;AAC3C,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { PropsWithChildren } from 'react';
2
2
  interface DetailRowProps {
3
- label: string;
3
+ label: JSX.Element | string;
4
4
  sublabel?: string;
5
5
  onClick?: () => void;
6
6
  }
@@ -1,7 +1,8 @@
1
1
  import type { PropsWithChildren } from 'react';
2
2
  interface DetailSectionProps {
3
3
  label?: string;
4
- tooltipContent?: string;
4
+ tooltipContent?: JSX.Element | string;
5
+ className?: string;
5
6
  }
6
- export declare function DetailSection({ label, tooltipContent, children, }: PropsWithChildren<DetailSectionProps>): JSX.Element;
7
+ export declare function DetailSection({ label, tooltipContent, className, children, }: PropsWithChildren<DetailSectionProps>): JSX.Element;
7
8
  export {};
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import classNames from 'classnames';
2
3
  import { Tooltip } from '../../../lib/ui/Tooltip/Tooltip.js';
3
- export function DetailSection({ label, tooltipContent, children, }) {
4
- return (_jsxs("div", { className: 'seam-detail-section', children: [_jsxs("div", { className: 'seam-detail-label-wrap', children: [label != null && _jsx("p", { className: 'seam-detail-label', children: label }), tooltipContent != null && _jsx(Tooltip, { children: tooltipContent })] }), _jsx("div", { className: 'seam-detail-group', children: children })] }));
4
+ export function DetailSection({ label, tooltipContent, className, children, }) {
5
+ return (_jsxs("div", { className: classNames('seam-detail-section', className), children: [_jsxs("div", { className: 'seam-detail-label-wrap', children: [label != null && _jsx("p", { className: 'seam-detail-label', children: label }), tooltipContent != null && _jsx(Tooltip, { children: tooltipContent })] }), _jsx("div", { className: 'seam-detail-group', children: children })] }));
5
6
  }
6
7
  //# sourceMappingURL=DetailSection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DetailSection.js","sourceRoot":"","sources":["../../../src/lib/ui/layout/DetailSection.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAOnD,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,cAAc,EACd,QAAQ,GAC8B;IACtC,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,eAAK,SAAS,EAAC,wBAAwB,aACpC,KAAK,IAAI,IAAI,IAAI,YAAG,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAK,EAC7D,cAAc,IAAI,IAAI,IAAI,KAAC,OAAO,cAAE,cAAc,GAAW,IAC1D,EAEN,cAAK,SAAS,EAAC,mBAAmB,YAAE,QAAQ,GAAO,IAC/C,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"DetailSection.js","sourceRoot":"","sources":["../../../src/lib/ui/layout/DetailSection.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AAGnC,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAQnD,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,cAAc,EACd,SAAS,EACT,QAAQ,GAC8B;IACtC,OAAO,CACL,eAAK,SAAS,EAAE,UAAU,CAAC,qBAAqB,EAAE,SAAS,CAAC,aAC1D,eAAK,SAAS,EAAC,wBAAwB,aACpC,KAAK,IAAI,IAAI,IAAI,YAAG,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAK,EAC7D,cAAc,IAAI,IAAI,IAAI,KAAC,OAAO,cAAE,cAAc,GAAW,IAC1D,EAEN,cAAK,SAAS,EAAC,mBAAmB,YAAE,QAAQ,GAAO,IAC/C,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import type { NoiseSensorDevice } from 'seamapi';
3
+ interface NoiseThresholdsListProps {
4
+ device: NoiseSensorDevice;
5
+ }
6
+ export declare function NoiseThresholdsList({ device, }: NoiseThresholdsListProps): JSX.Element;
7
+ export {};
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ZonedTime } from 'zoned-time';
3
+ import { formatTime, formatTimeZone } from '../../../lib/dates.js';
4
+ import { ArrowRightIcon } from '../../../lib/icons/ArrowRight.js';
5
+ import { useNoiseThresholds } from '../../../lib/seam/noise-sensors/use-noise-thresholds.js';
6
+ import { DetailRow } from '../../../lib/ui/layout/DetailRow.js';
7
+ import { DetailSection } from '../../../lib/ui/layout/DetailSection.js';
8
+ import { DetailSectionGroup } from '../../../lib/ui/layout/DetailSectionGroup.js';
9
+ export function NoiseThresholdsList({ device, }) {
10
+ const { noiseThresholds, isInitialLoading } = useNoiseThresholds({
11
+ device_id: device.device_id,
12
+ });
13
+ return (_jsx(DetailSectionGroup, { children: _jsxs("div", { className: 'seam-detail-section-wrap', children: [_jsx(DetailSection, { label: t.noiseThresholds, tooltipContent: device.device_type === 'minut_sensor' ? (_jsxs("div", { className: 'seam-detail-section-tooltip-inner-content', children: [_jsx("span", { className: 'seam-tooltip-content', children: t.minutTooltipFirst }), _jsx("span", { className: 'seam-tooltip-content', children: t.minutTooltipSecond })] })) : (t.tooltip), children: _jsx(Content, { isInitialLoading: isInitialLoading, noiseThresholds: noiseThresholds }) }), _jsxs("div", { className: 'seam-detail-section-footer', children: [_jsx("div", { className: 'seam-empty-div' }), _jsx("div", { className: 'seam-detail-section-footer-content', children: _jsx("div", { className: 'seam-detail-section-footer-content-text', children: _jsx("p", { children: getTimeZoneCaption(device, noiseThresholds) }) }) })] })] }) }));
14
+ }
15
+ function Content({ isInitialLoading, noiseThresholds, }) {
16
+ if (isInitialLoading) {
17
+ return (_jsx(DetailRow, { label: _jsx("span", { className: 'seam-detail-row-empty-label', children: t.loading }) }));
18
+ }
19
+ if (noiseThresholds == null || noiseThresholds.length === 0) {
20
+ return (_jsx(DetailRow, { label: _jsx("span", { className: 'seam-detail-row-empty-label', children: t.none }) }));
21
+ }
22
+ return noiseThresholds?.map((noiseThreshold) => (_jsx(DetailRow, { label: _jsxs("div", { className: 'seam-detail-row-label-column', children: [noiseThreshold.name !== '' && (_jsx("span", { className: 'seam-detail-row-label', children: noiseThreshold.name })), _jsxs("div", { className: 'seam-detail-row-label-block', children: [_jsx("span", { className: 'seam-row-sublabel seam-row-sublabel-text-default', children: formatTime(noiseThreshold.starts_daily_at) }), _jsx(ArrowRightIcon, {}), _jsx("span", { className: 'seam-row-sublabel seam-row-sublabel-text-default', children: formatTime(noiseThreshold.ends_daily_at) })] })] }), children: _jsxs("p", { children: [noiseThreshold.noise_threshold_decibels, " ", t.decibel] }) }, noiseThreshold.noise_threshold_id)));
23
+ }
24
+ const getTimeZoneCaption = (device, thresholds) => {
25
+ if (device.location?.timezone != null) {
26
+ return `${t.allTimesIn} ${formatTimeZone(device.location.timezone)}`;
27
+ }
28
+ const firstThreshold = thresholds?.[0];
29
+ if (firstThreshold != null) {
30
+ const zonedTime = ZonedTime.from(firstThreshold.starts_daily_at);
31
+ return `${t.allTimesIn} ${formatTimeZone(zonedTime.timeZone)}`;
32
+ }
33
+ return null;
34
+ };
35
+ const t = {
36
+ noiseThresholds: 'Noise thresholds',
37
+ tooltip: 'A noise threshold is the highest noise level (in dB) you want to allow for a given time range in the day.',
38
+ minutTooltipFirst: 'A noise threshold is the highest noise level (in dB) you want to allow.',
39
+ minutTooltipSecond: 'Quiet hours is a separate threshold that takes effect only for a specified time range.',
40
+ none: 'None',
41
+ loading: 'Loading...',
42
+ decibel: 'dB',
43
+ allTimesIn: 'All times in',
44
+ };
45
+ //# sourceMappingURL=NoiseThresholdsList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoiseThresholdsList.js","sourceRoot":"","sources":["../../../src/lib/ui/noise-sensor/NoiseThresholdsList.tsx"],"names":[],"mappings":"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"}
package/lib/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- declare const seamapiReactVersion = "2.14.0";
1
+ declare const seamapiReactVersion = "2.16.0";
2
2
  export default seamapiReactVersion;
package/lib/version.js CHANGED
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '2.14.0';
1
+ const seamapiReactVersion = '2.16.0';
2
2
  export default seamapiReactVersion;
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamapi/react",
3
- "version": "2.14.0",
3
+ "version": "2.16.0",
4
4
  "description": "Seam Components.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -133,7 +133,8 @@
133
133
  "queue": "^7.0.0",
134
134
  "react-hook-form": "^7.46.1",
135
135
  "seamapi": "^8.22.0",
136
- "uuid": "^9.0.0"
136
+ "uuid": "^9.0.0",
137
+ "zoned-time": "^1.1.2"
137
138
  },
138
139
  "devDependencies": {
139
140
  "@emotion/styled": "^11.10.6",
package/src/lib/dates.ts CHANGED
@@ -23,6 +23,11 @@ export const formatTimeZone = (timeZone: string): string => {
23
23
  return `${timeZone.replaceAll('_', ' ')} (${offset})`
24
24
  }
25
25
 
26
+ export const formatTime = (time: string): string => {
27
+ const dateTime = DateTime.fromISO(time)
28
+ return dateTime.isValid ? dateTime.toLocaleString(DateTime.TIME_SIMPLE) : ''
29
+ }
30
+
26
31
  export const serializeDateTimePickerValue = (
27
32
  dateTime: DateTime,
28
33
  timeZone: string
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Automatically generated by SVGR from assets/icons/*.svg.
3
+ * Do not edit this file or add other components to this directory.
4
+ */
5
+ import type { SVGProps } from 'react'
6
+ export function NoiseLevelsIcon(props: SVGProps<SVGSVGElement>): JSX.Element {
7
+ return (
8
+ <svg
9
+ xmlns='http://www.w3.org/2000/svg'
10
+ width={18}
11
+ height={19}
12
+ fill='none'
13
+ {...props}
14
+ >
15
+ <path
16
+ fill='#9DA1A9'
17
+ fillRule='evenodd'
18
+ d='M8.744 5.47q.046-.09.097-.18c.547-.966 1.534-1.77 3.412-1.77 1.016 0 1.76.259 2.302.638.546.381.934.916 1.186 1.537.516 1.273.415 2.81-.006 3.762-.362.816-.915 1.949-1.477 3.1-.464.952-.935 1.916-1.308 2.724-.603 1.303-1.939 1.383-2.55.842-.453-.401-.624-.87-.659-1.273-.018-.206 0-.389.034-.528.03-.127.062-.18.062-.18v.002l-.002.001a.767.767 0 0 0-.88-1.203 9.5 9.5 0 0 1-.745 1.489q-.021.264.002.55a3.43 3.43 0 0 0 1.171 2.291c1.467 1.298 3.974.783 4.96-1.346.338-.732.8-1.68 1.264-2.634.583-1.196 1.171-2.403 1.53-3.213.587-1.324.701-3.294.026-4.96-.343-.848-.901-1.64-1.73-2.22-.831-.58-1.89-.914-3.18-.914-2.106 0-3.509.827-4.378 1.983q.501.708.869 1.502M9.93 6.752c.298-.952 1.163-1.623 2.3-1.592.893.024 1.514.445 1.88.967.333.474.469 1.054.402 1.484a.767.767 0 0 1-1.517-.227v-.003a.5.5 0 0 0-.02-.11.8.8 0 0 0-.12-.263c-.106-.149-.289-.304-.666-.314-.45-.012-.701.219-.795.516-.1.32-.043.834.444 1.337.513.53.69 1.182.638 1.75-.046.5-.304 1.138-.898 1.382a.767.767 0 0 1-.665-1.38.4.4 0 0 0 .034-.14.69.69 0 0 0-.211-.544c-.822-.849-1.098-1.933-.806-2.863m.969 3.572.002-.003z'
19
+ clipRule='evenodd'
20
+ />
21
+ <path
22
+ fill='#27AE60'
23
+ d='m1.191 8.702-.816.974.844 1.007a1.312 1.312 0 0 0-.028-1.98M2.173 11.82l1.041 1.242a4.4 4.4 0 0 0 1.577-3.383c0-1.36-.614-2.575-1.58-3.385L2.17 7.536A2.79 2.79 0 0 1 3.17 9.679c0 .86-.387 1.628-.997 2.14'
24
+ />
25
+ <path
26
+ fill='#27AE60'
27
+ d='m4.154 14.183 1.042 1.242a7.48 7.48 0 0 0 2.679-5.746 7.48 7.48 0 0 0-2.683-5.748L4.151 5.173a5.87 5.87 0 0 1 2.103 4.506 5.87 5.87 0 0 1-2.1 4.503'
28
+ />
29
+ </svg>
30
+ )
31
+ }
@@ -1,10 +1,11 @@
1
- import { isLockDevice, isThermostatDevice } from 'seamapi'
1
+ import { isLockDevice, isNoiseSensorDevice, isThermostatDevice } from 'seamapi'
2
2
 
3
3
  import {
4
4
  type CommonProps,
5
5
  withRequiredCommonProps,
6
6
  } from 'lib/seam/components/common-props.js'
7
7
  import { LockDeviceDetails } from 'lib/seam/components/DeviceDetails/LockDeviceDetails.js'
8
+ import { NoiseSensorDeviceDetails } from 'lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js'
8
9
  import { ThermostatDeviceDetails } from 'lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js'
9
10
  import { useDevice } from 'lib/seam/devices/use-device.js'
10
11
  import { useComponentTelemetry } from 'lib/telemetry/index.js'
@@ -67,5 +68,9 @@ export function DeviceDetails({
67
68
  return <ThermostatDeviceDetails device={device} {...props} />
68
69
  }
69
70
 
71
+ if (isNoiseSensorDevice(device)) {
72
+ return <NoiseSensorDeviceDetails device={device} {...props} />
73
+ }
74
+
70
75
  return null
71
76
  }
@@ -23,7 +23,10 @@ export function DeviceInfo({
23
23
  }: DeviceInfoProps): JSX.Element | null {
24
24
  const { connectedAccount } = useConnectedAccount(device.connected_account_id)
25
25
  return (
26
- <DetailSection label={t.deviceInfo}>
26
+ <DetailSection
27
+ label={t.deviceInfo}
28
+ className='seam-device-details-device-info'
29
+ >
27
30
  <DetailRow label={t.manufacturer}>
28
31
  <div className='seam-detail-row-hstack'>
29
32
  {device.properties.model.manufacturer_display_name}
@@ -0,0 +1,58 @@
1
+ import type { NoiseSensorDevice } from 'seamapi'
2
+
3
+ import type { NestedSpecificDeviceDetailsProps } from 'lib/seam/components/DeviceDetails/DeviceDetails.js'
4
+ import { DeviceInfo } from 'lib/seam/components/DeviceDetails/DeviceInfo.js'
5
+ import { DeviceModel } from 'lib/seam/components/DeviceDetails/DeviceModel.js'
6
+ import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
7
+ import { OnlineStatus } from 'lib/ui/device/OnlineStatus.js'
8
+ import { NoiseThresholdsList } from 'lib/ui/noise-sensor/NoiseThresholdsList.js'
9
+
10
+ interface NoiseSensorDeviceDetailsProps
11
+ extends NestedSpecificDeviceDetailsProps {
12
+ device: NoiseSensorDevice
13
+ }
14
+
15
+ export function NoiseSensorDeviceDetails({
16
+ device,
17
+ disableConnectedAccountInformation,
18
+ disableResourceIds,
19
+ }: NoiseSensorDeviceDetailsProps): JSX.Element | null {
20
+ return (
21
+ <div className='seam-device-details'>
22
+ <div className='seam-body'>
23
+ <div className='seam-summary'>
24
+ <div className='seam-content'>
25
+ <div className='seam-image'>
26
+ <DeviceImage device={device} />
27
+ </div>
28
+ <div className='seam-info'>
29
+ <span className='seam-label'>{t.noiseSensor}</span>
30
+ <h4 className='seam-device-name'>{device.properties.name}</h4>
31
+ <div className='seam-properties'>
32
+ <span className='seam-label'>{t.status}:</span>{' '}
33
+ <OnlineStatus device={device} />
34
+ <DeviceModel device={device} />
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
39
+
40
+ <NoiseThresholdsList device={device} />
41
+
42
+ <DeviceInfo
43
+ device={device}
44
+ disableConnectedAccountInformation={
45
+ disableConnectedAccountInformation
46
+ }
47
+ disableResourceIds={disableResourceIds}
48
+ />
49
+ </div>
50
+ </div>
51
+ )
52
+ }
53
+
54
+ const t = {
55
+ noiseSensor: 'Noise Sensor',
56
+ status: 'Status',
57
+ noiseLevel: 'Noise level',
58
+ }
@@ -0,0 +1,46 @@
1
+ import { useQuery, useQueryClient } from '@tanstack/react-query'
2
+ import type {
3
+ NoiseThresholds,
4
+ NoiseThresholdsListRequest,
5
+ NoiseThresholdsListResponse,
6
+ SeamError,
7
+ } from 'seamapi'
8
+
9
+ import { useSeamClient } from 'lib/seam/use-seam-client.js'
10
+ import type { UseSeamQueryResult } from 'lib/seam/use-seam-query-result.js'
11
+
12
+ export type UseNoiseThresholdsParams = NoiseThresholdsListRequest
13
+ export type UseNoiseThresholdsData = NoiseThresholds[]
14
+
15
+ export function useNoiseThresholds(
16
+ params: UseNoiseThresholdsParams
17
+ ): UseSeamQueryResult<'noiseThresholds', UseNoiseThresholdsData> {
18
+ const { client } = useSeamClient()
19
+ const queryClient = useQueryClient()
20
+
21
+ const { data, ...rest } = useQuery<
22
+ NoiseThresholdsListResponse['noise_thresholds'],
23
+ SeamError
24
+ >({
25
+ enabled: client != null,
26
+ queryKey: ['noise_thresholds', 'list', params],
27
+ queryFn: async () => {
28
+ if (client == null) return []
29
+ return await client.noiseThresholds.list(params)
30
+ },
31
+ onSuccess: (noiseThresholds) => {
32
+ for (const noiseThreshold of noiseThresholds) {
33
+ queryClient.setQueryData(
34
+ [
35
+ 'noise_thresholds',
36
+ 'get',
37
+ { noise_threshold_id: noiseThreshold.noise_threshold_id },
38
+ ],
39
+ noiseThreshold
40
+ )
41
+ }
42
+ },
43
+ })
44
+
45
+ return { ...rest, noiseThresholds: data }
46
+ }
@@ -2,7 +2,7 @@ import classNames from 'classnames'
2
2
  import type { PropsWithChildren } from 'react'
3
3
 
4
4
  interface DetailRowProps {
5
- label: string
5
+ label: JSX.Element | string
6
6
  sublabel?: string
7
7
  onClick?: () => void
8
8
  }
@@ -1,19 +1,22 @@
1
+ import classNames from 'classnames'
1
2
  import type { PropsWithChildren } from 'react'
2
3
 
3
4
  import { Tooltip } from 'lib/ui/Tooltip/Tooltip.js'
4
5
 
5
6
  interface DetailSectionProps {
6
7
  label?: string
7
- tooltipContent?: string
8
+ tooltipContent?: JSX.Element | string
9
+ className?: string
8
10
  }
9
11
 
10
12
  export function DetailSection({
11
13
  label,
12
14
  tooltipContent,
15
+ className,
13
16
  children,
14
17
  }: PropsWithChildren<DetailSectionProps>): JSX.Element {
15
18
  return (
16
- <div className='seam-detail-section'>
19
+ <div className={classNames('seam-detail-section', className)}>
17
20
  <div className='seam-detail-label-wrap'>
18
21
  {label != null && <p className='seam-detail-label'>{label}</p>}
19
22
  {tooltipContent != null && <Tooltip>{tooltipContent}</Tooltip>}