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

mendersoftware / gui / 1081664682

22 Nov 2023 02:11PM UTC coverage: 82.798% (-17.2%) from 99.964%
1081664682

Pull #4214

gitlab-ci

tranchitella
fix: Fixed the infinite page redirects when the back button is pressed

Remove the location and navigate from the useLocationParams.setValue callback
dependencies as they change the set function that is presented in other
useEffect dependencies. This happens when the back button is clicked, which
leads to the location changing infinitely.

Changelog: Title
Ticket: MEN-6847
Ticket: MEN-6796

Signed-off-by: Ihor Aleksandrychiev <ihor.aleksandrychiev@northern.tech>
Signed-off-by: Fabio Tranchitella <fabio.tranchitella@northern.tech>
Pull Request #4214: fix: Fixed the infinite page redirects when the back button is pressed

4319 of 6292 branches covered (0.0%)

8332 of 10063 relevant lines covered (82.8%)

191.0 hits per line

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

91.89
/src/js/components/help/help.js
1
// Copyright 2017 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 { useSelector } from 'react-redux';
16
import { Navigate, useLocation, useParams } from 'react-router-dom';
17

18
import { Launch as LaunchIcon } from '@mui/icons-material';
19
import { ListItemIcon, useTheme } from '@mui/material';
20

21
import { getFeatures } from '../../selectors';
22
import LeftNav from '../common/left-nav';
23
import Downloads from './downloads';
24
import GetStarted from './getting-started';
25
import MenderHub from './mender-hub';
26
import Support from './support';
27

28
const components = {
3✔
29
  'get-started': {
30
    title: 'Getting started',
31
    component: GetStarted
32
  },
33
  downloads: {
34
    title: 'Downloads',
35
    component: Downloads,
36
    hosted: true
37
  },
38
  support: {
39
    title: 'Contact support',
40
    component: Support
41
  },
42
  'mender-hub': {
43
    title: 'Mender Hub',
44
    component: MenderHub
45
  },
46
  documentation: {
47
    title: 'Documentation',
48
    url: `https://docs.mender.io/`
49
  }
50
};
51

52
const contentWidth = 780;
3✔
53

54
const LinkIcon = () => (
3✔
55
  <ListItemIcon style={{ 'verticalAlign': 'middle' }}>
×
56
    <LaunchIcon style={{ 'fontSize': '1rem' }} />
57
  </ListItemIcon>
58
);
59

60
// build array of link list components
61
const eachRecursive = (obj, path, level, accu, isHosted, spacing) =>
3✔
62
  Object.entries(obj).reduce((bag, [key, value]) => {
5✔
63
    if (!isHosted && value.hosted) {
13✔
64
      return bag;
1✔
65
    }
66
    if (typeof value == 'object' && value !== null && key !== 'component') {
12✔
67
      const this_path = `${path}/${key}`;
4✔
68
      bag.push({
4✔
69
        title: value.title,
70
        level,
71
        path: this_path,
72
        hosted: value.hosted,
73
        style: { paddingLeft: `calc(${level} * ${spacing})` },
74
        exact: true,
75
        secondaryAction: value.url ? <LinkIcon /> : null,
4✔
76
        url: value.url ? value.url : ''
4✔
77
      });
78
      bag = eachRecursive(value, this_path, level + 1, bag, isHosted, spacing);
4✔
79
    }
80
    return bag;
12✔
81
  }, accu);
82

83
const helpPath = 'help/';
3✔
84
export const Help = () => {
3✔
85
  const spacing = useTheme().spacing(2);
2✔
86
  const [links, setLinks] = useState([]);
2✔
87
  const { pathname } = useLocation();
2✔
88
  const { section } = useParams();
2✔
89

90
  const { isHosted } = useSelector(getFeatures);
2✔
91

92
  useEffect(() => {
2✔
93
    // generate sidebar links
94
    setLinks(eachRecursive(components, '/help', 1, [], isHosted, spacing));
1✔
95
  }, [isHosted, spacing]);
96

97
  if (!section) {
2!
98
    return <Navigate replace to="/help/get-started" />;
×
99
  }
100

101
  let ComponentToShow = GetStarted;
2✔
102
  let breadcrumbs = '';
2✔
103
  let routeParams = pathname.includes(helpPath) ? pathname.substring(pathname.indexOf(helpPath) + helpPath.length) : '';
2!
104
  if (routeParams) {
2!
105
    let splitsplat = routeParams.split('/');
2✔
106
    let copyOfComponents = components;
2✔
107

108
    for (let i = 0; i < splitsplat.length; i++) {
2✔
109
      if (i === splitsplat.length - 1) {
2!
110
        ComponentToShow = copyOfComponents[splitsplat[i]].component;
2✔
111
      } else {
112
        copyOfComponents = copyOfComponents[splitsplat[i]];
×
113
      }
114
    }
115

116
    breadcrumbs = splitsplat[0] ? '  >  ' + components[splitsplat[0]].title : '';
2!
117
    breadcrumbs = splitsplat[1] ? breadcrumbs + '  >  ' + components[splitsplat[0]][splitsplat[1]].title : breadcrumbs;
2!
118
  }
119

120
  return (
2✔
121
    <div className="help-container">
122
      <LeftNav sections={[{ itemClass: 'helpNav', items: links, title: 'Help & support' }]} />
123
      <div style={{ maxWidth: contentWidth }}>
124
        <p className="muted">Help & support {breadcrumbs}</p>
125
        <div className="help-content relative margin-top-small">
126
          <ComponentToShow />
127
        </div>
128
      </div>
129
    </div>
130
  );
131
};
132

133
export default Help;
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