Skip to content

Commit

Permalink
Merge pull request #829 from osmlab/prerelease
Browse files Browse the repository at this point in the history
v3.3.3 release
  • Loading branch information
nrotstan authored Jul 25, 2019
2 parents d628e51 + 72e277a commit 777ad08
Show file tree
Hide file tree
Showing 117 changed files with 8,053 additions and 4,454 deletions.
7 changes: 4 additions & 3 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ REACT_APP_DEFAULT_MAP_LAYER_ID='MAPNIK'
# use, you need to define them in the `src/customLayers.json` file instead.
REACT_APP_ADDITIONAL_INDEX_LAYERS='tf-cycle'

# URL for Bing map layer tile server
REACT_APP_BING_MAP_TILESERVER_URL='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'

# Any API keys you wish to use for specific map layers. Should be structured as
# a JSON object with each key being the layer id as identified in the [OSM
# Editor Layer index](https://github.com/osmlab/editor-layer-index) (or the id
Expand All @@ -84,6 +81,10 @@ REACT_APP_BING_MAP_TILESERVER_URL='https://server.arcgisonline.com/ArcGIS/rest/s
# '{"tf-cycle": {"name": "apikey", "value": "yourapikey"}, "Mapbox": {"name": "access_token", "value": "yourapikey"}}'}'
REACT_APP_MAP_LAYER_API_KEYS=''

# Mapillary client id. If not provided, the Mapillary image map layer will be
# disabled.
REACT_APP_MAPILLARY_API_KEY=''

# The number of minutes to offset the attic query date to allow for the delay in
# Overpass receiving the data.
REACT_APP_ATTIC_QUERY_OFFSET_MINUTES = 10
Expand Down
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@ The format is based on
This project adheres to
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [v3.3.3] - 2019-07-24
### Added
- MapRoulette-specific tagging support for tasks ("MR Tags")
- Option to select next nearby task to work on from map of nearby tasks
- Export of challenges as GeoJSON from Create & Manage
- Honor active filters when exporting CSV and GeoJSON files
- Review Metrics widget for Create & Manage dashboards
- Toggle for inclusion of challenges in metrics in Create & Manage area
- Completion-progress indicators below each challenge in Create & Manage
- Show name of challenge parent project in virtual-project challenge listings
- Improved Mapillary integration and official Mapillary image viewer
- "All Time" duration option to Review Stats
- [internal] Upgrade various package dependencies, including React

### Fixed
- Bing map layer showing incorrect imagery
- Malfunctioning reviewed-on date filter on Tasks Review table
- Retrieval of next nearby task not honoring task priority
- JOSM editing bounds in task review inconsistent with task completion
- Task map in Create & Manage not resetting when all filters cleared
- Broken user profile images
- Broken links to top-challenges on leaderboards in some cases
- Insufficient Overpass timeout on attic queries
- Various minor visual fixes and adjustments

### Changed
- JOSM attic layer policy from locked to no upload and no download

### Removed
- Broken heatmap from Create & Manage project dashboard


## [v3.3.2] - 2019-06-20
### Added
- Virtual Projects
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,17 @@ file for documentation). For custom layers, an API key can also simply be
included in the specified layer url in `src/customLayers.json` if that is
simpler.

### Enabling the Mapillary Map Layer

