diff --git a/src/discussions/comments/comment/CommentHeader.jsx b/src/discussions/comments/comment/CommentHeader.jsx index 33ccc700..e28c79a4 100644 --- a/src/discussions/comments/comment/CommentHeader.jsx +++ b/src/discussions/comments/comment/CommentHeader.jsx @@ -5,14 +5,17 @@ import classNames from 'classnames'; import { useSelector } from 'react-redux'; import { injectIntl } from '@edx/frontend-platform/i18n'; -import { Avatar, Icon } from '@edx/paragon'; -import { CheckCircle, Verified } from '@edx/paragon/icons'; +import { logError } from '@edx/frontend-platform/logging'; +import { + Avatar, Icon, +} from '@edx/paragon'; -import { AvatarOutlineAndLabelColors, ThreadType } from '../../../data/constants'; +import { AvatarOutlineAndLabelColors, EndorsementStatus, ThreadType } from '../../../data/constants'; import { AuthorLabel } from '../../common'; import ActionsDropdown from '../../common/ActionsDropdown'; import { useAlertBannerVisible } from '../../data/hooks'; import { selectAuthorAvatars } from '../../posts/data/selectors'; +import { useActions } from '../../utils'; import { commentShape } from './proptypes'; function CommentHeader({ @@ -24,6 +27,20 @@ function CommentHeader({ const colorClass = AvatarOutlineAndLabelColors[comment.authorLabel]; const hasAnyAlert = useAlertBannerVisible(comment); + const actions = useActions({ + ...comment, + postType, + }); + const actionIcons = actions.find(({ action }) => action === EndorsementStatus.ENDORSED); + + const handleIcons = (action) => { + const actionFunction = actionHandlers[action]; + if (actionFunction) { + actionFunction(); + } else { + logError(`Unknown or unimplemented action ${action}`); + } + }; return (
- {comment.endorsed && ( - - { - postType === 'question' - ? - : - } - + + {actionIcons && ( + + { + handleIcons(actionIcons.action); + } + } + src={actionIcons.icon} + className={['endorse', 'unendorse'].includes(actionIcons.id) ? 'text-dark-500' : 'text-success-500'} + size="sm" + /> + )} + { @@ -48,7 +48,7 @@ describe('Comment Header', () => { it('should render verified icon for endorsed discussion posts', () => { renderComponent(mockComment, 'discussion', {}); - expect(screen.queryAllByTestId('verified-icon')).toHaveLength(1); + expect(screen.queryAllByTestId('check-icon')).toHaveLength(1); }); it('should render check icon for endorsed question posts', () => { renderComponent(mockComment, 'question', {}); diff --git a/src/discussions/common/AuthorLabel.jsx b/src/discussions/common/AuthorLabel.jsx index ea87c0ec..e3ea2c60 100644 --- a/src/discussions/common/AuthorLabel.jsx +++ b/src/discussions/common/AuthorLabel.jsx @@ -20,6 +20,7 @@ function AuthorLabel({ authorLabel, linkToProfile, labelColor, + alert, }) { const location = useLocation(); const { courseId } = useContext(DiscussionContext); @@ -46,8 +47,8 @@ function AuthorLabel({
@@ -97,12 +99,14 @@ AuthorLabel.propTypes = { authorLabel: PropTypes.string, linkToProfile: PropTypes.bool, labelColor: PropTypes.string, + alert: PropTypes.bool, }; AuthorLabel.defaultProps = { linkToProfile: false, authorLabel: null, labelColor: '', + alert: false, }; export default injectIntl(AuthorLabel); diff --git a/src/discussions/common/EndorsedAlertBanner.jsx b/src/discussions/common/EndorsedAlertBanner.jsx index 8f0a9e11..3e830412 100644 --- a/src/discussions/common/EndorsedAlertBanner.jsx +++ b/src/discussions/common/EndorsedAlertBanner.jsx @@ -39,14 +39,19 @@ function EndorsedAlertBanner({ )} - + {intl.formatMessage( isQuestion ? messages.answeredLabel : messages.endorsedLabel, )} - + {intl.formatMessage(messages.time, { time: timeago.format(content.endorsedAt, 'time-locale') })}
diff --git a/src/discussions/messages.js b/src/discussions/messages.js index e39fd662..0d84cd9c 100644 --- a/src/discussions/messages.js +++ b/src/discussions/messages.js @@ -63,7 +63,7 @@ const messages = defineMessages({ }, markAnsweredAction: { id: 'discussions.actions.markAnswered', - defaultMessage: 'Mark as Answered', + defaultMessage: 'Mark as answered', description: 'Action to mark a comment as answering a post', }, unmarkAnsweredAction: { diff --git a/src/discussions/utils.js b/src/discussions/utils.js index a95a87c0..ff84c9d1 100644 --- a/src/discussions/utils.js +++ b/src/discussions/utils.js @@ -5,7 +5,9 @@ import { generatePath, useRouteMatch } from 'react-router'; import { getConfig } from '@edx/frontend-platform'; import { - Delete, Edit, Pin, QuestionAnswer, Report, VerifiedBadge, + CheckCircle, + CheckCircleOutline, + Delete, Edit, Pin, QuestionAnswer, Report, Verified, VerifiedOutline, } from '@edx/paragon/icons'; import { InsertLink } from '../components/icons'; @@ -101,7 +103,7 @@ export const ACTIONS_LIST = [ { id: 'endorse', action: ContentActions.ENDORSE, - icon: VerifiedBadge, + icon: VerifiedOutline, label: messages.endorseAction, conditions: { endorsed: false, @@ -111,7 +113,7 @@ export const ACTIONS_LIST = [ { id: 'unendorse', action: ContentActions.ENDORSE, - icon: VerifiedBadge, + icon: Verified, label: messages.unendorseAction, conditions: { endorsed: true, @@ -121,7 +123,7 @@ export const ACTIONS_LIST = [ { id: 'answer', action: ContentActions.ENDORSE, - icon: VerifiedBadge, + icon: CheckCircleOutline, label: messages.markAnsweredAction, conditions: { endorsed: false, @@ -131,7 +133,7 @@ export const ACTIONS_LIST = [ { id: 'unanswer', action: ContentActions.ENDORSE, - icon: VerifiedBadge, + icon: CheckCircle, label: messages.unmarkAnsweredAction, conditions: { endorsed: true, @@ -183,6 +185,7 @@ export function useActions(content) { .every(condition => condition === true) : true ); + return ACTIONS_LIST.filter( ({ action,