Skip to content

Commit

Permalink
Merge pull request #3936 from appirio-tech/cf-22
Browse files Browse the repository at this point in the history
CF 22 - 18/20
  • Loading branch information
maxceem authored Apr 20, 2020
2 parents d116b92 + 21d7515 commit c07761e
Show file tree
Hide file tree
Showing 29 changed files with 242 additions and 73 deletions.
54 changes: 54 additions & 0 deletions docs/permissions.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ <h2>Project Plan</h2>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
</div>
</div>
<div class="row border-top">
<div class="col py-2">
Manage asset libraries files and links
<div><small><code>MANAGE_NOT_OWN_ATTACHEMENT</code></small></div>
<div class="text-black-50 small-text"></div>
</div>
<div class="col-9 py-2">
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
</div>
</div>
<div class="row border-top">
<div class="col py-2">
Manage completed phases
Expand Down Expand Up @@ -206,6 +217,49 @@ <h2>User Profile</h2>
<span class="badge badge-success" title="Allowed Topcoder Role">Project Manager</span>
</div>
</div>
<div class="row">
<div class="col pt-5 pb-2">
<h2>View Member Suggestions</h2>
</div>
</div>
<div class="row border-top">
<div class="col py-2">
Member Suggestions
<div><small><code>SEE_MEMBER_SUGGESTIONS</code></small></div>
<div class="text-black-50 small-text"></div>
</div>
<div class="col-9 py-2">
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Manager</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Account Manager</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Copilot Manager</span>
</div>
</div>
<div class="row">
<div class="col pt-5 pb-2">
<h2>My Projects Filter</h2>
</div>
</div>
<div class="row border-top">
<div class="col py-2">
My Projects Filter
<div><small><code>SEE_MY_PROJECTS_FILTER</code></small></div>
<div class="text-black-50 small-text"></div>
</div>
<div class="col-9 py-2">
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Manager</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Account Manager</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Business Development Representative</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Presales</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Account Executive</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Program Manager</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Solution Architect</span>
<span class="badge badge-success" title="Allowed Topcoder Role">Project Manager</span>
</div>
</div>
<div class="row">
<div class="col pt-5 pb-2">
<h2>DEMO/TEST example permissions</h2>
Expand Down
4 changes: 3 additions & 1 deletion src/components/AssetsLibrary/FilesGridView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
PROJECT_ASSETS_SHARED_WITH_TOPCODER_MEMBERS,
PROJECT_FEED_TYPE_MESSAGES
} from '../../config/constants'
import { hasPermission } from '../../helpers/permissions'
import PERMISSIONS from '../../config/permissions'

