@seamapi/react 2.14.0 → 2.15.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 +2 -2
- package/dist/elements.js +22404 -15789
- package/dist/elements.js.map +1 -1
- package/dist/index.css +49 -1
- package/dist/index.css.map +1 -1
- package/dist/index.min.css +1 -1
- package/dist/index.min.css.map +1 -1
- package/lib/dates.d.ts +1 -0
- package/lib/dates.js +4 -0
- package/lib/dates.js.map +1 -1
- package/lib/icons/NoiseLevels.d.ts +2 -0
- package/lib/icons/NoiseLevels.js +5 -0
- package/lib/icons/NoiseLevels.js.map +1 -0
- package/lib/seam/components/DeviceDetails/DeviceDetails.js +5 -1
- package/lib/seam/components/DeviceDetails/DeviceDetails.js.map +1 -1
- package/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.d.ts +8 -0
- package/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js +15 -0
- package/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js.map +1 -0
- package/lib/seam/noise-sensors/use-noise-thresholds.d.ts +5 -0
- package/lib/seam/noise-sensors/use-noise-thresholds.js +26 -0
- package/lib/seam/noise-sensors/use-noise-thresholds.js.map +1 -0
- package/lib/ui/layout/DetailRow.d.ts +1 -1
- package/lib/ui/layout/DetailSection.d.ts +1 -1
- package/lib/ui/noise-sensor/NoiseThresholdsList.d.ts +7 -0
- package/lib/ui/noise-sensor/NoiseThresholdsList.js +45 -0
- package/lib/ui/noise-sensor/NoiseThresholdsList.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +3 -2
- package/src/lib/dates.ts +5 -0
- package/src/lib/icons/NoiseLevels.tsx +31 -0
- package/src/lib/seam/components/DeviceDetails/DeviceDetails.tsx +6 -1
- package/src/lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.tsx +58 -0
- package/src/lib/seam/noise-sensors/use-noise-thresholds.ts +46 -0
- package/src/lib/ui/layout/DetailRow.tsx +1 -1
- package/src/lib/ui/layout/DetailSection.tsx +1 -1
- package/src/lib/ui/noise-sensor/NoiseThresholdsList.tsx +141 -0
- package/src/lib/version.ts +1 -1
- package/src/styles/_device-details.scss +1 -0
- package/src/styles/_layout.scss +55 -0
- 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;
|
|
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"}
|
|
@@ -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,7 +1,7 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
2
|
interface DetailSectionProps {
|
|
3
3
|
label?: string;
|
|
4
|
-
tooltipContent?: string;
|
|
4
|
+
tooltipContent?: JSX.Element | string;
|
|
5
5
|
}
|
|
6
6
|
export declare function DetailSection({ label, tooltipContent, children, }: PropsWithChildren<DetailSectionProps>): JSX.Element;
|
|
7
7
|
export {};
|
|
@@ -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.
|
|
1
|
+
declare const seamapiReactVersion = "2.15.0";
|
|
2
2
|
export default seamapiReactVersion;
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamapi/react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.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
|
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { NoiseSensorDevice, NoiseThresholds } from 'seamapi'
|
|
2
|
+
import { ZonedTime } from 'zoned-time'
|
|
3
|
+
|
|
4
|
+
import { formatTime, formatTimeZone } from 'lib/dates.js'
|
|
5
|
+
import { ArrowRightIcon } from 'lib/icons/ArrowRight.js'
|
|
6
|
+
import { useNoiseThresholds } from 'lib/seam/noise-sensors/use-noise-thresholds.js'
|
|
7
|
+
import { DetailRow } from 'lib/ui/layout/DetailRow.js'
|
|
8
|
+
import { DetailSection } from 'lib/ui/layout/DetailSection.js'
|
|
9
|
+
import { DetailSectionGroup } from 'lib/ui/layout/DetailSectionGroup.js'
|
|
10
|
+
|
|
11
|
+
interface NoiseThresholdsListProps {
|
|
12
|
+
device: NoiseSensorDevice
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function NoiseThresholdsList({
|
|
16
|
+
device,
|
|
17
|
+
}: NoiseThresholdsListProps): JSX.Element {
|
|
18
|
+
const { noiseThresholds, isInitialLoading } = useNoiseThresholds({
|
|
19
|
+
device_id: device.device_id,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<DetailSectionGroup>
|
|
24
|
+
<div className='seam-detail-section-wrap'>
|
|
25
|
+
<DetailSection
|
|
26
|
+
label={t.noiseThresholds}
|
|
27
|
+
tooltipContent={
|
|
28
|
+
device.device_type === 'minut_sensor' ? (
|
|
29
|
+
<div className='seam-detail-section-tooltip-inner-content'>
|
|
30
|
+
<span className='seam-tooltip-content'>
|
|
31
|
+
{t.minutTooltipFirst}
|
|
32
|
+
</span>
|
|
33
|
+
<span className='seam-tooltip-content'>
|
|
34
|
+
{t.minutTooltipSecond}
|
|
35
|
+
</span>
|
|
36
|
+
</div>
|
|
37
|
+
) : (
|
|
38
|
+
t.tooltip
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
>
|
|
42
|
+
<Content
|
|
43
|
+
isInitialLoading={isInitialLoading}
|
|
44
|
+
noiseThresholds={noiseThresholds}
|
|
45
|
+
/>
|
|
46
|
+
</DetailSection>
|
|
47
|
+
|
|
48
|
+
<div className='seam-detail-section-footer'>
|
|
49
|
+
<div className='seam-empty-div' />
|
|
50
|
+
<div className='seam-detail-section-footer-content'>
|
|
51
|
+
<div className='seam-detail-section-footer-content-text'>
|
|
52
|
+
<p>{getTimeZoneCaption(device, noiseThresholds)}</p>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</DetailSectionGroup>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function Content({
|
|
62
|
+
isInitialLoading,
|
|
63
|
+
noiseThresholds,
|
|
64
|
+
}: {
|
|
65
|
+
isInitialLoading: boolean
|
|
66
|
+
noiseThresholds: NoiseThresholds[] | undefined
|
|
67
|
+
}): JSX.Element | JSX.Element[] {
|
|
68
|
+
if (isInitialLoading) {
|
|
69
|
+
return (
|
|
70
|
+
<DetailRow
|
|
71
|
+
label={<span className='seam-detail-row-empty-label'>{t.loading}</span>}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (noiseThresholds == null || noiseThresholds.length === 0) {
|
|
77
|
+
return (
|
|
78
|
+
<DetailRow
|
|
79
|
+
label={<span className='seam-detail-row-empty-label'>{t.none}</span>}
|
|
80
|
+
/>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return noiseThresholds?.map((noiseThreshold) => (
|
|
85
|
+
<DetailRow
|
|
86
|
+
key={noiseThreshold.noise_threshold_id}
|
|
87
|
+
label={
|
|
88
|
+
<div className='seam-detail-row-label-column'>
|
|
89
|
+
{noiseThreshold.name !== '' && (
|
|
90
|
+
<span className='seam-detail-row-label'>{noiseThreshold.name}</span>
|
|
91
|
+
)}
|
|
92
|
+
<div className='seam-detail-row-label-block'>
|
|
93
|
+
<span className='seam-row-sublabel seam-row-sublabel-text-default'>
|
|
94
|
+
{formatTime(noiseThreshold.starts_daily_at)}
|
|
95
|
+
</span>
|
|
96
|
+
<ArrowRightIcon />
|
|
97
|
+
<span className='seam-row-sublabel seam-row-sublabel-text-default'>
|
|
98
|
+
{formatTime(noiseThreshold.ends_daily_at)}
|
|
99
|
+
</span>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
}
|
|
103
|
+
>
|
|
104
|
+
<p>
|
|
105
|
+
{noiseThreshold.noise_threshold_decibels} {t.decibel}
|
|
106
|
+
</p>
|
|
107
|
+
</DetailRow>
|
|
108
|
+
))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const getTimeZoneCaption = (
|
|
112
|
+
device: NoiseSensorDevice,
|
|
113
|
+
thresholds: NoiseThresholds[] | undefined
|
|
114
|
+
): string | null => {
|
|
115
|
+
if (device.location?.timezone != null) {
|
|
116
|
+
return `${t.allTimesIn} ${formatTimeZone(device.location.timezone)}`
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const firstThreshold = thresholds?.[0]
|
|
120
|
+
|
|
121
|
+
if (firstThreshold != null) {
|
|
122
|
+
const zonedTime = ZonedTime.from(firstThreshold.starts_daily_at)
|
|
123
|
+
return `${t.allTimesIn} ${formatTimeZone(zonedTime.timeZone)}`
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const t = {
|
|
130
|
+
noiseThresholds: 'Noise thresholds',
|
|
131
|
+
tooltip:
|
|
132
|
+
'A noise threshold is the highest noise level (in dB) you want to allow for a given time range in the day.',
|
|
133
|
+
minutTooltipFirst:
|
|
134
|
+
'A noise threshold is the highest noise level (in dB) you want to allow.',
|
|
135
|
+
minutTooltipSecond:
|
|
136
|
+
'Quiet hours is a separate threshold that takes effect only for a specified time range.',
|
|
137
|
+
none: 'None',
|
|
138
|
+
loading: 'Loading...',
|
|
139
|
+
decibel: 'dB',
|
|
140
|
+
allTimesIn: 'All times in',
|
|
141
|
+
}
|
package/src/lib/version.ts
CHANGED