• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / gui / 897326496

pending completion
897326496

Pull #3752

gitlab-ci

mzedel
chore(e2e): made use of shared timeout & login checking values to remove code duplication

Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
Pull Request #3752: chore(e2e-tests): slightly simplified log in test + separated log out test

4395 of 6392 branches covered (68.76%)

8060 of 9780 relevant lines covered (82.41%)

126.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.2
/src/js/components/devices/device-details/devicesystem.js
1
// Copyright 2022 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React, { useEffect, useState } from 'react';
15
import { connect } from 'react-redux';
16
import { Link, useNavigate } from 'react-router-dom';
17

18
import { Button } from '@mui/material';
19
import { makeStyles } from 'tss-react/mui';
20

21
import { setSnackbar } from '../../../actions/appActions';
22
import { getSystemDevices } from '../../../actions/deviceActions';
23
import { SORTING_OPTIONS } from '../../../constants/appConstants';
24
import { DEVICE_LIST_DEFAULTS } from '../../../constants/deviceConstants';
25
import { getDemoDeviceAddress, toggle, versionCompare } from '../../../helpers';
26
import { getDocsVersion, getIdAttribute, getTenantCapabilities } from '../../../selectors';
27
import { TwoColumnData } from '../../common/configurationobject';
28
import EnterpriseNotification from '../../common/enterpriseNotification';
29
import { getHeaders } from '../authorized-devices';
30
import { routes } from '../base-devices';
31
import Devicelist from '../devicelist';
32
import ConnectToGatewayDialog from '../dialogs/connecttogatewaydialog';
33
import DeviceDataCollapse from './devicedatacollapse';
34

35
const useStyles = makeStyles()(theme => ({ container: { maxWidth: 600, marginTop: theme.spacing(), marginBottom: theme.spacing() } }));
9✔
36

37
export const DeviceSystem = ({
9✔
38
  columnSelection,
39
  device,
40
  devicesById,
41
  docsVersion,
42
  getSystemDevices,
43
  hasFullFiltering,
44
  idAttribute,
45
  onConnectToGatewayClick,
46
  openSettingsDialog,
47
  setSnackbar
48
}) => {
49
  const [columnHeaders, setColumnHeaders] = useState([]);
×
50
  const [headerKeys, setHeaderKeys] = useState([]);
×
51
  const [page, setPage] = useState(DEVICE_LIST_DEFAULTS.page);
×
52
  const [perPage, setPerPage] = useState(DEVICE_LIST_DEFAULTS.perPage);
×
53
  const { classes } = useStyles();
×
54
  const navigate = useNavigate();
×
55

56
  const { systemDeviceIds = [], systemDeviceTotal = 0 } = device;
×
57
  const deviceIp = getDemoDeviceAddress([device]);
×
58

59
  const [sortOptions, setSortOptions] = useState([]);
×
60

61
  const onSortChange = attribute => {
×
62
    let changedOrder = SORTING_OPTIONS.asc;
×
63
    if (sortOptions.length && sortOptions[0].attribute == attribute.name) {
×
64
      changedOrder = sortOptions[0].order === SORTING_OPTIONS.desc ? SORTING_OPTIONS.asc : SORTING_OPTIONS.desc;
×
65
    }
66
    setSortOptions([{ attribute: attribute.name, scope: attribute.scope, order: changedOrder }]);
×
67
  };
68

69
  useEffect(() => {
×
70
    const columnHeaders = getHeaders(columnSelection, routes.allDevices.defaultHeaders, idAttribute, openSettingsDialog);
×
71
    setColumnHeaders(columnHeaders);
×
72
    setHeaderKeys(columnHeaders.map(({ attribute: { name, scope } }) => `${name}-${scope}`).join('-'));
×
73
  }, [columnSelection, idAttribute.attribute]);
74

75
  useEffect(() => {
×
76
    if (device.attributes) {
×
77
      getSystemDevices(device.id, { page, perPage, sortOptions });
×
78
    }
79
  }, [device.id, device.attributes?.mender_is_gateway, page, perPage, sortOptions]);
80

81
  const onDeviceClick = (device = {}) => navigate(`/devices/${device.status}?id=${device.id}&open=true&tab=identity`);
×
82

83
  return (
×
84
    <>
85
      <DeviceDataCollapse title="Mender Gateway">
86
        <TwoColumnData config={{ 'Server IP': deviceIp }} compact setSnackbar={setSnackbar} />
87
      </DeviceDataCollapse>
88
      <DeviceDataCollapse className={classes.container} title="System for this gateway">
89
        <EnterpriseNotification isEnterprise={hasFullFiltering} benefit="see devices connected to your gateway device for easy access" />
90
        {systemDeviceTotal ? (
×
91
          <Devicelist
92
            customColumnSizes={[]}
93
            columnHeaders={columnHeaders}
94
            devices={systemDeviceIds.map(id => devicesById[id])}
×
95
            deviceListState={{ page, perPage }}
96
            headerKeys={headerKeys}
97
            idAttribute={idAttribute}
98
            onChangeRowsPerPage={setPerPage}
99
            onExpandClick={onDeviceClick}
100
            onResizeColumns={false}
101
            onPageChange={setPage}
102
            onSelect={false}
103
            onSort={onSortChange}
104
            pageLoading={false}
105
            pageTotal={systemDeviceTotal}
106
          />
107
        ) : (
108
          <div className="dashboard-placeholder">
109
            <p>No devices have been connected to this gateway device yet.</p>
110
            <div>
111
              Visit the{' '}
112
              <a href={`https://docs.mender.io/${docsVersion}get-started/mender-gateway`} target="_blank" rel="noopener noreferrer">
113
                full Mender Gateway documentation
114
              </a>{' '}
115
              to learn how to make the most of the gateway functionality.
116
            </div>
117
          </div>
118
        )}
119
      </DeviceDataCollapse>
120
      <div className="flexbox">
121
        <Button color="secondary" component={Link} to={`/deployments?deviceId=${device.id}&open=true`}>
122
          Create deployment for this system
123
        </Button>
124
        <Button onClick={onConnectToGatewayClick}>Connect devices</Button>
125
      </div>
126
    </>
127
  );
128
};
129

130
const DeviceSystemTab = ({ docsVersion, device, isPreRelease, tenantToken, ...remainder }) => {
9✔
131
  const [open, setOpen] = useState(false);
×
132
  const gatewayIp = getDemoDeviceAddress([device]);
×
133
  const toggleDialog = () => setOpen(toggle);
×
134
  return (
×
135
    <>
136
      <DeviceSystem device={device} docsVersion={docsVersion} onConnectToGatewayClick={toggleDialog} {...remainder} />
137
      {open && (
×
138
        <ConnectToGatewayDialog docsVersion={docsVersion} gatewayIp={gatewayIp} isPreRelease={isPreRelease} onCancel={toggleDialog} tenantToken={tenantToken} />
139
      )}
140
    </>
141
  );
142
};
143

144
const actionCreators = { getSystemDevices, setSnackbar };
9✔
145

146
const mapStateToProps = state => {
9✔
147
  return {
×
148
    devicesById: state.devices.byId,
149
    docsVersion: getDocsVersion(state),
150
    hasFullFiltering: getTenantCapabilities(state),
151
    idAttribute: getIdAttribute(state),
152
    isPreRelease: versionCompare(state.app.versionInformation.Integration, 'next') > -1,
153
    tenantToken: state.organization.organization.tenant_token
154
  };
155
};
156

157
export default connect(mapStateToProps, actionCreators)(DeviceSystemTab);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc