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

mendersoftware / gui / 951400782

pending completion
951400782

Pull #3900

gitlab-ci

web-flow
chore: bump @testing-library/jest-dom from 5.16.5 to 5.17.0

Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 5.16.5 to 5.17.0.
- [Release notes](https://github.com/testing-library/jest-dom/releases)
- [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/jest-dom/compare/v5.16.5...v5.17.0)

---
updated-dependencies:
- dependency-name: "@testing-library/jest-dom"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #3900: chore: bump @testing-library/jest-dom from 5.16.5 to 5.17.0

4446 of 6414 branches covered (69.32%)

8342 of 10084 relevant lines covered (82.73%)

186.0 hits per line

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

78.67
/src/js/components/leftnav.js
1
// Copyright 2018 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, useRef, useState } from 'react';
15
import { useDispatch, useSelector } from 'react-redux';
16
import { Link, NavLink } from 'react-router-dom';
17

18
// material ui
19
import { List, ListItem, ListItemText, Tooltip } from '@mui/material';
20
import { makeStyles } from 'tss-react/mui';
21

22
import copy from 'copy-to-clipboard';
23

24
import { setSnackbar, setVersionInfo } from '../actions/appActions';
25
import { TIMEOUTS, canAccess } from '../constants/appConstants';
26
import { onboardingSteps } from '../constants/onboardingConstants';
27
import { getFeatures, getOnboardingState, getTenantCapabilities, getUserCapabilities, getVersionInformation } from '../selectors';
28
import { getOnboardingComponentFor } from '../utils/onboardingmanager';
29
import DocsLink from './common/docslink';
30

31
const listItems = [
3✔
32
  { route: '/', text: 'Dashboard', canAccess },
33
  { route: '/devices', text: 'Devices', canAccess: ({ userCapabilities: { canReadDevices } }) => canReadDevices },
59✔
34
  { route: '/releases', text: 'Releases', canAccess: ({ userCapabilities: { canReadReleases, canUploadReleases } }) => canReadReleases || canUploadReleases },
59✔
35
  { route: '/deployments', text: 'Deployments', canAccess: ({ userCapabilities: { canDeploy, canReadDeployments } }) => canReadDeployments || canDeploy },
59✔
36
  {
37
    route: '/auditlog',
38
    text: 'Audit log',
39
    canAccess: ({ tenantCapabilities: { hasAuditlogs }, userCapabilities: { canAuditlog } }) => hasAuditlogs && canAuditlog
59!
40
  }
41
];
42

43
const useStyles = makeStyles()(theme => ({
106✔
44
  licenseLink: { fontSize: '13px', position: 'relative', top: '6px', color: theme.palette.primary.main },
45
  infoList: { padding: 0, position: 'absolute', bottom: 30, left: 0, right: 0 },
46
  list: {
47
    backgroundColor: theme.palette.background.lightgrey,
48
    borderRight: `1px solid ${theme.palette.grey[300]}`
49
  },
50
  navLink: { padding: '22px 16px 22px 42px' },
51
  listItem: { padding: '16px 16px 16px 42px' },
52
  versions: { display: 'grid', gridTemplateColumns: 'max-content 60px', columnGap: theme.spacing(), '>a': { color: theme.palette.grey[100] } }
53
}));
54

55
const linkables = {
3✔
56
  'Integration': 'integration',
57
  'Mender-Client': 'mender',
58
  'Mender-Artifact': 'mender-artifact',
59
  'GUI': 'gui'
60
};
61

62
const VersionInfo = () => {
3✔
63
  const [clicks, setClicks] = useState(0);
61✔
64
  const timer = useRef();
61✔
65
  const { classes } = useStyles();
61✔
66

67
  const dispatch = useDispatch();
61✔
68
  const { isHosted } = useSelector(getFeatures);
61✔
69
  // eslint-disable-next-line no-unused-vars
70
  const { latestRelease, ...versionInformation } = useSelector(getVersionInformation);
61✔
71

72
  useEffect(() => {
61✔
73
    return () => {
5✔
74
      clearTimeout(timer.current);
5✔
75
    };
76
  }, []);
77

78
  const onVersionClick = () => {
61✔
79
    copy(JSON.stringify(versionInformation));
×
80
    dispatch(setSnackbar('Version information copied to clipboard'));
×
81
  };
82

83
  const versions = (
84
    <div className={classes.versions}>
61✔
85
      {Object.entries(versionInformation).reduce((accu, [key, version]) => {
86
        if (version) {
466✔
87
          accu.push(
225✔
88
            <React.Fragment key={key}>
89
              {linkables[key] ? (
225✔
90
                <a href={`https://github.com/mendersoftware/${linkables[key]}/tree/${version}`} target="_blank" rel="noopener noreferrer">
91
                  {key}
92
                </a>
93
              ) : (
94
                <div>{key}</div>
95
              )}
96
              <div className="align-right text-overflow" title={version}>
97
                {version}
98
              </div>
99
            </React.Fragment>
100
          );
101
        }
102
        return accu;
466✔
103
      }, [])}
104
    </div>
105
  );
106

107
  const onClick = () => {
61✔
108
    setClicks(clicks + 1);
×
109
    clearTimeout(timer.current);
×
110
    timer.current = setTimeout(() => {
×
111
      setClicks(0);
×
112
    }, TIMEOUTS.threeSeconds);
113
    if (clicks > 5) {
×
114
      dispatch(setVersionInfo({ Integration: 'next' }));
×
115
    }
116
    onVersionClick();
×
117
  };
118

119
  let title = versionInformation.Integration ? `Version: ${versionInformation.Integration}` : '';
61✔
120
  if (isHosted && versionInformation.Integration !== 'next') {
61!
121
    title = 'Version: latest';
×
122
  }
123
  return (
61✔
124
    <Tooltip title={versions} placement="top">
125
      <div className="clickable slightly-smaller" onClick={onClick}>
126
        {title}
127
      </div>
128
    </Tooltip>
129
  );
130
};
131

132
export const LeftNav = () => {
3✔
133
  const releasesRef = useRef();
59✔
134
  const { classes } = useStyles();
59✔
135

136
  const onboardingState = useSelector(getOnboardingState);
59✔
137
  const tenantCapabilities = useSelector(getTenantCapabilities);
59✔
138
  const userCapabilities = useSelector(getUserCapabilities);
59✔
139

140
  let onboardingComponent;
141
  if (releasesRef.current) {
59✔
142
    onboardingComponent = getOnboardingComponentFor(onboardingSteps.APPLICATION_UPDATE_REMINDER_TIP, onboardingState, {
49✔
143
      anchor: {
144
        left: releasesRef.current.offsetWidth - 48,
145
        top: releasesRef.current.offsetTop + releasesRef.current.offsetHeight / 2
146
      },
147
      place: 'right'
148
    });
149
  }
150
  return (
59✔
151
    <div className={`leftFixed leftNav ${classes.list}`}>
152
      <List style={{ padding: 0 }}>
153
        {listItems.reduce((accu, item, index) => {
154
          if (!item.canAccess({ tenantCapabilities, userCapabilities })) {
295✔
155
            return accu;
71✔
156
          }
157
          accu.push(
224✔
158
            <ListItem
159
              className={`navLink leftNav ${classes.navLink}`}
160
              component={NavLink}
161
              end={item.route === '/'}
162
              key={index}
163
              ref={item.route === '/releases' ? releasesRef : null}
224✔
164
              to={item.route}
165
            >
166
              <ListItemText primary={item.text} style={{ textTransform: 'uppercase' }} />
167
            </ListItem>
168
          );
169
          return accu;
224✔
170
        }, [])}
171
      </List>
172
      {onboardingComponent ? onboardingComponent : null}
59!
173
      <List className={classes.infoList}>
174
        <ListItem className={`navLink leftNav ${classes.listItem}`} component={Link} to="/help">
175
          <ListItemText primary="Help & support" />
176
        </ListItem>
177
        <ListItem className={classes.listItem}>
178
          <ListItemText
179
            primary={<VersionInfo />}
180
            secondary={<DocsLink className={classes.licenseLink} path="release-information/open-source-licenses" title="License information" />}
181
          />
182
        </ListItem>
183
      </List>
184
    </div>
185
  );
186
};
187

188
export default LeftNav;
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