let selectedLink
let clearing = false
Expand Down Expand Up @@ -251,7 +253,7 @@ const FilesGridView = ({
}
const onEditCancel = () => onEditIntent(-1)
const handleEditClick = () => onEditIntent(idx)
const canEdit = `${link.createdBy}` === `${loggedInUser.userId}`
const canEdit = `${link.createdBy}` === `${loggedInUser.userId}` || (hasPermission(PERMISSIONS.MANAGE_NOT_OWN_ATTACHEMENT))

const changeSubFolder = () => {
onChangeSubFolder(link)
Expand Down
2 changes: 1 addition & 1 deletion src/components/AssetsLibrary/GridView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@

.delete-confirmation-modal {
position: relative;
z-index: 20;
z-index: 15;
}

.hand {
Expand Down
12 changes: 7 additions & 5 deletions src/components/AssetsLibrary/LinksGridView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import {
PROJECT_FEED_TYPE_MESSAGES
} from '../../config/constants'
import FilterColHeader from './FilterColHeader'
import { hasPermission } from '../../helpers/permissions'
import PERMISSIONS from '../../config/permissions'

let selectedLink
let clearing = false

const LinksGridView = ({
canDelete,
canEdit,
links,
linkToDelete,
linkToEdit,
Expand All @@ -38,6 +38,7 @@ const LinksGridView = ({
onEdit,
onEditIntent,
title,
loggedInUser,
formatModifyDate,
formatFolderTitle,
assetsMembers,
Expand Down Expand Up @@ -201,7 +202,7 @@ const LinksGridView = ({
selectedLink = link
}
const owner = _.find(assetsMembers, m => m.userId === _.parseInt(link.createdBy))

const canEdit = `${link.createdBy}` === `${loggedInUser.userId}` || (hasPermission(PERMISSIONS.MANAGE_NOT_OWN_ATTACHEMENT))
if (Array.isArray(link.children) && link.children.length > 0) {
return (
<li styleName="assets-gridview-row" onClick={changeSubFolder} key={'assets-gridview-folder-' + idx}>
Expand Down Expand Up @@ -275,10 +276,10 @@ const LinksGridView = ({
</div>
<div styleName="flex-item item-modified">{formatModifyDate(link)}</div>
<div styleName="flex-item item-action">
{(canEdit || canDelete) && (
{(canEdit) && (
<ItemOperations
canEdit={canEdit}
canDelete={canDelete}
canDelete={canEdit}
handleEditClick={handleEditClick}
handleDeleteClick={handleDeleteClick}
/>)}
Expand All @@ -299,6 +300,7 @@ LinksGridView.propTypes = {
onChangeSubFolder: PropTypes.func,
onDelete: PropTypes.func,
title: PropTypes.string,
loggedInUser: PropTypes.object.isRequired,
formatModifyDate: PropTypes.func.isRequired,
formatFolderTitle: PropTypes.func.isRequired,
setFilter: PropTypes.func.isRequired,
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProjectInfo/ProjectInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class ProjectInfo extends Component {
<div className="project-status-ref">{_.unescape(code)}</div>
</div>
<div className="tooltip-body">
<span>{_.unescape(code)}</span>
<div>{_.unescape(code)}</div>
</div>
</Tooltip>
</div>
Expand Down
12 changes: 6 additions & 6 deletions src/components/ProjectInfo/ProjectInfo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@
.tooltip-target-container {
flex: 1;
width: 0;
display: flex;
justify-content: flex-end;
min-width: 0;

:global {
.tooltip-target {
Expand All @@ -140,11 +139,11 @@
.tooltip-body {
display: flex;

span {
width: 200px;
div {
word-wrap: break-word;
max-width: 200px;
white-space: normal;
display: flex;
justify-content: center;
overflow: hidden;
}
}
}
Expand All @@ -153,4 +152,5 @@
.tooltip {
max-width: 100%;
height: 100%;
float: right;
}
3 changes: 3 additions & 0 deletions src/components/StatusFilters/StatusFilters.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,7 @@
border-radius: 6px;
box-shadow: 0px 1px 3px 0px $tc-gray-30;
}
&.active {
cursor: default;
}
}
2 changes: 1 addition & 1 deletion src/components/StatusFilters/StatusFiltersList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const StatusFiltersList = ({ statuses, currentStatus, onStatusClick }) => (
<li
key={status.val || 'null'}
className={cn(style.item, { [style.active]: status.val === currentStatus })}
onClick={() => onStatusClick(status.val)}
onClick={() => status.val !== currentStatus ? onStatusClick(status.val) : ''}
>
{status.label}
</li>
Expand Down
2 changes: 1 addition & 1 deletion src/components/StatusFilters/StatusFiltersMobile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class StatusFiltersMobile extends React.Component {
<li
key={status.val || 'null'}
className={cn(style.item, { [style.active]: status.val === currentStatus })}
onClick={() => this.onStatusClick(status.val)}
onClick={() => status.val !== currentStatus ? this.onStatusClick(status.val) : ''}
>
{status.label}
</li>
Expand Down
12 changes: 5 additions & 7 deletions src/components/TeamManagement/AutocompleteInputContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ class AutocompleteInputContainer extends React.Component {
* Clear user suggestion list
*/
clearUserSuggestions() {
const { currentUser } = this.props
const { showSuggestions } = this.props

if (!currentUser.isCustomer) {
// When customer user is typing a user handle to invite we should not try to clear suggestions,
// because we don't show suggestions for customer
if (!showSuggestions) {
// When we don't show suggestions, we should not clean them
this.props.onClearUserSuggestions()
}
}

onInputChange(inputValue) {
const { currentUser } = this.props
const indexOfSpace = inputValue.indexOf(' ')
const indexOfSemiColon = inputValue.indexOf(';')

Expand All @@ -47,8 +45,8 @@ class AutocompleteInputContainer extends React.Component {
}

if (inputValue.length >= AUTOCOMPLETE_TRIGGER_LENGTH) {
// When customer user is typing a user handle to invite we should not try to show suggestions as we always get error 403
if (!currentUser.isCustomer) {
// When user doesn't have permissions to retrieve suggestions should not try to show suggestions as we always get error 403
if (this.props.showSuggestions) {
this.props.onLoadUserSuggestions(inputValue)
}
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/components/TeamManagement/ProjectManagementDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import moment from 'moment'
import Modal from 'react-modal'
import XMarkIcon from '../../assets/icons/icon-x-mark.svg'
import Avatar from 'appirio-tech-react-components/components/Avatar/Avatar'
import PERMISSIONS from '../../config/permissions'

import { hasPermission } from '../../helpers/permissions'
import {getAvatarResized, getFullNameWithFallback} from '../../helpers/tcHelpers'
import { compareEmail, compareHandles } from '../../helpers/utils'
import AutocompleteInputContainer from './AutocompleteInputContainer'
Expand Down Expand Up @@ -88,6 +91,7 @@ class ProjectManagementDialog extends React.Component {
onCancel, projectTeamInvites = [], selectedMembers, processingInvites,
} = this.props
const showRemove = currentUser.isAdmin || (!currentUser.isCopilot && isMember)
const showSuggestions = hasPermission(PERMISSIONS.SEE_MEMBER_SUGGESTIONS)
let i = 0
return (
<Modal
Expand Down Expand Up @@ -183,6 +187,7 @@ class ProjectManagementDialog extends React.Component {
currentUser={currentUser}
selectedMembers={selectedMembers}
disabled={processingInvites || (!currentUser.isAdmin && !isMember)}
showSuggestions={showSuggestions}
/>
{this.state.showAlreadyMemberError && <div className="error-message">
Project Member(s) can't be invited again. Please remove them from list.
Expand Down
3 changes: 3 additions & 0 deletions src/components/TeamManagement/TeamManagement.scss
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@
font-size: $tc-label-sm;
color: $tc-dark-blue;
display: block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;

> span {
display: block;
Expand Down
16 changes: 11 additions & 5 deletions src/components/TeamManagement/TopcoderManagementDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { getAvatarResized, getFullNameWithFallback } from '../../helpers/tcHelpe
import SelectDropdown from '../SelectDropdown/SelectDropdown'
import Tooltip from 'appirio-tech-react-components/components/Tooltip/Tooltip'
import AutocompleteInputContainer from './AutocompleteInputContainer'
import {PROJECT_MEMBER_INVITE_STATUS_REQUESTED, PROJECT_MEMBER_INVITE_STATUS_PENDING} from '../../config/constants'
import {
PROJECT_MEMBER_INVITE_STATUS_REQUESTED, PROJECT_MEMBER_INVITE_STATUS_PENDING,
PROJECT_MEMBER_INVITE_STATUS_REQUEST_APPROVED, PROJECT_MEMBER_INVITE_STATUS_REQUEST_REJECTED,
} from '../../config/constants'
import PERMISSIONS from '../../config/permissions'
import {hasPermission} from '../../helpers/permissions'
import { compareEmail, compareHandles } from '../../helpers/utils'
Expand Down Expand Up @@ -147,6 +150,7 @@ class TopcoderManagementDialog extends React.Component {
const { processingInviteRequestIds } = this.state
const showRemove = hasPermission(PERMISSIONS.MANAGE_TOPCODER_TEAM)
const showApproveDecline = currentUser.isAdmin || currentUser.isCopilotManager
const showSuggestions = hasPermission(PERMISSIONS.SEE_MEMBER_SUGGESTIONS)
let i = 0

return (
Expand Down Expand Up @@ -212,8 +216,9 @@ class TopcoderManagementDialog extends React.Component {
</div>
)
}
const types = ['Observer', 'Copilot', 'Manager', 'Account Manager', 'Account Executive', 'Program Manager', 'Solution Architect', 'Project Manager']
let types = ['Copilot', 'Manager', 'Account Manager', 'Account Executive', 'Program Manager', 'Solution Architect', 'Project Manager']
const currentType = role
types = currentType === 'Observer'? ['Observer', ...types] : [...types]
const onClick = (type) => {
this.onUserRoleChange(member.userId, member.id, type)
}
Expand Down Expand Up @@ -265,7 +270,7 @@ class TopcoderManagementDialog extends React.Component {
this.setState(prevState => ({ processingInviteRequestIds: [ ...prevState.processingInviteRequestIds, invite.id ] }))
approveOrDecline({
id: invite.id,
status: 'request_approved'
status: PROJECT_MEMBER_INVITE_STATUS_REQUEST_APPROVED
}).then(() => {
this.setState(prevState => ({ processingInviteRequestIds: _.xor(prevState.processingInviteRequestIds, [invite.id]) }))
})
Expand All @@ -274,7 +279,7 @@ class TopcoderManagementDialog extends React.Component {
this.setState(prevState => ({ processingInviteRequestIds: [ ...prevState.processingInviteRequestIds, invite.id ] }))
approveOrDecline({
id: invite.id,
status: 'request_rejected'
status: PROJECT_MEMBER_INVITE_STATUS_REQUEST_REJECTED
}).then(() => {
this.setState(prevState => ({ processingInviteRequestIds: _.xor(prevState.processingInviteRequestIds, [invite.id]) }))
})
Expand Down Expand Up @@ -351,6 +356,7 @@ class TopcoderManagementDialog extends React.Component {
currentUser={currentUser}
selectedMembers={selectedMembers}
disabled={processingInvites || (!currentUser.isAdmin && !isMember && !currentUser.isCopilotManager)}
showSuggestions={showSuggestions}
/>
{ this.state.showAlreadyMemberError && <div className="error-message">
Project Member(s) can\'t be invited again. Please remove them from list.
Expand All @@ -360,7 +366,7 @@ class TopcoderManagementDialog extends React.Component {
name="role"
value={this.state.userRole}
theme="role-drop-down default"
options={this.roles}
options={this.roles.filter(role => role.title !== 'Observer')}
onSelect={this.handleRoles}
/>
</Formsy.Form>
Expand Down
6 changes: 6 additions & 0 deletions src/components/User/UserTooltip.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.Tooltip {
&.customer-data {
.tooltip-target {
z-index: 0;
display: flex;
&>div:first-child {
margin-left: -5px;
Expand Down Expand Up @@ -127,6 +128,7 @@
flex-wrap: wrap;
align-content: flex-start;
position: relative;
width: 80%;
}

.user-name-container {
Expand Down Expand Up @@ -158,6 +160,10 @@
.user-email-container {
flex: 1;
padding-left: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 80%;

a {
font-size: 12px;
Expand Down
Loading

0 comments on commit c07761e

Please sign in to comment.