Skip to content

Commit

Permalink
Merge pull request #1247 from osmlab/prerelease
Browse files Browse the repository at this point in the history
v3.6.2
  • Loading branch information
nrotstan authored May 28, 2020
2 parents 289e1ee + 4fa5565 commit 587d7cb
Show file tree
Hide file tree
Showing 157 changed files with 7,442 additions and 1,722 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ REACT_APP_DEFAULT_LOCALE='en-US'
# MR2 back-end (scala) server
REACT_APP_MAP_ROULETTE_SERVER_URL='http://127.0.0.1:9000'
REACT_APP_MAP_ROULETTE_SERVER_WEBSOCKET_URL='ws://127.0.0.1:9000/ws'
REACT_APP_MAP_ROULETTE_SERVER_GRAPHQL_URL='http://127.0.0.1:9000/graphql'
REACT_APP_SERVER_OAUTH_URL='/auth/authenticate?redirect=/mr3'

# OSM API Server
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ This project adheres to
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).


## [v3.6.2] - 2020-05-28
### Added
- Revised Dashboard page
- Teams widget on Dashboard page
- Option to invert searches in various task tables
- Column for MR Tags on various task tables
- CSV export of mapper metrics for challenge owners and reviewers
- Bypass picker step when returning to Review as part of normal workflow
- Ability to edit task form responses when reworking a task
- Clarifying note about average time to complete challenge tasks
- Control to copy public challenge URL to clipboard when managing challenges
- Management tools for challenge snapshots for challenge managers
- Task Review metrics broken down by task status in Review Metrics widget
- Updated translations and new Ukrainian locale

