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

mendersoftware / mender-server / 1654640967

04 Feb 2025 09:27AM UTC coverage: 76.621%. First build
1654640967

push

gitlab-ci

web-flow
Merge pull request #412 from mineralsfree/MEN-7728

MEN-7728-fix(gui): prevented role creation dialog from closing in case of error

4337 of 6299 branches covered (68.85%)

Branch coverage included in aggregate %.

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

45469 of 58704 relevant lines covered (77.45%)

20.26 hits per line

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

76.79
/frontend/src/js/components/settings/role-management/RoleManagement.tsx
1
// Copyright 2020 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

17
// material ui
18
import { Add as AddIcon } from '@mui/icons-material';
19
import { Chip } from '@mui/material';
20

21
import DetailsIndicator from '@northern.tech/common-ui/DetailsIndicator';
22
import DetailsTable from '@northern.tech/common-ui/DetailsTable';
23
import { DOCSTIPS, DocsTooltip } from '@northern.tech/common-ui/DocsLink';
24
import EnterpriseNotification from '@northern.tech/common-ui/EnterpriseNotification';
25
import { InfoHintContainer } from '@northern.tech/common-ui/InfoHint';
26
import { BENEFITS, UiRoleDefinition, emptyRole, settingsKeys } from '@northern.tech/store/constants';
27
import { getGroupsByIdWithoutUngrouped, getIsEnterprise, getOrganization, getReleaseTagsById, getRelevantRoles } from '@northern.tech/store/selectors';
28
import { useAppDispatch } from '@northern.tech/store/store';
29
import { createRole, editRole, getDynamicGroups, getExistingReleaseTags, getGroups, getRoles, removeRole } from '@northern.tech/store/thunks';
30

31
import RoleDefinition from './RoleDefinition';
32

33
const columns = [
5✔
34
  { key: 'name', title: 'Role', render: ({ name }) => name },
104✔
35
  { key: 'description', title: 'Description', render: ({ description }) => description || '-' },
104✔
36
  { key: 'manage', title: 'Manage', render: DetailsIndicator }
37
];
38

39
export const RoleManagement = () => {
5✔
40
  const [adding, setAdding] = useState<boolean>(false);
14✔
41
  const [editing, setEditing] = useState<boolean>(false);
13✔
42
  const [role, setRole] = useState<UiRoleDefinition>({ ...emptyRole });
13✔
43
  const dispatch = useAppDispatch();
13✔
44
  const groups = useSelector(getGroupsByIdWithoutUngrouped);
13✔
45
  const releaseTags = useSelector(getReleaseTagsById);
13✔
46
  const isEnterprise = useSelector(getIsEnterprise);
13✔
47
  const { service_provider } = useSelector(getOrganization);
13✔
48
  const items = useSelector(getRelevantRoles);
13✔
49
  const isLikelyInitialized = window.sessionStorage.getItem(settingsKeys.initialized);
13✔
50

51
  useEffect(() => {
13✔
52
    if (service_provider || !isLikelyInitialized) {
3!
53
      return;
×
54
    }
55
    dispatch(getExistingReleaseTags());
3✔
56
  }, [dispatch, isLikelyInitialized, service_provider]);
57

58
  useEffect(() => {
13✔
59
    if (Object.keys(groups).length || service_provider || !isLikelyInitialized) {
3!
60
      return;
3✔
61
    }
62
    dispatch(getDynamicGroups());
×
63
    dispatch(getGroups());
×
64
    dispatch(getRoles());
×
65
    // eslint-disable-next-line react-hooks/exhaustive-deps
66
  }, [dispatch, isLikelyInitialized, JSON.stringify(groups), service_provider]);
67

68
  const addRole = () => {
13✔
69
    setAdding(true);
×
70
    setEditing(false);
×
71
    setRole({ ...emptyRole });
×
72
  };
73

74
  const onEditRole = editedRole => {
13✔
75
    setAdding(false);
4✔
76
    setEditing(true);
4✔
77
    setRole(editedRole);
4✔
78
  };
79

80
  const onCancel = () => {
13✔
81
    setAdding(false);
4✔
82
    setEditing(false);
4✔
83
  };
84

85
  const onSubmit = submittedRole => {
13✔
86
    let action = editRole(submittedRole);
2✔
87
    if (adding) {
2!
NEW
88
      action = createRole(submittedRole);
×
89
    }
90
    dispatch(action)
2✔
91
      .unwrap()
92
      .then(() => onCancel());
2✔
93
  };
94

95
  return (
13✔
96
    <div>
97
      <div className="flexbox center-aligned">
98
        <h2 style={{ marginLeft: 20 }}>Roles</h2>
99
        <InfoHintContainer>
100
          <EnterpriseNotification id={BENEFITS.rbac.id} />
101
          <DocsTooltip id={DOCSTIPS.rbac.id} />
102
        </InfoHintContainer>
103
      </div>
104
      <DetailsTable columns={columns} items={items} onItemClick={onEditRole} />
105
      <Chip color="primary" icon={<AddIcon />} label="Add a role" onClick={addRole} disabled={!isEnterprise} />
106
      <RoleDefinition
107
        adding={adding}
108
        editing={editing}
109
        isServiceProvider={!!service_provider}
110
        onCancel={onCancel}
111
        onSubmit={onSubmit}
112
        removeRole={name => dispatch(removeRole(name))}
2✔
113
        selectedRole={role}
114
        stateGroups={groups}
115
        stateReleaseTags={releaseTags}
116
      />
117
    </div>
118
  );
119
};
120

121
export default RoleManagement;
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