Skip to content

Commit

Permalink
Restrict editor programs for mapping and validation stages
Browse files Browse the repository at this point in the history
>**This PR includes a db migration**

Related Issue: hotosm#893

* Added list of editors in the `Settings` menu of a project-edit page where a project manager can select permitted editors for each editing stage
![Screen Shot 2019-03-21 at 10 37 50 AM](https://user-images.githubusercontent.com/9849118/54944416-10f7a880-4ef9-11e9-8824-6867463ebf3c.png)

* Updated the editor dropdown for to populate only with the permitted editors
![Screen Shot 2019-03-25 at 12 28 35 PM](https://user-images.githubusercontent.com/9849118/54944636-90857780-4ef9-11e9-9797-c8bd7a727e72.png)
  • Loading branch information
Zack LaVergne committed Apr 10, 2019
1 parent 79dc2ff commit dcc5d7e
Show file tree
Hide file tree
Showing 13 changed files with 385 additions and 32 deletions.
2 changes: 2 additions & 0 deletions Dockerfile
Expand Up @@ -12,6 +12,8 @@ RUN apt-get update \

WORKDIR /src

WORKDIR /src

# Add and install Python modules
ADD requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
Expand Down
91 changes: 91 additions & 0 deletions client/app/admin/edit-project/edit-project.controller.js
Expand Up @@ -40,6 +40,22 @@
other: false
};

// Editors for mapping
vm.mappingEditors = {
id: false,
josm: false,
potlatch2: false,
fieldpapers: false
};

// Editors for validation
vm.validationEditors = {
id: false,
josm: false,
potlatch2: false,
fieldpapers: false
};

// Tags
vm.organisationTags = [];
vm.campaignsTags = [];
Expand Down Expand Up @@ -82,6 +98,9 @@
// Form
vm.form = {};

// User role
vm.userRole = '';

activate();

function activate() {
Expand All @@ -99,6 +118,7 @@
if (session){
var resultsPromise = accountService.getUser(session.username);
resultsPromise.then(function (user) {
vm.userRole = user.role;
// Returned the user successfully. Check the user's role
if (user.role !== 'PROJECT_MANAGER' && user.role !== 'ADMIN'){
$location.path('/');
Expand Down Expand Up @@ -167,6 +187,8 @@
// Prepare the data for sending to API by removing any locales with no fields
if (!requiredFieldsMissing && vm.editForm.$valid){
vm.project.mappingTypes = getMappingTypesArray();
vm.project.mappingEditors = getMappingEditorsArray();
vm.project.validationEditors = getValidationEditorsArray();
vm.project.josmPreset = vm.josmPreset;
for (var i = 0; i < vm.project.projectInfoLocales.length; i++){
var info = vm.project.projectInfoLocales[i];
Expand Down Expand Up @@ -790,6 +812,8 @@
vm.project.dueDate = new Date(vm.project.dueDate);
}
populateTypesOfMapping();
populateEditorsForMapping();
populateEditorsForValidation();
addAOIToMap();
addPriorityAreasToMap();
if (vm.project.organisationTag) {
Expand Down Expand Up @@ -928,6 +952,73 @@
return mappingTypesArray;
}

/**
* Populate the mapping editor fields by checking which tags exist
* in the mappingEditors array on the project
*/
function populateEditorsForMapping(){
if (vm.project.mappingEditors) {
vm.mappingEditors.id = vm.project.mappingEditors.indexOf("ID") != -1;
vm.mappingEditors.josm = vm.project.mappingEditors.indexOf("JOSM") != -1;
vm.mappingEditors.potlatch2 = vm.project.mappingEditors.indexOf("POTLATCH_2") != -1;
vm.mappingEditors.fieldpapers = vm.project.mappingEditors.indexOf("FIELD_PAPERS") != -1;
}
}

/**
* Get map editors in array
*/
function getMappingEditorsArray(){
var mappingEditorsArray = [];
if (vm.mappingEditors.id){
mappingEditorsArray.push("ID");
}
if (vm.mappingEditors.josm){
mappingEditorsArray.push("JOSM");
}
if (vm.mappingEditors.potlatch2) {
mappingEditorsArray.push("POTLATCH_2");
}
if (vm.mappingEditors.fieldpapers){
mappingEditorsArray.push("FIELD_PAPERS");
}
return mappingEditorsArray;
}


/**
* Populate the validation editor fields by checking which tags exist
* in the validationEditors array on the project
*/
function populateEditorsForValidation(){
if (vm.project.validationEditors) {
vm.validationEditors.id = vm.project.validationEditors.indexOf("ID") != -1;
vm.validationEditors.josm = vm.project.validationEditors.indexOf("JOSM") != -1;
vm.validationEditors.potlatch2 = vm.project.validationEditors.indexOf("POTLATCH_2") != -1;
vm.validationEditors.fieldpapers = vm.project.validationEditors.indexOf("FIELD_PAPERS") != -1;
}
}

/**
* Get validate editors in array
*/
function getValidationEditorsArray(){
var validationEditorsArray = [];
if (vm.validationEditors.id){
validationEditorsArray.push("ID");
}
if (vm.validationEditors.josm){
validationEditorsArray.push("JOSM");
}
if (vm.validationEditors.potlatch2) {
validationEditorsArray.push("POTLATCH_2");
}
if (vm.validationEditors.fieldpapers){
validationEditorsArray.push("FIELD_PAPERS");
}
return validationEditorsArray;
}

/**
* Set organisation tags
*/
Expand Down
30 changes: 30 additions & 0 deletions client/app/admin/edit-project/edit-project.html
Expand Up @@ -447,6 +447,36 @@ <h1 class="section__aside-title">{{ 'In this area' | translate }}</h1>
</li>
</ul>
</div>
<div class="form__group form__group--section">
<label class="form__label">{{ 'Editors for mapping' | translate }}</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.mappingEditors.id"/>{{ 'iD Editor' | translate }}
</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.mappingEditors.josm"/>{{ 'JOSM' | translate }}
</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.mappingEditors.potlatch2"/>{{ 'Potlatch 2' | translate }}
</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.mappingEditors.fieldpapers"/>{{ 'Field Papers' | translate }}
</label>
</div>
<div class="form__group form__group--section">
<label class="form__label">{{ 'Editors for validation' | translate }}</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.validationEditors.id"/>{{ 'iD Editor' | translate }}
</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.validationEditors.josm"/>{{ 'JOSM' | translate }}
</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.validationEditors.potlatch2"/>{{ 'Potlatch 2' | translate }}
</label>
<label class="form__option">
<input type="checkbox" ng-model="editProjectCtrl.validationEditors.fieldpapers"/>{{ 'Field Papers' | translate }}
</label>
</div>
</fieldset>
</div>
<!--/ settings -->
Expand Down
74 changes: 67 additions & 7 deletions client/app/project/project.controller.js
Expand Up @@ -59,7 +59,10 @@

//editor
vm.editorStartError = '';
vm.selectedEditor = 'ideditor';
vm.selectedMappingEditor = 'ideditor';
vm.selectedValidationEditor = 'josm';
vm.mappingEditors = [];
vm.validationEditors = [];

//interaction
vm.selectInteraction = null;
Expand Down Expand Up @@ -99,7 +102,8 @@
vm.currentTab = 'instructions';
vm.mappingStep = 'selecting';
vm.validatingStep = 'selecting';
vm.selectedEditor = 'ideditor'; // default to iD editor
vm.selectedMappingEditor = 'ideditor'; // default to iD editor
vm.selectedValidationEditor = 'josm';
mapService.createOSMMap('map');
mapService.addOverviewMap();
vm.map = mapService.getOSMMap();
Expand Down Expand Up @@ -137,7 +141,9 @@
}, 10000);

// set up the preferred editor from user preferences
vm.selectedEditor = userPreferencesService.getFavouriteEditor();

vm.selectedMappingEditor = userPreferencesService.getFavouriteEditor();
vm.selectedValidationEditor = userPreferencesService.getFavouriteEditor();
}

// listen for navigation away from the page event and stop the autrefresh timer
Expand Down Expand Up @@ -172,14 +178,15 @@
};

vm.updatePreferedEditor = function () {
userPreferencesService.setFavouriteEditor(vm.selectedEditor);
userPreferencesService.setFavouriteEditor(vm.selectedMappingEditor);
};

/**
* Reset the user's selected editor back to the default
*/
vm.resetSelectedEditor = function() {
vm.selectedEditor = 'ideditor';
vm.selectedMappingEditor = vm.mappingEditors[0].value;
vm.selectedValidationEditor = vm.validationEditors[0].value;
vm.editorStartError = '';
};

Expand Down Expand Up @@ -442,6 +449,10 @@
resultsPromise.then(function (data) {
//project returned successfully
vm.projectData = data;
vm.mappingEditors = createEditorList(vm.projectData.mappingEditors);
vm.selectedMappingEditor = vm.mappingEditors[0].value;
vm.validationEditors = createEditorList(vm.projectData.validationEditors);
vm.selectedValidationEditor = vm.validationEditors[0].value;
vm.userCanMap = vm.user && projectService.userCanMapProject(vm.user.mappingLevel, vm.projectData.mapperLevel, vm.projectData.enforceMapperLevel);
vm.userCanValidate = vm.user && projectService.userCanValidateProject(vm.user.role, vm.projectData.enforceValidatorRole);
addAoiToMap(vm.projectData.areaOfInterest);
Expand All @@ -450,6 +461,22 @@
// Add OpenLayers interactions
addInteractions();


// set up the preferred editor from user preferences
// check if their preferred editor is in the allowed editors otherwise, pick first of allowed editors
if (vm.mappingEditors.filter(function(e) { return e.value === userPreferencesService.getFavouriteEditor() }).length > 0) {
vm.selectedMappingEditor = userPreferencesService.getFavouriteEditor();
}
else {
vm.selectedMappingEditor = vm.mappingEditors[0].value;
}
if (vm.validationEditors.filter(function(e) { return e.value === userPreferencesService.getFavouriteEditor() }).length > 0) {
vm.selectedValidationEditor = userPreferencesService.getFavouriteEditor();
}
else {
vm.selectedValidationEditor = vm.validationEditors[0].value;
}

//add a layer for users locked tasks
if (!vm.lockedByCurrentUserVectorLayer) {
var source = new ol.source.Vector();
Expand Down Expand Up @@ -876,7 +903,7 @@
//
// Use of the title attribute is a hack, but the sanitizer allows it
// through and it's important these comments get properly sanitized.
if (event.target.tagName === 'A' && vm.selectedEditor === 'josm') {
if (event.target.tagName === 'A' && (vm.selectedMappingEditor === 'josm' || vm.selectedValidationEditor === 'josm')) {
var title = event.target.getAttribute("title");
var editorCommand = null;
var params = null;
Expand Down Expand Up @@ -1555,7 +1582,7 @@

// Try sending to JOSM if it's user's chosen editor, otherwise Overpass Turbo.
var overpassApiURL = 'https://overpass-api.de/api/interpreter?data=' + encodeURIComponent(query);
if (vm.selectedEditor === 'josm') {
if (vm.selectedMappingEditor === 'josm' || vm.selectedValidationEditor === 'josm') {
editorService.sendJOSMCmd('http://127.0.0.1:8111/import', {
new_layer: 'true',
layer_name: adjustedDateString,
Expand Down Expand Up @@ -1851,6 +1878,39 @@
// especially when there are spaces in the username
return '@[' + item.username + ']';
};

/**
* Creates json objects for editors
* @params editors
*/
function createEditorList(editors) {
var result = [];
if (editors.includes("ID")) {
result.push({
"name": "iD Editor",
"value": "ideditor"
});
}
if (editors.includes("JOSM")) {
result.push({
"name": "JOSM",
"value": "josm"
});
}
if (editors.includes("POTLATCH_2")) {
result.push({
"name": "Potlatch 2",
"value": "potlatch2"
});
}
if (editors.includes("FIELD_PAPERS")) {
result.push({
"name": "Field Papers",
"value": "fieldpapers"
});
}
return result;
};
}
})
();

0 comments on commit dcc5d7e

Please sign in to comment.