• 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

71.21
/src/js/components/devices/device-details/monitoring.js
1
// Copyright 2021 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

17
import { useTheme } from '@mui/material/styles';
18

19
import { getDeviceAlerts, setAlertListState } from '../../../actions/monitorActions';
20
import { DEVICE_LIST_DEFAULTS } from '../../../constants/deviceConstants';
21
import { getDocsVersion, getOfflineThresholdSettings } from '../../../selectors';
22
import Pagination from '../../common/pagination';
23
import Time from '../../common/time';
24
import MonitorDetailsDialog from '../dialogs/monitordetailsdialog';
25
import { DeviceConnectionNote } from './connection';
26
import DeviceDataCollapse from './devicedatacollapse';
27
import { DeviceOfflineHeaderNotification, NoAlertsHeaderNotification, severityMap } from './notifications';
28

29
const { page: defaultPage, perPage: defaultPerPage } = DEVICE_LIST_DEFAULTS;
10✔
30

31
export const DeviceMonitorsMissingNote = ({ docsVersion }) => (
10✔
32
  <DeviceConnectionNote>
1✔
33
    No alert monitor is currently configured for this device.
34
    <br />
35
    Please{' '}
36
    <a target="_blank" rel="noopener noreferrer" href={`https://docs.mender.io/${docsVersion}add-ons/monitor`}>
37
      see the documentation
38
    </a>{' '}
39
    for a description on how to configure different kinds of monitors.
40
  </DeviceConnectionNote>
41
);
42

43
const MonitoringAlert = ({ alert, onDetailsClick, style }) => {
10✔
44
  const { description, lines_before = [], lines_after = [], line_matching = '' } = alert.subject.details;
2✔
45
  const lines = [...lines_before, line_matching, ...lines_after].filter(i => i);
2✔
46
  return (
2✔
47
    <div className="monitoring-alert column-data" style={style}>
48
      {severityMap[alert.level].icon}
49
      <div className="key muted">
50
        <b>{alert.name}</b>
51
      </div>
52
      <div>{alert.level}</div>
53
      <Time value={alert.timestamp} />
54
      {(lines.length || description) && <a onClick={() => onDetailsClick(alert)}>view {lines.length ? 'log' : 'details'}</a>}
×
55
    </div>
56
  );
57
};
58

59
const paginationCutoff = defaultPerPage;
10✔
60
export const DeviceMonitoring = ({
10✔
61
  alertListState = {},
×
62
  alerts,
63
  device,
64
  docsVersion,
65
  getAlerts,
66
  latestAlerts,
67
  offlineThresholdSettings,
68
  onDetailsClick,
69
  setAlertListState
70
}) => {
71
  const { page: pageNo = defaultPage, perPage: pageLength = defaultPerPage, total: alertCount } = alertListState;
1!
72
  const theme = useTheme();
1✔
73

74
  useEffect(() => {
1✔
75
    getAlerts(device.id, alertListState);
1✔
76
  }, [device.id, pageNo, pageLength]);
77

78
  const onChangePage = page => setAlertListState({ page });
1✔
79

80
  const onChangeRowsPerPage = perPage => setAlertListState({ page: 1, perPage });
1✔
81

82
  const { monitors = [], isOffline, updated_ts = '' } = device;
1!
83
  const hasMonitorsDefined = !!(monitors.length || alerts.length || latestAlerts.length);
1!
84

85
  return (
1✔
86
    <DeviceDataCollapse
87
      header={
88
        hasMonitorsDefined || isOffline ? (
2!
89
          <>
90
            {hasMonitorsDefined && !latestAlerts.length && <NoAlertsHeaderNotification />}
2!
91
            {latestAlerts.map(alert => (
92
              <MonitoringAlert alert={alert} key={alert.id} onDetailsClick={onDetailsClick} style={{ marginBottom: theme.spacing() }} />
1✔
93
            ))}
94
            {isOffline && <DeviceOfflineHeaderNotification offlineThresholdSettings={offlineThresholdSettings} />}
1!
95
          </>
96
        ) : (
97
          <DeviceMonitorsMissingNote docsVersion={docsVersion} />
98
        )
99
      }
100
      isAddOn
101
      title={
102
        <div className="flexbox center-aligned">
103
          <h4 className="margin-bottom-small margin-right">Monitoring</h4>
104
          {!!monitors.length && <Time className="muted" value={updated_ts} />}
1!
105
        </div>
106
      }
107
    >
108
      {alerts.length ? (
1!
109
        <>
110
          <div>
111
            <h4 className="muted">Alert history</h4>
112
            {alerts.map(alert => (
113
              <MonitoringAlert alert={alert} key={alert.id} onDetailsClick={onDetailsClick} />
1✔
114
            ))}
115
          </div>
116
          <div className="flexbox margin-top">
117
            {alertCount > paginationCutoff && (
2✔
118
              <Pagination
119
                className="margin-top-none"
120
                count={alertCount}
121
                rowsPerPage={pageLength}
122
                onChangeRowsPerPage={onChangeRowsPerPage}
123
                page={pageNo}
124
                onChangePage={onChangePage}
125
              />
126
            )}
127
          </div>
128
        </>
129
      ) : (
130
        hasMonitorsDefined && (
×
131
          <p className="muted margin-left-large" style={{ fontSize: 'larger' }}>
132
            There are currently no issues reported
133
          </p>
134
        )
135
      )}
136
    </DeviceDataCollapse>
137
  );
138
};
139

140
export const MonitoringTab = ({ alertListState, alerts, device, docsVersion, getDeviceAlerts, latestAlerts, offlineThresholdSettings, setAlertListState }) => {
10✔
141
  const [monitorDetails, setMonitorDetails] = useState();
1✔
142

143
  return (
1✔
144
    <>
145
      <DeviceMonitoring
146
        alertListState={alertListState}
147
        alerts={alerts}
148
        device={device}
149
        docsVersion={docsVersion}
150
        getAlerts={getDeviceAlerts}
151
        latestAlerts={latestAlerts}
152
        onDetailsClick={setMonitorDetails}
153
        setAlertListState={setAlertListState}
154
        offlineThresholdSettings={offlineThresholdSettings}
155
      />
156
      <MonitorDetailsDialog alert={monitorDetails} onClose={() => setMonitorDetails()} />
×
157
    </>
158
  );
159
};
160

161
const actionCreators = { getDeviceAlerts, setAlertListState };
10✔
162

163
const mapStateToProps = (state, ownProps) => {
10✔
164
  const { alerts = [], latest = [] } = state.monitor.alerts.byDeviceId[ownProps.device.id] || {};
1!
165
  return {
1✔
166
    alertListState: state.monitor.alerts.alertList,
167
    alerts,
168
    docsVersion: getDocsVersion(state),
169
    latestAlerts: latest,
170
    offlineThresholdSettings: getOfflineThresholdSettings(state)
171
  };
172
};
173

174
export default connect(mapStateToProps, actionCreators)(MonitoringTab);
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