MapRoulette has built-in support for a Mapillary map layer during task
completion, allowing the mapper to make of use of available street-level
imagery. To enable the layer, simply set the `REACT_APP_MAPILLARY_API_KEY` .env
key to your Mapillary client id and restart your dev server (or rebuild your
dev front-end for staging/production). If you don't have a client id, you can
set one up through the
[Mapillary Developer Tools](https://www.mapillary.com/developer)


# Development Notes

The project was bootstrapped with
Expand Down
33 changes: 20 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "maproulette3",
"version": "3.3.2",
"version": "3.3.3",
"private": true,
"dependencies": {
"@mapbox/geojsonhint": "^2.0.1",
Expand All @@ -23,41 +23,44 @@
"downshift": "^2.0.3",
"file-saver": "^2.0.2",
"fuse.js": "^3.1.0",
"leaflet": "^1.3.0",
"leaflet-vectoricon": "^0.2.0",
"leaflet.markercluster": "^1.3.0",
"leaflet": "^1.5.1",
"leaflet-vectoricon": "https://github.com/nrotstan/Leaflet.VectorIcon.git#with-viewbox",
"leaflet.markercluster": "^1.4.1",
"localforage": "^1.5.2",
"mapillary-js": "^2.18.0",
"node-sass": "^4.11.0",
"normalize.css": "^7.0.0",
"normalizr": "^3.2.3",
"parse-link-header": "^1.0.1",
"piwik-react-router": "^0.12.1",
"prop-types": "^15.6.0",
"query-string": "^5.1.0",
"react": "16.3.2",
"react": "^16.8.0",
"react-animate-height": "^2.0.7",
"react-burger-menu": "^2.4.4",
"react-calendar-heatmap": "^1.6.3",
"react-clickout": "^3.0.8",
"react-copy-to-clipboard": "^5.0.1",
"react-datepicker": "^2.3.0",
"react-delayed": "^0.2.0",
"react-dom": "^16.0.0",
"react-dom": "^16.8.0",
"react-dom-confetti": "^0.0.10",
"react-dropzone": "^4.2.3",
"react-dropzone": "^10.1.5",
"react-grid-layout": "^0.16.6",
"react-intl": "^2.8.0",
"react-intl": "^2.9.0",
"react-intl-formatted-duration": "^3.0.0",
"react-jsonschema-form": "1.5.0",
"react-jsonschema-form-async": "^0.2.0",
"react-leaflet": "^1.8.0",
"react-leaflet-markercluster": "^1.1.7",
"react-leaflet": "^2.4.0",
"react-leaflet-bing": "^4.1.0",
"react-leaflet-markercluster": "^2.0.0-rc3",
"react-onclickoutside": "^6.6.3",
"react-redux": "^5.0.5",
"react-responsive": "^4.1.0",
"react-router-dom": "^4.2.2",
"react-scripts": "2.1.8",
"react-scripts": "3.0.1",
"react-share": "^1.16.0",
"react-syntax-highlighter": "^7.0.2",
"react-syntax-highlighter": "^10.3.0",
"react-table": "^6.7.6",
"react-tagsinput": "^3.19.0",
"react-transition-group": "^2.2.1",
Expand Down Expand Up @@ -108,5 +111,9 @@
"not dead",
"not ie <= 11",
"not op_mini all"
]
],
"resolutions": {
"browserslist": "4.6.2",
"caniuse-lite": "1.0.30000974"
}
}
Binary file removed public/assets/images/user_no_image.png
Binary file not shown.
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ=="
crossorigin=""/>
<link href='https://unpkg.com/[email protected]/dist/mapillary.min.css' rel='stylesheet' />

<!--
Notice the use of %PUBLIC_URL% in the tags above.
Expand Down
41 changes: 40 additions & 1 deletion src/components/AdminPane/AdminPane.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@
}
}

.item-tally-toggle {
max-width: 50px;
float: right;
margin-left: 18px;
margin-right: 10px;
margin-top: 10px;

svg.icon {
height: 18px;
width: auto;
fill: $grey-lightest;
vertical-align: middle;

&.turnOff {
fill: $blue;
}

&.partialOn {
fill: $blue;
opacity: 0.5;
}
}
}

.tabs {
ul {
border-bottom: 2px solid $grey-lightest-less;
Expand Down Expand Up @@ -277,7 +301,7 @@
}
}

