diff --git a/src/components/ActionCard/Comment.jsx b/src/components/ActionCard/Comment.jsx index 2d16e0144..cd6187fdc 100644 --- a/src/components/ActionCard/Comment.jsx +++ b/src/components/ActionCard/Comment.jsx @@ -16,6 +16,7 @@ import { import './Comment.scss' import { PROJECT_ATTACHMENTS_FOLDER } from '../../config/constants' +import { getFullNameWithFallback } from '../../helpers/tcHelpers' class Comment extends React.Component { @@ -80,7 +81,7 @@ class Comment extends React.Component { const template = Handlebars.compile(commentAnchorPrefix) const messageAnchor = template({ postId: message.id }) const messageLink = window.location.pathname.substr(0, window.location.pathname.indexOf('#')) + `#${messageAnchor}` - const authorName = author ? (author.firstName + ' ' + author.lastName) : 'Connect user' + const authorName = getFullNameWithFallback(author) const avatarUrl = _.get(author, 'photoURL', null) const isDeleting = message && message.isDeletingComment diff --git a/src/components/Feed/FeedComments.jsx b/src/components/Feed/FeedComments.jsx index e988aff0d..0c16e242c 100644 --- a/src/components/Feed/FeedComments.jsx +++ b/src/components/Feed/FeedComments.jsx @@ -11,6 +11,7 @@ import NewPostMobile, { NEW_POST_STEP } from './NewPostMobile' import { SCREEN_BREAKPOINT_MD, POSTS_BUNDLE_TIME_DIFF } from '../../config/constants' import './FeedComments.scss' +import { getFullNameWithFallback } from '../../helpers/tcHelpers' function formatCommentDate(date) { const today = moment() @@ -185,10 +186,7 @@ class FeedComments extends React.Component { comments = _.sortBy(comments, 'createdBy') comments = comments.reverse() const { isNewCommentMobileOpen, stickyRowNext, stickyRowPrev } = this.state - let authorName = currentUser.firstName - if (authorName && currentUser.lastName) { - authorName += ' ' + currentUser.lastName - } + const authorName = getFullNameWithFallback(currentUser) const handleLoadMoreClick = () => { this.setState({showAll: true}, () => { this.updateStickyRow() diff --git a/src/components/Feed/NewPost.jsx b/src/components/Feed/NewPost.jsx index 165896a25..b35de4283 100644 --- a/src/components/Feed/NewPost.jsx +++ b/src/components/Feed/NewPost.jsx @@ -5,6 +5,7 @@ import './draftjs.scss' import RichTextArea from '../RichTextArea/RichTextArea' import './NewPost.scss' +import { getFullNameWithFallback } from '../../helpers/tcHelpers' class NewPost extends React.Component { @@ -14,10 +15,7 @@ class NewPost extends React.Component { render() { const {currentUser, allMembers, titlePlaceholder, contentPlaceholder, isCreating, hasError, expandedTitlePlaceholder, projectMembers, canAccessPrivatePosts} = this.props - let authorName = currentUser.firstName - if (authorName && currentUser.lastName) { - authorName += ' ' + currentUser.lastName - } + const authorName = getFullNameWithFallback(currentUser) const composerClasses = cn( 'modal', diff --git a/src/components/MessageDetails/MessageDetails.jsx b/src/components/MessageDetails/MessageDetails.jsx index 04f435fa8..fbd78504a 100644 --- a/src/components/MessageDetails/MessageDetails.jsx +++ b/src/components/MessageDetails/MessageDetails.jsx @@ -7,6 +7,7 @@ import { markdownToHTML } from '../../helpers/markdownToState' import BtnSeparator from '../ActionCard/BtnSeparator' import Comment from '../ActionCard/Comment' import AddComment from '../ActionCard/AddComment' +import { getFullNameWithFallback } from '../../helpers/tcHelpers' class MessageDetails extends React.Component { @@ -41,10 +42,7 @@ class MessageDetails extends React.Component { isAddingComment, error, allowAddingComment} = this.props - let authorName = currentUser.firstName - if (authorName && currentUser.lastName) { - authorName += ' ' + currentUser.lastName - } + const authorName = getFullNameWithFallback(currentUser) return ( { return { name: e.firstName + ' ' + e.lastName, handle: e.handle, userId: e.userId, link: '/users/' + e.handle } }) + const suggestions = _.map(_.values(this.props.projectMembers), (e) => { return { name: e.handle, userId: e.userId, link: '/users/' + e.handle } }) const projectId = this.props.match.params.projectId this.setState({ editorExpanded: this.props.editMode, @@ -420,7 +420,7 @@ class RichTextArea extends React.Component {
- {mention.get('name') + ' - ' + mention.get('handle')} + {mention.get('name')}
diff --git a/src/components/TeamManagement/ProjectManagementDialog.js b/src/components/TeamManagement/ProjectManagementDialog.js index f096f4e81..6cea633f7 100644 --- a/src/components/TeamManagement/ProjectManagementDialog.js +++ b/src/components/TeamManagement/ProjectManagementDialog.js @@ -5,7 +5,7 @@ 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 {getAvatarResized} from '../../helpers/tcHelpers' +import {getAvatarResized, getFullNameWithFallback} from '../../helpers/tcHelpers' import { compareEmail, compareHandles } from '../../helpers/utils' import AutocompleteInputContainer from './AutocompleteInputContainer' @@ -125,10 +125,7 @@ class ProjectManagementDialog extends React.Component { const remove = () => { removeMember(member) } - const firstName = _.get(member, 'firstName', '') - const lastName = _.get(member, 'lastName', '') - let userFullName = `${firstName} ${lastName}` - userFullName = userFullName.trim().length > 0 ? userFullName : 'Connect user' + const userFullName = getFullNameWithFallback(member) return (
0 ? userFullName : null + const userFullName = getFullNameWithFallback(invite.member) return (
{ onMemberDeleteConfirm(deletingMember) } - const firstName = _.get(deletingMember, 'firstName', '') - const lastName = _.get(deletingMember, 'lastName', '') - let userFullName = `${firstName} ${lastName}` - userFullName = userFullName.trim().length > 0 ? userFullName : 'Connect user' + const userFullName = getFullNameWithFallback(deletingMember) const isCurrentUser = (currentUser.userId === deletingMember.userId) const title = isCurrentUser ? LEAVE_TITLE : REMOVE_TITLE const content = isCurrentUser ? LEAVE_MESSAGE : REMOVE_USER_MESSAGE.replace('USERNAME', userFullName) diff --git a/src/components/TeamManagement/TopcoderManagementDialog.js b/src/components/TeamManagement/TopcoderManagementDialog.js index 56c13f942..36878e07f 100644 --- a/src/components/TeamManagement/TopcoderManagementDialog.js +++ b/src/components/TeamManagement/TopcoderManagementDialog.js @@ -6,7 +6,7 @@ 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 { getAvatarResized } from '../../helpers/tcHelpers' +import { getAvatarResized, getFullNameWithFallback } from '../../helpers/tcHelpers' import SelectDropdown from '../SelectDropdown/SelectDropdown' import Tooltip from 'appirio-tech-react-components/components/Tooltip/Tooltip' import AutocompleteInputContainer from './AutocompleteInputContainer' @@ -170,10 +170,7 @@ class TopcoderManagementDialog extends React.Component { const remove = () => { removeMember(member) } - const firstName = _.get(member, 'firstName', '') - const lastName = _.get(member, 'lastName', '') - let userFullName = `${firstName} ${lastName}` - userFullName = userFullName.trim().length > 0 ? userFullName : 'Connect user' + const userFullName = getFullNameWithFallback(member) const role = _.get(_.find(this.roles, r => r.value === member.role), 'title') return (
0 ? userFullName : 'Connect user' + const userFullName = getFullNameWithFallback(invite.member) i++ return (
{lastMessageAuthor - ? `${lastMessageAuthor.firstName} ${ - lastMessageAuthor.lastName - }` + ? lastMessageAuthorName : lastMessageUserId} diff --git a/src/components/User/UserTooltip.jsx b/src/components/User/UserTooltip.jsx index a74938f98..2d6399f04 100644 --- a/src/components/User/UserTooltip.jsx +++ b/src/components/User/UserTooltip.jsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types' import Tooltip from 'appirio-tech-react-components/components/Tooltip/Tooltip' import Avatar from 'appirio-tech-react-components/components/Avatar/Avatar' import { DOMAIN } from '../../config/constants' -import { getAvatarResized } from '../../helpers/tcHelpers' +import { getAvatarResized, getFullNameWithFallback } from '../../helpers/tcHelpers' import IconDirectArrow from '../../assets/icons/icon-direct-arrow.svg' require('./UserTooltip.scss') @@ -14,10 +14,7 @@ const UserTooltip = ({ usr, id, previewAvatar, size, invitedLabel, showEmailOnly const tooltipMargin = previewAvatar ? -(100 + (id * 20)) : 0 const userHandle = _.get(usr, 'handle') const userEmail = _.get(usr, 'email') - const firstName = _.get(usr, 'firstName', '') - const lastName = _.get(usr, 'lastName', '') - let userFullName = `${firstName} ${lastName}` - userFullName = userFullName.trim().length > 0 ? userFullName : 'Connect user' + const userFullName = getFullNameWithFallback(usr) const avatar = ( { const url = handle ? `//www.${DOMAIN}/members/${handle}/` : null + const userFullName = getFullNameWithFallback({ handle, firstName, lastName }) const avatar = ( ) @@ -23,8 +24,8 @@ const UserWithName = ({ handle, firstName, lastName, photoURL, photoSize, theme, } {url && isLink ? - {firstName} {lastName} : - {firstName} {lastName} + {userFullName} : + {userFullName} } {handle && {handle}} diff --git a/src/components/UserSummary/UserSummary.jsx b/src/components/UserSummary/UserSummary.jsx index 21d50880e..3e1f08303 100644 --- a/src/components/UserSummary/UserSummary.jsx +++ b/src/components/UserSummary/UserSummary.jsx @@ -4,6 +4,7 @@ import Avatar from 'appirio-tech-react-components/components/Avatar/Avatar' import moment from 'moment' import './UserSummary.scss' +import { getFullNameWithFallback } from '../../helpers/tcHelpers' const UserSummary = ({user}) => { // TODO: Replace hardcoded values with real data @@ -12,7 +13,7 @@ const UserSummary = ({user}) => { drafts: 7, delivered: 5 } */ - const userName = (user.firstName && user.lastName) && `${user.firstName} ${user.lastName}` + const userName = getFullNameWithFallback(user) const memberSince = moment(user.createdAt).format('MMM YYYY') return (
diff --git a/src/helpers/tcHelpers.js b/src/helpers/tcHelpers.js index 72919cefa..37f1f4b98 100644 --- a/src/helpers/tcHelpers.js +++ b/src/helpers/tcHelpers.js @@ -33,4 +33,15 @@ export const getAvatarResized = (avatarUrl, size) => { } return avatarUrl +} + +export const getFullNameWithFallback = (user) => { + if (!user) return '' + let userFullName = user.firstName + if (userFullName && user.lastName) { + userFullName += ' ' + user.lastName + } + userFullName = userFullName && userFullName.trim().length > 0 ? userFullName : user.handle + userFullName = userFullName && userFullName.trim().length > 0 ? userFullName : 'Connect user' + return userFullName } \ No newline at end of file diff --git a/src/projects/detail/containers/DashboardContainer.jsx b/src/projects/detail/containers/DashboardContainer.jsx index c2e27f9e3..58442b6e0 100644 --- a/src/projects/detail/containers/DashboardContainer.jsx +++ b/src/projects/detail/containers/DashboardContainer.jsx @@ -55,9 +55,11 @@ import { EVENT_TYPE, PHASE_STATUS_DRAFT, SCREEN_BREAKPOINT_MD, + CODER_BOT_USERID, } from '../../../config/constants' const SYSTEM_USER = { + handle: CODER_BOT_USERID, firstName: CODER_BOT_USER_FNAME, lastName: CODER_BOT_USER_LNAME, photoURL: require('../../../assets/images/avatar-coder.svg') diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index df6279851..36fa40a80 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -13,6 +13,7 @@ import { CODER_BOT_USER_FNAME, CODER_BOT_USER_LNAME, CONNECT_USER, + CODER_BOT_USERID, } from '../../../config/constants' import { connect } from 'react-redux' import update from 'react-addons-update' @@ -38,6 +39,7 @@ import PERMISSIONS from '../../../config/permissions' import './FeedContainer.scss' const SYSTEM_USER = { + handle: CODER_BOT_USERID, firstName: CODER_BOT_USER_FNAME, lastName: CODER_BOT_USER_LNAME, photoURL: require('../../../assets/images/avatar-coder.svg') diff --git a/src/projects/detail/containers/MessagesContainer.js b/src/projects/detail/containers/MessagesContainer.js index 86f9d530f..dd24cbce3 100644 --- a/src/projects/detail/containers/MessagesContainer.js +++ b/src/projects/detail/containers/MessagesContainer.js @@ -26,6 +26,7 @@ import { } from '../../../config/constants' const SYSTEM_USER = { + handle: CODER_BOT_USERID, firstName: CODER_BOT_USER_FNAME, lastName: CODER_BOT_USER_LNAME, photoURL: require('file-loader?../../../assets/images/avatar-coder.svg') diff --git a/src/projects/list/components/Projects/ProjectsGridView.jsx b/src/projects/list/components/Projects/ProjectsGridView.jsx index 444222149..5727f721b 100644 --- a/src/projects/list/components/Projects/ProjectsGridView.jsx +++ b/src/projects/list/components/Projects/ProjectsGridView.jsx @@ -26,6 +26,7 @@ import IconProjectStatusTitle from '../../../../assets/icons/status-ico.svg' import './ProjectsGridView.scss' import NotificationBadge from '../../../../components/NotificationBadge/NotificationBadge' +import { getFullNameWithFallback } from '../../../../helpers/tcHelpers' const EnhancedProjectStatus = editableProjectStatus(ProjectStatus) @@ -130,13 +131,14 @@ const ProjectsGridView = props => { const sortMetric = _.find(SORT_OPTIONS, o => currentSortField === o.val) || SORT_OPTIONS[0] const lastAction = DATE_TO_USER_FIELD_MAP[sortMetric.field] const lastEditor = members[item[lastAction]] + const lastEditorName = getFullNameWithFallback(lastEditor) const time = moment(item[sortMetric.field]) return (
{time.year() === moment().year() ? time.format('MMM D, h:mm a') : time.format('MMM D YYYY, h:mm a')}
{ - lastEditor ? `${lastEditor.firstName} ${lastEditor.lastName}` : 'Unknown' + lastEditor ? lastEditorName : 'Unknown' }