@seamapi/react 4.14.2 → 5.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.
Files changed (86) hide show
  1. package/README.md +2 -3
  2. package/dist/elements.js +9525 -10202
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +0 -345
  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/seam/components/index.d.ts +0 -2
  9. package/lib/seam/components/index.js +0 -2
  10. package/lib/seam/components/index.js.map +1 -1
  11. package/lib/version.d.ts +1 -1
  12. package/lib/version.js +1 -1
  13. package/lib/version.js.map +1 -1
  14. package/package.json +1 -1
  15. package/src/lib/seam/components/elements.ts +0 -2
  16. package/src/lib/seam/components/index.ts +0 -2
  17. package/src/lib/version.ts +1 -1
  18. package/src/styles/_main.scss +0 -4
  19. package/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.d.ts +0 -20
  20. package/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.js +0 -22
  21. package/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.js.map +0 -1
  22. package/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.d.ts +0 -6
  23. package/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.js +0 -8
  24. package/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.js.map +0 -1
  25. package/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.d.ts +0 -9
  26. package/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.js +0 -14
  27. package/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.js.map +0 -1
  28. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.d.ts +0 -13
  29. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js +0 -58
  30. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js.map +0 -1
  31. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.d.ts +0 -7
  32. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.js +0 -6
  33. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.js.map +0 -1
  34. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.d.ts +0 -12
  35. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.js +0 -58
  36. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.js.map +0 -1
  37. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.d.ts +0 -8
  38. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js +0 -39
  39. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js.map +0 -1
  40. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.d.ts +0 -10
  41. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js +0 -35
  42. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js.map +0 -1
  43. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.d.ts +0 -11
  44. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.js +0 -20
  45. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.js.map +0 -1
  46. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.d.ts +0 -6
  47. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js +0 -21
  48. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js.map +0 -1
  49. package/lib/seam/components/SupportedDeviceTable/use-device-model.d.ts +0 -7
  50. package/lib/seam/components/SupportedDeviceTable/use-device-model.js +0 -21
  51. package/lib/seam/components/SupportedDeviceTable/use-device-model.js.map +0 -1
  52. package/lib/seam/components/SupportedDeviceTable/use-device-models.d.ts +0 -7
  53. package/lib/seam/components/SupportedDeviceTable/use-device-models.js +0 -30
  54. package/lib/seam/components/SupportedDeviceTable/use-device-models.js.map +0 -1
  55. package/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.d.ts +0 -15
  56. package/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js +0 -45
  57. package/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js.map +0 -1
  58. package/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.d.ts +0 -10
  59. package/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.js +0 -42
  60. package/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.js.map +0 -1
  61. package/lib/seam/components/SupportedDeviceTable/use-manufacturer.d.ts +0 -7
  62. package/lib/seam/components/SupportedDeviceTable/use-manufacturer.js +0 -17
  63. package/lib/seam/components/SupportedDeviceTable/use-manufacturer.js.map +0 -1
  64. package/lib/seam/components/SupportedDeviceTable/use-manufacturers.d.ts +0 -7
  65. package/lib/seam/components/SupportedDeviceTable/use-manufacturers.js +0 -26
  66. package/lib/seam/components/SupportedDeviceTable/use-manufacturers.js.map +0 -1
  67. package/src/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.tsx +0 -78
  68. package/src/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.tsx +0 -13
  69. package/src/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.tsx +0 -32
  70. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx +0 -161
  71. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.tsx +0 -22
  72. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx +0 -145
  73. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.tsx +0 -109
  74. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx +0 -93
  75. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.element.ts +0 -15
  76. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.tsx +0 -70
  77. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts +0 -9
  78. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx +0 -64
  79. package/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts +0 -44
  80. package/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts +0 -57
  81. package/src/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.ts +0 -88
  82. package/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts +0 -69
  83. package/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts +0 -40
  84. package/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts +0 -53
  85. package/src/styles/_supported-device-table-manufacturer-keys.scss +0 -20
  86. package/src/styles/_supported-device-table.scss +0 -412
