Skip to content

Commit

Permalink
Merge pull request #1053 from ushahidi/release/comrades-and-fixes
Browse files Browse the repository at this point in the history
Bring master up to date with COMRADES changes and some fixes
  • Loading branch information
rjmackay authored Apr 5, 2018
2 parents ecedb9f + 20d0486 commit 9329073
Show file tree
Hide file tree
Showing 42 changed files with 1,156 additions and 308 deletions.
1 change: 1 addition & 0 deletions app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var backendUrl = window.ushahidi.backendUrl = (window.ushahidi.backendUrl || BAC
apiUrl = window.ushahidi.apiUrl = backendUrl + '/api/v3',
platform_websocket_redis_adapter_url = window.ushahidi.platform_websocket_redis_adapter_url || '',
claimedAnonymousScopes = [
'apikeys',
'posts',
'media',
'forms',
Expand Down
1 change: 1 addition & 0 deletions app/common/common-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ angular.module('ushahidi.common', [
.directive('ushSlider', require('./notifications/slider.directive.js'))

// API Endpoint wrappers
.service('ApiKeyEndpoint', require('./services/endpoints/apikey.js'))
.service('ConfigEndpoint', require('./services/endpoints/config.js'))
.service('UserEndpoint', require('./services/endpoints/user-endpoint.js'))
.service('FormEndpoint', require('./services/endpoints/form.js'))
Expand Down
5 changes: 4 additions & 1 deletion app/common/directives/add-category.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ function AddCategoryDirective() {
scope: {
formId: '=',
attribute: '=',
postValue: '='
postValue: '=',
available: '='
},
controller: AddCategoryController,
template: require('./add-category.html')
Expand Down Expand Up @@ -38,6 +39,7 @@ function AddCategoryController($rootScope, $scope, TagEndpoint, FormAttributeEnd
$scope.showInput = !$scope.showInput;
};


$scope.saveCategory = function ($event) {
$event.preventDefault();
$scope.category.tag = $scope.categoryName;
Expand All @@ -60,6 +62,7 @@ function AddCategoryController($rootScope, $scope, TagEndpoint, FormAttributeEnd
$scope.categoryName = '';
});
Notify.notify('category added', {response: response});
$scope.available.push.apply($scope.available, response);
}

}, function (errorResponse) {
Expand Down
107 changes: 65 additions & 42 deletions app/common/directives/category-selector.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ function CategorySelectorDirective() {
return {
restrict: 'E',
scope: {
available: '=',
selected: '=',
form: '='
enableParents: '=',
form: '=',
available: '='
},
controller: CategorySelectorController,
template: require('./category-selector.html')
Expand All @@ -20,51 +21,47 @@ function CategorySelectorController($scope, _) {
$scope.selectAll = selectAll;
$scope.selectChild = selectChild;
$scope.selectParent = selectParent;
$scope.selectedParents = [];
$scope.disabledCategories = [];
$scope.changeCategories = changeCategories;

activate();
$scope.selectAllEnabled = function () {
if ($scope.enableParents) {
return $scope.selected.length === $scope.available.length;
} else {
return ($scope.selected.length + $scope.selectedParents.length) === $scope.available.length;
}
};

function activate() {
// remove default null value when creating a new post
if ($scope.selected[0] === null) {
$scope.selected = [];
}
$scope.categories = formatCategories();

// filter out child categories posing as available parent
$scope.categories = _.filter($scope.categories, function (category) {
return category.parent_id === null;
});
$scope.categories = [];

$scope.categories = $scope.available;
// making sure no children are selected without their parents
$scope.changeCategories();
}

function formatCategories() {
return _.each($scope.available, function (category) {
if (category.children.length > 0) {
category.children = _.chain(category.children)
.map(function (child) {
return _.findWhere($scope.available, {id: child.id});
})
.filter()
.value();
}
});
}

function selectAll() {
if ($scope.form) {
// if used in a form, add the ng-dirty-class to categories.
$scope.form.$setDirty();
}

if ($scope.available.length === $scope.selected.length) {
$scope.selected.length = [];
if ($scope.selectAllEnabled()) {
$scope.selected.splice(0, $scope.selected.length);
$scope.selectedParents.splice(0, $scope.selectedParents.length);
} else {
_.each($scope.available, function (category) {
if (!_.contains($scope.selected, category.id)) {
$scope.selected.push(category.id);
var isParentWithChildren = !category.parent_id && category.children.length > 0;
if (!_.contains($scope.selected, category.id) && !isParentWithChildren) {
$scope.selected.push.apply($scope.selected, [category.id]);
} else if (isParentWithChildren && !_.contains($scope.selectedParents, category.id)) {
$scope.selectedParents.push.apply($scope.selectedParents, [category.id]);
}
});
}
Expand Down Expand Up @@ -102,25 +99,51 @@ function CategorySelectorController($scope, _) {

function changeCategories() {
_.each($scope.categories, function (category) {
var selectedChildren = _.chain(category.children)
.pluck('id')
.intersection($scope.selected)
.value();

// If children are selected, add to disabled categories
if (selectedChildren.length > 0) {
$scope.disabledCategories[category.id] = true;

// ... and ensure this category is selected
if (!_.contains($scope.selected, category.id)) {
$scope.selected.push(category.id);
}
} else {
// or, if no children are selected
// remove from disabled categories
$scope.disabledCategories[category.id] = false;
var selectedChildren = _.chain(category.children)
.pluck('id')
.intersection($scope.selected)
.value();
var parentIndexSelected = -1;
var isParentWithChildren = !category.parent_id && category.children.length > 0;
// If children are selected, add to disabled categories
if (selectedChildren.length > 0) {
$scope.disabledCategories[category.id] = true;
// ... and ensure this category is selected
if (!_.contains($scope.selectedParents, category.id)) {
$scope.selectedParents.push.apply($scope.selectedParents, [category.id]);
}
if (!_.contains($scope.selected, category.id) && $scope.enableParents === true) {
$scope.selected.push.apply($scope.selected, [category.id]);
}
} else {
var parentIndex = _.findIndex($scope.selectedParents, function (parentId) {
return parentId === category.id;
});
parentIndexSelected = _.findIndex($scope.selected, function (parentId) {
return parentId === category.id;
});
if (parentIndex >= 0) {
$scope.selectedParents.splice(parentIndex, 1);
if ($scope.enableParents === true) {
$scope.selected.splice(parentIndexSelected, 1);
}
}
if (isParentWithChildren) {
$scope.disabledCategories[category.id] = true;
} else {
$scope.disabledCategories[category.id] = false;
}
}

if ($scope.enableParents === false && isParentWithChildren) {
parentIndexSelected = _.findIndex($scope.selected, function (parentId) {
return parentId === category.id;
});
if (parentIndexSelected >= 0) {
$scope.selected.splice(parentIndexSelected, 1);
}
}
});

}
}
11 changes: 10 additions & 1 deletion app/common/directives/category-selector.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<label>
<input
type="checkbox"
ng-checked="available.length === selected.length"
ng-checked="selectAllEnabled()"
ng-click="selectAll()"
>
<em><span translate="category.select_all"></span></em>
Expand All @@ -12,13 +12,22 @@
<div class="form-field checkbox" ng-repeat="(index, category) in categories" ng-class="{ overflow : ($index > 1) }" ng-if="category.parent_id === null">
<label>
<input
ng-show="category.children.length === 0 || enableParents === true"
type="checkbox"
checklist-value="category.id"
ng-disabled="disabledCategories[category.id]"
value="category.id"
checklist-model="selected"
checklist-change="changeCategories()"
>
<input
ng-show="category.children.length > 0 && enableParents === false"
type="checkbox"
checklist-value="category.id"
ng-disabled="true"
value="category.id"
checklist-model="selectedParents"
>
{{ ::category.tag }}
</label>
<div class="form-field checkbox" ng-if="category.children" ng-repeat="child in category.children">
Expand Down
4 changes: 0 additions & 4 deletions app/common/directives/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ angular.module('ushahidi.common.dropdown', ['ui.bootstrap.position'])
$document.bind('keydown', keybindFilter);
}

if (openScope && openScope !== dropdownScope) {
openScope.isOpen = false;
}

openScope = dropdownScope;
};

Expand Down
18 changes: 17 additions & 1 deletion app/common/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"collection": "Collection",
"collections" : "Collections",
"create_collection" : "Create collection",
"export_to_csv" : "Export to CSV",
"export_to_csv" : "Export filtered data",
"create_new" : "Create new",
"create_new_survey" : "Create new survey",
"created_by" : "Created by {{author}}",
Expand Down Expand Up @@ -263,6 +263,9 @@
"require_task_desc" : "Require this task be completed before a post can be visible to the public",
"survey_permissions": "Survey permissions",
"who_can_add": "Who can add to this survey",
"survey_field": "Survey field",
"choose_survey_field": "Choose what should be assigned to each survey field",
"choose_survey_field_desc": "Each of the survey's fields are listed below. Choose the data from your tweets that you'd like to use to populate each of those fields.",
"who_can_contribute_to_task" : "Who can contribute to fields in this task",
"delete" : {
"desc" : "<strong>If you delete this survey</strong>, all of its posts will also be deleted. Proceed with caution.",
Expand Down Expand Up @@ -741,6 +744,7 @@
"webhook": {
"add_webhook" : "Add Role",
"edit_webhook" : "Edit Role",
"uuid" : "Webhook UUID",
"name" : "Name",
"shared_secret" : "Shared Secret",
"url" : "API URL",
Expand Down Expand Up @@ -851,6 +855,8 @@
"saved_map_settings": "Map Settings saved."
},
"settings": {
"api_key" : "API Key",
"api_key_desc" : "The API Key is unique to your deployment, it can be used to allow third party systems to interact with your Ushahidi deployment.",
"appearance" : "Appearance Settings",
"continue" : "Continue",
"current_header" : "Current background image",
Expand Down Expand Up @@ -878,7 +884,14 @@
"plans" : "Plans",
"plan_desc" : "Your deployment's current plan is <strong>{{current_plan}}</strong>."
},
"webhooks": {
"use_webhook_for": "Use webhook for",
"enable_source_destination" : "Enable Source and Destination Fields",
"enable_source_destination_desc" : "This webhook will only be applied to Surveys of the selected type."
},
"data_sources": {
"associate_with_form" : "Import to survey",
"associate_with_form_desc" : "All incoming data from {{provider}} will be used to create responses to the survey you choose",
"data_sources": "Data Sources",
"enable_provider_message" : "Accept survey submissions from this source",
"hint_turn_on_off": "You can configure options for data sources, and then turn sources on and off.",
Expand Down Expand Up @@ -1044,6 +1057,9 @@
"role": "Role"
},
"notify": {
"api_key" : {
"change_question" : "Are you sure you want to change the API Key?"
},
"contact" : {
"save_success" : "Contact saved",
"delete_confirm" : "Do you want to remove your account?",
Expand Down
31 changes: 31 additions & 0 deletions app/common/services/endpoints/apikey.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = [
'$resource',
'$rootScope',
'Util',
function (
$resource,
$rootScope,
Util
) {

var ApiKeyEndpoint = $resource(Util.apiUrl('/apikeys/:id'), {
id: '@id'
}, {
query: {
method: 'GET',
isArray: true,
transformResponse: function (data /*, header*/) {
return Util.transformResponse(data).results;
}
},
get: {
method: 'GET'
},
update: {
method: 'PUT'
}
});

return ApiKeyEndpoint;

}];
20 changes: 20 additions & 0 deletions app/main/posts/common/post-actions.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ function (
},
getStatuses: function () {
return ['published', 'draft', 'archived'];
},
filterPostEditorCategories: function (attributeOptions, categories) {
// adding category-objects attribute-options
return _.chain(attributeOptions)
.map((category) => {
const ret = angular.copy(_.findWhere(categories, {id: category}));
if (ret && ret.children.length > 0) {
ret.children = _.chain(ret.children)
.map((child) => {
if (attributeOptions.find((o) => o === child.id)) {
return _.findWhere(categories, {id: child.id});
}
})
.filter()
.value();
}
return ret;
})
.filter()
.value();
}
};

Expand Down
12 changes: 12 additions & 0 deletions app/main/posts/modify/post-category-editor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<category-selector
enable-parents="false"
selected="selected"
form="form"
available="available"
></category-selector>
<add-category
form-id="formId"
attribute="attribute"
post-value="postValue"
available="available"
></add-category>
23 changes: 23 additions & 0 deletions app/main/posts/modify/post-category-editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = PostCategoryEditorDirective;

PostCategoryEditorDirective.$inject = [];

function PostCategoryEditorDirective() {
return {
restrict: 'E',
scope: {
formId: '=',
attribute: '=',
postValue: '=',
available: '=',
selected: '=',
form: '='
},
controller: PostCategoryEditorController,
template: require('./post-category-editor.html')
};
}
PostCategoryEditorController.$inject = ['$rootScope','$scope', 'TagEndpoint', 'FormAttributeEndpoint', 'Notify', '_'];

function PostCategoryEditorController($rootScope, $scope, TagEndpoint, FormAttributeEndpoint, Notify, _) {
}
Loading

0 comments on commit 9329073

Please sign in to comment.