@seamapi/react 1.65.0 → 2.0.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 +6760 -6689
- package/dist/elements.js.map +1 -1
- package/dist/index.css +15 -15
- package/dist/index.min.css +1 -1
- package/dist/index.min.css.map +1 -1
- package/lib/seam/components/AccessCodeTable/AccessCodeTable.d.ts +1 -5
- package/lib/seam/components/AccessCodeTable/AccessCodeTable.js +2 -2
- package/lib/seam/components/AccessCodeTable/AccessCodeTable.js.map +1 -1
- package/lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js +2 -2
- package/lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js.map +1 -1
- package/lib/seam/components/DeviceTable/DeviceTable.d.ts +1 -5
- package/lib/seam/components/DeviceTable/DeviceTable.js +2 -2
- package/lib/seam/components/DeviceTable/DeviceTable.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.d.ts +3 -3
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js +11 -17
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.d.ts +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.js +1 -7
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.d.ts +3 -3
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.js +12 -31
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.d.ts +2 -2
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.js +2 -4
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.d.ts +8 -0
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js +35 -0
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js.map +1 -0
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.d.ts +2 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js +10 -6
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.d.ts +3 -7
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.js +4 -5
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.d.ts +5 -5
- package/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js +16 -17
- package/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js.map +1 -1
- package/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.d.ts +8 -0
- package/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.js +37 -0
- package/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +3 -3
- package/src/lib/seam/components/AccessCodeTable/AccessCodeTable.tsx +2 -8
- package/src/lib/seam/components/DeviceDetails/ThermostatDeviceDetails.tsx +2 -2
- package/src/lib/seam/components/DeviceTable/DeviceTable.tsx +2 -8
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx +23 -29
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.tsx +3 -9
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx +22 -41
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.tsx +8 -12
- package/src/lib/seam/components/SupportedDeviceTable/{SupportedDeviceBrandSection.tsx → SupportedDeviceManufacturerSection.tsx} +19 -26
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx +20 -11
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.element.ts +2 -3
- package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.tsx +10 -17
- package/src/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.ts +31 -20
- package/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts +54 -0
- package/src/lib/version.ts +1 -1
- package/src/styles/_supported-device-table.scss +4 -4
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceBrandSection.d.ts +0 -8
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceBrandSection.js +0 -42
- package/lib/seam/components/SupportedDeviceTable/SupportedDeviceBrandSection.js.map +0 -1
- package/lib/seam/components/SupportedDeviceTable/use-device-provider.d.ts +0 -2
- package/lib/seam/components/SupportedDeviceTable/use-device-provider.js +0 -13
- package/lib/seam/components/SupportedDeviceTable/use-device-provider.js.map +0 -1
- package/lib/seam/device-models/use-device-models.d.ts +0 -5
- package/lib/seam/device-models/use-device-models.js +0 -19
- package/lib/seam/device-models/use-device-models.js.map +0 -1
- package/lib/strings.d.ts +0 -1
- package/lib/strings.js +0 -4
- package/lib/strings.js.map +0 -1
- package/src/lib/seam/components/SupportedDeviceTable/use-device-provider.ts +0 -16
- package/src/lib/seam/device-models/use-device-models.ts +0 -39
- package/src/lib/strings.ts +0 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useManufacturers } from '../../../../lib/seam/components/SupportedDeviceTable/use-manufacturers.js';
|
|
2
|
+
export const useFilteredManufacturers = (params) => {
|
|
3
|
+
return useManufacturers({
|
|
4
|
+
liqe_query: createLiqeQuery(params),
|
|
5
|
+
});
|
|
6
|
+
};
|
|
7
|
+
export const createLiqeQuery = ({ manufacturers, excludedManufacturers, }) => {
|
|
8
|
+
if ((manufacturers?.some(isInvalidInput) ?? false) ||
|
|
9
|
+
excludedManufacturers.some(isInvalidInput)) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const excludedManufacturersClause = `NOT (${excludedManufacturers
|
|
13
|
+
.map(manufacturerToMatcher)
|
|
14
|
+
.join(' OR ')})`;
|
|
15
|
+
if (manufacturers == null) {
|
|
16
|
+
if (excludedManufacturers.length === 0)
|
|
17
|
+
return undefined;
|
|
18
|
+
return excludedManufacturersClause;
|
|
19
|
+
}
|
|
20
|
+
if (manufacturers.length === 0) {
|
|
21
|
+
return 'manufacturer_id:none';
|
|
22
|
+
}
|
|
23
|
+
const includedManufacturersClause = `(${manufacturers
|
|
24
|
+
.map(manufacturerToMatcher)
|
|
25
|
+
.join(' OR ')})`;
|
|
26
|
+
if (excludedManufacturers.length === 0)
|
|
27
|
+
return includedManufacturersClause;
|
|
28
|
+
return `${includedManufacturersClause} AND ${excludedManufacturersClause}`;
|
|
29
|
+
};
|
|
30
|
+
const manufacturerToMatcher = (value) => {
|
|
31
|
+
const [manufacturer, uuid] = value.split('=');
|
|
32
|
+
if (uuid != null)
|
|
33
|
+
return `manufacturer_id:"${uuid}"`;
|
|
34
|
+
return `display_name:"${manufacturer}"`;
|
|
35
|
+
};
|
|
36
|
+
const isInvalidInput = (value) => value.includes('"');
|
|
37
|
+
//# sourceMappingURL=use-filtered-manufacturers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-filtered-manufacturers.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+DAA+D,CAAA;AAMhG,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,MAAc,EACuB,EAAE;IACvC,OAAO,gBAAgB,CAAC;QACtB,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC;KACpC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,aAAa,EACb,qBAAqB,GACd,EAAsB,EAAE;IAC/B,IACE,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC;QAC9C,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,EAC1C;QACA,OAAO,SAAS,CAAA;KACjB;IAED,MAAM,2BAA2B,GAAG,QAAQ,qBAAqB;SAC9D,GAAG,CAAC,qBAAqB,CAAC;SAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAA;IAElB,IAAI,aAAa,IAAI,IAAI,EAAE;QACzB,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAA;QACxD,OAAO,2BAA2B,CAAA;KACnC;IAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9B,OAAO,sBAAsB,CAAA;KAC9B;IAED,MAAM,2BAA2B,GAAG,IAAI,aAAa;SAClD,GAAG,CAAC,qBAAqB,CAAC;SAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAA;IAElB,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,2BAA2B,CAAA;IAE1E,OAAO,GAAG,2BAA2B,QAAQ,2BAA2B,EAAE,CAAA;AAC5E,CAAC,CAAA;AAED,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAU,EAAE;IACtD,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC7C,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,oBAAoB,IAAI,GAAG,CAAA;IACpD,OAAO,iBAAiB,YAAY,GAAG,CAAA;AACzC,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA"}
|
package/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const seamapiReactVersion = "
|
|
1
|
+
declare const seamapiReactVersion = "2.0.0";
|
|
2
2
|
export default seamapiReactVersion;
|
package/lib/version.js
CHANGED
package/lib/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,mBAAmB,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,mBAAmB,GAAG,OAAO,CAAA;AAEnC,eAAe,mBAAmB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamapi/react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Seam Components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"luxon": "^3.3.0",
|
|
133
133
|
"queue": "^7.0.0",
|
|
134
134
|
"react-hook-form": "^7.46.1",
|
|
135
|
-
"seamapi": "^8.13.
|
|
135
|
+
"seamapi": "^8.13.3",
|
|
136
136
|
"uuid": "^9.0.0"
|
|
137
137
|
},
|
|
138
138
|
"devDependencies": {
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
"@mui/material": "^5.12.2",
|
|
142
142
|
"@rxfork/r2wc-react-to-web-component": "^2.4.0",
|
|
143
143
|
"@seamapi/fake-devicedb": "^1.1.0",
|
|
144
|
-
"@seamapi/fake-seam-connect": "^1.
|
|
144
|
+
"@seamapi/fake-seam-connect": "^1.37.1",
|
|
145
145
|
"@seamapi/http": "^0.2.1",
|
|
146
146
|
"@seamapi/types": "^1.28.0",
|
|
147
147
|
"@storybook/addon-designs": "^7.0.1",
|
|
@@ -49,10 +49,6 @@ export interface AccessCodeTableProps extends CommonProps {
|
|
|
49
49
|
onAccessCodeClick?: (accessCodeId: string) => void
|
|
50
50
|
preventDefaultOnAccessCodeClick?: boolean
|
|
51
51
|
heading?: string | null
|
|
52
|
-
/**
|
|
53
|
-
* @deprecated Use heading.
|
|
54
|
-
*/
|
|
55
|
-
title?: string | null
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
type AccessCode = UseAccessCodesData[number]
|
|
@@ -82,7 +78,6 @@ export function AccessCodeTable({
|
|
|
82
78
|
errorFilter = () => true,
|
|
83
79
|
warningFilter = () => true,
|
|
84
80
|
heading = t.accessCodes,
|
|
85
|
-
title = t.accessCodes,
|
|
86
81
|
className,
|
|
87
82
|
disableCreateAccessCode = false,
|
|
88
83
|
disableEditAccessCode = false,
|
|
@@ -231,10 +226,9 @@ export function AccessCodeTable({
|
|
|
231
226
|
<ContentHeader onBack={onBack} />
|
|
232
227
|
<TableHeader>
|
|
233
228
|
<div className='seam-left'>
|
|
234
|
-
{
|
|
229
|
+
{heading != null ? (
|
|
235
230
|
<TableTitle>
|
|
236
|
-
{heading
|
|
237
|
-
<Caption>({filteredAccessCodes.length})</Caption>
|
|
231
|
+
{heading} <Caption>({filteredAccessCodes.length})</Caption>
|
|
238
232
|
</TableTitle>
|
|
239
233
|
) : (
|
|
240
234
|
<div className='seam-fragment' />
|
|
@@ -133,7 +133,7 @@ export function ThermostatDeviceDetails({
|
|
|
133
133
|
</DetailSection>
|
|
134
134
|
|
|
135
135
|
<DetailSection label={t.deviceDetails}>
|
|
136
|
-
<DetailRow label={t.
|
|
136
|
+
<DetailRow label={t.manufacturer}>
|
|
137
137
|
<div className='seam-detail-row-hstack'>
|
|
138
138
|
{device.properties.model.manufacturer_display_name}
|
|
139
139
|
{device.properties.manufacturer === 'ecobee' && <BeeIcon />}
|
|
@@ -175,7 +175,7 @@ const t = {
|
|
|
175
175
|
defaultClimate: 'Default climate',
|
|
176
176
|
allowManualOverride: 'Allow manual override',
|
|
177
177
|
deviceDetails: 'Device details',
|
|
178
|
-
|
|
178
|
+
manufacturer: 'Manufacturer',
|
|
179
179
|
linkedAccount: 'Linked account',
|
|
180
180
|
deviceId: 'Device ID',
|
|
181
181
|
none: 'None',
|
|
@@ -41,10 +41,6 @@ export interface DeviceTableProps extends CommonProps {
|
|
|
41
41
|
onDeviceClick?: (deviceId: string) => void
|
|
42
42
|
preventDefaultOnDeviceClick?: boolean
|
|
43
43
|
heading?: string | null
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated Use heading.
|
|
46
|
-
*/
|
|
47
|
-
title?: string | null
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
export const defaultDeviceFilter = (
|
|
@@ -67,7 +63,6 @@ export function DeviceTable({
|
|
|
67
63
|
deviceFilter = defaultDeviceFilter,
|
|
68
64
|
deviceComparator = compareByCreatedAtDesc,
|
|
69
65
|
heading = t.devices,
|
|
70
|
-
title = t.devices,
|
|
71
66
|
errorFilter = () => true,
|
|
72
67
|
warningFilter = () => true,
|
|
73
68
|
disableLockUnlock = false,
|
|
@@ -129,10 +124,9 @@ export function DeviceTable({
|
|
|
129
124
|
<div className={classNames('seam-device-table', className)}>
|
|
130
125
|
<ContentHeader onBack={onBack} />
|
|
131
126
|
<TableHeader>
|
|
132
|
-
{
|
|
127
|
+
{heading != null ? (
|
|
133
128
|
<TableTitle>
|
|
134
|
-
{heading
|
|
135
|
-
<Caption>({filteredDevices.length})</Caption>
|
|
129
|
+
{heading} <Caption>({filteredDevices.length})</Caption>
|
|
136
130
|
</TableTitle>
|
|
137
131
|
) : (
|
|
138
132
|
<div className='seam-fragment' />
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeviceModelV1 } from '@seamapi/types/devicedb'
|
|
2
2
|
|
|
3
|
-
import { SupportedDeviceBrandSection } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceBrandSection.js'
|
|
4
3
|
import { SupportedDeviceFilterResultRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterResultRow.js'
|
|
4
|
+
import { SupportedDeviceManufacturerSection } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js'
|
|
5
|
+
import type { UseDeviceModelsData } from 'lib/seam/components/SupportedDeviceTable/use-device-models.js'
|
|
5
6
|
import {
|
|
6
7
|
type DeviceModelFilters,
|
|
7
8
|
useFilteredDeviceModels,
|
|
8
9
|
} from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js'
|
|
9
|
-
import type { UseDeviceModelsData } from 'lib/seam/device-models/use-device-models.js'
|
|
10
10
|
import { Button } from 'lib/ui/Button.js'
|
|
11
11
|
|
|
12
12
|
interface SupportedDeviceContentProps {
|
|
13
13
|
filterValue: string
|
|
14
14
|
resetFilterValue: () => void
|
|
15
15
|
filters: DeviceModelFilters
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
manufacturers: string[] | null
|
|
17
|
+
excludedManufacturers: string[]
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function SupportedDeviceContent({
|
|
21
21
|
resetFilterValue,
|
|
22
22
|
filterValue,
|
|
23
23
|
filters,
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
manufacturers,
|
|
25
|
+
excludedManufacturers,
|
|
26
26
|
}: SupportedDeviceContentProps): JSX.Element | null {
|
|
27
27
|
const { deviceModels, isLoading, isError, refetch } = useFilteredDeviceModels(
|
|
28
28
|
{
|
|
29
29
|
filterValue,
|
|
30
30
|
filters,
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
manufacturers,
|
|
32
|
+
excludedManufacturers,
|
|
33
33
|
}
|
|
34
34
|
)
|
|
35
35
|
|
|
@@ -74,20 +74,14 @@ export function SupportedDeviceContent({
|
|
|
74
74
|
)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
const hasFilters = filterValue.trim() !== '' || filters.
|
|
77
|
+
const hasFilters = filterValue.trim() !== '' || filters.manufacturer !== null
|
|
78
78
|
|
|
79
79
|
if (hasFilters) {
|
|
80
80
|
return (
|
|
81
81
|
<div className='seam-supported-device-table-content'>
|
|
82
|
-
{deviceModels.map((deviceModel
|
|
82
|
+
{deviceModels.map((deviceModel) => (
|
|
83
83
|
<SupportedDeviceFilterResultRow
|
|
84
|
-
key={
|
|
85
|
-
deviceModel.main_category,
|
|
86
|
-
deviceModel.brand,
|
|
87
|
-
deviceModel.model_name,
|
|
88
|
-
deviceModel.manufacturer_model_id,
|
|
89
|
-
index,
|
|
90
|
-
].join(':')}
|
|
84
|
+
key={deviceModel.device_model_id}
|
|
91
85
|
deviceModel={deviceModel}
|
|
92
86
|
/>
|
|
93
87
|
))}
|
|
@@ -97,11 +91,11 @@ export function SupportedDeviceContent({
|
|
|
97
91
|
|
|
98
92
|
return (
|
|
99
93
|
<>
|
|
100
|
-
{Object.entries(
|
|
101
|
-
([
|
|
102
|
-
<
|
|
103
|
-
key={
|
|
104
|
-
|
|
94
|
+
{Object.entries(groupDeviceModelsByManufacturer(deviceModels)).map(
|
|
95
|
+
([manufacturerId, models]) => (
|
|
96
|
+
<SupportedDeviceManufacturerSection
|
|
97
|
+
key={manufacturerId}
|
|
98
|
+
manufacturerId={manufacturerId}
|
|
105
99
|
deviceModels={models}
|
|
106
100
|
/>
|
|
107
101
|
)
|
|
@@ -142,15 +136,15 @@ function EmptyResult({
|
|
|
142
136
|
)
|
|
143
137
|
}
|
|
144
138
|
|
|
145
|
-
function
|
|
139
|
+
function groupDeviceModelsByManufacturer(
|
|
146
140
|
deviceModels: UseDeviceModelsData
|
|
147
|
-
): Record<string,
|
|
148
|
-
const result: Record<string,
|
|
141
|
+
): Record<string, DeviceModelV1[]> {
|
|
142
|
+
const result: Record<string, DeviceModelV1[]> = {}
|
|
149
143
|
|
|
150
144
|
for (const model of deviceModels) {
|
|
151
|
-
const {
|
|
152
|
-
const list = result[
|
|
153
|
-
result[
|
|
145
|
+
const { manufacturer } = model
|
|
146
|
+
const list = result[manufacturer.manufacturer_id] ?? []
|
|
147
|
+
result[manufacturer.manufacturer_id] = [...list, model]
|
|
154
148
|
}
|
|
155
149
|
return result
|
|
156
150
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SupportedDeviceRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js'
|
|
2
|
-
import type { UseDeviceModelsData } from 'lib/seam/
|
|
2
|
+
import type { UseDeviceModelsData } from 'lib/seam/components/SupportedDeviceTable/use-device-models.js'
|
|
3
3
|
|
|
4
4
|
interface SupportedDeviceContentRowsProps {
|
|
5
5
|
deviceModels: UseDeviceModelsData
|
|
@@ -10,15 +10,9 @@ export function SupportedDeviceContentRows({
|
|
|
10
10
|
}: SupportedDeviceContentRowsProps): JSX.Element | null {
|
|
11
11
|
return (
|
|
12
12
|
<div className='seam-supported-device-table-content'>
|
|
13
|
-
{deviceModels.map((deviceModel
|
|
13
|
+
{deviceModels.map((deviceModel) => (
|
|
14
14
|
<SupportedDeviceRow
|
|
15
|
-
key={
|
|
16
|
-
deviceModel.main_category,
|
|
17
|
-
deviceModel.brand,
|
|
18
|
-
deviceModel.model_name,
|
|
19
|
-
deviceModel.manufacturer_model_id,
|
|
20
|
-
index,
|
|
21
|
-
].join(':')}
|
|
15
|
+
key={deviceModel.device_model_id}
|
|
22
16
|
deviceModel={deviceModel}
|
|
23
17
|
/>
|
|
24
18
|
))}
|
|
@@ -2,19 +2,19 @@ import type { Dispatch, SetStateAction } from 'react'
|
|
|
2
2
|
|
|
3
3
|
import { FilterCategoryMenu } from 'lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.js'
|
|
4
4
|
import type { DeviceModelFilters } from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js'
|
|
5
|
-
import { useDeviceModels } from 'lib/seam/device-models/use-device-models.js'
|
|
6
|
-
import { capitalize } from 'lib/strings.js'
|
|
7
5
|
import { Button } from 'lib/ui/Button.js'
|
|
8
6
|
import { Menu } from 'lib/ui/Menu/Menu.js'
|
|
9
7
|
import { SearchTextField } from 'lib/ui/TextField/SearchTextField.js'
|
|
10
8
|
|
|
9
|
+
import { useFilteredManufacturers } from './use-filtered-manufacturers.js'
|
|
10
|
+
|
|
11
11
|
interface SupportedDeviceFilterAreaProps {
|
|
12
12
|
filterValue: string
|
|
13
13
|
setFilterValue: (filter: string) => void
|
|
14
14
|
filters: DeviceModelFilters
|
|
15
15
|
setFilters: Dispatch<SetStateAction<DeviceModelFilters>>
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
manufacturers: string[] | null
|
|
17
|
+
excludedManufacturers: string[]
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function SupportedDeviceFilterArea({
|
|
@@ -22,12 +22,15 @@ export function SupportedDeviceFilterArea({
|
|
|
22
22
|
setFilterValue,
|
|
23
23
|
filters,
|
|
24
24
|
setFilters,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
manufacturers,
|
|
26
|
+
excludedManufacturers,
|
|
27
27
|
}: SupportedDeviceFilterAreaProps): JSX.Element {
|
|
28
28
|
const appliedFiltersCount = getAppliedFilterCount(filters)
|
|
29
29
|
|
|
30
|
-
const
|
|
30
|
+
const { manufacturers: availableManufacturers } = useFilteredManufacturers({
|
|
31
|
+
manufacturers,
|
|
32
|
+
excludedManufacturers,
|
|
33
|
+
})
|
|
31
34
|
|
|
32
35
|
const resetFilter = (filterType: keyof DeviceModelFilters): void => {
|
|
33
36
|
setFilters((filters) => ({
|
|
@@ -64,18 +67,22 @@ export function SupportedDeviceFilterArea({
|
|
|
64
67
|
>
|
|
65
68
|
<div className='seam-filter-menu-row'>
|
|
66
69
|
<FilterCategoryMenu
|
|
67
|
-
label={t.
|
|
70
|
+
label={t.manufacturer}
|
|
68
71
|
allLabel={allLabel}
|
|
69
|
-
options={
|
|
70
|
-
|
|
72
|
+
options={
|
|
73
|
+
availableManufacturers?.map(
|
|
74
|
+
(manufacturer) => manufacturer.display_name
|
|
75
|
+
) ?? []
|
|
76
|
+
}
|
|
77
|
+
onSelect={(manufacturer: string) => {
|
|
71
78
|
setFilters((filters) => ({
|
|
72
79
|
...filters,
|
|
73
|
-
|
|
80
|
+
manufacturer,
|
|
74
81
|
}))
|
|
75
82
|
}}
|
|
76
|
-
buttonLabel={filters.
|
|
83
|
+
buttonLabel={filters.manufacturer ?? allLabel}
|
|
77
84
|
onAllOptionSelect={() => {
|
|
78
|
-
resetFilter('
|
|
85
|
+
resetFilter('manufacturer')
|
|
79
86
|
}}
|
|
80
87
|
/>
|
|
81
88
|
</div>
|
|
@@ -118,40 +125,14 @@ export function SupportedDeviceFilterArea({
|
|
|
118
125
|
|
|
119
126
|
const getAppliedFilterCount = (filters: DeviceModelFilters): number => {
|
|
120
127
|
let count = 0
|
|
121
|
-
if (filters.
|
|
128
|
+
if (filters.manufacturer !== null) count++
|
|
122
129
|
if (!filters.supportedOnly) count++
|
|
123
130
|
return count
|
|
124
131
|
}
|
|
125
132
|
|
|
126
|
-
const useAvailableBrands = (
|
|
127
|
-
brands: string[] | null,
|
|
128
|
-
excludedBrands: string[]
|
|
129
|
-
): string[] => {
|
|
130
|
-
const { deviceModels } = useDeviceModels()
|
|
131
|
-
|
|
132
|
-
if (deviceModels == null) return []
|
|
133
|
-
|
|
134
|
-
const availableBrands = deviceModels
|
|
135
|
-
.map(({ brand }) => brand.trim())
|
|
136
|
-
.filter((brand) => {
|
|
137
|
-
// UPSTREAM: API can return an empty value for brand.
|
|
138
|
-
return brand !== ''
|
|
139
|
-
})
|
|
140
|
-
.filter((brand) => {
|
|
141
|
-
if (brands === null) return true
|
|
142
|
-
return brands.includes(brand)
|
|
143
|
-
})
|
|
144
|
-
.filter((brand) => {
|
|
145
|
-
return !excludedBrands.includes(brand)
|
|
146
|
-
})
|
|
147
|
-
.map((brand) => capitalize(brand))
|
|
148
|
-
|
|
149
|
-
return Array.from(new Set(availableBrands))
|
|
150
|
-
}
|
|
151
|
-
|
|
152
133
|
const t = {
|
|
153
134
|
all: 'All',
|
|
154
|
-
|
|
135
|
+
manufacturer: 'Manufacturer',
|
|
155
136
|
supported: 'Supported',
|
|
156
137
|
filter: 'Filter',
|
|
157
138
|
filters: 'Filters',
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeviceModelV1 } from '@seamapi/types/devicedb'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
connectionTypeNames,
|
|
5
4
|
ImageColumn,
|
|
6
5
|
StatusColumn,
|
|
7
6
|
} from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js'
|
|
8
|
-
import { useDeviceProvider } from 'lib/seam/components/SupportedDeviceTable/use-device-provider.js'
|
|
9
7
|
import { DotDivider } from 'lib/ui/layout/DotDivider.js'
|
|
10
8
|
|
|
11
9
|
interface SupportedDeviceFilterResultRowProps {
|
|
12
|
-
deviceModel:
|
|
10
|
+
deviceModel: DeviceModelV1
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
export function SupportedDeviceFilterResultRow({
|
|
@@ -27,23 +25,21 @@ export function SupportedDeviceFilterResultRow({
|
|
|
27
25
|
export function ModelColumn({
|
|
28
26
|
deviceModel,
|
|
29
27
|
}: SupportedDeviceFilterResultRowProps): JSX.Element {
|
|
30
|
-
const deviceProvider = useDeviceProvider(deviceModel.brand)
|
|
31
|
-
|
|
32
28
|
return (
|
|
33
29
|
<div className='seam-col seam-model-col'>
|
|
34
30
|
<div className='seam-model-name'>
|
|
35
31
|
<img
|
|
36
|
-
src={
|
|
37
|
-
alt={deviceModel.
|
|
38
|
-
className='seam-
|
|
32
|
+
src={deviceModel.manufacturer.logo?.url}
|
|
33
|
+
alt={deviceModel.manufacturer.display_name}
|
|
34
|
+
className='seam-manufacturer-image'
|
|
39
35
|
/>{' '}
|
|
40
|
-
<div className='seam-truncated-text'>{deviceModel.
|
|
36
|
+
<div className='seam-truncated-text'>{deviceModel.display_name}</div>
|
|
41
37
|
</div>
|
|
42
38
|
<div className='seam-model-id'>
|
|
43
39
|
<div className='seam-truncated-text'>
|
|
44
|
-
{deviceModel.
|
|
40
|
+
{deviceModel.device_model_id}
|
|
45
41
|
<DotDivider />
|
|
46
|
-
{
|
|
42
|
+
{deviceModel.main_connection_type}
|
|
47
43
|
</div>
|
|
48
44
|
</div>
|
|
49
45
|
</div>
|
|
@@ -1,30 +1,29 @@
|
|
|
1
|
+
import type { DeviceModelV1 } from '@seamapi/types/devicedb'
|
|
1
2
|
import classNames from 'classnames'
|
|
2
|
-
import type { DeviceModel } from 'seamapi'
|
|
3
3
|
|
|
4
4
|
import { ChevronRightIcon } from 'lib/icons/ChevronRight.js'
|
|
5
5
|
import { HiddenDevicesOverlay } from 'lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.js'
|
|
6
6
|
import { ShowAllDevicesButton } from 'lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.js'
|
|
7
7
|
import { SupportedDeviceRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js'
|
|
8
|
-
import {
|
|
8
|
+
import { useManufacturer } from 'lib/seam/components/SupportedDeviceTable/use-manufacturer.js'
|
|
9
9
|
import { useToggle } from 'lib/ui/use-toggle.js'
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* How many device models required before
|
|
13
|
-
*
|
|
14
|
-
* view all.
|
|
12
|
+
* How many device models required before collapsing the list,
|
|
13
|
+
* and requiring the user to click to view all.
|
|
15
14
|
*/
|
|
16
15
|
const maxDevicesBeforeCollapsing = 3
|
|
17
16
|
|
|
18
|
-
interface
|
|
19
|
-
|
|
20
|
-
deviceModels:
|
|
17
|
+
interface SupportedDeviceManufacturerSectionProps {
|
|
18
|
+
manufacturerId: string
|
|
19
|
+
deviceModels: DeviceModelV1[]
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
export function
|
|
24
|
-
|
|
22
|
+
export function SupportedDeviceManufacturerSection({
|
|
23
|
+
manufacturerId,
|
|
25
24
|
deviceModels,
|
|
26
|
-
}:
|
|
27
|
-
const
|
|
25
|
+
}: SupportedDeviceManufacturerSectionProps): JSX.Element | null {
|
|
26
|
+
const { manufacturer } = useManufacturer({ manufacturer_id: manufacturerId })
|
|
28
27
|
|
|
29
28
|
const [expanded, toggleExpand] = useToggle()
|
|
30
29
|
|
|
@@ -47,32 +46,26 @@ export function SupportedDeviceBrandSection({
|
|
|
47
46
|
|
|
48
47
|
return (
|
|
49
48
|
<div
|
|
50
|
-
className={classNames('seam-
|
|
49
|
+
className={classNames('seam-manufacturer-section', {
|
|
51
50
|
'can-expand': canExpand,
|
|
52
51
|
expanded,
|
|
53
52
|
})}
|
|
54
53
|
>
|
|
55
54
|
<div className='seam-header' onClick={handleHeaderClick}>
|
|
56
55
|
<img
|
|
57
|
-
src={
|
|
58
|
-
alt={
|
|
59
|
-
className='seam-
|
|
56
|
+
src={manufacturer?.logo?.url}
|
|
57
|
+
alt={manufacturer?.display_name}
|
|
58
|
+
className='seam-manufacturer-image'
|
|
60
59
|
/>
|
|
61
|
-
<h5 className='seam-
|
|
62
|
-
{
|
|
60
|
+
<h5 className='seam-manufacturer-name'>
|
|
61
|
+
{manufacturer?.display_name} {t.devices}
|
|
63
62
|
</h5>
|
|
64
63
|
{canExpand && <ChevronRightIcon className='chevron' />}
|
|
65
64
|
</div>
|
|
66
65
|
<div className='seam-supported-device-table-content'>
|
|
67
|
-
{visibleDevices.map((deviceModel
|
|
66
|
+
{visibleDevices.map((deviceModel) => (
|
|
68
67
|
<SupportedDeviceRow
|
|
69
|
-
key={
|
|
70
|
-
deviceModel.main_category,
|
|
71
|
-
deviceModel.brand,
|
|
72
|
-
deviceModel.model_name,
|
|
73
|
-
deviceModel.manufacturer_model_id,
|
|
74
|
-
index,
|
|
75
|
-
].join(':')}
|
|
68
|
+
key={deviceModel.device_model_id}
|
|
76
69
|
deviceModel={deviceModel}
|
|
77
70
|
/>
|
|
78
71
|
))}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { DeviceModelV1 } from '@seamapi/types/devicedb'
|
|
1
2
|
import classNames from 'classnames'
|
|
2
3
|
import type { DeviceModel } from 'seamapi'
|
|
3
4
|
|
|
4
5
|
import { DotDivider } from 'lib/ui/layout/DotDivider.js'
|
|
5
6
|
|
|
6
7
|
interface SupportedDeviceRowProps {
|
|
7
|
-
deviceModel:
|
|
8
|
+
deviceModel: DeviceModelV1
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export function SupportedDeviceRow({
|
|
@@ -25,7 +26,10 @@ export function ImageColumn({
|
|
|
25
26
|
return (
|
|
26
27
|
<div className='seam-col seam-device-image-col'>
|
|
27
28
|
<div className='seam-image-box'>
|
|
28
|
-
<img
|
|
29
|
+
<img
|
|
30
|
+
width={40}
|
|
31
|
+
src={deviceModel.aesthetic_variants[0]?.images[0]?.url}
|
|
32
|
+
/>
|
|
29
33
|
</div>
|
|
30
34
|
</div>
|
|
31
35
|
)
|
|
@@ -37,13 +41,13 @@ export function ModelColumn({
|
|
|
37
41
|
return (
|
|
38
42
|
<div className='seam-col seam-model-col'>
|
|
39
43
|
<div className='seam-model-name'>
|
|
40
|
-
<div className='seam-truncated-text'>{deviceModel.
|
|
44
|
+
<div className='seam-truncated-text'>{deviceModel.display_name}</div>
|
|
41
45
|
</div>
|
|
42
46
|
<div className='seam-model-id'>
|
|
43
47
|
<div className='seam-truncated-text'>
|
|
44
|
-
{deviceModel.
|
|
48
|
+
{deviceModel.device_model_id}
|
|
45
49
|
<DotDivider />
|
|
46
|
-
{
|
|
50
|
+
{deviceModel.main_connection_type}
|
|
47
51
|
</div>
|
|
48
52
|
</div>
|
|
49
53
|
</div>
|
|
@@ -53,30 +57,35 @@ export function ModelColumn({
|
|
|
53
57
|
export function StatusColumn({
|
|
54
58
|
deviceModel,
|
|
55
59
|
}: SupportedDeviceRowProps): JSX.Element {
|
|
56
|
-
const statusColor =
|
|
60
|
+
const statusColor =
|
|
61
|
+
supportLevelColors[deviceModel.manufacturer.integration] ?? 'unknown'
|
|
57
62
|
|
|
58
63
|
return (
|
|
59
64
|
<div className='seam-col seam-status-col'>
|
|
60
65
|
<div className={classNames('seam-status-pill', `status-${statusColor}`)}>
|
|
61
|
-
<span>{status[deviceModel.
|
|
66
|
+
<span>{status[deviceModel.manufacturer.integration]}</span>
|
|
62
67
|
</div>
|
|
63
68
|
</div>
|
|
64
69
|
)
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
const supportLevelColors: Record<
|
|
68
|
-
|
|
73
|
+
DeviceModelV1['manufacturer']['integration'],
|
|
69
74
|
'green' | 'blue' | 'unknown'
|
|
70
75
|
> = {
|
|
71
|
-
|
|
76
|
+
stable: 'green',
|
|
72
77
|
beta: 'blue',
|
|
78
|
+
planned: 'unknown',
|
|
73
79
|
unsupported: 'unknown',
|
|
80
|
+
inquire: 'unknown',
|
|
74
81
|
}
|
|
75
82
|
|
|
76
|
-
const status: Record<
|
|
77
|
-
|
|
83
|
+
const status: Record<DeviceModelV1['manufacturer']['integration'], string> = {
|
|
84
|
+
stable: 'LIVE',
|
|
78
85
|
beta: 'BETA',
|
|
79
86
|
unsupported: 'Inquire',
|
|
87
|
+
planned: 'Inquire',
|
|
88
|
+
inquire: 'Inquire',
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
export const connectionTypeNames: Record<
|
|
@@ -5,10 +5,9 @@ import type { SupportedDeviceTableProps } from './SupportedDeviceTable.js'
|
|
|
5
5
|
export const name = 'seam-supported-device-table'
|
|
6
6
|
|
|
7
7
|
export const props: ElementProps<SupportedDeviceTableProps> = {
|
|
8
|
-
cannotFilter: 'boolean',
|
|
9
8
|
disableFilter: 'boolean',
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
manufacturers: 'array',
|
|
10
|
+
excludedManufacturers: 'array',
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
export { SupportedDeviceTable as Component } from './SupportedDeviceTable.js'
|