Skip to content

Commit e651f16

Browse files
committed
New users tab and permission functionality
#1435
1 parent 00c51e0 commit e651f16

File tree

13 files changed

+1473
-6
lines changed

13 files changed

+1473
-6
lines changed

src/actions/projects.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,28 @@ import {
22
LOAD_PROJECT_BILLING_ACCOUNT,
33
LOAD_CHALLENGE_MEMBERS_SUCCESS,
44
LOAD_PROJECT_DETAILS,
5-
LOAD_PROJECT_PHASES
5+
LOAD_PROJECT_PHASES,
6+
LOAD_CHALLENGE_MEMBERS
67
} from '../config/constants'
7-
import { fetchProjectById, fetchBillingAccount, fetchProjectPhases } from '../services/projects'
8+
import {
9+
fetchProjectById,
10+
fetchBillingAccount,
11+
fetchProjectPhases
12+
} from '../services/projects'
813

914
/**
1015
* Loads project details
1116
*/
12-
export function loadProject (projectId) {
17+
export function loadProject (projectId, filterMembers = true) {
1318
return (dispatch, getState) => {
1419
return dispatch({
1520
type: LOAD_PROJECT_DETAILS,
1621
payload: fetchProjectById(projectId).then((project) => {
1722
if (project && project.members) {
18-
const members = project.members.filter(m => m.role === 'manager' || m.role === 'copilot')
23+
const members = filterMembers ? project.members.filter(m => m.role === 'manager' || m.role === 'copilot') : project.members
1924
dispatch({
2025
type: LOAD_CHALLENGE_MEMBERS_SUCCESS,
21-
members
26+
payload: members
2227
})
2328
}
2429

@@ -39,3 +44,18 @@ export function loadProject (projectId) {
3944
})
4045
}
4146
}
47+
48+
export function reloadProjectMembers (projectId) {
49+
return (dispatch) => {
50+
return dispatch({
51+
type: LOAD_CHALLENGE_MEMBERS,
52+
payload: fetchProjectById(projectId)
53+
.then((project) => {
54+
if (project && project.members) {
55+
return project.members
56+
}
57+
return []
58+
})
59+
})
60+
}
61+
}

src/components/Tab/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ const Tab = ({
2121
selectTab(2)
2222
}
2323

24+
const onUsersClick = () => {
25+
if (currentTab === 3) {
26+
return
27+
}
28+
selectTab(3)
29+
}
30+
2431
const tabComponent = (
2532
<ul className={styles.challengeTab}>
2633
<li
@@ -51,6 +58,20 @@ const Tab = ({
5158
>
5259
Projects
5360
</li>
61+
<li
62+
key='tab-item-users'
63+
className={cn(styles.item, { [styles.active]: currentTab === 3 })}
64+
onClick={onUsersClick}
65+
onKeyDown={e => {
66+
if (e.key !== 'Enter') {
67+
return
68+
}
69+
onUsersClick()
70+
}}
71+
role='presentation'
72+
>
73+
Users
74+
</li>
5475
</ul>
5576
)
5677

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
@import "../../styles/includes";
2+
3+
.item {
4+
display: flex;
5+
font-size: 14px;
6+
gap: 30px;
7+
height: 30px;
8+
padding: 0 20px;
9+
10+
.col5 {
11+
display: flex;
12+
width: 150px;
13+
flex-direction: column;
14+
justify-content: center;
15+
}
16+
}
17+
18+
.tcRadioButton {
19+
.tc-radioButton-label {
20+
@include roboto-light();
21+
22+
line-height: 17px;
23+
font-weight: 300;
24+
margin-left: 21px;
25+
user-select: none;
26+
cursor: pointer;
27+
width: 195px;
28+
font-size: 14px;
29+
color: #3d3d3d;
30+
}
31+
32+
height: 18px;
33+
margin: 0;
34+
padding: 0;
35+
vertical-align: bottom;
36+
position: relative;
37+
display: inline-block;
38+
39+
input[type=radio] {
40+
display: none;
41+
}
42+
43+
label {
44+
@include roboto-light();
45+
46+
line-height: 17px;
47+
font-weight: 300;
48+
cursor: pointer;
49+
position: absolute;
50+
display: inline-block;
51+
width: 16px;
52+
height: 16px;
53+
border-radius: 8px;
54+
top: 0;
55+
left: 0;
56+
border: none;
57+
box-shadow: none;
58+
background: $tc-gray-30;
59+
transition: all 0.15s ease-in-out;
60+
61+
&::after {
62+
opacity: 0;
63+
content: '';
64+
position: absolute;
65+
width: 8px;
66+
height: 8px;
67+
background: transparent;
68+
top: 4px;
69+
left: 4px;
70+
border: 4px solid $tc-blue-20;
71+
border-radius: 4px;
72+
transition: all 0.15s ease-in-out;
73+
}
74+
75+
&:hover::after {
76+
opacity: 0.3;
77+
}
78+
79+
div {
80+
margin-left: 24px;
81+
width: 150px;
82+
}
83+
}
84+
85+
input[type=radio]:checked ~ label {
86+
background: $tc-blue-20;
87+
}
88+
89+
input[type=radio]:checked + label::after {
90+
opacity: 1;
91+
border-color: $white;
92+
}
93+
}
94+
95+
.modalContainer {
96+
padding: 0;
97+
position: fixed;
98+
overflow: auto;
99+
z-index: 10000;
100+
top: 0;
101+
right: 0;
102+
bottom: 0;
103+
left: 0;
104+
box-sizing: border-box;
105+
width: auto;
106+
max-width: none;
107+
transform: none;
108+
background: transparent;
109+
color: $text-color;
110+
opacity: 1;
111+
display: flex;
112+
justify-content: center;
113+
align-items: center;
114+
115+
:global {
116+
button.close {
117+
margin-right: 5px;
118+
margin-top: 5px;
119+
}
120+
}
121+
122+
.contentContainer {
123+
box-sizing: border-box;
124+
background: $white;
125+
opacity: 1;
126+
position: relative;
127+
display: flex;
128+
flex-direction: column;
129+
justify-content: flex-start;
130+
align-items: center;
131+
border-radius: 6px;
132+
margin: 0 auto;
133+
width: 852px;
134+
padding: 30px;
135+
136+
.content {
137+
padding: 30px;
138+
width: 100%;
139+
height: 100%;
140+
}
141+
142+
.title {
143+
@include roboto-bold();
144+
145+
font-size: 30px;
146+
line-height: 36px;
147+
margin-bottom: 30px;
148+
margin-top: 0;
149+
}
150+
151+
span {
152+
@include roboto;
153+
154+
font-size: 22px;
155+
font-weight: 400;
156+
line-height: 26px;
157+
}
158+
159+
&.confirm {
160+
width: 999px;
161+
162+
.buttonGroup {
163+
display: flex;
164+
justify-content: space-between;
165+
margin-top: 30px;
166+
167+
.buttonSizeA {
168+
width: 193px;
169+
height: 40px;
170+
margin-right: 33px;
171+
172+
span {
173+
font-size: 18px;
174+
font-weight: 500;
175+
}
176+
}
177+
178+
.buttonSizeB {
179+
width: 160px;
180+
height: 40px;
181+
182+
span {
183+
font-size: 18px;
184+
font-weight: 500;
185+
line-height: 22px;
186+
}
187+
}
188+
}
189+
}
190+
191+
.buttonGroup {
192+
display: flex;
193+
justify-content: space-between;
194+
margin-top: 30px;
195+
196+
.button {
197+
width: 135px;
198+
height: 40px;
199+
margin-right: 66px;
200+
201+
span {
202+
font-size: 18px;
203+
font-weight: 500;
204+
}
205+
}
206+
207+
.button:last-child {
208+
margin-right: 0;
209+
}
210+
}
211+
}
212+
}

0 commit comments

Comments
 (0)