diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a3aa3a50..05761d99a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,15 @@ This project adheres to
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [v3.6.1] - 2020-04-28
+### Added
+- Links to review tasks on Browse Challenge and Browse Project pages
+
+### Fixed
+- User metrics failing to load
+- Remove limit when fetching lists of challenges and projects for review
+
+
## [v3.6.0] - 2020-04-23
### Added
- Cooperative challenges
diff --git a/package.json b/package.json
index 9b57a6da4..6e2adf2be 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "maproulette3",
- "version": "3.6.0",
+ "version": "3.6.1",
"private": true,
"dependencies": {
"@mapbox/geo-viewport": "^0.4.0",
diff --git a/src/components/ChallengeDetail/ChallengeDetail.js b/src/components/ChallengeDetail/ChallengeDetail.js
index f5486ec9d..96ee5726d 100644
--- a/src/components/ChallengeDetail/ChallengeDetail.js
+++ b/src/components/ChallengeDetail/ChallengeDetail.js
@@ -1,6 +1,7 @@
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { FormattedMessage, FormattedRelative, injectIntl } from 'react-intl'
+import classNames from 'classnames'
import _isObject from 'lodash/isObject'
import _get from 'lodash/get'
import _findIndex from 'lodash/findIndex'
@@ -225,7 +226,19 @@ export class ChallengeDetail extends Component {
{unsaveControl}
)}
- {manageControl &&
{manageControl}}
+
+ {_get(this.props.user, 'settings.isReviewer') &&
+
+
+
+ }
+ {manageControl}
+
diff --git a/src/components/ChallengeDetail/Messages.js b/src/components/ChallengeDetail/Messages.js
index cd84d732f..e7b49830b 100644
--- a/src/components/ChallengeDetail/Messages.js
+++ b/src/components/ChallengeDetail/Messages.js
@@ -54,4 +54,9 @@ export default defineMessages({
defaultMessage: "View Leaderboard",
},
+ viewReviews: {
+ id: "ChallengeDetails.fields.viewReviews.label",
+ defaultMessage: "Review",
+ },
+
})
diff --git a/src/components/ProjectDetail/Messages.js b/src/components/ProjectDetail/Messages.js
index 75bad114b..137effaa6 100644
--- a/src/components/ProjectDetail/Messages.js
+++ b/src/components/ProjectDetail/Messages.js
@@ -55,4 +55,9 @@ export default defineMessages({
id: "ProjectDetails.fields.viewLeaderboard.label",
defaultMessage: "View Leaderboard",
},
+
+ viewReviews: {
+ id: "ProjectDetails.fields.viewReviews.label",
+ defaultMessage: "Review",
+ },
})
diff --git a/src/components/ProjectDetail/ProjectDetail.js b/src/components/ProjectDetail/ProjectDetail.js
index bd801bca4..558e0af84 100644
--- a/src/components/ProjectDetail/ProjectDetail.js
+++ b/src/components/ProjectDetail/ProjectDetail.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
+import classNames from 'classnames'
import { FormattedMessage, FormattedRelative, injectIntl } from 'react-intl'
import _isObject from 'lodash/isObject'
import _get from 'lodash/get'
@@ -124,8 +125,20 @@ export class ProjectDetail extends Component {
-
- {manageControl && - {manageControl}
}
+
+ -
+ {_get(this.props.user, 'settings.isReviewer') &&
+
+
+
+ }
+ {manageControl}
+
diff --git a/src/lang/en-US.json b/src/lang/en-US.json
index 67bda1680..42aeae9e9 100644
--- a/src/lang/en-US.json
+++ b/src/lang/en-US.json
@@ -309,6 +309,7 @@
"ChallengeDetails.fields.lastChallengeDetails.TaskRefresh.label": "Tasks From",
"ChallengeDetails.fields.lastChallengeDetails.DataOriginDate.label": "Tasks built on {refreshDate} from data sourced on {sourceDate}.",
"ChallengeDetails.fields.viewLeaderboard.label": "View Leaderboard",
+ "ChallengeDetails.fields.viewReviews.label": "Review",
"ChallengeEndModal.header": "Challenge End",
"ChallengeEndModal.primaryMessage": "You have marked all remaining tasks in this challenge as either skipped or too hard.",
"ChallengeEndModal.control.dismiss.label": "Continue",
@@ -613,6 +614,7 @@
"ProjectDetails.fields.created.label": "Created",
"ProjectDetails.fields.modified.label": "Modified",
"ProjectDetails.fields.viewLeaderboard.label": "View Leaderboard",
+ "ProjectDetails.fields.viewReviews.label": "Review",
"Admin.TaskReview.controls.updateReviewStatusTask.label": "Update Review Status",
"Admin.TaskReview.controls.currentTaskStatus.label": "Task Status:",
"Admin.TaskReview.controls.currentReviewStatus.label": "Review Status:",
@@ -1021,7 +1023,7 @@
"Review.Dashboard.myReviewTasks": "My Reviewed Tasks",
"Review.Dashboard.allReviewedTasks": "All Review-related Tasks",
"Review.Dashboard.volunteerAsReviewer.label": "Volunteer as a Reviewer",
- "Review.Dashboard.goBack.label": "Go Back",
+ "Review.Dashboard.goBack.label": "Reconfigure Reviews",
"ReviewStatus.metrics.title": "Review Status",
"ReviewStatus.metrics.awaitingReview": "Tasks awaiting review",
"ReviewStatus.metrics.approvedReview": "Review tasks that passed",
diff --git a/src/pages/Review/Messages.js b/src/pages/Review/Messages.js
index b432d1130..8586217ba 100644
--- a/src/pages/Review/Messages.js
+++ b/src/pages/Review/Messages.js
@@ -31,6 +31,6 @@ export default defineMessages({
goBack: {
id: "Review.Dashboard.goBack.label",
- defaultMessage: "Go Back",
+ defaultMessage: "Reconfigure Reviews",
}
})
diff --git a/src/pages/Review/Review.js b/src/pages/Review/Review.js
index b421b55d2..57f5a445b 100644
--- a/src/pages/Review/Review.js
+++ b/src/pages/Review/Review.js
@@ -4,9 +4,12 @@ import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
import { injectIntl } from 'react-intl'
import MediaQuery from 'react-responsive'
+import queryString from 'query-string'
import classNames from 'classnames'
import _cloneDeep from 'lodash/cloneDeep'
import _get from 'lodash/get'
+import _isFinite from 'lodash/isFinite'
+import _parseInt from 'lodash/parseInt'
import _isUndefined from 'lodash/isUndefined'
import AsEndUser from '../../interactions/User/AsEndUser'
import WithCurrentUser from '../../components/HOCs/WithCurrentUser/WithCurrentUser'
@@ -63,6 +66,19 @@ export class ReviewTasksDashboard extends Component {
}
componentDidUpdate(prevProps) {
+ if (!this.state.filterSelected[this.state.showType] &&
+ _get(this.props.history, 'location.search')) {
+ const urlParams = queryString.parse(_get(this.props, 'location.search'))
+ if (_isFinite(_parseInt(urlParams.challengeId))) {
+ this.setSelectedChallenge(urlParams.challengeId, urlParams.challengeName)
+ return
+ }
+ else if (_isFinite(_parseInt(urlParams.projectId))) {
+ this.setSelectedProject(urlParams.projectId, urlParams.projectName)
+ return
+ }
+ }
+
if (this.props.location.pathname !== prevProps.location.pathname &&
this.props.location.search !== prevProps.location.search) {
window.scrollTo(0, 0)
@@ -103,6 +119,9 @@ export class ReviewTasksDashboard extends Component {
const filterSelected = _cloneDeep(this.state.filterSelected)
filterSelected[this.state.showType] = null
this.setState({filterSelected})
+ this.props.history.push({
+ pathname: `/review/${this.state.showType}`
+ })
}
changeTab = (tab) => {
diff --git a/src/services/Task/TaskReview/TaskReview.js b/src/services/Task/TaskReview/TaskReview.js
index b3cf99425..b7137bff8 100644
--- a/src/services/Task/TaskReview/TaskReview.js
+++ b/src/services/Task/TaskReview/TaskReview.js
@@ -331,7 +331,8 @@ export const fetchReviewChallenges = function(reviewTasksType,
return new Endpoint(
api.challenges.withReviewTasks,
{schema: [challengeSchema()],
- params:{reviewTasksType: type, excludeOtherReviewers, tStatus}}
+ params:{reviewTasksType: type, excludeOtherReviewers, tStatus,
+ limit: -1}}
).execute().then(normalizedResults => {
dispatch(receiveReviewChallenges(normalizedResults.entities.challenges, RequestStatus.success))
dispatch(receiveReviewProjects(normalizedResults.entities.projects, RequestStatus.success))