From e99c30f21337e615bd1ad5c3f00edbb78ba21989 Mon Sep 17 00:00:00 2001 From: Awais Ansari <79941147+awais-ansari@users.noreply.github.com> Date: Thu, 16 Feb 2023 20:54:53 +0500 Subject: [PATCH] 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 --- src/data/constants.js | 1 + .../in-context-topics/TopicPostsView.jsx | 24 +++++++++++++++---- .../components/BackButton.jsx | 13 +++++++--- .../in-context-topics/data/slices.js | 2 +- src/discussions/posts/PostsList.jsx | 10 ++++---- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/data/constants.js b/src/data/constants.js index 7420940a..15508a8f 100644 --- a/src/data/constants.js +++ b/src/data/constants.js @@ -63,6 +63,7 @@ export const ContentActions = { * @enum {string} */ export const RequestStatus = { + IDLE: 'idle', IN_PROGRESS: 'in-progress', SUCCESSFUL: 'successful', FAILED: 'failed', diff --git a/src/discussions/in-context-topics/TopicPostsView.jsx b/src/discussions/in-context-topics/TopicPostsView.jsx index b0daea1c..494b68a3 100644 --- a/src/discussions/in-context-topics/TopicPostsView.jsx +++ b/src/discussions/in-context-topics/TopicPostsView.jsx @@ -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 }) {
{topicId ? ( ) : ( @@ -56,6 +69,7 @@ function TopicPostsView({ intl }) { ) : ( selectedSubsectionUnits?.map((unit) => ( @@ -65,10 +79,10 @@ function TopicPostsView({ intl }) { /> )) )} - {(category && selectedSubsectionUnits.length === 0 && topicsLoadingStatus === RequestStatus.SUCCESSFUL) && ( + {(category && selectedSubsectionUnits.length === 0 && topicsStatus === RequestStatus.SUCCESSFUL) && ( )} - {(category && topicsLoadingStatus === RequestStatus.IN_PROGRESS) && ( + {(category && topicsInProgress) && (
diff --git a/src/discussions/in-context-topics/components/BackButton.jsx b/src/discussions/in-context-topics/components/BackButton.jsx index cadfe332..0757aec9 100644 --- a/src/discussions/in-context-topics/components/BackButton.jsx +++ b/src/discussions/in-context-topics/components/BackButton.jsx @@ -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)} />
- {title} + {loading ? : title}
@@ -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); diff --git a/src/discussions/in-context-topics/data/slices.js b/src/discussions/in-context-topics/data/slices.js index da670578..41a61468 100644 --- a/src/discussions/in-context-topics/data/slices.js +++ b/src/discussions/in-context-topics/data/slices.js @@ -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: [], diff --git a/src/discussions/posts/PostsList.jsx b/src/discussions/posts/PostsList.jsx index 12ca8a9e..e0ecbff0 100644 --- a/src/discussions/posts/PostsList.jsx +++ b/src/discussions/posts/PostsList.jsx @@ -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 && } - {loadingStatus === RequestStatus.IN_PROGRESS ? ( + {loadingStatus === RequestStatus.IN_PROGRESS || parentIsLoading ? (
@@ -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);