### Fixed
- Join comma-separated priority-rule values based on rule (not group) operator
- Broken rendering of mustache tags in task forms (#1239)
- Minor visual fixes

### Changed
- Make the Dashboard page the landing page for users who are already signed-in
- Rename "Saved" challenges to "Favorite" challenges


## [v3.6.1] - 2020-04-28
### Added
- Links to review tasks on Browse Challenge and Browse Project pages
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ us with free service through their Open Source program. Translation files are
pulled into the code repository from time to time and stored in the `src/lang/`
directory.

Adding support for additional locales is quick and straight-forward: edit
`src/services/User/Locale/Locale.js` and follow the directions at the top of
the file.

By default, the en-US locale will be used for users who have not set a locale in
their MapRoulette user settings. This default locale can be changed with the
`REACT_APP_DEFAULT_LOCALE` .env setting. Users who have set a locale will
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "maproulette3",
"version": "3.6.1",
"version": "3.6.2",
"private": true,
"dependencies": {
"@apollo/client": "^3.0.0-beta.44",
"@mapbox/geo-viewport": "^0.4.0",
"@mapbox/geojsonhint": "^2.0.1",
"@nivo/bar": "^0.61.1",
Expand All @@ -27,6 +28,7 @@
"downshift": "^2.0.3",
"file-saver": "^2.0.2",
"fuse.js": "^3.1.0",
"graphql": "^15.0.0",
"handlebars": "^4.2.0",
"leaflet": "^1.5.1",
"leaflet-lasso": "^2.0.4",
Expand All @@ -53,6 +55,7 @@
"react-dom": "^16.8.0",
"react-dom-confetti": "^0.0.10",
"react-dropzone": "^10.1.5",
"react-elastic-carousel": "^0.4.1",
"react-grid-layout": "^0.16.6",
"react-intl": "^2.9.0",
"react-intl-formatted-duration": "^3.0.0",
Expand All @@ -79,6 +82,7 @@
"remark-react": "^6.0.0",
"route-matcher": "^0.1.0",
"stale-lru-cache": "^5.1.1",
"styled-components": "^5.1.0",
"uuid": "^3.3.2",
"uuid-time": "^1.0.0",
"vkbeautify": "^0.99.3",
Expand Down
10 changes: 8 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom'
import { Switch, Route, Redirect } from 'react-router-dom'
import { withRouter } from 'react-router'
import Home from './pages/Home/Home'
import Profile from './pages/Profile/Profile'
Expand Down Expand Up @@ -48,6 +48,12 @@ const CurrentVirtualChallengeTaskPane =
WithVirtualChallenge(WithCurrentTask(TaskPane))
const VirtualChallengePane = WithVirtualChallenge(ChallengePane)
const ErrorPane = WithExternalError(ChallengePane)
const HomeOrDashboard = props => {
const goHome = sessionStorage.getItem('goHome')
const loggedIn = localStorage.getItem('isLoggedIn')
sessionStorage.removeItem('goHome')
return (loggedIn && !goHome) ? <Redirect to="/dashboard" /> : <Home />
}

/**
* App represents the top level component of the application. It renders a
Expand Down Expand Up @@ -82,7 +88,7 @@ export class App extends Component {

<main role="main" className="mr-bg-white mr-text-grey">
<Switch>
<CachedRoute exact path='/' component={Home} />
<CachedRoute exact path='/' component={HomeOrDashboard} />
<CachedRoute exact path='/browse/challenges' component={ChallengePane} />
<CachedRoute path='/browse/challenges/:challengeId' component={ChallengeDetail} />
<CachedRoute path='/browse/projects/:projectId' component={ProjectDetail} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const WithChallengeMetrics = function(WrappedComponent, applyFilters = false) {
if (challengeId && props.fetchChallengeActions) {
this.setState({loading: true})
const criteria = {filters: _get(props.searchFilters, 'filters')}
criteria.invertFields = _get(props.searchCriteria, 'filters.invertFields')

if (props.includeTaskStatuses && this.isFiltering(props.includeTaskStatuses)) {
criteria.status = _keys(_pickBy(props.includeTaskStatuses)).join(',')
Expand Down Expand Up @@ -80,24 +81,29 @@ const WithChallengeMetrics = function(WrappedComponent, applyFilters = false) {

if (challengeId) {
if (challengeId !== _get(this.props.challenge, 'id')) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (this.props.includeTaskStatuses !== prevProps.includeTaskStatuses) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (this.props.includeTaskReviewStatuses !== prevProps.includeTaskReviewStatuses) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (this.props.includeTaskPriorities !== prevProps.includeTaskPriorities) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (!_isEqual(_get(this.props.searchFilters, 'filters'),
_get(prevProps.searchFilters, 'filters'))) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (!_isEqual(_get(this.props.searchCriteria, 'filters.invertFields'),
_get(prevProps.searchCriteria, 'filters.invertFields'))) {
return this.updateMetrics(this.props)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const WithChallengeReviewMetrics = function(WrappedComponent) {
_merge(filters, _get(props.searchFilters, 'filters'))

const criteria = {filters}
criteria.invertFields = _get(props.searchCriteria, 'filters.invertFields')

if (props.includeTaskStatuses) {
criteria.filters.status = _keys(_pickBy(props.includeTaskStatuses)).join(',')
Expand All @@ -50,23 +51,23 @@ export const WithChallengeReviewMetrics = function(WrappedComponent) {

componentDidUpdate(prevProps) {
if (_get(prevProps.challenge, 'id') !== _get(this.props.challenge, 'id')) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (this.props.includeTaskStatuses !== prevProps.includeTaskStatuses) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (this.props.includeTaskReviewStatuses !== prevProps.includeTaskReviewStatuses) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (this.props.includeTaskPriorities !== prevProps.includeTaskPriorities) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}

if (_get(this.props.searchFilters, 'filters') !== _get(prevProps.searchFilters, 'filters')) {
this.updateMetrics(this.props)
return this.updateMetrics(this.props)
}
}

Expand All @@ -82,7 +83,8 @@ export const WithChallengeReviewMetrics = function(WrappedComponent) {

const mapStateToProps = state => (
{reviewMetrics: _get(state, 'currentReviewTasks.metrics.reviewActions'),
reviewMetricsByPriority: _get(state, 'currentReviewTasks.metrics.priorityReviewActions')}
reviewMetricsByPriority: _get(state, 'currentReviewTasks.metrics.priorityReviewActions'),
reviewMetricsByTaskStatus: _get(state, 'currentReviewTasks.metrics.statusReviewActions') }
)

const mapDispatchToProps = (dispatch, ownProps) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import _get from 'lodash/get'
import _find from 'lodash/find'
import _values from 'lodash/values'
import { fetchChallengeSnapshotList,
recordChallengeSnapshot } from '../../../../services/Challenge/ChallengeSnapshot'
recordChallengeSnapshot,
removeChallengeSnapshot } from '../../../../services/Challenge/ChallengeSnapshot'
import WithComputedMetrics from '../../HOCs/WithComputedMetrics/WithComputedMetrics'

const WithChallengeSnapshots = function(WrappedComponent, applyFilters = false) {
Expand Down Expand Up @@ -40,6 +41,15 @@ const WithChallengeSnapshots = function(WrappedComponent, applyFilters = false)
}
}

deleteSnapshot(props, snapshotId) {
if (snapshotId) {
this.setState({loading: true})
removeChallengeSnapshot(snapshotId).then(() => {
this.updateSnapshots(props)
})
}
}

setSelectedSnapshot = (snapshotId) => {
if (snapshotId) {
const snapshot = _find(this.state.snapshotList, s => s.id === snapshotId)
Expand Down Expand Up @@ -79,6 +89,7 @@ const WithChallengeSnapshots = function(WrappedComponent, applyFilters = false)
return <WrappedComponent
{...this.props}
recordSnapshot={() => this.recordSnapshot(this.props)}
deleteSnapshot={(snapshotId) => this.deleteSnapshot(this.props, snapshotId)}
snapshotList={this.state.snapshotList}
setSelectedSnapshot={this.setSelectedSnapshot}
currentMetrics={this.props.taskMetrics}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import { fetchManageableProjects,
fetchProject,
fetchProjectsById,
addProjectManager,
setProjectManagerGroupType,
setProjectManagerRole,
fetchProjectManagers,
removeProjectManager,
saveProject,
removeProject,
deleteProject} from '../../../../services/Project/Project'
import { setTeamProjectRole, removeTeamFromProject }
from '../../../../services/Team/Team'
import { addChallenge,
removeChallenge } from '../../../../services/Project/VirtualProject'
import { fetchProjectChallengeListing }
Expand Down Expand Up @@ -123,9 +125,11 @@ const mapDispatchToProps = dispatch => {
fetchProjectChallengeListing,
saveProject,
addProjectManager,
setTeamProjectRole,
fetchProjectManagers,
setProjectManagerGroupType,
setProjectManagerRole,
removeProjectManager,
removeTeamFromProject,
addChallenge,
removeChallenge,
}, dispatch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export const WithProjectReviewMetrics = function(WrappedComponent) {

const mapStateToProps = state => (
{reviewMetrics: _get(state, 'currentReviewTasks.metrics.reviewActions'),
reviewMetricsByPriority: _get(state, 'currentReviewTasks.metrics.priorityReviewActions')}
reviewMetricsByPriority: _get(state, 'currentReviewTasks.metrics.priorityReviewActions'),
reviewMetricsByTaskStatus: _get(state, 'currentReviewTasks.metrics.statusReviewActions') }
)

const mapDispatchToProps = (dispatch, ownProps) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { FormattedMessage } from 'react-intl'
import { Link } from 'react-router-dom'
import { CopyToClipboard } from 'react-copy-to-clipboard'
import _get from 'lodash/get'
import _isObject from 'lodash/isObject'
import _isFinite from 'lodash/isFinite'
Expand Down Expand Up @@ -65,7 +67,17 @@ export default class ChallengeControls extends Component {
<FormattedMessage {...messages.startChallengeLabel} />
</Link>
}

{this.props.includeCopyURL &&
<CopyToClipboard
text={`${process.env.REACT_APP_URL}/browse/challenges/${this.props.challenge.id}`}
onCopy={this.props.onControlComplete}>
<div
className={classNames(this.props.controlClassName,
"mr-text-green-lighter hover:mr-text-white mr-cursor-pointer")}>
<FormattedMessage {...messages.copyChallengeURLLabel} />
</div>
</CopyToClipboard>
}
{!inVirtualProject && manager.canWriteProject(parent) &&
<React.Fragment>
<Link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import TaskDeletingProgress
from '../TaskDeletingProgress/TaskDeletingProgress'
import ChallengeControls from '../ChallengeCard/ChallengeControls'
import BusySpinner from '../../../BusySpinner/BusySpinner'
import ChallengeNameLink from '../../../ChallengeNameLink/ChallengeNameLink'
import manageMessages from '../Messages'
import './ChallengeDashboard.scss'

Expand Down Expand Up @@ -104,10 +105,8 @@ export class ChallengeDashboard extends Component {
</li>
<li className="is-active">
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a aria-current="page">
{this.props.challenge.name}
{this.props.loadingChallenge && <BusySpinner inline />}
</a>
<ChallengeNameLink {...this.props} showBelow />
{this.props.loadingChallenge && <BusySpinner inline />}
</li>
</ul>
</nav>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export default defineMessages({
defaultMessage: "Clone Challenge",
},

copyChallengeURLLabel: {
id: "Admin.ChallengeAnalysisTable.controls.copyChallengeURL.label",
defaultMessage: "Copy URL",
},

deleteChallengeLabel: {
id: "Admin.Challenge.controls.delete.label",
defaultMessage: "Delete Challenge",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default class ChallengeList extends Component {
hideTallyControl={this.props.hideTallyControl}
showProjectName={this.props.project.isVirtual}
link={link}
includeCopyURL
/>
)
}),
Expand Down
Loading

0 comments on commit 587d7cb

Please sign in to comment.