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

mendersoftware / mender-server / 10423

11 Nov 2025 04:53PM UTC coverage: 74.435% (-0.1%) from 74.562%
10423

push

gitlab-ci

web-flow
Merge pull request #1071 from mendersoftware/dependabot/npm_and_yarn/frontend/main/development-dependencies-92732187be

3868 of 5393 branches covered (71.72%)

Branch coverage included in aggregate %.

5 of 5 new or added lines in 2 files covered. (100.0%)

176 existing lines in 95 files now uncovered.

64605 of 86597 relevant lines covered (74.6%)

7.74 hits per line

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

97.63
/frontend/src/js/components/settings/user-management/UserManagement.tsx
1
// Copyright 2017 Northern.tech AS
2✔
2
//
2✔
3
//    Licensed under the Apache License, Version 2.0 (the "License");
2✔
4
//    you may not use this file except in compliance with the License.
2✔
5
//    You may obtain a copy of the License at
2✔
6
//
2✔
7
//        http://www.apache.org/licenses/LICENSE-2.0
2✔
8
//
2✔
9
//    Unless required by applicable law or agreed to in writing, software
2✔
10
//    distributed under the License is distributed on an "AS IS" BASIS,
2✔
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2✔
12
//    See the License for the specific language governing permissions and
2✔
13
//    limitations under the License.
2✔
14
import { useEffect, useState } from 'react';
2✔
15
import { useDispatch, useSelector } from 'react-redux';
2✔
16

2✔
17
import { Add as AddIcon } from '@mui/icons-material';
2✔
18
// material ui
2✔
19
import { Button, Chip, DialogActions, DialogContent } from '@mui/material';
2✔
20

2✔
21
import { BaseDialog } from '@northern.tech/common-ui/dialogs/BaseDialog';
2✔
22
import storeActions from '@northern.tech/store/actions';
2✔
23
import {
2✔
24
  getCurrentUser,
2✔
25
  getFeatures,
2✔
26
  getIsEnterprise,
2✔
27
  getOrganization,
2✔
28
  getRelevantRoles,
2✔
29
  getUserCapabilities,
2✔
30
  getUsersList
2✔
31
} from '@northern.tech/store/selectors';
2✔
32
import { addUserToCurrentTenant, createUser, editUser, getUserList, passwordResetStart, removeUser } from '@northern.tech/store/thunks';
2✔
33

2✔
34
import { UserDefinition } from './UserDefinition';
2✔
35
import UserForm from './UserForm';
2✔
36
import UserList from './UserList';
2✔
37

2✔
38
const { setSnackbar } = storeActions;
7✔
39

2✔
40
const actions = {
7✔
41
  add: 'addUser',
2✔
42
  create: 'createUser',
2✔
43
  edit: 'editUser',
2✔
44
  remove: 'removeUser'
2✔
45
};
2✔
46

2✔
47
const DeleteUserDialog = ({ dismiss, open, submit, user }) => (
7✔
48
  <BaseDialog title="Delete user?" open={open} onClose={dismiss}>
16✔
49
    <DialogContent style={{ overflow: 'hidden' }}>
2✔
50
      Are you sure you want to delete the user with email{' '}
2✔
51
      <b>
2✔
52
        <i>{user.email}</i>
2✔
53
      </b>
2✔
54
      ?
2✔
55
    </DialogContent>
2✔
56
    <DialogActions>
2✔
57
      <Button style={{ marginRight: 10 }} onClick={dismiss}>
2✔
58
        Cancel
2✔
59
      </Button>
2✔
UNCOV
60
      <Button variant="contained" color="primary" onClick={() => submit(user, 'remove', user.id)}>
2✔
61
        Delete user
2✔
62
      </Button>
2✔
63
    </DialogActions>
2✔
64
  </BaseDialog>
2✔
65
);
2✔
66

