mirror of https://github.com/nextcloud/contacts
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
This commit is contained in:
parent
9523b407cb
commit
6529a8e9d4
|
@ -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();
|
||||
};
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
});
|
|
@ -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')
|
||||
};
|
||||
});
|
|
@ -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;
|
||||
};
|
||||
}]);
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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')
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
|
@ -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')
|
||||
);
|
||||
});
|
||||
});
|
|
@ -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>
|
||||
|
|
|
@ -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()}">
|
||||
|
|
|
@ -38,6 +38,7 @@ vendor_style('select2/select2');
|
|||
<div id="app-settings-content">
|
||||
<addressBookList></addressBookList>
|
||||
<contactImport></contactImport>
|
||||
<sortBy></sortBy>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue