Skip to content

Commit 7261f57

Browse files
authored
Merge pull request #4221 from appirio-tech/feature/generic-phases-with-new-milestone-types
Generic Phases with New Milestone Types
2 parents 894ce6a + ea184b1 commit 7261f57

File tree

57 files changed

+2810
-726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2810
-726
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ workflows:
128128
- build-dev
129129
filters:
130130
branches:
131-
only: ['dev']
131+
only: ['dev', 'feature/generic-phases-with-new-milestone-types']
132132

133133
- deployTest01:
134134
context : org-global

config/constants/dev.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module.exports = {
4343
PREDIX_PROGRAM_ID : 3448,
4444
IBM_COGNITIVE_PROGRAM_ID : 3449,
4545
HEAP_ANALYTICS_APP_ID : '4153837120',
46+
PHASE_PRODUCT_TEMPLATE_ID : 166,
4647

4748
TC_NOTIFICATION_URL: 'https://api.topcoder-dev.com/v5/notifications',
4849
CONNECT_MESSAGE_API_URL: 'https://api.topcoder-dev.com/v5',

config/constants/master.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module.exports = {
4343
PREDIX_PROGRAM_ID : 3448,
4444
IBM_COGNITIVE_PROGRAM_ID : 3449,
4545
HEAP_ANALYTICS_APP_ID : '638908330',
46+
PHASE_PRODUCT_TEMPLATE_ID : 33,
4647

4748
TC_NOTIFICATION_URL: 'https://api.topcoder.com/v5/notifications',
4849
CONNECT_MESSAGE_API_URL: 'https://api.topcoder.com/v5',

config/constants/qa.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module.exports = {
4242
PREDIX_PROGRAM_ID : 3448,
4343
IBM_COGNITIVE_PROGRAM_ID : 3449,
4444
HEAP_ANALYTICS_APP_ID : '4153837120',
45+
PHASE_PRODUCT_TEMPLATE_ID : 166,
4546

4647
TC_NOTIFICATION_URL: 'https://api.topcoder-dev.com/v5/notifications',
4748
CONNECT_MESSAGE_API_URL: 'https://api.topcoder-qa.com/v5',

docs/permissions.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,30 @@ <h2 class="anchor-container">
996996
</div>
997997
</div>
998998
</div>
999+
<div class="row border-top">
1000+
<div class="col py-2">
1001+
<div class="permission-title anchor-container">
1002+
<a href="#EDIT_PROJECT_STATUS_TO_SPECIAL" name="EDIT_PROJECT_STATUS_TO_SPECIAL" class="anchor"></a>Edit project status to special
1003+
</div>
1004+
<div class="permission-variable"><small><code>EDIT_PROJECT_STATUS_TO_SPECIAL</code></small></div>
1005+
<div class="text-black-50 small-text">Special values are any values except of &quot;Active&quot; and &quot;Completed&quot;.</div>
1006+
</div>
1007+
<div class="col-9 py-2">
1008+
<div>
1009+
<span class="badge badge-primary" title="Allowed Project Role">manager</span>
1010+
<span class="badge badge-primary" title="Allowed Project Role">account_manager</span>
1011+
<span class="badge badge-primary" title="Allowed Project Role">account_executive</span>
1012+
<span class="badge badge-primary" title="Allowed Project Role">project_manager</span>
1013+
<span class="badge badge-primary" title="Allowed Project Role">program_manager</span>
1014+
<span class="badge badge-primary" title="Allowed Project Role">solution_architect</span>
1015+
</div>
1016+
1017+
<div>
1018+
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
1019+
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
1020+
</div>
1021+
</div>
1022+
</div>
9991023
<div class="row border-top">
10001024
<div class="col py-2">
10011025
<div class="permission-title anchor-container">
@@ -1167,6 +1191,12 @@ <h2 class="anchor-container">
11671191
<div class="col-9 py-2">
11681192
<div>
11691193
<span class="badge badge-primary" title="Allowed Project Role">customer</span>
1194+
<span class="badge badge-primary" title="Allowed Project Role">manager</span>
1195+
<span class="badge badge-primary" title="Allowed Project Role">account_manager</span>
1196+
<span class="badge badge-primary" title="Allowed Project Role">account_executive</span>
1197+
<span class="badge badge-primary" title="Allowed Project Role">project_manager</span>
1198+
<span class="badge badge-primary" title="Allowed Project Role">program_manager</span>
1199+
<span class="badge badge-primary" title="Allowed Project Role">solution_architect</span>
11701200
</div>
11711201

11721202
<div>

src/api/projects.js

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -184,26 +184,6 @@ export function createPhaseProduct(projectId, phaseId, product) {
184184
.then( resp => resp.data)
185185
}
186186

187-
export function createProjectWithStatus(projectProps, status) {
188-
// Phase out discussions
189-
// TODO: Remove this once none of the active projects
190-
// have the discussions tab enabled
191-
projectProps.details.hideDiscussions = true
192-
193-
return axios.post(`${PROJECTS_API_URL}/v5/projects/`, projectProps)
194-
.then( resp => resp.data)
195-
.then(project => {
196-
const updatedProps = { status }
197-
const projectId = project.id
198-
return axios.patch(`${PROJECTS_API_URL}/v5/projects/${projectId}/`, updatedProps)
199-
.then(resp => resp.data)
200-
.catch(error => { // eslint-disable-line no-unused-vars
201-
// return created project even if status update fails to prevent error page
202-
return project
203-
})
204-
})
205-
}
206-
207187
export function deleteProject(projectId) {
208188
return axios.delete(`${PROJECTS_API_URL}/v5/projects/${projectId}/`)
209189
.then(() => {

src/components/Layout/Layout.scss

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,5 @@
2222
&[data-route*='new-project'] {
2323
background-color: $tc-gray-neutral-light;
2424
}
25-
&[data-route*='add-phase'] {
26-
background-color: $tc-gray-neutral-light;
27-
}
2825
}
2926
}

src/components/ProjectStatus/ProjectStatus.scss

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@
88
.ProjectStatus {
99
position: relative;
1010
height: $status-height;
11-
11+
1212
.status-icon {
1313
position: relative;
1414
display: inline-block;
1515
min-width: 4 * $base-unit;
1616
width: 4 * $base-unit;
1717
height: 4 * $base-unit;
1818
// top: 3px;
19-
19+
2020
i {
2121
display: block;
2222
width: 4 * $base-unit;
2323
height: 4 * $base-unit;
2424
}
2525
}
26-
26+
2727
.status-label {
2828
position: relative;
2929
@include tc-label-xs;
@@ -33,7 +33,7 @@
3333
margin-left: 10px;
3434
}
3535
}
36-
36+
3737
.EditableProjectStatus {
3838
&.modal-active {
3939
.modal-overlay {
@@ -59,7 +59,7 @@
5959
.status-label {
6060
vertical-align: top;
6161
}
62-
62+
6363
.status-header {
6464
display: flex;
6565
// position: absolute;
@@ -70,19 +70,19 @@
7070
user-select: none;
7171
border-radius: $base-unit*4;
7272
cursor: default;
73-
73+
7474
.caret {
7575
display: none;
7676
}
77-
77+
7878
&.editable {
7979
cursor: pointer;
80-
80+
8181
&:hover {
8282
&::after {
8383
}
8484
}
85-
85+
8686
.caret {
8787
// content: '';
8888
// z-index: 3;
@@ -97,33 +97,33 @@
9797
path {
9898
stroke: $tc-gray-70;
9999
}
100-
100+
101101
.Icon {
102102
width: 100%;
103103
height: 100%;
104104
display: block;
105105
}
106106
}
107107
}
108-
109-
108+
109+
110110
&.unified-header {
111111
background-color: $tc-gray-40;
112-
112+
113113
.status-label {
114114
color: $tc-white;
115115
}
116116
}
117117
}
118-
118+
119119
.status-label {
120120
position: relative;
121121
@include tc-label-xs;
122122
height: $base-unit*4;
123123
padding-right: $base-unit;
124124
margin-left: 10px;
125125
}
126-
126+
127127
// Stylize the dropdown elements
128128
.status-dropdown {
129129
min-width: 150px;
@@ -138,12 +138,12 @@
138138
right: -10px;
139139
z-index: 20;
140140
transition: 250ms all;
141-
141+
142142
&.dropdown-up {
143143
top: auto;
144144
bottom: 0;
145145
}
146-
146+
147147
.status-header {
148148
@include roboto-medium;
149149
font-size: $tc-label-md;
@@ -154,7 +154,7 @@
154154
margin-bottom: 2px;
155155
white-space: nowrap;
156156
}
157-
157+
158158
.status-option {
159159
display: flex;
160160
@include roboto-medium;
@@ -163,19 +163,37 @@
163163
line-height: 30px;
164164
padding: 0 20px;
165165
white-space: nowrap;
166-
166+
167167
&:hover {
168168
background: $tc-dark-blue-10;
169169
}
170-
170+
171171
&.active {
172172
background: $tc-gray-10;
173173
}
174-
174+
175+
&.disabled {
176+
&,
177+
&:hover,
178+
&:active,
179+
&:focus {
180+
background: transparent;
181+
cursor: default;
182+
183+
.status-label {
184+
color: $tc-gray-30;
185+
}
186+
187+
svg {
188+
opacity: 0.5;
189+
}
190+
}
191+
}
192+
175193
svg {
176194
margin-top: 7px;
177195
}
178-
196+
179197
.status-label {
180198
color: $tc-gray-80;
181199
line-height: 30px;
@@ -185,4 +203,4 @@
185203
}
186204
}
187205
}
188-
206+

src/components/ProjectStatus/editableProjectStatus.js

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ import ProjectStatusChangeConfirmation from './ProjectStatusChangeConfirmation'
44
import cn from 'classnames'
55
import _ from 'lodash'
66
import enhanceDropdown from 'appirio-tech-react-components/components/Dropdown/enhanceDropdown'
7+
import Tooltip from 'appirio-tech-react-components/components/Tooltip/Tooltip'
78
import {
89
PROJECT_STATUS,
910
PROJECT_STATUS_COMPLETED,
1011
PROJECT_STATUS_CANCELLED,
11-
PROJECT_STATUS_DRAFT
12+
PROJECT_STATUS_DRAFT,
13+
TOOLTIP_DEFAULT_DELAY
1214
} from '../../config/constants'
1315
import CarretDownNormal9px from '../../assets/icons/arrow-9px-carret-down-normal.svg'
16+
import { hasPermission } from '../../helpers/permissions'
17+
import { PERMISSIONS } from '../../config/permissions'
1418

1519

1620
const hocStatusDropdown = (CompositeComponent, statusList) => {
@@ -55,24 +59,33 @@ const hocStatusDropdown = (CompositeComponent, statusList) => {
5559
<div className="status-header">Project Status</div>
5660
<ul>
5761
{
58-
statusList.sort((a, b) => a.order - b.order).map((item) =>
59-
(
60-
<div key={item.value} className="tooltip-target">
61-
<li>
62-
<a
63-
href="javascript:"
64-
className={cn('status-option', 'status-' + item.value, { active: item.value === status, disabled: item.disabled })}
65-
onClick={(e) => {
66-
if (!item.disabled)
67-
onItemSelect(item.value, e)
68-
}}
69-
>
70-
<CompositeComponent status={item} showText />
71-
</a>
72-
</li>
73-
</div>
62+
statusList.sort((a, b) => a.order - b.order).map((item) => {
63+
const selectItem = (
64+
<li key={item.value}>
65+
<a
66+
href="javascript:"
67+
className={cn('status-option', 'status-' + item.value, { active: item.value === status, disabled: item.disabled })}
68+
onClick={(e) => {
69+
if (!item.disabled)
70+
onItemSelect(item.value, e)
71+
}}
72+
>
73+
<CompositeComponent status={item} showText />
74+
</a>
75+
</li>
7476
)
75-
)
77+
78+
return item.toolTipMessage ? (
79+
<Tooltip theme="light" tooltipDelay={TOOLTIP_DEFAULT_DELAY} key={item.value} usePortal>
80+
<div className="tooltip-target">
81+
{selectItem}
82+
</div>
83+
<div className="tooltip-body">
84+
{item.toolTipMessage}
85+
</div>
86+
</Tooltip>
87+
) : selectItem
88+
})
7689
}
7790
</ul>
7891
</div>
@@ -132,10 +145,29 @@ const editableProjectStatus = (CompositeComponent) => class extends Component {
132145
}
133146

134147
getProjectStatusDropdownValues(status) {
135-
if (status === PROJECT_STATUS_DRAFT) {
136-
return [{color: 'gray', name: 'Draft', fullName: 'Project is in draft', value: PROJECT_STATUS_DRAFT, order: 2, dropDownOrder: 1 }].concat(PROJECT_STATUS)
148+
const statusList = status === PROJECT_STATUS_DRAFT
149+
// if current status, is "Draft" which is deprecated, then show it on the list
150+
? [{color: 'gray', name: 'Draft', fullName: 'Project is in draft', value: PROJECT_STATUS_DRAFT, order: 2, dropDownOrder: 1 }].concat(PROJECT_STATUS)
151+
// otherwise don't show deprecated status
152+
: PROJECT_STATUS
153+
154+
if (hasPermission(PERMISSIONS.EDIT_PROJECT_STATUS_TO_SPECIAL)) {
155+
return statusList
156+
} else {
157+
return statusList.map((statusOption) => {
158+
// if option is not special anyone can choose it
159+
// also, don't disable special option, if it's the current value
160+
if (!statusOption.isSpecial || statusOption.value === status) {
161+
return statusOption
162+
}
163+
164+
return {
165+
...statusOption,
166+
disabled: true,
167+
toolTipMessage: 'Only managers and admins can change to this status'
168+
}
169+
})
137170
}
138-
return PROJECT_STATUS
139171
}
140172

141173
render() {

0 commit comments

Comments
 (0)