fix: unnamed topic/unit issue in inContext topics (#432)

* fix: unnamed topic/unit issue in incontext topics

* fix: sync topics and posts list loading for better UX
This commit is contained in:
Awais Ansari
2023-02-16 20:54:53 +05:00
committed by GitHub
parent eacc16b7f1
commit e99c30f213
5 changed files with 37 additions and 13 deletions

View File

@@ -63,6 +63,7 @@ export const ContentActions = {
* @enum {string}
*/
export const RequestStatus = {
IDLE: 'idle',
IN_PROGRESS: 'in-progress',
SUCCESSFUL: 'successful',
FAILED: 'failed',

View File

@@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import React, { useContext, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
@@ -8,6 +8,7 @@ import { Spinner } from '@edx/paragon';
import { RequestStatus, Routes } from '../../data/constants';
import { DiscussionContext } from '../common/context';
import { selectDiscussionProvider } from '../data/selectors';
import { selectTopicThreads } from '../posts/data/selectors';
import PostsList from '../posts/PostsList';
import { discussionsPath, handleKeyDown } from '../utils';
@@ -15,14 +16,18 @@ import {
selectArchivedTopic, selectLoadingStatus, selectNonCoursewareTopics,
selectSubsection, selectSubsectionUnits, selectUnits,
} from './data/selectors';
import { fetchCourseTopicsV3 } from './data/thunks';
import { BackButton, NoResults } from './components';
import messages from './messages';
import { Topic } from './topic';
function TopicPostsView({ intl }) {
const location = useLocation();
const dispatch = useDispatch();
const { courseId, topicId, category } = useContext(DiscussionContext);
const topicsLoadingStatus = useSelector(selectLoadingStatus);
const provider = useSelector(selectDiscussionProvider);
const topicsStatus = useSelector(selectLoadingStatus);
const topicsInProgress = topicsStatus === RequestStatus.IN_PROGRESS;
const posts = useSelector(selectTopicThreads([topicId]));
const selectedSubsectionUnits = useSelector(selectSubsectionUnits(category));
const selectedSubsection = useSelector(selectSubsection(category));
@@ -30,6 +35,12 @@ function TopicPostsView({ intl }) {
const selectedNonCoursewareTopic = useSelector(selectNonCoursewareTopics)?.find(topic => topic.id === topicId);
const selectedArchivedTopic = useSelector(selectArchivedTopic(topicId));
useEffect(() => {
if (provider && topicsStatus === RequestStatus.IDLE) {
dispatch(fetchCourseTopicsV3(courseId));
}
}, [provider]);
const backButtonPath = () => {
const path = selectedUnit ? Routes.TOPICS.CATEGORY : Routes.TOPICS.ALL;
const params = selectedUnit ? { courseId, category: selectedUnit?.parentId } : { courseId };
@@ -40,12 +51,14 @@ function TopicPostsView({ intl }) {
<div className="discussion-posts d-flex flex-column h-100">
{topicId ? (
<BackButton
loading={topicsInProgress}
path={backButtonPath()}
title={selectedUnit?.name || selectedNonCoursewareTopic?.name || selectedArchivedTopic?.name
|| intl.formatMessage(messages.unnamedTopic)}
/>
) : (
<BackButton
loading={topicsInProgress}
path={discussionsPath(Routes.TOPICS.ALL, { courseId })(location)}
title={selectedSubsection?.displayName || intl.formatMessage(messages.unnamedSubsection)}
/>
@@ -56,6 +69,7 @@ function TopicPostsView({ intl }) {
<PostsList
posts={posts}
topics={[topicId]}
parentIsLoading={topicsInProgress}
/>
) : (
selectedSubsectionUnits?.map((unit) => (
@@ -65,10 +79,10 @@ function TopicPostsView({ intl }) {
/>
))
)}
{(category && selectedSubsectionUnits.length === 0 && topicsLoadingStatus === RequestStatus.SUCCESSFUL) && (
{(category && selectedSubsectionUnits.length === 0 && topicsStatus === RequestStatus.SUCCESSFUL) && (
<NoResults />
)}
{(category && topicsLoadingStatus === RequestStatus.IN_PROGRESS) && (
{(category && topicsInProgress) && (
<div className="d-flex justify-content-center p-4">
<Spinner animation="border" variant="primary" size="lg" />
</div>

View File

@@ -4,12 +4,14 @@ import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Icon, IconButton } from '@edx/paragon';
import { Icon, IconButton, Spinner } from '@edx/paragon';
import { ArrowBack } from '@edx/paragon/icons';
import messages from '../messages';
function BackButton({ intl, path, title }) {
function BackButton({
intl, path, title, loading,
}) {
const history = useHistory();
return (
@@ -24,7 +26,7 @@ function BackButton({ intl, path, title }) {
alt={intl.formatMessage(messages.backAlt)}
/>
<div className="d-flex flex-fill justify-content-center align-items-center mr-4.5">
{title}
{loading ? <Spinner animation="border" variant="primary" size="sm" /> : title}
</div>
</div>
<div className="border-bottom border-light-400" />
@@ -36,6 +38,11 @@ BackButton.propTypes = {
intl: intlShape.isRequired,
path: PropTypes.shape({}).isRequired,
title: PropTypes.string.isRequired,
loading: PropTypes.bool,
};
BackButton.defaultProps = {
loading: false,
};
export default injectIntl(BackButton);

View File

@@ -6,7 +6,7 @@ import { RequestStatus } from '../../../data/constants';
const topicsSlice = createSlice({
name: 'inContextTopics',
initialState: {
status: RequestStatus.IN_PROGRESS,
status: RequestStatus.IDLE,
topics: [],
coursewareTopics: [],
nonCoursewareTopics: [],

View File

@@ -23,7 +23,7 @@ import NoResults from './NoResults';
import { PostLink } from './post';
function PostsList({
posts, topics, intl, isTopicTab,
posts, topics, intl, isTopicTab, parentIsLoading,
}) {
const dispatch = useDispatch();
const {
@@ -85,10 +85,10 @@ function PostsList({
return (
<>
{postInstances(pinnedPosts)}
{postInstances(unpinnedPosts)}
{!parentIsLoading && postInstances(pinnedPosts)}
{!parentIsLoading && postInstances(unpinnedPosts)}
{posts?.length === 0 && loadingStatus === RequestStatus.SUCCESSFUL && <NoResults />}
{loadingStatus === RequestStatus.IN_PROGRESS ? (
{loadingStatus === RequestStatus.IN_PROGRESS || parentIsLoading ? (
<div className="d-flex justify-content-center p-4 mx-auto my-auto">
<Spinner animation="border" variant="primary" size="lg" />
</div>
@@ -110,6 +110,7 @@ PostsList.propTypes = {
})),
topics: PropTypes.arrayOf(PropTypes.string),
isTopicTab: PropTypes.bool,
parentIsLoading: PropTypes.bool,
intl: intlShape.isRequired,
};
@@ -117,6 +118,7 @@ PostsList.defaultProps = {
posts: [],
topics: undefined,
isTopicTab: false,
parentIsLoading: undefined,
};
export default injectIntl(PostsList);