@@ -1,17 +0,0 @@
1
- import { useSeamClient } from '@seamapi/react-query';
2
- import { useQuery } from '@tanstack/react-query';
3
- export function useManufacturer(params) {
4
- const { client: seam } = useSeamClient();
5
- const { data, ...rest } = useQuery({
6
- enabled: seam != null,
7
- queryKey: ['internal', 'manufacturers', 'get', params],
8
- queryFn: async () => {
9
- if (seam == null)
10
- return null;
11
- const { data: { manufacturer }, } = await seam.client.get('/internal/devicedb/v1/manufacturers/get', { params });
12
- return manufacturer;
13
- },
14
- });
15
- return { ...rest, manufacturer: data };
16
- }
17
- //# sourceMappingURL=use-manufacturer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-manufacturer.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAMpD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAQhD,MAAM,UAAU,eAAe,CAC7B,MAA6B;IAE7B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAA;IACxC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAwC;QACxE,OAAO,EAAE,IAAI,IAAI,IAAI;QACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,CAAC;QACtD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,IAAI,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAA;YAC7B,MAAM,EACJ,IAAI,EAAE,EAAE,YAAY,EAAE,GACvB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CACvB,yCAAyC,EACzC,EAAE,MAAM,EAAE,CACX,CAAA;YACD,OAAO,YAAY,CAAA;QACrB,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;AACxC,CAAC"}
@@ -1,7 +0,0 @@
1
- import type { Manufacturer, RouteRequestParams } from '@seamapi/types/devicedb';
2
- import type { UseSeamQueryResultLegacy } from '../../../../lib/seam/use-seam-query-result.js';
3
- export type UseManufacturersParams = ManufacturersListParams;
4
- export type UseManufacturersData = Manufacturer[];
5
- export declare function useManufacturers(params?: UseManufacturersParams): UseSeamQueryResultLegacy<'manufacturers', UseManufacturersData>;
6
- type ManufacturersListParams = RouteRequestParams<'/v1/manufacturers/list'>;
7
- export {};
@@ -1,26 +0,0 @@
1
- import { useSeamClient } from '@seamapi/react-query';
2
- import { useQuery, useQueryClient } from '@tanstack/react-query';
3
- export function useManufacturers(params) {
4
- const { client: seam } = useSeamClient();
5
- const queryClient = useQueryClient();
6
- const { data, ...rest } = useQuery({
7
- enabled: seam != null,
8
- queryKey: ['internal', 'manufacturers', 'list', params],
9
- queryFn: async () => {
10
- if (seam == null)
11
- return [];
12
- const { data: { manufacturers }, } = await seam.client.get('/internal/devicedb/v1/manufacturers/list', { params });
13
- for (const manufacturer of manufacturers) {
14
- queryClient.setQueryData([
15
- 'internal',
16
- 'manufacturers',
17
- 'get',
18
- { manufacturer_id: manufacturer.manufacturer_id },
19
- ], manufacturer);
20
- }
21
- return manufacturers;
22
- },
23
- });
24
- return { ...rest, manufacturers: data };
25
- }
26
- //# sourceMappingURL=use-manufacturers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-manufacturers.js","sourceRoot":"","sources":["../../../../src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAMpD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAQhE,MAAM,UAAU,gBAAgB,CAC9B,MAA+B;IAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAA;IACxC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAyC;QACzE,OAAO,EAAE,IAAI,IAAI,IAAI;QACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC;QACvD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,IAAI,IAAI,IAAI;gBAAE,OAAO,EAAE,CAAA;YAC3B,MAAM,EACJ,IAAI,EAAE,EAAE,aAAa,EAAE,GACxB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CACvB,0CAA0C,EAC1C,EAAE,MAAM,EAAE,CACX,CAAA;YACD,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACzC,WAAW,CAAC,YAAY,CACtB;oBACE,UAAU;oBACV,eAAe;oBACf,KAAK;oBACL,EAAE,eAAe,EAAE,YAAY,CAAC,eAAe,EAAE;iBAClD,EACD,YAAY,CACb,CAAA;YACH,CAAC;YACD,OAAO,aAAa,CAAA;QACtB,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAA;AACzC,CAAC"}
@@ -1,78 +0,0 @@
1
- import { ChevronDownIcon } from 'lib/icons/ChevronDown.js'
2
- import { Menu } from 'lib/ui/Menu/Menu.js'
3
- import { MenuItem } from 'lib/ui/Menu/MenuItem.js'
4
-
5
- export type FilterCategoryMenuProps =
6
- | FilterCategoryMenuPropsWithAllOption
7
- | FilterCategoryMenuPropsWithoutAllOption
8
-
9
- interface FilterCategoryMenuPropsWithAllOption
10
- extends FilterCategoryMenuBaseProps {
11
- hideAllOption?: false
12
- allLabel: string
13
- onAllOptionSelect: () => void
14
- }
15
-
16
- interface FilterCategoryMenuPropsWithoutAllOption
17
- extends FilterCategoryMenuBaseProps {
18
- hideAllOption: true
19
- allLabel: never
20
- onAllOptionSelect?: never
21
- }
22
-
23
- interface FilterCategoryMenuBaseProps {
24
- label: string
25
- options: string[]
26
- onSelect: (option: string) => void
27
- buttonLabel?: string
28
- }
29
-
30
- export function FilterCategoryMenu({
31
- label = t.filter,
32
- allLabel,
33
- options,
34
- hideAllOption = false,
35
- onSelect,
36
- onAllOptionSelect,
37
- buttonLabel,
38
- }: FilterCategoryMenuProps): JSX.Element {
39
- const sortedOptions = [...options].sort((a, b) => a.localeCompare(b))
40
- const usableOptions = hideAllOption
41
- ? sortedOptions
42
- : [allLabel, ...sortedOptions]
43
-
44
- return (
45
- <div className='seam-supported-device-table-filter-menu-wrap'>
46
- <p>{label}</p>
47
- <Menu
48
- renderButton={({ onOpen }) => (
49
- <button type='button' onClick={onOpen}>
50
- <span>{buttonLabel}</span>
51
- <ChevronDownIcon />
52
- </button>
53
- )}
54
- >
55
- <div className='seam-supported-device-table-filter-menu-content'>
56
- {usableOptions.map((option, index) => (
57
- <MenuItem
58
- key={`${index}:${option}`}
59
- onClick={() => {
60
- if (option === allLabel) {
61
- onAllOptionSelect?.()
62
- } else {
63
- onSelect(option)
64
- }
65
- }}
66
- >
67
- <span>{option}</span>
68
- </MenuItem>
69
- ))}
70
- </div>
71
- </Menu>
72
- </div>
73
- )
74
- }
75
-
76
- const t = {
77
- filter: 'Filter',
78
- }
@@ -1,13 +0,0 @@
1
- interface HiddenDevicesOverlayProps {
2
- visible: boolean
3
- }
4
-
5
- export function HiddenDevicesOverlay({
6
- visible,
7
- }: HiddenDevicesOverlayProps): JSX.Element | null {
8
- if (!visible) {
9
- return null
10
- }
11
-
12
- return <div className='hidden-devices-overlay' />
13
- }
@@ -1,32 +0,0 @@
1
- import { ChevronRightIcon } from 'lib/icons/ChevronRight.js'
2
-
3
- interface ShowAllDevicesButtonProps {
4
- onClick: () => void
5
- visible: boolean
6
- expanded: boolean
7
- totalDeviceCount: number
8
- }
9
-
10
- export function ShowAllDevicesButton({
11
- onClick,
12
- visible,
13
- expanded,
14
- totalDeviceCount,
15
- }: ShowAllDevicesButtonProps): JSX.Element | null {
16
- if (!visible) {
17
- return null
18
- }
19
-
20
- const label = expanded ? t.showLess : t.showAll(totalDeviceCount)
21
-
22
- return (
23
- <button type='button' className='show-all-devices-button' onClick={onClick}>
24
- <ChevronRightIcon /> {label}
25
- </button>
26
- )
27
- }
28
-
29
- const t = {
30
- showLess: 'Show less',
31
- showAll: (count: number) => `See all ${count}`,
32
- }
@@ -1,161 +0,0 @@
1
- import type { DeviceModel } from '@seamapi/types/devicedb'
2
- import { useMemo } from 'react'
3
-
4
- import { SupportedDeviceManufacturerSection } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js'
5
- import {
6
- type DeviceModelFilters,
7
- useFilteredDeviceModels,
8
- } from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js'
9
- import { Button } from 'lib/ui/Button.js'
10
-
11
- interface SupportedDeviceContentProps {
12
- filterValue: string
13
- resetFilterValue: () => void
14
- filters: DeviceModelFilters
15
- manufacturers: string[] | null
16
- excludedManufacturers: string[]
17
- includeIf: string[] | null
18
- excludeIf: string[]
19
- }
20
-
21
- export function SupportedDeviceContent({
22
- resetFilterValue,
23
- filterValue,
24
- filters,
25
- manufacturers,
26
- excludedManufacturers,
27
- includeIf,
28
- excludeIf,
29
- }: SupportedDeviceContentProps): JSX.Element | null {
30
- const { deviceModels, isPending, isError, refetch } = useFilteredDeviceModels(
31
- {
32
- filterValue,
33
- filters,
34
- manufacturers,
35
- excludedManufacturers,
36
- includeIf,
37
- excludeIf,
38
- }
39
- )
40
-
41
- const groupedDeviceModels = useMemo(
42
- () => groupDeviceModelsByManufacturer(deviceModels ?? []),
43
- [deviceModels]
44
- )
45
-
46
- if (isPending) {
47
- return (
48
- <div className='seam-supported-device-table-content-state-block'>
49
- <p>{t.loading}</p>
50
- </div>
51
- )
52
- }
53
-
54
- if (isError) {
55
- return (
56
- <div className='seam-supported-device-table-content-state-block'>
57
- <p>{t.error}</p>
58
- <Button
59
- variant='solid'
60
- size='small'
61
- onClick={() => {
62
- void refetch()
63
- }}
64
- >
65
- {t.retry}
66
- </Button>
67
- </div>
68
- )
69
- }
70
-
71
- if (deviceModels == null) {
72
- return null
73
- }
74
-
75
- const isEmpty = deviceModels.length === 0
76
- if (isEmpty) {
77
- return (
78
- <div className='seam-supported-device-table-content'>
79
- <EmptyResult
80
- filterValue={filterValue}
81
- resetFilterValue={resetFilterValue}
82
- />
83
- </div>
84
- )
85
- }
86
-
87
- return (
88
- <>
89
- {Object.entries(groupedDeviceModels)
90
- .sort(
91
- (e1, e2) =>
92
- e1[1][0]?.manufacturer.display_name.localeCompare(
93
- e2[1][0]?.manufacturer.display_name ?? ''
94
- ) ?? 0
95
- )
96
- .map(([manufacturerId, models]) => {
97
- return (
98
- <SupportedDeviceManufacturerSection
99
- key={manufacturerId}
100
- manufacturerId={manufacturerId}
101
- deviceModels={models}
102
- />
103
- )
104
- })}
105
- </>
106
- )
107
- }
108
-
109
- function EmptyResult({
110
- filterValue,
111
- resetFilterValue,
112
- }: Pick<
113
- SupportedDeviceContentProps,
114
- 'filterValue' | 'resetFilterValue'
115
- >): JSX.Element {
116
- const noMatchingRows = (
117
- <>
118
- <p>{t.noMatch}</p>
119
- <Button
120
- variant='outline'
121
- size='small'
122
- onClick={resetFilterValue}
123
- className='seam-supported-device-table-content-message-clear-search'
124
- >
125
- {t.clear}
126
- </Button>
127
- </>
128
- )
129
-
130
- return (
131
- <div className='seam-supported-device-table-content-message-row'>
132
- <div>
133
- <div className='seam-supported-device-table-content-message'>
134
- {filterValue.length === 0 ? <p>{t.noneFound}</p> : noMatchingRows}
135
- </div>
136
- </div>
137
- </div>
138
- )
139
- }
140
-
141
- const groupDeviceModelsByManufacturer = (
142
- deviceModels: DeviceModel[]
143
- ): Record<string, DeviceModel[]> => {
144
- const result: Record<string, DeviceModel[]> = {}
145
-
146
- for (const model of deviceModels) {
147
- const { manufacturer } = model
148
- const list = result[manufacturer.manufacturer_id] ?? []
149
- result[manufacturer.manufacturer_id] = [...list, model]
150
- }
151
- return result
152
- }
153
-
154
- const t = {
155
- loading: 'Loading device models...',
156
- retry: 'Retry',
157
- error: 'There was an error fetching device models.',
158
- noneFound: 'No device models found.',
159
- noMatch: 'No device models matched your search.',
160
- clear: 'Clear search terms',
161
- }
@@ -1,22 +0,0 @@
1
- import type { DeviceModel } from '@seamapi/types/devicedb'
2
-
3
- import { SupportedDeviceRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js'
4
-
5
- interface SupportedDeviceContentRowsProps {
6
- deviceModels: DeviceModel[]
7
- }
8
-
9
- export function SupportedDeviceContentRows({
10
- deviceModels,
11
- }: SupportedDeviceContentRowsProps): JSX.Element | null {
12
- return (
13
- <div className='seam-supported-device-table-content'>
14
- {deviceModels.map((deviceModel) => (
15
- <SupportedDeviceRow
16
- key={deviceModel.device_model_id}
17
- deviceModel={deviceModel}
18
- />
19
- ))}
20
- </div>
21
- )
22
- }
@@ -1,145 +0,0 @@
1
- import type { Dispatch, SetStateAction } from 'react'
2
-
3
- import { FilterCategoryMenu } from 'lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.js'
4
- import {
5
- type DeviceModelFilters,
6
- supportedIntegrationSupportLevels,
7
- } from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js'
8
- import { Button } from 'lib/ui/Button.js'
9
- import { Menu } from 'lib/ui/Menu/Menu.js'
10
- import { SearchTextField } from 'lib/ui/TextField/SearchTextField.js'
11
-
12
- import { useFilteredManufacturers } from './use-filtered-manufacturers.js'
13
-
14
- interface SupportedDeviceFilterAreaProps {
15
- filterValue: string
16
- setFilterValue: (filter: string) => void
17
- filters: DeviceModelFilters
18
- setFilters: Dispatch<SetStateAction<DeviceModelFilters>>
19
- manufacturers: string[] | null
20
- excludedManufacturers: string[]
21
- }
22
-
23
- export function SupportedDeviceFilterArea({
24
- filterValue,
25
- setFilterValue,
26
- filters,
27
- setFilters,
28
- manufacturers,
29
- excludedManufacturers,
30
- }: SupportedDeviceFilterAreaProps): JSX.Element {
31
- const appliedFiltersCount = getAppliedFilterCount(filters)
32
-
33
- const { manufacturers: manufacturersData } = useFilteredManufacturers({
34
- integrationSupportLevels: filters.supportedOnly
35
- ? supportedIntegrationSupportLevels
36
- : null,
37
- manufacturers,
38
- excludedManufacturers,
39
- })
40
-
41
- const resetFilter = (filterType: keyof DeviceModelFilters): void => {
42
- setFilters((filters) => ({
43
- ...filters,
44
- [filterType]: null,
45
- }))
46
- }
47
-
48
- const filterButtonLabel =
49
- appliedFiltersCount > 0 ? `${t.filters} (${appliedFiltersCount})` : t.filter
50
-
51
- const allLabel = t.all
52
-
53
- return (
54
- <div className='seam-supported-device-table-filter-area'>
55
- <div className='seam-deliberate-block' />
56
- <div className='seam-filters-wrap'>
57
- <Menu
58
- renderButton={({ onOpen }) => (
59
- <Button
60
- variant='outline'
61
- className='seam-filters-button'
62
- onClick={onOpen}
63
- >
64
- {filterButtonLabel}
65
- </Button>
66
- )}
67
- >
68
- <div
69
- className='seam-supported-device-table-filter-menu'
70
- onClick={(event) => {
71
- event.stopPropagation()
72
- }}
73
- >
74
- <div className='seam-filter-menu-row'>
75
- <FilterCategoryMenu
76
- label={t.manufacturer}
77
- allLabel={allLabel}
78
- options={
79
- manufacturersData?.map(
80
- (manufacturer) => manufacturer.display_name
81
- ) ?? []
82
- }
83
- onSelect={(manufacturer: string) => {
84
- setFilters((filters) => ({
85
- ...filters,
86
- manufacturer,
87
- }))
88
- }}
89
- buttonLabel={filters.manufacturer ?? allLabel}
90
- onAllOptionSelect={() => {
91
- resetFilter('manufacturer')
92
- }}
93
- />
94
- </div>
95
- <div className='seam-filter-menu-row'>
96
- <label
97
- htmlFor='supportedOnly'
98
- className='seam-filter-checkbox-label'
99
- >
100
- <p>{t.supported}</p>
101
- <input
102
- id='supportedOnly'
103
- name='supportedOnly'
104
- type='checkbox'
105
- className='seam-filter-checkbox'
106
- checked={filters.supportedOnly}
107
- onChange={(event) => {
108
- setFilters((filters) => ({
109
- ...filters,
110
- supportedOnly: event.target.checked,
111
- }))
112
- }}
113
- />
114
- </label>
115
- </div>
116
- </div>
117
- </Menu>
118
- <div className='seam-supported-device-table-filter-area-search-bar-wrap'>
119
- <SearchTextField
120
- value={filterValue}
121
- onChange={(value) => {
122
- setFilterValue(value)
123
- }}
124
- className='seam-supported-device-table-filter-area-search-bar'
125
- />
126
- </div>
127
- </div>
128
- </div>
129
- )
130
- }
131
-
132
- const getAppliedFilterCount = (filters: DeviceModelFilters): number => {
133
- let count = 0
134
- if (filters.manufacturer !== null) count++
135
- if (!filters.supportedOnly) count++
136
- return count
137
- }
138
-
139
- const t = {
140
- all: 'All',
141
- manufacturer: 'Manufacturer',
142
- supported: 'Supported',
143
- filter: 'Filter',
144
- filters: 'Filters',
145
- }
@@ -1,109 +0,0 @@
1
- import type {
2
- DeviceModel,
3
- ManufacturerAnnotation,
4
- } from '@seamapi/types/devicedb'
5
- import classNames from 'classnames'
6
-
7
- import { ChevronRightIcon } from 'lib/icons/ChevronRight.js'
8
- import { InfoBlueIcon } from 'lib/icons/InfoBlue.js'
9
- import { HiddenDevicesOverlay } from 'lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.js'
10
- import { ShowAllDevicesButton } from 'lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.js'
11
- import { SupportedDeviceRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js'
12
- import { useManufacturer } from 'lib/seam/components/SupportedDeviceTable/use-manufacturer.js'
13
- import { useToggle } from 'lib/ui/use-toggle.js'
14
-
15
- /**
16
- * How many device models required before collapsing the list,
17
- * and requiring the user to click to view all.
18
- */
19
- const maxDevicesBeforeCollapsing = 3
20
-
21
- interface SupportedDeviceManufacturerSectionProps {
22
- manufacturerId: string
23
- deviceModels: DeviceModel[]
24
- }
25
-
26
- export function SupportedDeviceManufacturerSection({
27
- manufacturerId,
28
- deviceModels,
29
- }: SupportedDeviceManufacturerSectionProps): JSX.Element | null {
30
- const { manufacturer } = useManufacturer({ manufacturer_id: manufacturerId })
31
-
32
- const [expanded, toggleExpand] = useToggle()
33
-
34
- const canExpand = deviceModels.length > maxDevicesBeforeCollapsing
35
-
36
- const visibleDevices =
37
- !canExpand || expanded
38
- ? deviceModels
39
- : deviceModels.filter(
40
- (_deviceModel, index) => index < maxDevicesBeforeCollapsing
41
- )
42
-
43
- const handleHeaderClick = (): void => {
44
- if (!canExpand) {
45
- return
46
- }
47
-
48
- toggleExpand()
49
- }
50
-
51
- return (
52
- <div
53
- className={classNames('seam-manufacturer-section', {
54
- 'can-expand': canExpand,
55
- expanded,
56
- })}
57
- >
58
- <div className='seam-header' onClick={handleHeaderClick}>
59
- <img
60
- src={manufacturer?.logo?.url}
61
- alt={manufacturer?.display_name}
62
- className='seam-manufacturer-image'
63
- />
64
- <h5 className='seam-manufacturer-name'>
65
- {manufacturer?.display_name} {t.devices}
66
- </h5>
67
- {canExpand && <ChevronRightIcon className='chevron' />}
68
- </div>
69
- {manufacturer?.annotations.map((annotation, idx) => (
70
- <ManufacturerAnnotationBox
71
- key={[annotation.annotation_code, idx].join('_')}
72
- annotation={annotation}
73
- />
74
- ))}
75
- <div className='seam-supported-device-table-content'>
76
- {visibleDevices.map((deviceModel) => (
77
- <SupportedDeviceRow
78
- key={deviceModel.device_model_id}
79
- deviceModel={deviceModel}
80
- />
81
- ))}
82
- </div>
83
- <ShowAllDevicesButton
84
- visible={canExpand}
85
- onClick={toggleExpand}
86
- expanded={expanded}
87
- totalDeviceCount={deviceModels.length}
88
- />
89
- <HiddenDevicesOverlay visible={canExpand && !expanded} />
90
- </div>
91
- )
92
- }
93
-
94
- function ManufacturerAnnotationBox({
95
- annotation,
96
- }: {
97
- annotation: ManufacturerAnnotation
98
- }): JSX.Element {
99
- return (
100
- <div className='seam-manufacturer-annotation-box'>
101
- <InfoBlueIcon />
102
- <p className='seam-annotation'>{annotation.message}</p>
103
- </div>
104
- )
105
- }
106
-
107
- const t = {
108
- devices: 'Devices',
109
- }