@iotready/nextjs-components-library 1.0.0-preview24 → 1.0.0-preview25

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.
@@ -187,7 +187,7 @@ function getCsvData(data, measures) {
187
187
  const TrendChart = ({ deviceId, measures1, annotationsDataFn, measures2, enableDatePicker, handleGetInfluxData, handleGetDwSlotsCB, handleExportDataCB, theme, initialTimeStart, initialTimeEnd }) => {
188
188
  const [chartJsLoaded, setChartJsLoaded] = useState(false);
189
189
  // Dichiarazione di annotationsData come funzione che ritorna una Promise<any>
190
- const [annotationsData, setAnnotationsData] = useState([]);
190
+ const [annotationsData, setAnnotationsData] = useState(null);
191
191
  const [annotationsEnabled, setAnnotationsEnabled] = useState(true);
192
192
  const [dataMeasures, setDataMeasures] = useState(null);
193
193
  const [chartPeriod, setChartPeriod] = useState('1D');
@@ -431,7 +431,7 @@ const TrendChart = ({ deviceId, measures1, annotationsDataFn, measures2, enableD
431
431
  const { paddedMin: paddedMin2, paddedMax: paddedMax2 } = getPaddedMinMax(min2, max2);
432
432
  // Handle undefined/null annotationsData
433
433
  let dynamicAnnotations = {};
434
- if (Array.isArray(annotationsData) && annotationsData.length > 0 && annotationsEnabled) {
434
+ if (annotationsData && Array.isArray(annotationsData) && annotationsData.length > 0 && annotationsEnabled) {
435
435
  dynamicAnnotations = annotationsData.reduce((acc, [timestamp, label], index) => {
436
436
  const yVal = paddedMin1 !== null && paddedMin1 !== undefined
437
437
  ? paddedMin1 + 0.01 * (paddedMax1 - paddedMin1)
@@ -659,7 +659,7 @@ const TrendChart = ({ deviceId, measures1, annotationsDataFn, measures2, enableD
659
659
  '& .MuiToggleButton-root': {
660
660
  color: 'text.primary', fontSize: '0.95rem', fontWeight: 'normal', paddingTop: '6px', paddingBottom: '6px'
661
661
  }
662
- }, disabled: chartLoading, children: [_jsx(ToggleButton, { value: "1D", sx: { px: 1 }, children: "1d" }), _jsx(ToggleButton, { value: "1W", sx: { px: 1 }, children: "1w" }), _jsx(ToggleButton, { value: "1M", sx: { px: 1 }, children: "1M" }), _jsx(ToggleButton, { value: "3M", sx: { px: 1 }, children: "3M" }), _jsx(ToggleButton, { value: "6M", sx: { px: 1 }, children: "6M" }), _jsx(ToggleButton, { value: "1Y", sx: { px: 1 }, children: "1Y" }), _jsx(ToggleButton, { value: "ALL", sx: { px: 1 }, children: "ALL" })] }), _jsx(MuiTooltip, { placement: "top", arrow: true, title: "Connect point values", children: _jsx("span", { children: _jsx(ToggleButton, { value: "check", color: "primary", size: "small", selected: spanGapsOption, disabled: chartLoading, onChange: () => handleSpanGaps(!spanGapsOption), sx: { ml: 1 }, children: _jsx(TimelineIcon, {}) }) }) }), annotationsData !== undefined && (_jsx(MuiTooltip, { placement: "top", arrow: true, title: "Show annotations", children: _jsx("span", { children: _jsx(ToggleButton, { value: "check", color: "primary", size: "small", selected: annotationsEnabled, disabled: chartLoading, onChange: () => setAnnotationsEnabled(!annotationsEnabled), sx: { ml: 1 }, children: _jsx(EditNoteIcon, {}) }) }) }))] })] }), _jsx(Box, { component: 'div', className: "chart-container", sx: { mt: 2, height: '100%' }, children: chartJsLoaded && !chartLoading && typeof window !== 'undefined' ?
662
+ }, disabled: chartLoading, children: [_jsx(ToggleButton, { value: "1D", sx: { px: 1 }, children: "1d" }), _jsx(ToggleButton, { value: "1W", sx: { px: 1 }, children: "1w" }), _jsx(ToggleButton, { value: "1M", sx: { px: 1 }, children: "1M" }), _jsx(ToggleButton, { value: "3M", sx: { px: 1 }, children: "3M" }), _jsx(ToggleButton, { value: "6M", sx: { px: 1 }, children: "6M" }), _jsx(ToggleButton, { value: "1Y", sx: { px: 1 }, children: "1Y" }), _jsx(ToggleButton, { value: "ALL", sx: { px: 1 }, children: "ALL" })] }), _jsx(MuiTooltip, { placement: "top", arrow: true, title: "Connect point values", children: _jsx("span", { children: _jsx(ToggleButton, { value: "check", color: "primary", size: "small", selected: spanGapsOption, disabled: chartLoading, onChange: () => handleSpanGaps(!spanGapsOption), sx: { ml: 1 }, children: _jsx(TimelineIcon, {}) }) }) }), annotationsData !== null && (_jsx(MuiTooltip, { placement: "top", arrow: true, title: "Show annotations", children: _jsx("span", { children: _jsx(ToggleButton, { value: "check", color: "primary", size: "small", selected: annotationsEnabled, disabled: chartLoading, onChange: () => setAnnotationsEnabled(!annotationsEnabled), sx: { ml: 1 }, children: _jsx(EditNoteIcon, {}) }) }) }))] })] }), _jsx(Box, { component: 'div', className: "chart-container", sx: { mt: 2, height: '100%' }, children: chartJsLoaded && !chartLoading && typeof window !== 'undefined' ?
663
663
  _jsx(_Fragment, { children: dataMeasures && (dataMeasures.length > 1 || (dataMeasures.length === 1 && dataMeasures[0].data?.length)) ?
664
664
  (_jsx(Line, { options: options, data: {
665
665
  // datasets: dataMeasures || [{ data: [] }]
@@ -1,14 +1,10 @@
1
- import { UserType } from '../../types';
2
- declare const GroupUpdate: ({ userInfo, groupInfo, usersGroup, usersList, devicesList, handleAddUserToGroup, handleRemoveUserFromGroup, handleGetGroups, handleUpdateGroup, handleUpdateDevice, handleDeleteGroup, container, containerProps, afterUpdateCallback, afterRemoveCallback, confirmMui }: {
1
+ import { AssetType, TrackleDeviceType, UserType } from '../../types';
2
+ declare const GroupUpdate: ({ groupInfo, usersGroup, usersList, devicesList, handleAddUserToGroup, handleRemoveUserFromGroup, handleUpdateGroup, handleDeleteGroup, container, containerProps, afterUpdateCallback, afterRemoveCallback, confirmMui }: {
3
3
  userInfo: UserType;
4
4
  groupInfo: any;
5
5
  usersGroup: any[];
6
6
  usersList: any[];
7
- devicesList: {
8
- id: string;
9
- state: any;
10
- managers: any[];
11
- }[];
7
+ devicesList: AssetType[] | TrackleDeviceType[];
12
8
  handleAddUserToGroup: (groupID: string, userName: string, userID: string) => Promise<any>;
13
9
  handleRemoveUserFromGroup: (groupID: string, userID: string) => Promise<any>;
14
10
  handleUpdateDevice: (id: string, body: any, user: UserType) => Promise<any>;
@@ -8,15 +8,13 @@ import AddIcon from '@mui/icons-material/Add';
8
8
  import CloseIcon from '@mui/icons-material/Close';
9
9
  import DeleteIcon from '@mui/icons-material/Delete';
10
10
  import { LoadingButton } from '@mui/lab';
11
- const GroupUpdate = ({ userInfo, groupInfo, usersGroup, usersList, devicesList, handleAddUserToGroup, handleRemoveUserFromGroup, handleGetGroups, handleUpdateGroup, handleUpdateDevice, handleDeleteGroup, container = 'Box', containerProps = {}, afterUpdateCallback, afterRemoveCallback, confirmMui }) => {
11
+ const GroupUpdate = ({ groupInfo, usersGroup, usersList, devicesList, handleAddUserToGroup, handleRemoveUserFromGroup, handleUpdateGroup, handleDeleteGroup, container = 'Box', containerProps = {}, afterUpdateCallback, afterRemoveCallback, confirmMui }) => {
12
12
  const [group, setGroup] = useState(groupInfo);
13
13
  const [loadingUpdateButton, setLoadingUpdateButton] = useState(false);
14
14
  const [loadingRemoveUserButton, setLoadingRemoveUserButton] = useState(false);
15
15
  const [loadingAddUserButton, setLoadingAddUserButton] = useState(false);
16
16
  const [loadingDeleteGroupButton, setLoadingDeleteGroupButton] = useState(false);
17
17
  const [selectedUser, setSelectedUser] = useState(null);
18
- const [error, setError] = useState(null);
19
- const [success, setSuccess] = useState(null);
20
18
  function handleChange(event) {
21
19
  setGroup({ ...group, [event.target.name]: event.target.value });
22
20
  }
@@ -25,23 +23,6 @@ const GroupUpdate = ({ userInfo, groupInfo, usersGroup, usersList, devicesList,
25
23
  try {
26
24
  const response = await handleRemoveUserFromGroup(group.id, userId);
27
25
  if (response) {
28
- if (devicesList.length > 0) {
29
- // should check if device is present in other groups the user is member of
30
- const groupsData = await handleGetGroups({ role: 'support', uid: userId });
31
- const userGroupIds = groupsData.map((group) => group.id);
32
- // for all devices in the group set the selectedUser as manager
33
- for (const device of devicesList) {
34
- // check device is in a group of user is member of
35
- const found = device.state.groups.some((gID) => userGroupIds.includes(gID));
36
- if (!found) {
37
- // remove user from managers
38
- const managers = device.managers && device.managers.filter(man => man !== userId) || [];
39
- await handleUpdateDevice(device.id, {
40
- managers
41
- }, userInfo);
42
- }
43
- }
44
- }
45
26
  if (afterUpdateCallback) {
46
27
  await afterUpdateCallback(group);
47
28
  }
@@ -60,17 +41,6 @@ const GroupUpdate = ({ userInfo, groupInfo, usersGroup, usersList, devicesList,
60
41
  try {
61
42
  const response = await handleAddUserToGroup(group.id, selectedUser.label, selectedUser.id);
62
43
  if (response) {
63
- if (devicesList.length > 0) {
64
- for (const device of devicesList) {
65
- // for all devices in the group set the selectedUser as manager
66
- await handleUpdateDevice(device.id, {
67
- managers: [
68
- ...(device?.managers || []),
69
- selectedUser.id
70
- ]
71
- }, userInfo);
72
- }
73
- }
74
44
  if (afterUpdateCallback) {
75
45
  await afterUpdateCallback(group);
76
46
  }
@@ -1,7 +1,6 @@
1
- import { UserType } from '../../types/user';
2
- import { Position } from "./Map";
3
1
  import { Theme } from "@emotion/react";
4
- declare const GroupsDevices: ({ userInfo, handleGetUsersList, handleAddUserToGroup, handleRemoveUserFromGroup, handleGetGroups, handleGetUsersGroup, handleGetDevices, handleUpdateDevice, handleGetPositions, handleAddDevicesToGroup, handleRemoveDevicesFromGroup, handleCreateGroup, handleDeleteGroup, handleUpdateGroup, group, columnsArray, containerDataGrid, props, propsDatagrid, loadingComponent, containerProps, enableMaps, mapsHeight, mapsClickCallback, theme, confirmMui }: {
2
+ import { UserType, AssetType, DevicePositionType, TrackleDeviceType } from "../../types";
3
+ declare const GroupsDevices: ({ userInfo, handleGetUsersList, handleAddUserToGroup, handleRemoveUserFromGroup, handleGetGroups, handleGetUsersGroup, handleGetDevices, handleUpdateDevice, handleGetPositions, handleAddDevicesToGroup, handleRemoveDevicesFromGroup, handleCreateGroup, handleDeleteGroup, handleUpdateGroup, group, columnsArray, containerDataGrid, props, propsDatagrid, loadingComponent, containerProps, enableMaps, mapsHeight, mapsClickCallback, theme, confirmMui, propsHeaderGroups, forceGetDevices, groupsLabelAll }: {
5
4
  userInfo: UserType;
6
5
  handleGetUsersList: ({ page, pageSize }: {
7
6
  page: number;
@@ -14,24 +13,27 @@ declare const GroupsDevices: ({ userInfo, handleGetUsersList, handleAddUserToGro
14
13
  handleGetGroups: (userInfo?: UserType) => Promise<any>;
15
14
  handleGetUsersGroup: (groupID: string) => Promise<any>;
16
15
  handleCreateGroup: (group: any) => Promise<any>;
17
- handleGetDevices: (user: UserType, query: string) => Promise<any>;
18
- handleGetPositions: (devices: any) => Promise<any>;
19
- handleAddDevicesToGroup: (user: UserType, group: string, devicesToPatch: any[]) => Promise<any>;
20
- handleRemoveDevicesFromGroup: (user: UserType, group: string, devicesToPatch: any[]) => Promise<any>;
16
+ handleGetDevices: (user: UserType, group: string, selectedGroup: string) => Promise<AssetType[] | TrackleDeviceType[]>;
17
+ handleGetPositions?: (devices: any) => Promise<DevicePositionType[]>;
18
+ handleAddDevicesToGroup: (user: UserType, group: string, devicesToPatch: AssetType[] | TrackleDeviceType[]) => Promise<TrackleDeviceType[]>;
19
+ handleRemoveDevicesFromGroup: (user: UserType, group: string, devicesToPatch: AssetType[] | TrackleDeviceType[]) => Promise<TrackleDeviceType[]>;
21
20
  handleDeleteGroup: (id: string) => Promise<void>;
22
21
  handleUpdateGroup: (id: string, group: any) => Promise<void>;
23
- handleUpdateDevice: (id: string, body: any, user: UserType) => Promise<any>;
22
+ handleUpdateDevice: (id: string, body: any, user: UserType) => Promise<void>;
24
23
  group: string;
25
24
  columnsArray: any[];
26
25
  containerDataGrid?: "Card" | "Box";
27
26
  props?: any;
28
27
  propsDatagrid?: any;
28
+ propsHeaderGroups?: any;
29
29
  loadingComponent?: React.ReactNode;
30
30
  containerProps?: any;
31
31
  enableMaps?: boolean;
32
32
  mapsHeight: string;
33
- mapsClickCallback?: (position: Position) => void;
33
+ mapsClickCallback?: (position: DevicePositionType) => void;
34
34
  theme: Theme;
35
35
  confirmMui?: (options?: any) => Promise<void>;
36
+ forceGetDevices: number;
37
+ groupsLabelAll?: string;
36
38
  }) => string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<import("react").ReactNode> | Promise<import("react").AwaitedReactNode> | null;
37
39
  export default GroupsDevices;
@@ -15,8 +15,8 @@ import GroupUpdate from "./GroupUpdate";
15
15
  import BackIcon from '@mui/icons-material/ArrowBack';
16
16
  import dynamic from "next/dynamic";
17
17
  import { ThemeProvider } from '@mui/material/styles';
18
- const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, handleRemoveUserFromGroup, handleGetGroups, handleGetUsersGroup, handleGetDevices, handleUpdateDevice, handleGetPositions, handleAddDevicesToGroup, handleRemoveDevicesFromGroup, handleCreateGroup, handleDeleteGroup, handleUpdateGroup, group = 'all', columnsArray = [], containerDataGrid = 'Card', props = {}, propsDatagrid = {}, loadingComponent = _jsx(CircularProgress, {}), containerProps = {}, enableMaps = true, mapsHeight = '400px', mapsClickCallback = () => { }, theme, confirmMui }) => {
19
- const [devices, setDevices] = useState(null);
18
+ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, handleRemoveUserFromGroup, handleGetGroups, handleGetUsersGroup, handleGetDevices, handleUpdateDevice, handleGetPositions, handleAddDevicesToGroup, handleRemoveDevicesFromGroup, handleCreateGroup, handleDeleteGroup, handleUpdateGroup, group = 'all', columnsArray = [], containerDataGrid = 'Card', props = {}, propsDatagrid = {}, loadingComponent = _jsx(CircularProgress, {}), containerProps = {}, enableMaps = true, mapsHeight = '400px', mapsClickCallback = () => { }, theme, confirmMui, propsHeaderGroups, forceGetDevices, groupsLabelAll }) => {
19
+ const [devices, setDevices] = useState([]);
20
20
  const [positions, setPositions] = useState([]);
21
21
  const [loadingDevices, setLoadingDevices] = useState(false);
22
22
  const [loadingGroups, setLoadingGroups] = useState(false);
@@ -73,22 +73,9 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
73
73
  const fetchDevices = async (group, selected) => {
74
74
  try {
75
75
  setLoadingDevices(true);
76
- let queryParams = "last_handshake_at!=null";
77
- if (group !== "all") {
78
- queryParams = `last_handshake_at!=null&state.groups=/${group}/`;
79
- if (userInfo.role === "admin") {
80
- queryParams += "&quarantined=false";
81
- }
82
- }
83
- else if (selected !== "all") {
84
- queryParams = `last_handshake_at!=null&state.groups!=/${selected}/`;
85
- if (userInfo.role === "admin") {
86
- queryParams += "&quarantined=false";
87
- }
88
- }
89
- const devices = await handleGetDevices(userInfo, queryParams);
76
+ const devices = await handleGetDevices(userInfo, group, selected);
90
77
  setDevices(devices);
91
- if (enableMaps) {
78
+ if (enableMaps && handleGetPositions) {
92
79
  const positions = await handleGetPositions(devices);
93
80
  setPositions(positions);
94
81
  }
@@ -138,6 +125,11 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
138
125
  fetchDevices(currentGroup, currentGroup);
139
126
  }
140
127
  }, [currentGroup]);
128
+ useEffect(() => {
129
+ if (forceGetDevices !== 0) {
130
+ fetchDevices(currentGroup, currentGroup);
131
+ }
132
+ }, [forceGetDevices]);
141
133
  const handleSubmit = async (e) => {
142
134
  e.preventDefault();
143
135
  setLoadingAdd(true);
@@ -186,28 +178,12 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
186
178
  const addToSelectedGroup = async () => {
187
179
  setLoadingGroups(true);
188
180
  try {
189
- const selectedData = devices.filter((row) => devicesToAdd.includes(row.id));
190
- const devicesToPatch = selectedData?.map((device) => ({ id: device.id, groups: device.state.groups, managers: device.managers }));
191
- const devicesPatched = await handleAddDevicesToGroup(userInfo, selectedGroup, devicesToPatch);
192
- if (devicesPatched && devicesPatched.length > 0) {
193
- // get all members of the group
194
- const userIdsToAdd = usersGroup && usersGroup.map((ug) => ug.user.userId) || [];
195
- if (userIdsToAdd && userIdsToAdd.length > 0) {
196
- for (const device of devicesToPatch) {
197
- // add members to devices managers
198
- await handleUpdateDevice(device.id, {
199
- managers: [
200
- ...(device?.managers || []),
201
- ...userIdsToAdd
202
- ]
203
- }, userInfo);
204
- }
205
- }
206
- setLoadingGroups(false);
207
- setCurrentGroup(selectedGroup);
208
- setDevicesToAdd([...[]]);
209
- fetchDevices(selectedGroup, selectedGroup);
210
- }
181
+ const devicesToPatch = devices.filter((row) => devicesToAdd.includes(row.id));
182
+ await handleAddDevicesToGroup(userInfo, selectedGroup, devicesToPatch);
183
+ setLoadingGroups(false);
184
+ setCurrentGroup(selectedGroup);
185
+ setDevicesToAdd([...[]]);
186
+ fetchDevices(selectedGroup, selectedGroup);
211
187
  }
212
188
  catch (err) {
213
189
  console.error(err);
@@ -220,31 +196,10 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
220
196
  setLoadingGroups(true);
221
197
  try {
222
198
  const devicesToRemove = devices.filter((row) => devicesToAdd.includes(row.id));
223
- const devicesToPatch = devicesToRemove?.map((device) => ({ id: device.id, groups: device.state.groups, managers: device.managers }));
224
- const devicesPatched = await handleRemoveDevicesFromGroup(userInfo, selectedGroup, devicesToPatch);
225
- if (devicesPatched && devicesPatched.length > 0) {
226
- for (const device of devicesToPatch) {
227
- if (device.managers && device.managers.length > 0) {
228
- let managersToKeep = device.managers;
229
- for (const manager of device.managers) {
230
- // should check if device is present in other groups the user is member of
231
- const groupsData = await handleGetGroups({ role: 'support', uid: manager });
232
- const userGroupIds = groupsData && groupsData.map((group) => group.id) || [];
233
- const found = device.groups && device.groups.some((gID) => userGroupIds.includes(gID));
234
- if (!found) {
235
- // @ts-ignore
236
- managersToKeep = managersToKeep.filter(man => man !== manager);
237
- }
238
- }
239
- await handleUpdateDevice(device.id, {
240
- managers: managersToKeep
241
- }, userInfo);
242
- }
243
- }
244
- setLoadingGroups(false);
245
- setDevicesToAdd([]);
246
- fetchDevices(currentGroup, selectedGroup);
247
- }
199
+ await handleRemoveDevicesFromGroup(userInfo, selectedGroup, devicesToRemove);
200
+ setLoadingGroups(false);
201
+ setDevicesToAdd([]);
202
+ fetchDevices(currentGroup, selectedGroup);
248
203
  }
249
204
  catch (err) {
250
205
  console.error(err);
@@ -279,6 +234,7 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
279
234
  sorting: {
280
235
  sortModel: [{ field: 'online', sort: 'desc' }],
281
236
  },
237
+ pagination: { paginationModel: { pageSize: 100 } }
282
238
  }, ...propsDatagrid }) }));
283
239
  const renderTabContext = (_jsxs(TabContext, { value: valueTab, children: [_jsx(Box, { sx: { borderBottom: 1, borderColor: 'divider' }, children: _jsxs(TabList, { onChange: handleChangeTab, sx: { minHeight: 20 }, children: [_jsx(Tab, { label: "List", value: "1", sx: { minHeight: 20 } }), _jsx(Tab, { label: "Map", value: "2", sx: { minHeight: 20 } })] }) }), _jsx(TabPanel, { value: "1", sx: { p: 0 }, children: renderDataGrid }), _jsx(TabPanel, { value: "2", sx: { p: 0 }, children: renderMaps })] }));
284
240
  const renderDatagridAndMaps = (enableMaps ?
@@ -287,10 +243,10 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
287
243
  _jsx(Card, { ...containerProps, children: renderDataGrid }) : _jsx(Box, { ...containerProps, children: renderDataGrid }));
288
244
  if (!userInfo || !groups || !devices)
289
245
  return loadingComponent;
290
- return (_jsx(ThemeProvider, { theme: theme, children: _jsxs(Box, { ...props, children: [_jsxs(Box, { component: "div", sx: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1, backgroundColor: editGroup ? 'secondary.light' : '', borderRadius: 3, px: editGroup ? 2 : 0, py: 1, height: 50 }, children: [editGroup ? _jsxs(Typography, { variant: 'subtitle1', children: [_jsx(Box, { component: 'span', sx: { display: { xs: 'none' } }, children: "Edit group" }), " ", _jsx("b", { children: groupInfo?.name })] }) : '', groups && !checkboxSelection && !(editGroup && currentGroup === 'all') ?
291
- _jsx(Autocomplete, { disablePortal: true, onChange: handleChangeGroupSelect, value: groupInfo?.name || 'All devices', disableClearable: currentGroup === 'all', isOptionEqualToValue: (o, v) => o.label === v, options: [{ label: 'All devices', id: 'all' }, ...groups.map((grp) => ({ label: grp.name, id: grp.id }))], sx: { width: { xs: 200, sm: 300 }, textAlign: 'left' }, size: 'small', renderInput: (params) => _jsx(TextField, { ...params, label: "Group" }) })
246
+ return (_jsx(ThemeProvider, { theme: theme, children: _jsxs(Box, { ...props, children: [_jsxs(Box, { component: "div", sx: { display: 'flex', alignItems: 'center', mb: 1, backgroundColor: editGroup ? 'secondary.light' : '', borderRadius: 3, px: editGroup ? 2 : 0, py: 1, height: 50, ...propsHeaderGroups }, children: [editGroup ? _jsxs(Typography, { variant: 'subtitle1', children: [_jsx(Box, { component: 'span', sx: { display: { xs: 'none' } }, children: "Edit group" }), " ", _jsx("b", { children: groupInfo?.name })] }) : '', groups && !checkboxSelection && !(editGroup && currentGroup === 'all') ?
247
+ _jsx(Autocomplete, { disablePortal: true, onChange: handleChangeGroupSelect, value: groupInfo?.name || groupsLabelAll || 'All devices', disableClearable: currentGroup === 'all', isOptionEqualToValue: (o, v) => o.label === v, options: [{ label: groupsLabelAll || 'All devices', id: 'all' }, ...groups.map((grp) => ({ label: grp.name, id: grp.id }))], sx: { width: { xs: 200, sm: 300 }, textAlign: 'left' }, size: 'small', renderInput: (params) => _jsx(TextField, { ...params, label: "Group" }) })
292
248
  : '', userInfo.role === 'admin' &&
293
- _jsxs(Box, { children: [checkboxSelection ?
249
+ _jsxs(Box, { sx: { ml: 2 }, children: [checkboxSelection ?
294
250
  _jsx(Input, { value: selectedGroup, type: 'hidden', size: 'small' })
295
251
  : '', selectedGroup === 'all' ? _jsxs(Button, { variant: "contained", color: "primary", onClick: () => { handleOpenAdd(); }, children: [_jsx(AddIcon, { sx: { mr: 1 } }), _jsx(Box, { component: 'span', sx: { display: { xs: 'none', sm: 'inline' } }, children: "Create\u00A0" }), " group"] }) : '', editGroup ?
296
252
  currentGroup === 'all' ?
@@ -308,6 +264,6 @@ const GroupsDevices = ({ userInfo, handleGetUsersList, handleAddUserToGroup, han
308
264
  transform: 'translate(-50%, -50%)',
309
265
  width: 400,
310
266
  borderRadius: 4
311
- }, children: [_jsx(CardHeader, { title: "New Group", action: _jsx(IconButton, { onClick: handleCloseAdd, children: _jsx(CloseIcon, {}) }) }), _jsx(CardContent, { children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TextField, { fullWidth: true, label: "Group Name", value: groupName, onChange: (e) => setGroupName(e.target.value), required: true }), _jsx(TextField, { fullWidth: true, label: "Description", value: description, onChange: (e) => setDescription(e.target.value), margin: "normal", multiline: true, rows: 4 }), _jsxs(Box, { mt: 2, display: "flex", justifyContent: "space-between", children: [_jsx(Button, { variant: "contained", color: "info", onClick: handleCloseAdd, children: "Cancel" }), _jsx(LoadingButton, { loading: loadingAdd, variant: "contained", color: "primary", type: "submit", children: "Create" })] })] }) })] }) }), !groupUpdateVisible && renderDatagridAndMaps, groupInfo && editGroup && groupUpdateVisible && _jsx(GroupUpdate, { confirmMui: confirmMui, userInfo: userInfo, usersGroup: usersGroup, usersList: usersList, handleGetGroups: handleGetGroups, handleUpdateDevice: handleUpdateDevice, handleAddUserToGroup: handleAddUserToGroup, handleRemoveUserFromGroup: handleRemoveUserFromGroup, groupInfo: groupInfo, afterUpdateCallback: async (groupInfo) => { setGroupInfo(groupInfo); await getGroups(); await getUsersGroup(groupInfo.id); }, afterRemoveCallback: async () => { closeEditGroup(); await getGroups(); setCurrentGroup('all'); }, container: 'Card', handleDeleteGroup: handleDeleteGroup, handleUpdateGroup: handleUpdateGroup, devicesList: devices.map((device) => ({ id: device.id, state: device.state, managers: device.managers })) })] }) }));
267
+ }, children: [_jsx(CardHeader, { title: "New Group", action: _jsx(IconButton, { onClick: handleCloseAdd, children: _jsx(CloseIcon, {}) }) }), _jsx(CardContent, { children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TextField, { fullWidth: true, label: "Group Name", value: groupName, onChange: (e) => setGroupName(e.target.value), required: true }), _jsx(TextField, { fullWidth: true, label: "Description", value: description, onChange: (e) => setDescription(e.target.value), margin: "normal", multiline: true, rows: 4 }), _jsxs(Box, { mt: 2, display: "flex", justifyContent: "space-between", children: [_jsx(Button, { variant: "contained", color: "info", onClick: handleCloseAdd, children: "Cancel" }), _jsx(LoadingButton, { loading: loadingAdd, variant: "contained", color: "primary", type: "submit", children: "Create" })] })] }) })] }) }), !groupUpdateVisible && renderDatagridAndMaps, groupInfo && editGroup && groupUpdateVisible && _jsx(GroupUpdate, { confirmMui: confirmMui, userInfo: userInfo, usersGroup: usersGroup, usersList: usersList, handleGetGroups: handleGetGroups, handleUpdateDevice: handleUpdateDevice, handleAddUserToGroup: handleAddUserToGroup, handleRemoveUserFromGroup: handleRemoveUserFromGroup, groupInfo: groupInfo, afterUpdateCallback: async (groupInfo) => { setGroupInfo(groupInfo); await getGroups(); await getUsersGroup(groupInfo.id); }, afterRemoveCallback: async () => { closeEditGroup(); await getGroups(); setCurrentGroup('all'); }, container: 'Card', handleDeleteGroup: handleDeleteGroup, handleUpdateGroup: handleUpdateGroup, devicesList: devices })] }) }));
312
268
  };
313
269
  export default GroupsDevices;
@@ -1,14 +1,9 @@
1
1
  import 'leaflet/dist/leaflet.css';
2
2
  import "leaflet-defaulticon-compatibility";
3
3
  import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
4
- export type Position = {
5
- deviceID: string;
6
- name: string;
7
- lat: number;
8
- lng: number;
9
- };
4
+ import { DevicePositionType } from "../../types/device";
10
5
  export default function Map({ positions, height, mapsClickCallback }: {
11
- positions: Position[];
6
+ positions: DevicePositionType[];
12
7
  height: string;
13
- mapsClickCallback: (position: Position) => void;
8
+ mapsClickCallback: (position: DevicePositionType) => void;
14
9
  }): import("react/jsx-runtime").JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iotready/nextjs-components-library",
3
- "version": "1.0.0-preview24",
3
+ "version": "1.0.0-preview25",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "build": "rm -rf dist && tsc --project tsconfig.build.json && cp package.json dist/",
@@ -1,5 +1,5 @@
1
1
  import { Firestore } from "firebase-admin/firestore";
2
- export declare const getGroups: (db: Firestore, productID: number, userID?: string) => Promise<{
2
+ export declare const getGroups: (db: Firestore, productID: number, userID?: string, assetID?: string) => Promise<{
3
3
  id: string;
4
4
  }[]>;
5
5
  export declare const getGroupById: (db: Firestore, id: string) => Promise<{
@@ -11,5 +11,8 @@ export declare const deleteGroup: (db: Firestore, id: string) => Promise<void>;
11
11
  export declare const getUsersGroup: (db: Firestore, groupID: string) => Promise<{
12
12
  id: string;
13
13
  }[]>;
14
+ export declare const getGroupsUser: (db: Firestore, userID: string) => Promise<{
15
+ id: string;
16
+ }[]>;
14
17
  export declare const addUsersGroup: (db: Firestore, groupID: string, userName: string, userID: string) => Promise<string>;
15
18
  export declare const removeUserGroup: (db: Firestore, groupID: string, userID: string) => Promise<string | undefined>;
@@ -1,10 +1,11 @@
1
1
  "use server";
2
2
  // 1. GET GROUPS
3
- export const getGroups = async (db, productID, userID) => {
4
- const groupsRef = db
5
- .collection("groups")
6
- .where("productID", "==", productID)
7
- .orderBy("created", "desc");
3
+ export const getGroups = async (db, productID, userID, assetID) => {
4
+ let groupsRef = db.collection("groups").where("productID", "==", productID);
5
+ if (assetID) {
6
+ groupsRef = groupsRef.where("assets", "array-contains", assetID);
7
+ }
8
+ groupsRef = groupsRef.orderBy("created", "desc");
8
9
  let groupIds = null;
9
10
  if (userID) {
10
11
  const userGroupsSnapshot = await db
@@ -67,6 +68,17 @@ export const getUsersGroup = async (db, groupID) => {
67
68
  ...doc.data()
68
69
  }));
69
70
  };
71
+ // 6b. GET GROUPS USER
72
+ export const getGroupsUser = async (db, userID) => {
73
+ const snapshot = await db
74
+ .collection("userGroups")
75
+ .where("user.userId", "==", userID)
76
+ .get();
77
+ return snapshot.docs.map((doc) => ({
78
+ id: doc.id,
79
+ ...doc.data()
80
+ }));
81
+ };
70
82
  // 7. ADD USER TO GROUP
71
83
  export const addUsersGroup = async (db, groupID, userName, userID) => {
72
84
  const created = new Date().toISOString();
@@ -1,3 +1,4 @@
1
+ import { TrackleDeviceType } from "../types";
1
2
  export type TrackleConfig = {
2
3
  orgName: string;
3
4
  apiUrl: string;
@@ -32,5 +33,5 @@ export declare function post(trackleConfig: TrackleConfig, id: string, endpoint:
32
33
  export declare function put(trackleConfig: TrackleConfig, id: string, endpoint: string, value: any, productId?: number, uid?: string): Promise<{
33
34
  return_value: number;
34
35
  }>;
35
- export declare function addDevicesToGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: any[]): Promise<string[]>;
36
- export declare function removeDevicesFromGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: any[]): Promise<string[]>;
36
+ export declare function addDevicesToGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: TrackleDeviceType[]): Promise<TrackleDeviceType[]>;
37
+ export declare function removeDevicesFromGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: TrackleDeviceType[]): Promise<TrackleDeviceType[]>;
@@ -110,7 +110,9 @@ export async function put(trackleConfig, id, endpoint, value, productId, uid) {
110
110
  export async function addDevicesToGroup(trackleConfig, productId, uid, group, devicesToPatch) {
111
111
  const devicesPatched = [];
112
112
  for (const device of devicesToPatch) {
113
- const newGroups = device?.groups && device?.groups instanceof Array ? device?.groups : [];
113
+ const newGroups = device.state?.groups && device.state?.groups instanceof Array
114
+ ? device.state?.groups
115
+ : [];
114
116
  if (!newGroups.includes(group)) {
115
117
  newGroups.push(group);
116
118
  await wretchApi(trackleConfig, uid)
@@ -120,7 +122,7 @@ export async function addDevicesToGroup(trackleConfig, productId, uid, group, de
120
122
  })
121
123
  .setTimeout(trackleConfig.apiTimeout)
122
124
  .res();
123
- devicesPatched.push(device.id);
125
+ devicesPatched.push(device);
124
126
  }
125
127
  }
126
128
  return devicesPatched;
@@ -128,7 +130,9 @@ export async function addDevicesToGroup(trackleConfig, productId, uid, group, de
128
130
  export async function removeDevicesFromGroup(trackleConfig, productId, uid, group, devicesToPatch) {
129
131
  const devicesPatched = [];
130
132
  for (const device of devicesToPatch) {
131
- let newGroups = device?.groups && device?.groups instanceof Array ? device?.groups : [];
133
+ let newGroups = device.state?.groups && device.state?.groups instanceof Array
134
+ ? device.state?.groups
135
+ : [];
132
136
  if (newGroups.includes(group)) {
133
137
  newGroups = newGroups.filter((newGroup) => newGroup !== group);
134
138
  await wretchApi(trackleConfig, uid)
@@ -138,7 +142,7 @@ export async function removeDevicesFromGroup(trackleConfig, productId, uid, grou
138
142
  })
139
143
  .setTimeout(trackleConfig.apiTimeout)
140
144
  .res();
141
- devicesPatched.push(device.id);
145
+ devicesPatched.push(device);
142
146
  }
143
147
  }
144
148
  return devicesPatched;
@@ -0,0 +1,19 @@
1
+ export type AssetType = {
2
+ id: string;
3
+ device?: TrackleDeviceType;
4
+ [key: string]: any;
5
+ };
6
+ export type TrackleDeviceType = {
7
+ id: string;
8
+ state: {
9
+ groups: string[] | null;
10
+ };
11
+ managers: string[] | null;
12
+ [key: string]: any;
13
+ };
14
+ export type DevicePositionType = {
15
+ deviceID: string;
16
+ name: string;
17
+ lat: number;
18
+ lng: number;
19
+ };
@@ -0,0 +1 @@
1
+ export {};
package/types/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./user";
2
+ export * from "./device";
package/types/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./user";
2
+ export * from "./device";