diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index e2359193383a..36aae5445d9f 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -2467,7 +2467,7 @@ $LANG = array(
'stopped' => 'Stopped',
'ascending' => 'Ascending',
'descending' => 'Descending',
- 'direction' => 'Direction',
+ 'sort_direction' => 'Direction',
);
diff --git a/resources/views/tasks/time_tracker.blade.php b/resources/views/tasks/time_tracker.blade.php
index 7372884ab1a2..8b690a2d8fe4 100644
--- a/resources/views/tasks/time_tracker.blade.php
+++ b/resources/views/tasks/time_tracker.blade.php
@@ -235,18 +235,18 @@
{!! Former::select('sort_by')
- ->addOption(trans('texts.date'), 'date')
+ ->addOption(trans('texts.date'), 'createdAt')
->addOption(trans('texts.duration'), 'duration')
->addOption(trans('texts.client'), 'client')
->addOption(trans('texts.project'), 'project')
->addOption(trans('texts.description'), 'description')
- ->data_bind('value: sortBy') !!}
+ ->data_bind('value: sortBy, event: {change: onSortChange}') !!}
- {!! Former::select('direction')
- ->addOption(trans('texts.ascending'), 'asc')
- ->addOption(trans('texts.descending'), 'desc')
- ->data_bind('value: sortDirection') !!}
+ {!! Former::select('sort_direction')
+ ->addOption(trans('texts.ascending'), 'ascending')
+ ->addOption(trans('texts.descending'), 'descending')
+ ->data_bind('value: sortDirection, event: {change: onSortChange}') !!}
diff --git a/resources/views/tasks/time_tracker_knockout.blade.php b/resources/views/tasks/time_tracker_knockout.blade.php
index a1313febcfa9..e581595e4bdd 100644
--- a/resources/views/tasks/time_tracker_knockout.blade.php
+++ b/resources/views/tasks/time_tracker_knockout.blade.php
@@ -14,8 +14,8 @@
self.selectedProject = ko.observable(false);
self.filterState = ko.observable('all');
- self.sortBy = ko.observable('date');
- self.sortDirection = ko.observable('desc');
+ self.sortBy = ko.observable('createdAt');
+ self.sortDirection = ko.observable('descending');
self.isDesktop = function() {
return navigator.userAgent == 'Time Tracker';
@@ -31,6 +31,10 @@
task.save(data, true);
}
+ self.onSortChange = function() {
+ console.log('sort change...');
+ }
+
self.onFilterClick = function(event) {
$('#filterPanel').toggle();
}
@@ -323,14 +327,10 @@
}
self.filteredTasks = ko.computed(function() {
-
var tasks = self.tasks();
- // bind to fields
- self.filterState();
-
var filtered = ko.utils.arrayFilter(tasks, function(task) {
- return task.matchesFilter();
+ return task.matchesFilter(self.filter(), self.filterState());
});
if (! self.filter() || filtered.length > 0) {
@@ -339,12 +339,21 @@
// sort the data
tasks.sort(function (left, right) {
- return right.createdAt() - left.createdAt();
- /*
- right = right.firstTime() ? right.firstTime().order() : right.createdAt();
- left = left.firstTime() ? left.firstTime().order() : left.createdAt();
- return right - left;
- */
+ var leftSortValue = left.sortValue(self.sortBy());
+ var rightSortValue = right.sortValue(self.sortBy());
+ if (self.sortBy() == 'createdAt' || self.sortBy() == 'duration') {
+ if (self.sortDirection() == 'descending') {
+ return rightSortValue - leftSortValue
+ } else {
+ return leftSortValue - rightSortValue;
+ }
+ } else {
+ if (self.sortDirection() == 'ascending') {
+ return leftSortValue.localeCompare(rightSortValue);
+ } else {
+ return rightSortValue.localeCompare(leftSortValue);
+ }
+ }
});
return tasks;
@@ -560,6 +569,18 @@
self.update(data);
}
+ self.sortValue = function(field) {
+ if (field == 'client') {
+ return self.client() && self.client().displayName() ? self.client().displayName().toLowerCase() : '';
+ } else if (field == 'project') {
+ return self.project() && self.project().name() ? self.project().name().toLowerCase() : '';
+ } else if (field == 'duration') {
+ return self.seconds(true);
+ } else {
+ return self[field]();
+ }
+ }
+
self.isNew = ko.computed(function() {
return ! self.public_id();
});
@@ -595,8 +616,8 @@
return times;
}
- self.matchesFilter = function() {
- if (model.filter()) {
+ self.matchesFilter = function(filter, filterState) {
+ if (filter) {
filter = model.filter().toLowerCase();
var parts = filter.split(' ');
for (var i=0; i