Challenge Overview
Refactor components for showing posts for phases into a general component to show posts.
Project Background
Topcode Connect is a client-facing application of Topcoder. Customer use Topcoder Connect to input requirements of their projects, then managers and copilots take it from there.
Currently, we have the ability to create posts for the project phases, see screenshot and live project demo. We want to add posts to other places. Instead of duplicating the same functionality for handling the posts for each new place, we would like to convert the current logic which we have for phases posts into a general component so after we could use it at any place.
There is another place where we are showing posts - on Messages page inside a drawer. That place has a separate code from phases and we will refactor that code in the future challenges to use the new component implemented in this challenge.
Technology Stack
-
React
-
Redux
-
CSS Modules
Code access
The work for this challenge has to be done in one repository:
- Connect App repo https://github.com/appirio-tech/connect-app feature/posts-component branch
- User for testing is provided on the forum.
Information
You shouldn’t take care of the next thing but for the information: when we create a phase on the sever-side we automatically create a topic for that phase and marking such topic with tag like “phase#<phase_id>”. So later we can retrieve such a topic in the client-side knowing only the phase_id, and without knowing the topic id. So the posts which we are showing for the phase are the posts which belong to that associated topic. See screenshot with explanation.
Individual requirements
Currently, we have the ability to create comments for the project phases, see screenshot and live project demo. It’s implemented using phaseFeedHOC which wraps ProjectStage component and pass prepared props from HOC to render PhaseFeed component which renders the list of posts. The current code renders the posts knowing phase_id, but as we want to use show such posts for anything, we should refactor the code to use a more general thing - tag, instead of phase_id to identify the topic.
-
As an outcome of this challenge, current functionality won’t be changed, and everything should work as it is. The only difference would be that we refactor code to have a component which we can reuse in other places.
-
Our aim here is to have one container component like this:
<PostsContainer
tag=”phase#345”
postUrlTemplate=”/projects/1234/plan#phase-345-posts-{{postId}}”
/>
- tag - is used to load topics from the server.
- postUrlTemplate - is Handlebar template to format a link to the particular comment, see now. -
Update code of ProjectStage component to use this new component instead of PhaseFeed and without passing many props like now it should take care about everything: it should be connected to the Redux store and it should take care about loading comments, all the actions for adding, editing and removing comments and so on. So no more phaseFeedHOC should be used.
-
As we want to have a general PostsContainer not only for phases. So we should refactor/rename all associated actions, reducers, components and so on. They should know nothing about phases and show posts for any topic which is defined by the tag.
-
When PostsContainer is mounted it should start loading topic, but only if:
- topic is not loaded yet
- topic is not in the process of loading (as it can be preloaded by some other component) -
During loading of the topic, PostsContainer should show the loading indicator, no matter who started loading, the PostsContainer or some other component.
Implementation requirements
-
Currently, we store topics in the Redux store in phasesTopics property, see screenshot. We use phase ids as keys. As we are going to use our new PostsContainer not only for phases, we should change the structure:
- rename phasesTopics to topics
- instead of using phase.id as keys, use tag as key, so it would look something like this:
topics: {
“phase#345”: {
isLoading: false,
error: false,
topic: {...}
},
“work#678”: {...},
“other#901”: {...}
} -
Refactor existent phaseFeedHOC into new PostsContainer, and place it inside folder “src/components/Posts”.
-
Refactor/rename existent PhaseFeed into PostsView component, and also place it inside the folder “src/components/Posts”.
-
The PostsContainer should not be HOC and should render PostsView directly.
-
Refactor/rename actions in “src/projects/actions/phasesTopics.js” to “src/actions/topics.js”:
- loadFeedsForPhases -> loadTopics
- loadPhaseFeed -> loadTopic
- getPhaseTopicWithMember -> getTopicWithMember
- addPhaseFeedComment -> addTopicPost
- deletePhaseFeedComment -> deleteTopicPost
- savePhaseFeedComment -> updateTopicPost -
Rename all related action names like LOAD_PHASE_FEED_COMMENTS -> LOAD_TOPIC_POSTS and so on.
General requirements
-
Avoid using multilevel nesting in SCSS. As we use CSS Modules we don’t have to add prefixes or nest class selectors.
-
Don’t use :global in CSS Modules unless you have to change some global styles. New styles shouldn’t use :global.
-
User React and Redux best practices.
-
Lint should pass
-
Existent unit tests should pass
Would you have any questions or concerns, don’t hesitate to raise a question on the forum.
Verification guide / demo
Demonstrate the fact that PostsContainer can be used for showing any posts for any topic. Provide a verification guide and demo to check it. For example, you can add one <PostsContainer> to the Dashboard page and another one to the Assets Library page to demonstrate that we can add it anywhere and we only have to provide tag and postUrlTemplate. For this purpose create two topics using different tags like: “<your_handle>#1” and “<your_handle>#2”. See how to build request to the message service https://github.com/topcoder-platform/tc-project-service/blob/dev/src/events/projectPhases/index.js#L72-L76.
Your demo code should be easy to remove from the project code after.
Final Submission Guidelines
-
Patch to the Connect App.
-
The winner would be required to raise a PR to the repository.