2✔
67
export const UserManagement = () => {
7✔
68
  const [showCreate, setShowCreate] = useState(false);
16✔
69
  const [removeDialog, setRemoveDialog] = useState(false);
16✔
70
  const [user, setUser] = useState({});
16✔
71
  const dispatch = useDispatch();
16✔
72

2✔
73
  const { canManageUsers } = useSelector(getUserCapabilities);
16✔
74
  const { isHosted } = useSelector(getFeatures);
16✔
75
  const isEnterprise = useSelector(getIsEnterprise);
16✔
76
  const currentUser = useSelector(getCurrentUser);
16✔
77
  const roles = useSelector(getRelevantRoles);
16✔
78
  const users = useSelector(getUsersList);
16✔
79
  const { trial: isTrial } = useSelector(getOrganization);
16✔
80
  const props = {
16✔
81
    canManageUsers,
2✔
UNCOV
82
    addUser: id => dispatch(addUserToCurrentTenant(id)),
2✔
83
    createUser: userData => dispatch(createUser(userData)),
3✔
84
    currentUser,
2✔
85
    editUser: (id, userData) => dispatch(editUser({ ...userData, id })),
3✔
86
    isEnterprise,
2✔
87
    isHosted,
2✔
UNCOV
88
    removeUser: id => dispatch(removeUser(id)),
2✔
89
    roles,
2✔
90
    users,
2✔
91
    isTrial
2✔
92
  };
2✔
93

2✔
94
  useEffect(() => {
16✔
95
    dispatch(getUserList());
6✔
96
  }, [dispatch]);
2✔
97

2✔
98
  const openEdit = user => {
16✔
99
    setUser(user);
5✔
100
    setRemoveDialog(false);
5✔
101
    dispatch(setSnackbar(''));
5✔
102
  };
2✔
103

2✔
104
  const openRemove = () => {
16✔
105
    dispatch(setSnackbar(''));
3✔
106
    setRemoveDialog(true);
3✔
107
  };
2✔
108

2✔
109
  const dialogDismiss = () => {
16✔
110
    setUser({});
5✔
111
    setShowCreate(false);
5✔
112
    setRemoveDialog(false);
5✔
113
  };
2✔
114

2✔
115
  const submit = (userData, type, id, passwordResetEmail) => {
16✔
116
    if (userData) {
4!
117
      let request = null;
4✔
118
      if (id) {
4✔
119
        request = props[actions[type]](id, userData);
3✔
120
      } else {
2✔
121
        request = props[actions[type]](userData);
3✔
122
      }
2✔
123
      return request.then(() => {
4✔
124
        if (passwordResetEmail) {
4!
125
          dispatch(passwordResetStart(passwordResetEmail));
2✔
126
        }
2✔
127
        dialogDismiss();
4✔
128
      });
2✔
129
    }
2✔
130
    if (passwordResetEmail) {
2!
131
      dispatch(passwordResetStart(passwordResetEmail));
2✔
132
    }
2✔
133
    return dialogDismiss();
2✔
134
  };
2✔
135

2✔
136
  return (
16✔
137
    <div>
2✔
138
      <div className="flexbox centered space-between" style={{ marginLeft: '20px' }}>
2✔
139
        <h2>Users</h2>
2✔
140
      </div>
2✔
141

2✔
142
      <UserList {...props} editUser={openEdit} />
2✔
143
      <Chip color="primary" icon={<AddIcon />} label="Add new user" onClick={setShowCreate} />
2✔
144
      {showCreate && <UserForm {...props} closeDialog={dialogDismiss} submit={submit} />}
2✔
145
      <UserDefinition
2✔
146
        currentUser={currentUser}
2✔
147
        isEnterprise={isEnterprise}
2✔
148
        onRemove={openRemove}
2✔
149
        onCancel={dialogDismiss}
2✔
150
        onSubmit={submit}
2✔
151
        roles={roles}
2✔
152
        selectedUser={user}
2✔
153
      />
2✔
154
      <DeleteUserDialog dismiss={dialogDismiss} open={removeDialog} submit={submit} user={user} />
2✔
155
    </div>
2✔
156
  );
2✔
157
};
2✔
158

2✔
159
export default UserManagement;
2✔
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