• 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

89.19
/src/js/components/deployments/deployment-wizard/rolloutoptions.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

16
import { Autocomplete, Checkbox, Collapse, FormControl, FormControlLabel, FormGroup, TextField } from '@mui/material';
17
import { makeStyles } from 'tss-react/mui';
18

19
import { BENEFITS, TIMEOUTS } from '../../../constants/appConstants';
20
import { toggle } from '../../../helpers';
21
import { useDebounce } from '../../../utils/debouncehook';
22
import { DOCSTIPS, DocsTooltip } from '../../common/docslink';
23
import EnterpriseNotification from '../../common/enterpriseNotification';
24
import { InfoHintContainer } from '../../common/info-hint';
25
import { HELPTOOLTIPS, MenderHelpTooltip } from '../../helptips/helptooltips';
26
import RolloutSteps from './rolloutsteps';
27

28
const useStyles = makeStyles()(() => ({
18✔
29
  defaultBox: { marginTop: 0, marginBottom: -15 },
30
  heading: { marginBottom: 0 },
31
  retryInput: { maxWidth: 150, minWidth: 130 },
32
  wrapper: { minHeight: 300 }
33
}));
34

35
export const ForceDeploy = ({ deploymentObject, setDeploymentSettings }) => {
11✔
36
  const [forceDeploy, setForceDeploy] = useState(deploymentObject.forceDeploy ?? false);
242✔
37
  const { classes } = useStyles();
242✔
38

39
  useEffect(() => {
242✔
40
    setDeploymentSettings({ forceDeploy });
6✔
41
  }, [forceDeploy, setDeploymentSettings]);
42

43
  return (
242✔
44
    <div>
45
      <FormControlLabel
46
        className={classes.heading}
47
        control={<Checkbox color="primary" checked={forceDeploy} onChange={() => setForceDeploy(toggle)} size="small" />}
×
48
        label={
49
          <div className="flexbox center-aligned">
50
            <b className="margin-right-small">Force update</b> (optional)
51
            <MenderHelpTooltip
52
              id={HELPTOOLTIPS.forceDeployment.id}
53
              disableFocusListener={false}
54
              disableHoverListener={false}
55
              disableTouchListener={false}
56
              style={{ marginLeft: 15 }}
57
            />
58
          </div>
59
        }
60
      />
61
    </div>
62
  );
63
};
64

65
export const RolloutOptions = ({ deploymentObject, isEnterprise, setDeploymentSettings }) => {
11✔
66
  const { phases = [], release = {} } = deploymentObject;
242✔
67
  const { classes } = useStyles();
242✔
68

69
  const { states = {} } = deploymentObject.update_control_map || {};
242✔
70
  const [isPaused, setIsPaused] = useState(!!Object.keys(states).length);
242✔
71

72
  const onStepChangeClick = step => {
242✔
73
    const { action } = step;
×
74
    setDeploymentSettings({ update_control_map: { states: { ...states, [step.state]: { action } } } });
×
75
  };
76

77
  const onIsPausedClick = () => setIsPaused(toggle);
242✔
78

79
  return (
242✔
80
    <>
81
      <FormControlLabel
82
        className={classes.heading}
83
        control={<Checkbox color="primary" checked={isPaused} disabled={!isEnterprise} onChange={onIsPausedClick} size="small" />}
84
        label={
85
          <div className="flexbox center-aligned">
86
            <b className="margin-right-small">Add pauses between update steps</b> (optional)
87
            <InfoHintContainer>
88
              <EnterpriseNotification id={BENEFITS.pausedDeployments.id} />
89
              <DocsTooltip id={DOCSTIPS.pausedDeployments.id} />
90
            </InfoHintContainer>
91
          </div>
92
        }
93
      />
94
      <Collapse in={isPaused} className={classes.wrapper}>
95
        <RolloutSteps disabled={phases.length > 1 || !isEnterprise} onStepChange={onStepChangeClick} release={release} steps={states} />
441✔
96
      </Collapse>
97
    </>
98
  );
99
};
100

101
export const Retries = ({
11✔
102
  canRetry,
103
  commonClasses,
104
  deploymentObject,
105
  hasNewRetryDefault = false,
2✔
106
  onSaveRetriesSetting,
107
  previousRetries,
108
  setDeploymentSettings
109
}) => {
110
  const { retries } = deploymentObject;
244✔
111
  const { classes } = useStyles();
244✔
112

113
  const [currentAttempts, setCurrentAttempts] = useState(Number(retries ?? previousRetries ?? 0) + 1);
244!
114
  const debouncedAttempts = useDebounce(currentAttempts, TIMEOUTS.debounceShort);
244✔
115

116
  useEffect(() => {
244✔
117
    setDeploymentSettings({ retries: Number(debouncedAttempts) - 1 });
7✔
118
  }, [debouncedAttempts, setDeploymentSettings]);
119

120
  const formatValue = value => {
244✔
121
    const newValue = Math.max(0, Math.min(value, 100));
530✔
122
    return newValue ? `${newValue}` : '';
530✔
123
  };
124

125
  const onInputChange = (e, value, reason) => {
244✔
126
    if (reason === 'clear') {
7!
127
      return setDeploymentSettings({ retries: 0 });
×
128
    } else if ((reason === 'reset' && !e) || reason === 'blur') {
7✔
129
      return;
6✔
130
    }
131
    setCurrentAttempts(formatValue(value));
1✔
132
  };
133

134
  const onSaveRetriesSettingClick = (_, checked) => onSaveRetriesSetting(checked);
244✔
135

136
  return (
244✔
137
    <>
138
      <div className="flexbox center-aligned margin-top-small">
139
        <b className={canRetry ? '' : commonClasses.disabled}>Select the number of times each device will attempt to apply the update</b>
244✔
140
        <InfoHintContainer>
141
          <EnterpriseNotification id={BENEFITS.retryDeployments.id} />
142
          <DocsTooltip id={DOCSTIPS.phasedDeployments.id} />
143
        </InfoHintContainer>
144
      </div>
145
      <FormControl className="margin-top-none" disabled={!canRetry}>
146
        <FormGroup row>
147
          <Autocomplete
148
            autoSelect
149
            autoHighlight
150
            className={`margin-right ${classes.retryInput}`}
151
            freeSolo
152
            disabled={!canRetry}
153
            getOptionLabel={formatValue}
154
            handleHomeEndKeys
155
            id="deployment-retries-selection"
156
            options={[1, 2, 3, 4]}
157
            onInputChange={onInputChange}
158
            renderInput={params => (
159
              <TextField
250✔
160
                {...params}
161
                className={classes.retryInput}
162
                inputProps={{ ...params.inputProps, value: formatValue(params.inputProps.value) }}
163
                InputProps={{ ...params.InputProps }}
164
                type="number"
165
              />
166
            )}
167
            value={currentAttempts}
168
          />
169
          <FormControlLabel
170
            className={classes.defaultBox}
171
            control={<Checkbox checked={hasNewRetryDefault} onChange={onSaveRetriesSettingClick} />}
172
            label="Save as default"
173
          />
174
        </FormGroup>
175
      </FormControl>
176
    </>
177
  );
178
};
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