• 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

94.87
/src/js/reducers/deviceReducer.js
1
// Copyright 2019 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 { SORTING_OPTIONS } from '../constants/appConstants';
15
import * as DeviceConstants from '../constants/deviceConstants';
16
import * as MonitorConstants from '../constants/monitorConstants';
17
import { duplicateFilter } from '../helpers';
18

19
export const initialState = {
183✔
20
  byId: {
21
    // [deviceId]: {
22
    //   ...,
23
    //   twinsByIntegration: { [external.provider.id]: twinData }
24
    // }
25
  },
26
  byStatus: {
27
    [DeviceConstants.DEVICE_STATES.accepted]: { deviceIds: [], total: 0 },
28
    active: { deviceIds: [], total: 0 },
29
    inactive: { deviceIds: [], total: 0 },
30
    [DeviceConstants.DEVICE_STATES.pending]: { deviceIds: [], total: 0 },
31
    [DeviceConstants.DEVICE_STATES.preauth]: { deviceIds: [], total: 0 },
32
    [DeviceConstants.DEVICE_STATES.rejected]: { deviceIds: [], total: 0 }
33
  },
34
  deviceList: {
35
    deviceIds: [],
36
    ...DeviceConstants.DEVICE_LIST_DEFAULTS,
37
    selectedAttributes: [],
38
    selectedIssues: [],
39
    selection: [],
40
    sort: {
41
      direction: SORTING_OPTIONS.desc
42
      // key: null,
43
      // scope: null
44
    },
45
    state: DeviceConstants.DEVICE_STATES.accepted,
46
    total: 0
47
  },
48
  filters: [
49
    // { key: 'device_type', value: 'raspberry', operator: '$eq', scope: 'inventory' }
50
  ],
51
  filteringAttributes: { identityAttributes: [], inventoryAttributes: [], systemAttributes: [], tagAttributes: [] },
52
  filteringAttributesLimit: 10,
53
  filteringAttributesConfig: {
54
    attributes: {
55
      // inventory: ['some_attribute']
56
    },
57
    count: 0,
58
    limit: 100
59
  },
60
  reports: [
61
    // { items: [{ key: "someKey", count: 42  }], otherCount: 123, total: <otherCount + itemsCount> }
62
  ],
63
  total: 0,
64
  limit: 0,
65
  groups: {
66
    byId: {
67
      // groupName: { deviceIds: [], total: 0, filters: [] },
68
      // dynamo: { deviceIds: [], total: 3, filters: [{ a: 1 }] }
69
    },
70
    selectedGroup: undefined
71
  }
72
};
73

