summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJury Verrigni <jury.verrigni@gmail.com>2017-02-01 12:04:55 +0000
committerAlexander Weidinger <alexwegoo@gmail.com>2017-02-07 00:25:11 +0100
commit6529a8e9d4e668e159825a6476a3504526b487df (patch)
tree23f0acea41c97974b8ff1379897ff03d12258609
parent9523b407cbfc5ed6643d54a9e5cafb000929f129 (diff)
Added sort functionality (visible in settings, bottom left) (#569)
* Added sort functionality (visible in settings, bottom left) * Fallback to fullName if the sort criteria is not set within the contact; displayName is now the default sort criteria * Changing display name based on sort order; sorting takes both first and second name in consideration
-rw-r--r--js/components/contact/contact_controller.js27
-rw-r--r--js/components/contactList/contactList_controller.js8
-rw-r--r--js/components/sortBy/sortBy_controller.js16
-rw-r--r--js/components/sortBy/sortBy_directive.js11
-rw-r--r--js/filters/localeOrderBy_filter.js8
-rw-r--r--js/models/contact_model.js39
-rw-r--r--js/services/sortBy_service.js39
-rw-r--r--js/tests/services/sortBy_service.js20
-rw-r--r--templates/contact.html2
-rw-r--r--templates/contactList.html2
-rw-r--r--templates/main.php1
-rw-r--r--templates/sortBy.html4
12 files changed, 172 insertions, 5 deletions
diff --git a/js/components/contact/contact_controller.js b/js/components/contact/contact_controller.js
index 2d84076f..6e5daa96 100644
--- a/js/components/contact/contact_controller.js
+++ b/js/components/contact/contact_controller.js
@@ -1,5 +1,5 @@
angular.module('contactsApp')
-.controller('contactCtrl', function($route, $routeParams) {
+.controller('contactCtrl', function($route, $routeParams, SortByService) {
var ctrl = this;
ctrl.t = {
@@ -11,4 +11,29 @@ angular.module('contactsApp')
gid: $routeParams.gid,
uid: ctrl.contact.uid()});
};
+
+ ctrl.getName = function() {
+ // If lastName equals to firstName then none of them is set
+ if (ctrl.contact.lastName() === ctrl.contact.firstName()) {
+ return ctrl.contact.displayName();
+ }
+
+ if (SortByService.getSortBy() === 'sortLastName') {
+ return (
+ ctrl.contact.lastName() + ', '
+ + ctrl.contact.firstName() + ' '
+ + ctrl.contact.additionalNames()
+ ).trim();
+ }
+
+ if (SortByService.getSortBy() === 'sortFirstName') {
+ return (
+ ctrl.contact.firstName() + ' '
+ + ctrl.contact.additionalNames() + ' '
+ + ctrl.contact.lastName()
+ ).trim();
+ }
+
+ return ctrl.contact.displayName();
+ };
});
diff --git a/js/components/contactList/contactList_controller.js b/js/components/contactList/contactList_controller.js
index 8d144081..a22180d2 100644
--- a/js/components/contactList/contactList_controller.js
+++ b/js/components/contactList/contactList_controller.js
@@ -1,5 +1,5 @@
angular.module('contactsApp')
-.controller('contactlistCtrl', function($scope, $filter, $route, $routeParams, ContactService, vCardPropertiesService, SearchService) {
+.controller('contactlistCtrl', function($scope, $filter, $route, $routeParams, ContactService, SortByService, vCardPropertiesService, SearchService) {
var ctrl = this;
ctrl.routeParams = $routeParams;
@@ -9,6 +9,8 @@ angular.module('contactsApp')
ctrl.show = true;
ctrl.invalid = false;
+ ctrl.sortBy = SortByService.getSortBy();
+
ctrl.t = {
emptySearch : t('contacts', 'No search result for {query}', {query: ctrl.searchTerm})
};
@@ -21,6 +23,10 @@ angular.module('contactsApp')
return contact.matches(SearchService.getSearchTerm());
};
+ SortByService.subscribe(function(newValue) {
+ ctrl.sortBy = newValue;
+ });
+
SearchService.registerObserverCallback(function(ev) {
if (ev.event === 'submitSearch') {
var uid = !_.isEmpty(ctrl.contactList) ? ctrl.contactList[0].uid() : undefined;
diff --git a/js/components/sortBy/sortBy_controller.js b/js/components/sortBy/sortBy_controller.js
new file mode 100644
index 00000000..d740f8e1
--- /dev/null
+++ b/js/components/sortBy/sortBy_controller.js
@@ -0,0 +1,16 @@
+angular.module('contactsApp')
+.controller('sortbyCtrl', function(SortByService) {
+ var ctrl = this;
+
+ var sortText = t('contacts', 'Sort by');
+ ctrl.sortText = sortText;
+
+ var sortList = SortByService.getSortByList();
+ ctrl.sortList = sortList;
+
+ ctrl.defaultOrder = SortByService.getSortBy();
+
+ ctrl.updateSortBy = function() {
+ SortByService.setSortBy(ctrl.defaultOrder);
+ };
+});
diff --git a/js/components/sortBy/sortBy_directive.js b/js/components/sortBy/sortBy_directive.js
new file mode 100644
index 00000000..faf943a7
--- /dev/null
+++ b/js/components/sortBy/sortBy_directive.js
@@ -0,0 +1,11 @@
+angular.module('contactsApp')
+.directive('sortby', function() {
+ return {
+ priority: 1,
+ scope: {},
+ controller: 'sortbyCtrl',
+ controllerAs: 'ctrl',
+ bindToController: {},
+ templateUrl: OC.linkTo('contacts', 'templates/sortBy.html')
+ };
+});
diff --git a/js/filters/localeOrderBy_filter.js b/js/filters/localeOrderBy_filter.js
index f95c8496..24576fe1 100644
--- a/js/filters/localeOrderBy_filter.js
+++ b/js/filters/localeOrderBy_filter.js
@@ -27,10 +27,16 @@ angular.module('contactsApp')
return !reverseOrder ? valueA - valueB : valueB - valueA;
}
+ if (angular.isArray(valueA)) {
+ if (valueA[0] === valueB[0]) {
+ return !reverseOrder ? valueA[1].localeCompare(valueB[1]) : valueB[1].localeCompare(valueA[1]);
+ }
+ return !reverseOrder ? valueA[0].localeCompare(valueB[0]) : valueB[0].localeCompare(valueA[0]);
+ }
+
return 0;
});
return arrayCopy;
};
}]);
-
diff --git a/js/models/contact_model.js b/js/models/contact_model.js
index 65218f4f..7ac65bc5 100644
--- a/js/models/contact_model.js
+++ b/js/models/contact_model.js
@@ -31,6 +31,18 @@ angular.module('contactsApp')
}
},
+ sortFirstName: function() {
+ return [this.firstName(), this.lastName()];
+ },
+
+ sortLastName: function() {
+ return [this.lastName(), this.firstName()];
+ },
+
+ sortDisplayName: function() {
+ return this.displayName();
+ },
+
displayName: function() {
var displayName = this.fullName() || this.org() || '';
if(angular.isArray(displayName)) {
@@ -49,6 +61,33 @@ angular.module('contactsApp')
},
+ firstName: function() {
+ var property = this.getProperty('n');
+ if (property) {
+ return property.value[1];
+ } else {
+ return this.displayName();
+ }
+ },
+
+ lastName: function() {
+ var property = this.getProperty('n');
+ if (property) {
+ return property.value[0];
+ } else {
+ return this.displayName();
+ }
+ },
+
+ additionalNames: function() {
+ var property = this.getProperty('n');
+ if (property) {
+ return property.value[2];
+ } else {
+ return '';
+ }
+ },
+
fullName: function(value) {
var model = this;
if (angular.isDefined(value)) {
diff --git a/js/services/sortBy_service.js b/js/services/sortBy_service.js
new file mode 100644
index 00000000..42f0957a
--- /dev/null
+++ b/js/services/sortBy_service.js
@@ -0,0 +1,39 @@
+angular.module('contactsApp')
+.service('SortByService', function () {
+ var subscriptions = [];
+ var sortBy = 'sortDisplayName';
+
+ var defaultOrder = window.localStorage.getItem('contacts_default_order');
+ if (defaultOrder) {
+ sortBy = defaultOrder;
+ }
+
+ function notifyObservers () {
+ angular.forEach(subscriptions, function (subscription) {
+ if (typeof subscription === 'function') {
+ subscription(sortBy);
+ }
+ });
+ }
+
+ return {
+ subscribe: function (callback) {
+ subscriptions.push (callback);
+ },
+ setSortBy: function (value) {
+ sortBy = value;
+ window.localStorage.setItem ('contacts_default_order', value);
+ notifyObservers ();
+ },
+ getSortBy: function () {
+ return sortBy;
+ },
+ getSortByList: function () {
+ return {
+ sortDisplayName: t('contacts', 'Display name'),
+ sortFirstName: t('contacts', 'First name'),
+ sortLastName: t('contacts', 'Last name')
+ };
+ }
+ };
+});
diff --git a/js/tests/services/sortBy_service.js b/js/tests/services/sortBy_service.js
new file mode 100644
index 00000000..4ea227c5
--- /dev/null
+++ b/js/tests/services/sortBy_service.js
@@ -0,0 +1,20 @@
+describe('sortbyService', function() {
+
+ var $Service;
+ beforeEach(module('contactsApp'));
+
+ beforeEach(inject(function(SortByService){
+ $Service = SortByService;
+ }));
+
+ it('should return sortDisplayName as default sorting method', function() {
+ expect($Service.getSortBy()).to.equal('sortDisplayName');
+ });
+
+ it('should store sorting method', function() {
+ $Service.setSortBy('sortLastName');
+ expect($Service.getSortBy()).to.equal(
+ window.localStorage.getItem('contacts_default_order')
+ );
+ });
+});
diff --git a/templates/contact.html b/templates/contact.html
index b6e68c00..ac528cdb 100644
--- a/templates/contact.html
+++ b/templates/contact.html
@@ -3,6 +3,6 @@
<div class="app-content-list-item-icon contact__icon" ng-show="ctrl.contact.photo()===undefined" ng-style="{'background-color': (ctrl.contact.uid() | contactColor) }">{{ ctrl.contact.displayName() | firstCharacter }}</div>
<div class="app-content-list-item-star icon-star" data-starred="false"></div>
<div class="app-content-list-item-failed icon-error" tooltip-placement="auto left" ng-if="ctrl.contact.failedProps.length>0" uib-tooltip="{{ ctrl.t.errorMessage }}"></div>
- <div class="app-content-list-item-line-one" ng-class="{'no-line-two':!ctrl.contact.email()}">{{ ctrl.contact.displayName() | newContact }}</div>
+ <div class="app-content-list-item-line-one" ng-class="{'no-line-two':!ctrl.contact.email()}">{{ ctrl.getName() | newContact }}</div>
<div class="app-content-list-item-line-two">{{ctrl.contact.email()}}</div>
</a>
diff --git a/templates/contactList.html b/templates/contactList.html
index a1a99ae3..47d30067 100644
--- a/templates/contactList.html
+++ b/templates/contactList.html
@@ -1,6 +1,6 @@
<div style="height: 90%" class="contacts-list" ng-class="{loading: ctrl.loading, 'mobile-show': ctrl.show}">
<div class="app-content-list-item"
- ng-repeat="contact in ctrl.contactList = (ctrl.contacts | contactGroupFilter:ctrl.routeParams.gid | localeOrderBy:'displayName' | filter:query) as filtered track by contact.uid()"
+ ng-repeat="contact in ctrl.contactList = (ctrl.contacts | contactGroupFilter:ctrl.routeParams.gid | localeOrderBy:ctrl.sortBy | filter:query) as filtered track by contact.uid()"
contact data="contact"
ng-click="setSelected(contact.uid())"
ng-class="{active: contact.uid() === ctrl.getSelectedId()}">
diff --git a/templates/main.php b/templates/main.php
index a1454dfa..e165fc73 100644
--- a/templates/main.php
+++ b/templates/main.php
@@ -38,6 +38,7 @@ vendor_style('select2/select2');
<div id="app-settings-content">
<addressBookList></addressBookList>
<contactImport></contactImport>
+ <sortBy></sortBy>
</div>
</div>
</div>
diff --git a/templates/sortBy.html b/templates/sortBy.html
new file mode 100644
index 00000000..d29cc605
--- /dev/null
+++ b/templates/sortBy.html
@@ -0,0 +1,4 @@
+<label for="contact-import">{{ctrl.sortText}}:</label>
+<select ng-change="ctrl.updateSortBy()" ng-model="ctrl.defaultOrder" id="sort-by">
+ <option ng-repeat="(key, value) in ctrl.sortList" ng-model="ctrl.sortList[key]" ng-selected="ctrl.defaultOrder == key" value="{{key}}">{{value}}</option>
+</select>