diff --git a/docs/permissions.html b/docs/permissions.html index 923e00b4e..65e337cbd 100644 --- a/docs/permissions.html +++ b/docs/permissions.html @@ -82,7 +82,6 @@

Project Members

Invite new members or delete them. There are some additional restrictions for some roles.
- copilot manager account_manager account_executive @@ -93,6 +92,48 @@

Project Members

Connect Admin
+
+
+ Join topcoder team +
JOIN_TOPCODER_TEAM
+
Join Topcoder Team without invitation
+
+
+ administrator + Connect Admin + Connect Manager +
+
+
+
+ Manage copilots +
MANAGE_COPILOTS
+
Directly invite copilots to the project.
+
+
+ administrator + Connect Admin + Connect Copilot Manager +
+
+
+
+ Request copilots +
REQUEST_COPILOTS
+
Request copilots to the project.
+
+
+ manager + account_manager + account_executive + project_manager + program_manager + solution_architect + administrator + Connect Admin + Connect Copilot Manager +
+

Topics & Posts

@@ -188,6 +229,7 @@

User Profile

administrator Connect Admin Connect Manager + Connect Copilot Manager Connect Account Manager Business Development Representative Presales @@ -208,6 +250,7 @@

User Profile

administrator Connect Admin Connect Manager + Connect Copilot Manager Connect Account Manager Business Development Representative Presales @@ -217,6 +260,58 @@

User Profile

Project Manager
+
+
+ View User Profile as Copilot +
VIEW_USER_PROFILE_AS_COPILOT
+
+
+
+ Connect Copilot +
+
+
+
+ View User Profile as Topcoder Employee +
VIEW_USER_PROFILE_AS_TOPCODER_EMPLOYEE
+
+
+
+ administrator + Connect Admin + Connect Manager + Connect Copilot Manager + Connect Account Manager + Business Development Representative + Presales + Account Executive + Program Manager + Solution Architect + Project Manager +
+
+
+
+ View User Profile as Customer +
VIEW_USER_PROFILE_AS_CUSTOMER
+
+
+
+ Topcoder User + administrator + Connect Admin + Connect Manager + Connect Copilot Manager + Connect Account Manager + Business Development Representative + Presales + Account Executive + Program Manager + Solution Architect + Project Manager + Connect Copilot +
+

View Member Suggestions

@@ -251,6 +346,7 @@

My Projects Filter

