diff --git a/src/discussions/common/AlertBanner.jsx b/src/discussions/common/AlertBanner.jsx
index 3c2a96e7..1027faee 100644
--- a/src/discussions/common/AlertBanner.jsx
+++ b/src/discussions/common/AlertBanner.jsx
@@ -65,7 +65,7 @@ function AlertBanner({
{intl.formatMessage(messages.editedBy)}
-
+
{intl.formatMessage(messages.reason)}: {content.lastEdit.reason}
@@ -76,7 +76,7 @@ function AlertBanner({
{intl.formatMessage(messages.closedBy)}
-
+
{intl.formatMessage(messages.reason)}: {content.closeReason}
diff --git a/src/discussions/common/AuthorLabel.jsx b/src/discussions/common/AuthorLabel.jsx
index a58ed76f..001c9c88 100644
--- a/src/discussions/common/AuthorLabel.jsx
+++ b/src/discussions/common/AuthorLabel.jsx
@@ -1,14 +1,18 @@
-import React from 'react';
+import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import capitalize from 'lodash/capitalize';
+import { Link, useLocation } from 'react-router-dom';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Icon } from '@edx/paragon';
import { Institution, School } from '@edx/paragon/icons';
+import { Routes } from '../../data/constants';
import messages from '../messages';
+import { discussionsPath } from '../utils';
+import { DiscussionContext } from './context';
function AuthorLabel({
intl,
@@ -17,6 +21,8 @@ function AuthorLabel({
linkToProfile,
labelColor,
}) {
+ const location = useLocation();
+ const { courseId } = useContext(DiscussionContext);
let icon = null;
let authorLabelMessage = null;
@@ -33,8 +39,12 @@ function AuthorLabel({
const className = classNames('d-flex align-items-center', labelColor);
const labelContents = (
- <>
-
+
+
{capitalize(author)}
{icon && (
@@ -54,16 +64,25 @@ function AuthorLabel({
{authorLabelMessage}
)}
- >
+
);
return linkToProfile
- ? React.createElement('a', { href: '#nowhere', className }, labelContents)
- : React.createElement('div', { className }, labelContents);
+ ? (
+
+ {labelContents}
+
+ )
+ : <>{labelContents}>;
}
AuthorLabel.propTypes = {
- intl: intlShape,
+ intl: intlShape.isRequired,
author: PropTypes.string.isRequired,
authorLabel: PropTypes.string,
linkToProfile: PropTypes.bool,
diff --git a/src/discussions/discussions-home/DiscussionSidebar.test.jsx b/src/discussions/discussions-home/DiscussionSidebar.test.jsx
index 1dccc6de..2158c5a2 100644
--- a/src/discussions/discussions-home/DiscussionSidebar.test.jsx
+++ b/src/discussions/discussions-home/DiscussionSidebar.test.jsx
@@ -11,6 +11,7 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';
import { initializeStore } from '../../store';
+import { DiscussionContext } from '../common/context';
import { fetchConfigSuccess } from '../data/slices';
import { threadsApiUrl } from '../posts/data/api';
import DiscussionSidebar from './DiscussionSidebar';
@@ -27,9 +28,11 @@ function renderComponent(displaySidebar = true, location = `/${courseId}/`) {
-
-
-
+
+
+
+
+
,
diff --git a/src/discussions/learners/LearnerPostsView.jsx b/src/discussions/learners/LearnerPostsView.jsx
index 956c0fe7..828c01e3 100644
--- a/src/discussions/learners/LearnerPostsView.jsx
+++ b/src/discussions/learners/LearnerPostsView.jsx
@@ -20,7 +20,6 @@ import {
import NoResults from '../posts/NoResults';
import { PostLink } from '../posts/post';
import { discussionsPath } from '../utils';
-import { selectLearnerProfile } from './data/selectors';
import { fetchUserPosts } from './data/thunks';
import messages from './messages';
@@ -33,14 +32,13 @@ function LearnerPostsView({ intl }) {
const loadingStatus = useSelector(threadsLoadingStatus());
const { courseId, learnerUsername: username } = useContext(DiscussionContext);
const nextPage = useSelector(selectThreadNextPage());
- const { id: userId } = useSelector(selectLearnerProfile(username));
useEffect(() => {
- dispatch(fetchUserPosts(courseId, username, userId));
+ dispatch(fetchUserPosts(courseId, username));
}, [courseId, username]);
const loadMorePosts = () => (
- dispatch(fetchUserPosts(courseId, username, userId, {
+ dispatch(fetchUserPosts(courseId, username, {
page: nextPage,
}))
);
@@ -57,11 +55,11 @@ function LearnerPostsView({ intl }) {
return (
-
+
);
}
- return ();
+ return ();
});
return (
@@ -89,10 +87,10 @@ function LearnerPostsView({ intl }) {
) : (
- nextPage && (
-
+ nextPage && loadingStatus === RequestStatus.SUCCESSFUL && (
+
)
)}
diff --git a/src/discussions/learners/LearnersView.jsx b/src/discussions/learners/LearnersView.jsx
index 71e1f088..e51f40ab 100644
--- a/src/discussions/learners/LearnersView.jsx
+++ b/src/discussions/learners/LearnersView.jsx
@@ -66,7 +66,7 @@ function LearnersView({ intl }) {
) : (
- nextPage && (
+ nextPage && loadingStatus === RequestStatus.SUCCESSFUL && (
diff --git a/src/discussions/learners/data/api.js b/src/discussions/learners/data/api.js
index 3419acce..5aca91d3 100644
--- a/src/discussions/learners/data/api.js
+++ b/src/discussions/learners/data/api.js
@@ -45,10 +45,10 @@ export async function getUserProfiles(usernames) {
* pagination: {count, num_pages, next, previous}
* }
*/
-export async function getUserPosts(courseId, userId, { page }) {
+export async function getUserPosts(courseId, username, { page }) {
const learnerPostsApiUrl = `${coursesApiUrl}${courseId}/learner/`;
const { data } = await getAuthenticatedHttpClient()
- .get(learnerPostsApiUrl, { params: { user_id: userId, page } });
+ .get(learnerPostsApiUrl, { params: { username, page } });
return data;
}
diff --git a/src/discussions/learners/data/selectors.js b/src/discussions/learners/data/selectors.js
index 15926553..fae8940c 100644
--- a/src/discussions/learners/data/selectors.js
+++ b/src/discussions/learners/data/selectors.js
@@ -25,5 +25,3 @@ export const selectLearner = (username) => createSelector(
[selectAllLearners],
learners => learners.find(l => l.username === username) || {},
);
-
-export const selectLearnerProfile = (username) => state => state.learners.learnerProfiles[username] || {};
diff --git a/src/discussions/learners/data/thunks.js b/src/discussions/learners/data/thunks.js
index 33718eca..094a25a2 100644
--- a/src/discussions/learners/data/thunks.js
+++ b/src/discussions/learners/data/thunks.js
@@ -59,16 +59,16 @@ export function fetchLearners(courseId, {
* redux state
*
* @param {string} courseId Course ID of the course eg., course-v1:X+Y+Z
- * @param {string} userId userId of the learner
+ * @param {string} username name of the learner
* @param page
* @returns a promise that will update the state with the learner's posts
*/
-export function fetchUserPosts(courseId, username, userId, { page = 1 } = {}) {
+export function fetchUserPosts(courseId, username, { page = 1 } = {}) {
return async (dispatch) => {
try {
dispatch(fetchLearnerThreadsRequest({ courseId, author: username }));
- const data = await getUserPosts(courseId, userId, { page });
+ const data = await getUserPosts(courseId, username, { page });
const normalisedData = normaliseThreads(camelCaseObject(data));
dispatch(fetchThreadsSuccess({ ...normalisedData, page, author: username }));
diff --git a/src/discussions/posts/PostsList.jsx b/src/discussions/posts/PostsList.jsx
index d4e43223..a04d9556 100644
--- a/src/discussions/posts/PostsList.jsx
+++ b/src/discussions/posts/PostsList.jsx
@@ -79,7 +79,7 @@ function PostsList({ posts, topics, intl }) {
) : (
- nextPage && (
+ nextPage && loadingStatus === RequestStatus.SUCCESSFUL && (
diff --git a/src/discussions/posts/data/slices.js b/src/discussions/posts/data/slices.js
index 12a82ef4..5344fe5b 100644
--- a/src/discussions/posts/data/slices.js
+++ b/src/discussions/posts/data/slices.js
@@ -43,6 +43,7 @@ const threadsSlice = createSlice({
if (state.author !== payload.author) {
state.pages = [];
state.author = payload.author;
+ state.totalThreads = null;
}
state.status = RequestStatus.IN_PROGRESS;
},
diff --git a/src/discussions/posts/post/PostLink.jsx b/src/discussions/posts/post/PostLink.jsx
index 617a954c..e4818173 100644
--- a/src/discussions/posts/post/PostLink.jsx
+++ b/src/discussions/posts/post/PostLink.jsx
@@ -21,6 +21,7 @@ function PostLink({
post,
isSelected,
intl,
+ learnerTab,
}) {
const {
page,
@@ -72,7 +73,7 @@ function PostLink({
className={
classNames('text-truncate font-weight-500 font-size-14 text-primary-500 font-style-normal font-family-inter',
{ 'font-weight-bolder': !post.read })
-}
+ }
>
{post.title}
@@ -100,6 +101,7 @@ function PostLink({
author={post.author || intl.formatMessage(messages.anonymous)}
authorLabel={post.authorLabel}
labelColor={authorLabelColor && `text-${authorLabelColor}`}
+ linkToProfile={!learnerTab && post.author}
/>
- true} />
+
+ true} learnerTab={learnerTab} />
+
,
);
@@ -65,3 +69,30 @@ describe('PostFooter', () => {
expect(screen.getByTestId('reported-post')).toBeTruthy();
});
});
+
+describe('Post username', () => {
+ beforeEach(async () => {
+ initializeMockApp({
+ authenticatedUser: {
+ userId: 3,
+ username: 'abc123',
+ administrator: true,
+ roles: [],
+ },
+ });
+ store = initializeStore();
+ });
+
+ it.each([
+ true,
+ false,
+ ])('is a clickable link %s', (leanerTab) => {
+ renderComponent(mockPost, leanerTab);
+
+ if (leanerTab) {
+ expect(screen.queryByTestId('learner-posts-link')).not.toBeInTheDocument();
+ } else {
+ expect(screen.queryByTestId('learner-posts-link')).toBeInTheDocument();
+ }
+ });
+});