diff --git a/__tests__/shared/components/challenge-listing/__snapshots__/index.jsx.snap b/__tests__/shared/components/challenge-listing/__snapshots__/index.jsx.snap index 69fd209cb3..f590d36b19 100644 --- a/__tests__/shared/components/challenge-listing/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/challenge-listing/__snapshots__/index.jsx.snap @@ -43,6 +43,7 @@ exports[`Matches shallow shapshot 1 shapshot 1 1`] = ` setFilterState={[MockFunction]} setSort={[MockFunction]} sorts={Object {}} + userChallenges={Array []} />
service.getUserChallenges(user, newFilter, params) .catch(() => ({ challenges: [] }))), page); } - // uch array contains challenges where the user is participating in - return Promise.all(calls).then(([ch, uch]) => ({ - uuid, - challenges: mapUserWithChallenges(user, ch, uch), - ...filter, - })); + return Promise.all(calls).then(([ch, uch]) => { + /* uch array contains challenges where the user is participating in +@@ -111,8 +124,8 @@ function getAllActiveChallengesDone(uuid, tokenV3) { + * challenges in an efficient way. */ + if (uch) { + const map = {}; + uch.forEach((item) => { map[item.id] = item; }); + ch.forEach((item) => { + if (map[item.id]) { + /* It is fine to reassing, as the array we modifying is created just + * above within the same function. */ + /* eslint-disable no-param-reassign */ + item.users[user] = true; + item.userDetails = map[item.id].userDetails; + /* eslint-enable no-param-reassign */ + } + }); + } + + return { uuid, challenges: ch, ...filter }; + }); } /** TODO: Inspect if the 2 actions bellow can be removed? @@ -168,12 +182,12 @@ function getActiveChallengesDone(uuid, page, backendFilter, tokenV3, frontFilter // Handle any errors on this endpoint so that the non-user specific challenges // will still be loaded. - calls.push(getAll(params => service.getUserChallenges(user, filter, params) - .catch(() => ({ challenges: [] })))); + calls.push(service.getUserChallenges(user, filter, {}) + .catch(() => ({ challenges: [] }))); } - return Promise.all(calls).then(([ch, uch]) => ({ + return Promise.all(calls).then(([ch]) => ({ uuid, - challenges: mapUserWithChallenges(user, ch.challenges, uch), + challenges: ch.challenges, meta: ch.meta, frontFilter, })); @@ -325,7 +339,7 @@ function getUserChallengesInit(uuid) { function getUserChallengesDone(userId, tokenV3) { const service = getService(tokenV3); - return service.getUserResources(userId) + return service.getUserResources(userId, 1, 10000) .then(item => item) .catch((error) => { fireErrorMessage('Error Getting User Challenges', error.content || error); diff --git a/src/shared/components/challenge-listing/Listing/index.jsx b/src/shared/components/challenge-listing/Listing/index.jsx index 88c95ce7dc..12e29b1b91 100644 --- a/src/shared/components/challenge-listing/Listing/index.jsx +++ b/src/shared/components/challenge-listing/Listing/index.jsx @@ -21,6 +21,7 @@ function Listing({ auth, challenges, challengeTypes, + userChallenges, challengesUrl, communityName, extraBucket, @@ -46,7 +47,7 @@ function Listing({ pastSearchTimestamp, isLoggedIn, }) { - const buckets = getBuckets(_.get(auth, 'user.userId')); + const buckets = getBuckets(userChallenges); const isChallengesAvailable = (bucket) => { const filter = Filter.getFilterFunction(buckets[bucket].filter); const clonedChallenges = _.clone(challenges); @@ -179,6 +180,7 @@ Listing.defaultProps = { // onExpandFilterResult: _.noop, openChallengesInNewTabs: false, pastSearchTimestamp: 0, + userChallenges: [], }; Listing.propTypes = { @@ -214,6 +216,7 @@ Listing.propTypes = { setSort: PT.func.isRequired, sorts: PT.shape().isRequired, pastSearchTimestamp: PT.number, + userChallenges: PT.arrayOf(PT.string), isLoggedIn: PT.bool.isRequired, }; diff --git a/src/shared/components/challenge-listing/index.jsx b/src/shared/components/challenge-listing/index.jsx index 59ccbf868d..4c381ab420 100644 --- a/src/shared/components/challenge-listing/index.jsx +++ b/src/shared/components/challenge-listing/index.jsx @@ -115,6 +115,7 @@ export default function ChallengeListing(props) { sorts={props.sorts} loadMoreActive={props.loadMoreActive} loadingActiveChallenges={props.loadingChallenges} + userChallenges={props.userChallenges} isLoggedIn={isLoggedIn} /> ); @@ -169,6 +170,7 @@ ChallengeListing.defaultProps = { expandTag: null, loadMoreActive: null, isBucketSwitching: false, + userChallenges: [], }; ChallengeListing.propTypes = { @@ -205,5 +207,6 @@ ChallengeListing.propTypes = { auth: PT.shape(), loadMoreActive: PT.func, isBucketSwitching: PT.bool, + userChallenges: PT.arrayOf(PT.string), isLoggedIn: PT.bool.isRequired, }; diff --git a/src/shared/containers/challenge-listing/Listing/index.jsx b/src/shared/containers/challenge-listing/Listing/index.jsx index 3764fc6b24..8b27e52269 100644 --- a/src/shared/containers/challenge-listing/Listing/index.jsx +++ b/src/shared/containers/challenge-listing/Listing/index.jsx @@ -149,6 +149,7 @@ export class ListingContainer extends React.Component { auth, getActiveChallenges, lastRequestedPageOfActiveChallenges, + getUserChallenges, } = this.props; const f = this.getBackendFilter(); getActiveChallenges( @@ -157,6 +158,10 @@ export class ListingContainer extends React.Component { auth.tokenV3, f.front, ); + if (auth.tokenV3) { + const userId = _.get(auth.user, 'userId'); + getUserChallenges(userId, auth.tokenV3); + } } render() { @@ -204,6 +209,7 @@ export class ListingContainer extends React.Component { sorts, hideTcLinksInSidebarFooter, isBucketSwitching, + userChallenges, } = this.props; const { tokenV3 } = auth; @@ -306,6 +312,7 @@ export class ListingContainer extends React.Component { groupIds={groupIds} auth={auth} isBucketSwitching={isBucketSwitching} + userChallenges={userChallenges} isLoggedIn={isLoggedIn} />
@@ -333,6 +340,7 @@ ListingContainer.defaultProps = { queryBucket: BUCKETS.ALL, meta: {}, isBucketSwitching: false, + userChallenges: [], }; ListingContainer.propTypes = { @@ -402,6 +410,8 @@ ListingContainer.propTypes = { meta: PT.shape(), isBucketSwitching: PT.bool, selectBucketDone: PT.func.isRequired, + userChallenges: PT.arrayOf(PT.string), + getUserChallenges: PT.func.isRequired, }; const mapStateToProps = (state, ownProps) => { @@ -445,6 +455,7 @@ const mapStateToProps = (state, ownProps) => { isBucketSwitching: cl.sidebar.isBucketSwitching, expandedTags: cl.expandedTags, meta: cl.meta, + userChallenges: cl.userChallenges, }; }; @@ -491,6 +502,11 @@ function mapDispatchToProps(dispatch) { setSort: (bucket, sort) => dispatch(a.setSort(bucket, sort)), markHeaderMenu: () => dispatch(ah.setCurrentNav('Compete', 'All Challenges')), expandTag: id => dispatch(a.expandTag(id)), + getUserChallenges: (userId, tokenV3) => { + const uuid = shortId(); + dispatch(a.getUserChallengesInit(uuid)); + dispatch(a.getUserChallengesDone(userId, tokenV3)); + }, }; } diff --git a/src/shared/containers/challenge-listing/Sidebar.jsx b/src/shared/containers/challenge-listing/Sidebar.jsx index 3f74289e7b..dd89d7795b 100644 --- a/src/shared/containers/challenge-listing/Sidebar.jsx +++ b/src/shared/containers/challenge-listing/Sidebar.jsx @@ -57,12 +57,12 @@ export class SidebarContainer extends React.Component { setFilter, setSearchText, tokenV2, - user, updateAllSavedFilters, updateSavedFilter, + userChallenges, } = this.props; - const buckets = getBuckets(_.get(user, 'userId', null)); + const buckets = getBuckets(userChallenges); if (extraBucket) { buckets[extraBucket.name] = extraBucket; @@ -115,6 +115,7 @@ SidebarContainer.defaultProps = { selectedCommunityId: '', tokenV2: null, user: null, + userChallenges: [], }; SidebarContainer.propTypes = { @@ -135,6 +136,7 @@ SidebarContainer.propTypes = { updateAllSavedFilters: PT.func.isRequired, updateSavedFilter: PT.func.isRequired, user: PT.shape(), + userChallenges: PT.arrayOf(PT.string), }; function mapDispatchToProps(dispatch) { @@ -167,6 +169,7 @@ function mapStateToProps(state, ownProps) { selectedCommunityId: state.challengeListing.selectedCommunityId, tokenV2: state.auth.tokenV2, user: state.auth.user, + userChallenges: state.challengeListing.userChallenges, }; } diff --git a/src/shared/utils/challenge-listing/buckets.js b/src/shared/utils/challenge-listing/buckets.js index 3327b17777..1d83495beb 100644 --- a/src/shared/utils/challenge-listing/buckets.js +++ b/src/shared/utils/challenge-listing/buckets.js @@ -134,9 +134,9 @@ export const NO_LIVE_CHALLENGES_CONFIG = { * @param {String} userId id of the authenticated * user to filter out My Challenges. */ -export function getBuckets(userId) { +export function getBuckets(userChallenges) { const res = _.cloneDeep(BUCKET_DATA); - res[BUCKETS.MY].filter.userId = userId; + res[BUCKETS.MY].filter.userChallenges = userChallenges; return res; } diff --git a/src/shared/utils/challenge-listing/helper.js b/src/shared/utils/challenge-listing/helper.js index c95850e071..192dafcc04 100644 --- a/src/shared/utils/challenge-listing/helper.js +++ b/src/shared/utils/challenge-listing/helper.js @@ -29,26 +29,3 @@ export function phaseStartDate(phase) { // For all other cases, take the `actualStartDate` as phase is already started return new Date(phase.actualStartDate); } - -/** - * Map user details with challenges - * - * @param {String} userId user id - * @param {Array} challenges all challenges - * @param {Array} userChallenges challenges user is participating in - */ -export function mapUserWithChallenges(userId, challenges, userChallenges) { - if (userChallenges) { - const map = {}; - userChallenges.forEach((item) => { map[item.id] = item; }); - challenges.forEach((item) => { - if (map[item.id]) { - /* eslint-disable no-param-reassign */ - item.users[userId] = true; - item.userDetails = map[item.id].userDetails; - /* eslint-enable no-param-reassign */ - } - }); - } - return challenges; -}