taskwarrior-web 1.1.8 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -6,5 +6,6 @@ script: "rake spec"
6
6
  before_install:
7
7
  - sudo apt-get update -qq
8
8
  - sudo apt-get install task -qq
9
- - cp -v /home/vagrant/builds/theunraveler/taskwarrior-web/spec/files/taskrc /home/vagrant/.taskrc
10
- - mkdir /home/vagrant/.task
9
+ before_script:
10
+ - cp -v spec/files/taskrc $HOME/.taskrc
11
+ - mkdir $HOME/.task
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## v1.1.9 (5/21/13)
2
+
3
+ * Sorting by priority sorts intelligently (http://github.com/theunraveler/taskwarrior-web/issues/39)
4
+ * Fixes updating tasks in taskwarrior 2.2.0+ (http://github.com/theunraveler/taskwarrior-web/issues/36)
5
+
1
6
  ## v1.1.8 (1/15/13)
2
7
 
3
8
  * Support for adding and removing annotations on tasks.
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  A lightweight, Sinatra-based web interface for the
4
4
  wonderful [Taskwarrior](http://taskwarrior.org/) todo application.
5
5
 
6
- ![TaskwarriorWeb screenshot](https://dl.dropbox.com/u/107599300/screenshot.png)
6
+ ![TaskwarriorWeb screenshot](https://raw.github.com/theunraveler/taskwarrior-web/gh-pages/images/screenshot.png)
7
7
 
8
8
  [![Gem Version](https://badge.fury.io/rb/taskwarrior-web.png)](http://badge.fury.io/rb/taskwarrior-web)
9
9
  [![Build Status](https://secure.travis-ci.org/theunraveler/taskwarrior-web.png)](http://travis-ci.org/theunraveler/taskwarrior-web)
@@ -2,9 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  require 'rubygems'
5
- require 'active_support/core_ext/object/blank'
6
- require 'active_support/core_ext/string/inflections'
7
- require 'active_support/core_ext/string/filters'
5
+ require 'active_support/core_ext'
8
6
  require 'taskwarrior-web/version'
9
7
 
10
8
  module TaskwarriorWeb
@@ -83,5 +83,3 @@ table.table thead .sorting_desc { background: url('../img/sort_desc.png') no-rep
83
83
 
84
84
  table.table thead .sorting_asc_disabled { background: url('../img/sort_asc_disabled.png') no-repeat center right; }
85
85
  table.table thead .sorting_desc_disabled { background: url('../img/sort_desc_disabled.png') no-repeat center right; }
86
-
87
- #annotations-modal textarea { width: 100%; }
@@ -54,21 +54,21 @@ var initTaskCompletion = function() {
54
54
  e.preventDefault();
55
55
 
56
56
  // Cache the checkbox in case we need to restore it.
57
- var container = $(this).parent(),
58
- checkbox = container.html(),
59
- row = $(this).closest('tr');
60
- container.html('<img src="/img/ajax-loader.gif" />');
57
+ var $container = $(this).parent(),
58
+ checkbox = $container.html(),
59
+ $row = $(this).closest('tr');
60
+ $container.html('<img src="/img/ajax-loader.gif" />');
61
61
  $.ajax({
62
62
  url: '/ajax/task-complete/' + $(this).data('task-id'),
63
63
  type: 'POST',
64
64
  success: function(data) {
65
65
  refreshPageContents();
66
66
  set_message(data === '' ? 'Task marked as completed.' : data);
67
- row.fadeOut();
67
+ $row.fadeOut();
68
68
  },
69
69
  error: function(data) {
70
70
  set_message('There was an error when marking the task as completed.', 'error');
71
- container.html(checkbox);
71
+ $container.html(checkbox);
72
72
  }
73
73
  });
74
74
  });
@@ -102,16 +102,38 @@ var initTablesort = function() {
102
102
  sWrapper: "dataTables_wrapper form-inline"
103
103
  });
104
104
 
105
- $('.table-sortable').each(function(index, el) {
105
+ $('.table-sortable').each(function(index, table) {
106
+ var $table = $(table);
107
+
106
108
  // Find out which columns are sortable.
107
- var aoColumns = [], element = $(el);
108
- element.find('thead th').each(function () {
109
- var def = $(this).hasClass('no-sort') ? { "bSortable": false } : null;
110
- aoColumns.push(def);
109
+ var aoColumns = $.map($table.find('thead th'), function (header) {
110
+ var $header = $(header);
111
+
112
+ // Headers with ".no-sort" are not sortable.
113
+ if ($header.hasClass('no-sort')) {
114
+ return {'bSortable': false};
115
+ }
116
+
117
+ // Headers with "data-sort-map" should provide a JS object of display to
118
+ // sort parameter maps.
119
+ if ($header.data('sort-map')) {
120
+ var map = $header.data('sort-map');
121
+ return {'mData': function(source, type, val) {
122
+ if (type === 'set') {
123
+ source.raw = val;
124
+ source.numeric = map[val];
125
+ return;
126
+ }
127
+
128
+ return type === 'sort' ? source.numeric : source.raw;
129
+ }};
130
+ }
131
+
132
+ return {};
111
133
  });
112
134
 
113
135
  // Initialze the sorter.
114
- element.dataTable({
136
+ $table.dataTable({
115
137
  sDom: "t",
116
138
  bInfo: false,
117
139
  bPaginate: false,
@@ -135,11 +157,11 @@ var initAnnotationsModal = function() {
135
157
  var initUjs = function() {
136
158
  $('[data-method]').click(function(e) {
137
159
  e.preventDefault();
138
- var link = $(this);
139
- if (confirm(link.data('confirm') || 'Are you sure?')) {
140
- $('<form action="' + link.attr('href') + '" method="POST" style="display: none;">')
141
- .append('<input type="hidden" name="_method" value="' + link.data('method') + '" />')
142
- .insertAfter(link)
160
+ var $link = $(this);
161
+ if (confirm($link.data('confirm') || 'Are you sure?')) {
162
+ $('<form action="' + $link.attr('href') + '" method="POST" style="display: none;">')
163
+ .append('<input type="hidden" name="_method" value="' + $link.data('method') + '" />')
164
+ .insertAfter($link)
143
165
  .submit();
144
166
  }
145
167
  });
@@ -1,5 +1,5 @@
1
1
  module TaskwarriorWeb::Runner
2
- TASK_BIN = 'task rc.xterm.title=no rc.color=off rc.verbose=no'
2
+ TASK_BIN = 'task rc.xterm.title=no rc.color=off rc.verbose=no rc.confirmation=no'
3
3
 
4
4
  def run
5
5
  @built ||= build
@@ -1,3 +1,3 @@
1
1
  module TaskwarriorWeb
2
- VERSION = '1.1.8'
2
+ VERSION = '1.1.9'
3
3
  end
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE HTML>
1
2
  <html>
2
3
  <head>
3
4
  <title><%= @title %> | TaskwarriorWeb</title>
@@ -6,7 +6,7 @@
6
6
  <h3 id="annotations-modal-label">Add annotation to "<%= @task %>"</h3>
7
7
  </div>
8
8
  <div class="modal-body">
9
- <textarea name="annotation[description]" placeholder="New annotation..." required="required"></textarea>
9
+ <textarea name="annotation[description]" class="input-block-level" placeholder="New annotation..." required="required"></textarea>
10
10
  <input type="hidden" name="annotation[task_id]" value="<%= @task.uuid %>" />
11
11
  </div>
12
12
  <div class="modal-footer">
@@ -1,21 +1,21 @@
1
1
  <div class="control-group">
2
2
  <label for="task-description" class="control-label">Description</label>
3
3
  <div class="controls">
4
- <input type="textfield" required="required" id="task-description" name="task[description]" value="<%= @task.description unless @task.nil? %>" />
4
+ <input type="text" required="required" id="task-description" name="task[description]" value="<%= @task.description unless @task.nil? %>" />
5
5
  </div>
6
6
  </div>
7
7
 
8
8
  <div class="control-group">
9
9
  <label for="task-project" class="control-label">Project</label>
10
10
  <div class="controls">
11
- <input type="textfield" id="task-project" name="task[project]" value="<%= @task.project unless @task.nil? %>" autocomplete="off" />
11
+ <input type="text" id="task-project" name="task[project]" value="<%= @task.project unless @task.nil? %>" autocomplete="off" />
12
12
  </div>
13
13
  </div>
14
14
 
15
15
  <div class="control-group">
16
16
  <label for="task-due" class="control-label">Due Date</label>
17
17
  <div class="controls">
18
- <input class="date-picker" type="textfield" id="task-due" name="task[due]" value="<%= format_date(@task.due) unless @task.nil? || @task.due.blank? %>" data-date-format="<%= @date_format %>" />
18
+ <input class="date-picker" type="text" id="task-due" name="task[due]" value="<%= format_date(@task.due) unless @task.nil? || @task.due.blank? %>" data-date-format="<%= @date_format %>" />
19
19
  </div>
20
20
  </div>
21
21
 
@@ -37,7 +37,7 @@
37
37
  <div class="control-group">
38
38
  <label for="task-tags" class="control-label">Tags</label>
39
39
  <div class="controls">
40
- <input type="textfield" id="task-tags" name="task[tags]" value="<%= @task.tags.join(', ') unless @task.nil? %>" autocomplete="off" />
40
+ <input type="text" id="task-tags" name="task[tags]" value="<%= @task.tags.join(', ') unless @task.nil? %>" autocomplete="off" />
41
41
  <span class="help-block">Enter tags separated by commas or spaces (e.g. <em>each, word will,be a tag</em>)</span>
42
42
  </div>
43
43
  </div>
@@ -1,4 +1,5 @@
1
1
  <% can_edit = @can_edit && params[:status].in?(['pending', 'waiting']) %>
2
+ <% priority_map = { nil => 0, 'L' => 1, 'M' => -1, 'H' => -2 } %>
2
3
 
3
4
  <div id="listing">
4
5
  <% if @tasks.empty? and params[:status] == 'pending' %>
@@ -16,7 +17,7 @@
16
17
  <th>Project</th>
17
18
  <th>Due</th>
18
19
  <th>Tags</th>
19
- <th>Priority</th>
20
+ <th data-sort-map='{"H": 0, "M": 1, "": 2, "L": 3}'>Priority</th>
20
21
  <% if can_edit %><th class="no-sort"></th><% end %>
21
22
  </tr>
22
23
  </thead>
@@ -19,13 +19,7 @@ describe TaskwarriorWeb::App::Helpers do
19
19
  helpers.format_date('2012-01-11 12:23:00').should eq('1/11/2012')
20
20
  helpers.format_date('2012-01-11').should eq('1/11/2012')
21
21
  helpers.format_date('20121231T230000Z').should eq(Time.parse('20121231T230000Z').localtime.strftime('%-m/%-d/%Y'))
22
-
23
- # This test will fail if run in UTC :-)
24
- if Time.current.zone == 'UTC'
25
- helpers.format_date('20121231T230000Z').should eq(Time.parse('20121231T230000Z').strftime('%-m/%-d/%Y'))
26
- else
27
- helpers.format_date('20121231T230000Z').should_not eq(Time.parse('20121231T230000Z').strftime('%-m/%-d/%Y'))
28
- end
22
+ helpers.format_date('20121231T230000Z').should eq(Time.parse('20121231T230000Z').strftime('%-m/%-d/%Y'))
29
23
  end
30
24
  end
31
25
 
@@ -114,7 +114,7 @@ describe TaskwarriorWeb::Task do
114
114
  end
115
115
 
116
116
  it 'should have keys for each of the object\'s instance variables' do
117
- @task.to_hash.should eq({:description => 'Testing', :due => '12/2/12', :tags => ['hello', 'twice']})
117
+ @task.to_hash.should eq({:description => 'Testing', :due => '12/2/12', :tags => ['hello', 'twice'], :annotations => []})
118
118
  end
119
119
  end
120
120
 
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency('activesupport')
25
25
  s.add_dependency('sinatra-simple-navigation')
26
26
  s.add_dependency('rack-flash3')
27
+ s.add_dependency('json', '~> 1.7.7')
27
28
 
28
29
  s.add_development_dependency('rake')
29
30
  s.add_development_dependency('rack-test')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taskwarrior-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.8
4
+ version: 1.1.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-16 00:00:00.000000000 Z
12
+ date: 2013-05-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -139,6 +139,22 @@ dependencies:
139
139
  - - ! '>='
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: json
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 1.7.7
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 1.7.7
142
158
  - !ruby/object:Gem::Dependency
143
159
  name: rake
144
160
  requirement: !ruby/object:Gem::Requirement
@@ -307,7 +323,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
307
323
  version: '0'
308
324
  segments:
309
325
  - 0
310
- hash: -4275568887696200084
326
+ hash: -1134852019242031936
311
327
  requirements: []
312
328
  rubyforge_project: taskwarrior-web
313
329
  rubygems_version: 1.8.23