74
const deviceReducer = (state = initialState, action) => {
183✔
75
  switch (action.type) {
2,591✔
76
    case DeviceConstants.RECEIVE_GROUPS:
77
    case DeviceConstants.RECEIVE_DYNAMIC_GROUPS:
78
    case DeviceConstants.REMOVE_STATIC_GROUP:
79
    case DeviceConstants.REMOVE_DYNAMIC_GROUP:
80
      return {
37✔
81
        ...state,
82
        groups: {
83
          ...state.groups,
84
          byId: action.groups
85
        }
86
      };
87
    case DeviceConstants.ADD_TO_GROUP: {
88
      let group = {
2✔
89
        deviceIds: action.deviceIds,
90
        filters: [],
91
        total: 1
92
      };
93
      if (state.groups.byId[action.group]) {
2!
94
        group = {
×
95
          filters: [],
96
          ...state.groups.byId[action.group],
97
          deviceIds: [...state.groups.byId[action.group].deviceIds, ...action.deviceIds],
98
          total: state.groups.byId[action.group].total + 1
99
        };
100
        group.deviceIds.filter(duplicateFilter);
×
101
      }
102
      return {
2✔
103
        ...state,
104
        groups: {
105
          ...state.groups,
106
          byId: {
107
            ...state.groups.byId,
108
            [action.group]: group
109
          }
110
        }
111
      };
112
    }
113
    case DeviceConstants.REMOVE_FROM_GROUP: {
114
      const { deviceIds = [], total = 0, ...maybeExistingGroup } = state.groups.byId[action.group] || {};
3✔
115
      const group = {
3✔
116
        ...maybeExistingGroup,
117
        deviceIds: deviceIds.filter(id => !action.deviceIds.includes(id)),
4✔
118
        total: Math.max(total - action.deviceIds.length, 0)
119
      };
120
      let byId = {};
3✔
121
      let selectedGroup = state.groups.selectedGroup;
3✔
122
      if (group.total || group.deviceIds.length) {
3✔
123
        byId = {
1✔
124
          ...state.groups.byId,
125
          [action.group]: group
126
        };
127
      } else if (state.groups.selectedGroup === action.group) {
2✔
128
        selectedGroup = undefined;
1✔
129
        // eslint-disable-next-line no-unused-vars
130
        const { [action.group]: removal, ...remainingById } = state.groups.byId;
1✔
131
        byId = remainingById;
1✔
132
      }
133
      return {
3✔
134
        ...state,
135
        groups: {
136
          ...state.groups,
137
          byId,
138
          selectedGroup
139
        }
140
      };
141
    }
142
    case DeviceConstants.ADD_DYNAMIC_GROUP:
143
    case DeviceConstants.ADD_STATIC_GROUP:
144
    case DeviceConstants.RECEIVE_GROUP_DEVICES:
145
      return {
19✔
146
        ...state,
147
        groups: {
148
          ...state.groups,
149
          byId: { ...state.groups.byId, [action.groupName]: action.group }
150
        }
151
      };
152
    case DeviceConstants.SELECT_GROUP:
153
      return {
1✔
154
        ...state,
155
        deviceList: {
156
          ...state.deviceList,
157
          deviceIds: state.groups.byId[action.group] && state.groups.byId[action.group].deviceIds.length > 0 ? state.groups.byId[action.group].deviceIds : []
3!
158
        },
159
        groups: {
160
          ...state.groups,
161
          selectedGroup: action.group
162
        }
163
      };
164
    case DeviceConstants.SET_DEVICE_LIST_STATE:
165
      return { ...state, deviceList: action.state };
7✔
166
    case DeviceConstants.SET_FILTER_ATTRIBUTES:
167
      return { ...state, filteringAttributes: action.attributes };
11✔
168
    case DeviceConstants.SET_FILTERABLES_CONFIG:
169
      return {
3✔
170
        ...state,
171
        filteringAttributesConfig: {
172
          attributes: action.attributes,
173
          count: action.count,
174
          limit: action.limit
175
        }
176
      };
177
    case DeviceConstants.RECEIVE_DEVICES:
178
      return {
33✔
179
        ...state,
180
        byId: {
181
          ...state.byId,
182
          ...action.devicesById
183
        }
184
      };
185
    case DeviceConstants.SET_DEVICE_FILTERS: {
186
      const filters = action.filters.filter(filter => filter.key && filter.operator && filter.scope && typeof filter.value !== 'undefined');
2✔
187
      return {
2✔
188
        ...state,
189
        filters
190
      };
191
    }
192

193
    case DeviceConstants.SET_INACTIVE_DEVICES:
194
      return {
2✔
195
        ...state,
196
        byStatus: {
197
          ...state.byStatus,
198
          active: {
199
            total: action.activeDeviceTotal
200
          },
201
          inactive: {
202
            total: action.inactiveDeviceTotal
203
          }
204
        }
205
      };
206
    case DeviceConstants.SET_DEVICE_REPORTS:
207
      return {
10✔
208
        ...state,
209
        reports: action.reports
210
      };
211
    case DeviceConstants.SET_PENDING_DEVICES:
212
    case DeviceConstants.SET_REJECTED_DEVICES:
213
    case DeviceConstants.SET_PREAUTHORIZED_DEVICES:
214
    case DeviceConstants.SET_ACCEPTED_DEVICES: {
215
      const statusDeviceInfo = action.total || action.forceUpdate ? { deviceIds: action.deviceIds, total: action.total } : state.byStatus[action.status];
11✔
216
      return {
11✔
217
        ...state,
218
        byStatus: {
219
          ...state.byStatus,
220
          [action.status]: {
221
            ...statusDeviceInfo
222
          }
223
        }
224
      };
225
    }
226

227
    case DeviceConstants.SET_ACCEPTED_DEVICES_COUNT:
228
    case DeviceConstants.SET_PENDING_DEVICES_COUNT:
229
    case DeviceConstants.SET_REJECTED_DEVICES_COUNT:
230
    case DeviceConstants.SET_PREAUTHORIZED_DEVICES_COUNT:
231
      return {
405✔
232
        ...state,
233
        byStatus: {
234
          ...state.byStatus,
235
          [action.status]: {
236
            ...state.byStatus[action.status],
237
            total: action.count
238
          }
239
        }
240
      };
241
    case DeviceConstants.SET_TOTAL_DEVICES:
242
      return { ...state, total: action.count };
2✔
243
    case DeviceConstants.SET_DEVICE_LIMIT:
244
      return { ...state, limit: action.limit };
2✔
245
    case DeviceConstants.RECEIVE_DEVICE:
246
    case DeviceConstants.RECEIVE_DEVICE_CONFIG:
247
    case DeviceConstants.RECEIVE_DEVICE_CONNECT:
248
    case MonitorConstants.RECEIVE_DEVICE_MONITOR_CONFIG: {
249
      const { device } = action;
5✔
250
      return {
5✔
251
        ...state,
252
        byId: {
253
          ...state.byId,
254
          [device.id]: {
255
            ...state.byId[device.id],
256
            ...device
257
          }
258
        }
259
      };
260
    }
261
    default:
262
      return state;
2,036✔
263
  }
264
};
265

266
export default deviceReducer;
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