administrator Connect Admin Connect Manager + Connect Copilot Manager Connect Account Manager Business Development Representative Presales diff --git a/src/config/constants.js b/src/config/constants.js index a3501fcf0..cd068c2d0 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -1039,28 +1039,11 @@ export const PROJECT_CATEGORY_TAAS = 'talent-as-a-service' * - if field is not on the list means it should not be shown */ export const PROFILE_FIELDS_CONFIG = { - // this config is used to show any user profile - DEFAULT: { - // required fields - firstName: true, - lastName: true, - country: true, - title: true, - timeZone: true, - businessPhone: true, - companyName: true, - - // optional fields - avatar: false, - workingHourStart: false, - workingHourEnd: false, - }, - - // configs below are used when we ask users to fill missing fields (progressive registration) TOPCODER: { // required fields firstName: true, lastName: true, + title: true, country: true, timeZone: true, workingHourStart: true, @@ -1068,9 +1051,9 @@ export const PROFILE_FIELDS_CONFIG = { // optional fields avatar: false, - title: false, - companyName: false, - businessPhone: false, + // companyName: false, + // companyURL: false, + // businessPhone: false, }, CUSTOMER: { // required fields @@ -1079,13 +1062,30 @@ export const PROFILE_FIELDS_CONFIG = { country: true, title: true, companyName: true, + companyURL: true, businessPhone: true, + businessEmail: true, // optional fields - businessEmail: false, avatar: false, timeZone: false, workingHourStart: false, workingHourEnd: false, + }, + COPILOT: { + // required fields + firstName: true, + lastName: true, + country: true, + timeZone: true, + workingHourStart: true, + workingHourEnd: true, + + // optional fields + avatar: false, + // title: false, + // companyName: false, + // companyURL: true, + // businessPhone: false, } } diff --git a/src/config/permissions.js b/src/config/permissions.js index 88c59dc7a..c5857f609 100644 --- a/src/config/permissions.js +++ b/src/config/permissions.js @@ -331,6 +331,43 @@ export default { ], }, + VIEW_USER_PROFILE_AS_COPILOT: { + _meta: { + group: 'User Profile', + title: 'View User Profile as Copilot', + }, + topcoderRoles: [ + ROLE_CONNECT_COPILOT + ], + }, + + VIEW_USER_PROFILE_AS_TOPCODER_EMPLOYEE: { + _meta: { + group: 'User Profile', + title: 'View User Profile as Topcoder Employee', + }, + topcoderRoles: [ + ..._.difference(TOPCODER_ALL, [ROLE_TOPCODER_USER, ROLE_CONNECT_COPILOT]) + ], + }, + + VIEW_USER_PROFILE_AS_CUSTOMER: { + _meta: { + group: 'User Profile', + title: 'View User Profile as Customer', + }, + allowRule: { + topcoderRoles: [ + ROLE_TOPCODER_USER + ] + }, + denyRule: { + topcoderRoles: [ + ..._.difference(TOPCODER_ALL, [ROLE_TOPCODER_USER]) + ], + } + }, + SEE_MEMBER_SUGGESTIONS: { _meta: { group: 'View Member Suggestions', diff --git a/src/helpers/tcHelpers.js b/src/helpers/tcHelpers.js index 8abb69c26..d86af5825 100644 --- a/src/helpers/tcHelpers.js +++ b/src/helpers/tcHelpers.js @@ -9,6 +9,8 @@ import { NON_CUSTOMER_ROLES, PROFILE_FIELDS_CONFIG, } from '../config/constants' +import { hasPermission } from './permissions' +import PERMISSIONS from '../config/permissions' /** * Check if a user is a special system user @@ -73,3 +75,22 @@ export const isUserProfileComplete = (user, profileSettings) => { return !isMissingUserInfo } + +/** + * Get User Profile fields config based on the current user roles. + * + * @returns {Object} fields config + */ +export const getUserProfileFieldsConfig = () => { + if (hasPermission(PERMISSIONS.VIEW_USER_PROFILE_AS_TOPCODER_EMPLOYEE)) { + return PROFILE_FIELDS_CONFIG.TOPCODER + } + + if (hasPermission(PERMISSIONS.VIEW_USER_PROFILE_AS_COPILOT)) { + return PROFILE_FIELDS_CONFIG.COPILOT + } + + if (hasPermission(PERMISSIONS.VIEW_USER_PROFILE_AS_CUSTOMER)) { + return PROFILE_FIELDS_CONFIG.CUSTOMER + } +} diff --git a/src/routes/settings/routes/profile/components/ProfileSettingsForm.jsx b/src/routes/settings/routes/profile/components/ProfileSettingsForm.jsx index ce6cf221e..e501a337d 100644 --- a/src/routes/settings/routes/profile/components/ProfileSettingsForm.jsx +++ b/src/routes/settings/routes/profile/components/ProfileSettingsForm.jsx @@ -15,7 +15,6 @@ import ISOCountries from '../../../../../helpers/ISOCountries' import { formatPhone } from '../../../../../helpers/utils' import { hasPermission } from '../../../../../helpers/permissions' import PERMISSIONS from '../../../../../config/permissions' -import { PROFILE_FIELDS_CONFIG } from '../../../../../config/constants' import './ProfileSettingsForm.scss' const countries = _.orderBy(ISOCountries, ['name'], ['asc']).map((country) => ({ @@ -137,6 +136,11 @@ class ProfileSettingsForm extends Component { validationErrors.isEmail = 'Please, enter correct email' } + if (name === 'companyURL') { + validations.isRelaxedUrl = true + validationErrors.isRelaxedUrl = 'Please, enter correct URL' + } + return (
@@ -235,13 +239,11 @@ class ProfileSettingsForm extends Component { {!_.isUndefined(fieldsConfig.firstName) && this.getField('First Name', 'firstName', fieldsConfig.firstName)} {!_.isUndefined(fieldsConfig.lastName) && this.getField('Last Name', 'lastName', fieldsConfig.lastName)} {!_.isUndefined(fieldsConfig.title) && this.getField('Title', 'title', fieldsConfig.title)} - {!_.isUndefined(fieldsConfig.businessEmail) && - this.getField('Business Email', 'businessEmail', fieldsConfig.businessEmail, true)} {!_.isUndefined(fieldsConfig.businessPhone) && (
Business Phone  - * + {fieldsConfig.businessPhone && *}
)} - {!_.isUndefined(fieldsConfig.companyName) && - this.getField( - 'Company Name', - 'companyName', - fieldsConfig.companyName, - disableCompanyInput - )} + {!_.isUndefined(fieldsConfig.businessEmail) && this.getField('Business Email', 'businessEmail', fieldsConfig.businessEmail, true)} + {!_.isUndefined(fieldsConfig.companyName) && this.getField('Company Name', 'companyName', fieldsConfig.companyName, disableCompanyInput)} + {!_.isUndefined(fieldsConfig.companyURL) && this.getField('Company URL', 'companyURL', fieldsConfig.companyURL)} {!_.isUndefined(fieldsConfig.country) && (
{fieldsConfig.country ? ( @@ -414,8 +412,6 @@ class ProfileSettingsForm extends Component { } ProfileSettingsForm.defaultProps = { - // default config is same for user profile for any kind of users - fieldsConfig: PROFILE_FIELDS_CONFIG.DEFAULT, showBackButton: false, submitButton: 'Save settings', onBack: () => {}, @@ -434,6 +430,7 @@ ProfileSettingsForm.propTypes = { lastName: PropTypes.bool, title: PropTypes.bool, companyName: PropTypes.bool, + companyURL: PropTypes.bool, businessPhone: PropTypes.bool, businessEmail: PropTypes.bool, country: PropTypes.bool, diff --git a/src/routes/settings/routes/profile/containers/ProfileSettingsContainer.jsx b/src/routes/settings/routes/profile/containers/ProfileSettingsContainer.jsx index 2e94f89cf..55dc1dd3c 100644 --- a/src/routes/settings/routes/profile/containers/ProfileSettingsContainer.jsx +++ b/src/routes/settings/routes/profile/containers/ProfileSettingsContainer.jsx @@ -10,6 +10,7 @@ import spinnerWhileLoading from '../../../../../components/LoadingSpinner' import { requiresAuthentication } from '../../../../../components/AuthenticatedComponent' import { getProfileSettings, saveProfileSettings, uploadProfilePhoto } from '../../../actions/index' import { formatProfileSettings } from '../../../helpers/settings' +import { getUserProfileFieldsConfig } from '../../../../../helpers/tcHelpers' const enhance = spinnerWhileLoading(props => !props.values.isLoading) const ProfileSettingsFormEnhanced = enhance(ProfileSettingsForm) @@ -20,6 +21,7 @@ class ProfileSettingsContainer extends Component { render() { const { profileSettings, saveProfileSettings, uploadProfilePhoto, user } = this.props + const fieldsConfig = getUserProfileFieldsConfig() return ( )