.column.item-pinned {
.item-pinned {
max-width: 50px;

svg.icon {
Expand All @@ -293,6 +317,21 @@
}
}

.item-tallied {
max-width: 50px;

svg.icon {
height: 18px;
width: auto;
fill: $grey-lightest;
vertical-align: middle;

&.enabled {
fill: $blue;
}
}
}

.column.item-id {
max-width: 100px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import _sortBy from 'lodash/sortBy'
import _reverse from 'lodash/reverse'
import parse from 'date-fns/parse'
import WithComputedMetrics from '../../HOCs/WithComputedMetrics/WithComputedMetrics'
import WithDashboardEntityFilter
from '../../HOCs/WithDashboardEntityFilter/WithDashboardEntityFilter'

import { TaskStatus }
from '../../../../services/Task/TaskStatus/TaskStatus'

Expand Down Expand Up @@ -71,5 +74,21 @@ const WithChallengeMetrics = function(WrappedComponent) {
}
}

export const includeChallengeInMetrics = function(challenge, manager, tallied, challengeFilters, props) {
const tallyMarks = tallied(_get(props.project, 'id'))
if (tallyMarks && tallyMarks.length > 0 && tallyMarks.indexOf(challenge.id) === -1) {
return false
}

return true
}

export default WrappedComponent =>
WithComputedMetrics(injectIntl(WithChallengeMetrics(WrappedComponent)))
WithDashboardEntityFilter(
WithComputedMetrics(injectIntl(WithChallengeMetrics(WrappedComponent))),
'challenge',
'challenges',
'talliedChallenges',
'challenges',
includeChallengeInMetrics
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
import _omit from 'lodash/omit'
import _get from 'lodash/get'
import { fetchReviewMetrics, ReviewTasksType }
from '../../../../services/Task/TaskReview/TaskReview'
import WithCurrentUser from '../../../HOCs/WithCurrentUser/WithCurrentUser'

/**
* WithChallengeReviewMetrics retrieves review metrics for the challenge tasks
*
* @author [Kelli Rotstan](https://github.com/krotstan)
*/
export const WithChallengeReviewMetrics = function(WrappedComponent) {
return class extends Component {
state = {
loading: false
}

updateMetrics(props) {
this.setState({loading: true})

props.updateReviewMetrics(_get(props.user, 'id'), _get(props.challenge, 'id')).then(() => {
this.setState({loading: false})
})
}

componentDidMount() {
this.updateMetrics(this.props)
}

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

render() {
return (
<WrappedComponent reviewMetrics = {this.props.reviewMetrics}
loading={this.state.loading}
{..._omit(this.props, ['updateReviewMetrics'])} />)
}
}
}

const mapStateToProps = state => ({ reviewMetrics: _get(state, 'currentReviewTasks.metrics') })

const mapDispatchToProps = (dispatch, ownProps) => ({
updateReviewMetrics: (userId, challengeId) => {
return dispatch(fetchReviewMetrics(userId, ReviewTasksType.allReviewedTasks, {filters:{challengeId}}))
},
})

export default WrappedComponent =>
connect(mapStateToProps, mapDispatchToProps)(WithCurrentUser(WithChallengeReviewMetrics(WrappedComponent)))
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const WithDashboardEntityFilter = function(WrappedComponent,
_get(this.props.currentConfiguration.filters, this.filterFieldName(), {})

const filteredDashboardEntities = _filter(this.props[itemsProp], entities =>
passesFilterFunction(entities, manager, this.props[pinsProp], filters)
passesFilterFunction(entities, manager, this.props[pinsProp], filters, this.props)
)

// Generate prop names based on filter type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { fetchProjectChallengeListing }
import WithCurrentUser from '../../../HOCs/WithCurrentUser/WithCurrentUser'
import AsManager from '../../../../interactions/User/AsManager'
import WithPinned from '../../HOCs/WithPinned/WithPinned'
import WithTallied from '../../HOCs/WithTallied/WithTallied'

/**
* WithManageableProjects makes available to the WrappedComponent all the
Expand Down Expand Up @@ -140,5 +141,8 @@ const mapDispatchToProps = dispatch => {

export default (WrappedComponent, includeChallenges) =>
connect(mapStateToProps, mapDispatchToProps)(
WithCurrentUser(WithPinned(WithManageableProjects(WrappedComponent, includeChallenges)))
WithCurrentUser(
WithPinned(
WithTallied(
WithManageableProjects(WrappedComponent, includeChallenges))))
)
Loading

0 comments on commit 777ad08

Please sign in to comment.