@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.
- package/README.md +2 -2
- package/dist/elements.js +22418 -15795
- 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/DeviceInfo.js +1 -1
- package/lib/seam/components/DeviceDetails/DeviceInfo.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 +3 -2
- package/lib/ui/layout/DetailSection.js +3 -2
- package/lib/ui/layout/DetailSection.js.map +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/DeviceInfo.tsx +4 -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 +5 -2
- 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,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
package/src/styles/_layout.scss
CHANGED
|
@@ -40,6 +40,12 @@
|
|
|
40
40
|
gap: 32px;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
.seam-detail-section-wrap {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
gap: 6px;
|
|
47
|
+
}
|
|
48
|
+
|
|
43
49
|
.seam-detail-section {
|
|
44
50
|
width: 100%;
|
|
45
51
|
}
|
|
@@ -66,6 +72,27 @@
|
|
|
66
72
|
border: 1px solid colors.$text-gray-3;
|
|
67
73
|
overflow: hidden;
|
|
68
74
|
}
|
|
75
|
+
|
|
76
|
+
.seam-detail-section-footer {
|
|
77
|
+
width: 100%;
|
|
78
|
+
display: flex;
|
|
79
|
+
justify-content: space-between;
|
|
80
|
+
align-items: center;
|
|
81
|
+
flex-direction: row;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.seam-detail-section-footer-content-text {
|
|
85
|
+
font-size: 12px;
|
|
86
|
+
color: colors.$text-gray-2-5;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.seam-detail-section-tooltip-inner-content {
|
|
90
|
+
display: flex;
|
|
91
|
+
justify-content: flex-start;
|
|
92
|
+
align-items: flex-start;
|
|
93
|
+
flex-direction: column;
|
|
94
|
+
gap: 8px;
|
|
95
|
+
}
|
|
69
96
|
}
|
|
70
97
|
|
|
71
98
|
@mixin detail-row-common {
|
|
@@ -105,17 +132,45 @@
|
|
|
105
132
|
gap: 4px;
|
|
106
133
|
}
|
|
107
134
|
|
|
135
|
+
.seam-detail-row-label-column {
|
|
136
|
+
display: flex;
|
|
137
|
+
justify-content: flex-start;
|
|
138
|
+
align-items: flex-start;
|
|
139
|
+
flex-direction: column;
|
|
140
|
+
gap: 4px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.seam-detail-row-label-block {
|
|
144
|
+
display: flex;
|
|
145
|
+
justify-content: flex-start;
|
|
146
|
+
align-items: center;
|
|
147
|
+
flex-direction: row;
|
|
148
|
+
gap: 4px;
|
|
149
|
+
}
|
|
150
|
+
|
|
108
151
|
.seam-row-label {
|
|
109
152
|
font-size: 16px;
|
|
110
153
|
font-weight: 600;
|
|
111
154
|
line-height: 118%;
|
|
112
155
|
}
|
|
113
156
|
|
|
157
|
+
.seam-detail-row-empty-label {
|
|
158
|
+
font-size: 16px;
|
|
159
|
+
font-style: italic;
|
|
160
|
+
font-weight: 400;
|
|
161
|
+
line-height: 118%;
|
|
162
|
+
color: colors.$text-gray-2;
|
|
163
|
+
}
|
|
164
|
+
|
|
114
165
|
.seam-row-sublabel {
|
|
115
166
|
color: colors.$text-gray-1;
|
|
116
167
|
font-size: 14px;
|
|
117
168
|
font-weight: 400;
|
|
118
169
|
line-height: 118%;
|
|
170
|
+
|
|
171
|
+
&.seam-row-sublabel-text-default {
|
|
172
|
+
color: colors.$text-default;
|
|
173
|
+
}
|
|
119
174
|
}
|
|
120
175
|
|
|
121
176
|
.seam-detail-row-hstack {
|