Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Major changes to support time tracking and Rails 3.1

  • Loading branch information...
commit 038b2502e1baec9806a802fd7d475b1451384a73 1 parent 7fa95e9
Sacha Chua authored December 25, 2011

Showing 227 changed files with 9,395 additions and 49,736 deletions. Show diff stats Hide diff stats

  1. 20  Gemfile
  2. 162  Gemfile.lock
  3. 9  app/assets/javascripts/application.js
  4. 2  public/javascripts/application.js → app/assets/javascripts/quantified.js
  5. 0  app/{ → assets}/stylesheets/_forms.sass
  6. 0  app/{ → assets}/stylesheets/_mixins.sass
  7. 0  app/{ → assets}/stylesheets/_patterns.sass
  8. 0  app/{ → assets}/stylesheets/_reset.sass
  9. 0  app/{ → assets}/stylesheets/_scaffolding.sass
  10. 0  app/{ → assets}/stylesheets/_tables.sass
  11. 0  app/{ → assets}/stylesheets/_type.sass
  12. 0  app/{ → assets}/stylesheets/_variables.sass
  13. 116  app/assets/stylesheets/application.sass
  14. 0  app/{ → assets}/stylesheets/compass_bootstrap.sass
  15. 0  app/{ → assets}/stylesheets/ie.sass
  16. 0  app/{ → assets}/stylesheets/mobile.sass
  17. 0  app/{ → assets}/stylesheets/print.sass
  18. 0  app/{ → assets}/stylesheets/screen.sass
  19. 14  app/{stylesheets/application.sass → assets/stylesheets/style.css.sass}
  20. 106  app/assets/stylesheets/style.sass
  21. 31  app/controllers/application_controller.rb
  22. 123  app/controllers/record_categories_controller.rb
  23. 122  app/controllers/records_controller.rb
  24. 220  app/controllers/time_controller.rb
  25. 69  app/helpers/application_helper.rb
  26. 2  app/helpers/record_categories_helper.rb
  27. 2  app/helpers/records_helper.rb
  28. 2  app/models/ability.rb
  29. 151  app/models/record.rb
  30. 141  app/models/record_category.rb
  31. 227  app/models/time_tracker_log.rb
  32. 16  app/models/user.rb
  33. 0  app/views/{partials → application}/_clothing_log_entry.html.haml
  34. 0  app/views/{partials → application}/_clothing_thumbnails.html.erb
  35. 0  app/views/{partials → application}/_colours.html.haml
  36. 13  app/views/application/_filters.html.haml
  37. 0  app/views/{partials → application}/_login.html.haml
  38. 0  app/views/{partials → application}/_sidebar.html.haml
  39. 0  app/views/{partials → application}/_time_sparklines.html.erb
  40. 27  app/views/home/index.html.haml
  41. 29  app/views/layouts/application.html.haml
  42. 50  app/views/record_categories/_activity_summary.html.haml
  43. 14  app/views/record_categories/_form.html.haml
  44. 23  app/views/record_categories/_list.html.haml
  45. 7  app/views/record_categories/edit.html.haml
  46. 5  app/views/record_categories/index.html.haml
  47. 5  app/views/record_categories/new.html.haml
  48. 28  app/views/record_categories/show.html.haml
  49. 9  app/views/records/_form.html.haml
  50. 25  app/views/records/_summary.html.haml
  51. 8  app/views/records/edit.html.haml
  52. 21  app/views/records/index.html.haml
  53. 5  app/views/records/new.html.haml
  54. 37  app/views/records/show.html.haml
  55. 1  app/views/tap_log_records/show.html.haml
  56. 54  app/views/time/_activity_summary.html.haml
  57. 65  app/views/time/_activity_summary_daily.html.haml
  58. 44  app/views/time/_activity_summary_weekly.html.haml
  59. 7  app/views/time/_nav.html.haml
  60. 16  app/views/time/dashboard.html.haml
  61. 67  app/views/time/graph.html.erb
  62. 7  app/views/time/refresh.html.haml
  63. 15  app/views/time/review.html.haml
  64. 7  config/application.rb
  65. 1  config/cucumber.yml
  66. 9  config/environments/development.rb
  67. 14  config/environments/production.rb
  68. 9  config/environments/test.rb
  69. 1  config/initializers/formtastic.rb
  70. 0  public/javascripts/Examples/css/HeatMap.css → config/initializers/sass.rb
  71. 1  config/initializers/will_paginate.rb
  72. 14  config/initializers/wrap_parameters.rb
  73. 16  config/locales/en.yml
  74. 22  config/routes.rb
  75. 17  db/migrate/20111223144028_create_record_categories.rb
  76. 20  db/migrate/20111223154542_create_records.rb
  77. 9  db/migrate/20111223191834_add_nolink_to_record_category.rb
  78. 5  db/migrate/20111224130846_add_date_to_record.rb
  79. 15  db/migrate/20111224174240_move_old_time_records.rb
  80. 5  db/migrate/20111225133526_add_color_to_record_category.rb
  81. 37  db/schema.rb
  82. 16  features/record_categories.feature
  83. 8  features/step_definitions/life_steps.rb
  84. 27  features/step_definitions/steps.rb
  85. 123  lib/old_records.rb
  86. 61  public/javascripts/Examples/AreaChart/example1.html
  87. 146  public/javascripts/Examples/AreaChart/example1.js
  88. 56  public/javascripts/Examples/BarChart/example1.html
  89. 143  public/javascripts/Examples/BarChart/example1.js
  90. 56  public/javascripts/Examples/BarChart/example2.html
  91. 142  public/javascripts/Examples/BarChart/example2.js
  92. 59  public/javascripts/Examples/ForceDirected/example1.html
  93. 592  public/javascripts/Examples/ForceDirected/example1.js
  94. 61  public/javascripts/Examples/ForceDirected/example2.html
  95. 639  public/javascripts/Examples/ForceDirected/example2.js
  96. 57  public/javascripts/Examples/Hypertree/example1.html
  97. 435  public/javascripts/Examples/Hypertree/example1.js
  98. 58  public/javascripts/Examples/Hypertree/example2.html
  99. 320  public/javascripts/Examples/Hypertree/example2.js
  100. 199  public/javascripts/Examples/Hypertree/example3.html
  101. 625  public/javascripts/Examples/Hypertree/example3.js
  102. 82  public/javascripts/Examples/Icicle/example1.html
  103. 3,497  public/javascripts/Examples/Icicle/example1.js
  104. 83  public/javascripts/Examples/Icicle/example2.html
  105. 7,151  public/javascripts/Examples/Icicle/example2.js
  106. 58  public/javascripts/Examples/Other/example1.html
  107. 569  public/javascripts/Examples/Other/example1.js
  108. 58  public/javascripts/Examples/Other/example2.html
  109. 295  public/javascripts/Examples/Other/example2.js
  110. 58  public/javascripts/Examples/Other/example3.html
  111. 309  public/javascripts/Examples/Other/example3.js
  112. 57  public/javascripts/Examples/PieChart/example1.html
  113. 135  public/javascripts/Examples/PieChart/example1.js
  114. 58  public/javascripts/Examples/RGraph/example1.html
  115. 478  public/javascripts/Examples/RGraph/example1.js
  116. 58  public/javascripts/Examples/RGraph/example2.html
  117. 341  public/javascripts/Examples/RGraph/example2.js
  118. 199  public/javascripts/Examples/RGraph/example3.html
  119. 617  public/javascripts/Examples/RGraph/example3.js
  120. 58  public/javascripts/Examples/RGraph/example4.html
  121. 568  public/javascripts/Examples/RGraph/example4.js
  122. 115  public/javascripts/Examples/Spacetree/example1.html
  123. 899  public/javascripts/Examples/Spacetree/example1.js
  124. 90  public/javascripts/Examples/Spacetree/example2.html
  125. 216  public/javascripts/Examples/Spacetree/example2.js
  126. 75  public/javascripts/Examples/Spacetree/example3.html
  127. 865  public/javascripts/Examples/Spacetree/example3.js
  128. 78  public/javascripts/Examples/Spacetree/example4.html
  129. 899  public/javascripts/Examples/Spacetree/example4.js
  130. 172  public/javascripts/Examples/Spacetree/example5.html
  131. 303  public/javascripts/Examples/Spacetree/example5.js
  132. 58  public/javascripts/Examples/Sunburst/example1.html
  133. 325  public/javascripts/Examples/Sunburst/example1.js
  134. 57  public/javascripts/Examples/Sunburst/example2.html
  135. 772  public/javascripts/Examples/Sunburst/example2.js
  136. 87  public/javascripts/Examples/Treemap/example1.html
  137. 977  public/javascripts/Examples/Treemap/example1.js
  138. 86  public/javascripts/Examples/Treemap/example2.html
  139. 165  public/javascripts/Examples/Treemap/example2.js
  140. 87  public/javascripts/Examples/Treemap/example3.html
  141. 1,025  public/javascripts/Examples/Treemap/example3.js
  142. 114  public/javascripts/Examples/css/AreaChart.css
  143. 112  public/javascripts/Examples/css/BarChart.css
  144. 27  public/javascripts/Examples/css/ForceDirected.css
  145. 12  public/javascripts/Examples/css/ForceDirected3D.css
  146. 3  public/javascripts/Examples/css/Hypertree.css
  147. 79  public/javascripts/Examples/css/Icicle.css
  148. 8  public/javascripts/Examples/css/Other.css
  149. 112  public/javascripts/Examples/css/PieChart.css
  150. 59  public/javascripts/Examples/css/Spacetree.css
  151. 32  public/javascripts/Examples/css/Sunburst.css
  152. 113  public/javascripts/Examples/css/TimeGraph.css
  153. 109  public/javascripts/Examples/css/Treemap.css
  154. 123  public/javascripts/Examples/css/base.css
  155. BIN  public/javascripts/Examples/css/col1.png
  156. BIN  public/javascripts/Examples/css/col2.png
  157. BIN  public/javascripts/Examples/css/gradient.png
  158. 1,416  public/javascripts/Extras/excanvas.js
  159. BIN  public/javascripts/Jit-2.0.1.zip
  160. 11,729  public/javascripts/jquery-ui.js
  161. 8,981  public/javascripts/jquery.js
  162. 879  public/stylesheets/application.css
  163. 0  public/{javascripts/Examples/css/RGraph.css → stylesheets/record_summary.css.css}
  164. 3,132  public/stylesheets/style.css
  165. 3,132  public/stylesheets/style.css.css
  166. 1  script/rails
  167. 157  spec/controllers/record_categories_controller_spec.rb
  168. 157  spec/controllers/records_controller_spec.rb
  169. 12  spec/factories/record_categories.rb
  170. 14  spec/factories/records.rb
  171. 7  spec/factories/signups.rb
  172. 15  spec/helpers/record_categories_helper_spec.rb
  173. 15  spec/helpers/records_helper_spec.rb
  174. 5  spec/models/record_category_spec.rb
  175. 5  spec/models/record_spec.rb
  176. 5  spec/models/signup_spec.rb
  177. 11  spec/requests/record_categories_spec.rb
  178. 11  spec/requests/records_spec.rb
  179. 35  spec/routing/record_categories_routing_spec.rb
  180. 35  spec/routing/records_routing_spec.rb
  181. 28  spec/views/record_categories/edit.html.haml_spec.rb
  182. 40  spec/views/record_categories/index.html.haml_spec.rb
  183. 28  spec/views/record_categories/new.html.haml_spec.rb
  184. 30  spec/views/record_categories/show.html.haml_spec.rb
  185. 28  spec/views/records/edit.html.haml_spec.rb
  186. 40  spec/views/records/index.html.haml_spec.rb
  187. 28  spec/views/records/new.html.haml_spec.rb
  188. 30  spec/views/records/show.html.haml_spec.rb
  189. 0  {public → vendor/assets}/javascripts/autocomplete-rails.js
  190. 0  {public → vendor/assets}/javascripts/bootstrap-alerts.js
  191. 0  {public → vendor/assets}/javascripts/bootstrap-dropdown.js
  192. 0  {public → vendor/assets}/javascripts/bootstrap-modal.js
  193. 0  {public → vendor/assets}/javascripts/bootstrap-popover.js
  194. 0  {public → vendor/assets}/javascripts/bootstrap-scrollspy.js
  195. 0  {public → vendor/assets}/javascripts/bootstrap-tabs.js
  196. 0  {public → vendor/assets}/javascripts/bootstrap-twipsy.js
  197. 0  {public → vendor/assets}/javascripts/g.pie-min.js
  198. 0  {public → vendor/assets}/javascripts/g.raphael-min.js
  199. 0  {public → vendor/assets}/javascripts/jit-yc.js
  200. 0  {public → vendor/assets}/javascripts/jit.js
  201. 0  {public → vendor/assets}/javascripts/jquery-ui.min.js
  202. 0  {public → vendor/assets}/javascripts/jquery.min.js
  203. 0  {public → vendor/assets}/javascripts/jquery.sparkline.min.js
  204. 0  {public → vendor/assets}/javascripts/jquery_ujs.js
  205. 0  {public → vendor/assets}/javascripts/protovis.min.js
  206. 0  {public → vendor/assets}/javascripts/raphael-min.js
  207. BIN  vendor/cache/abstract-1.0.0.gem
  208. BIN  vendor/cache/actionmailer-3.0.10.gem
  209. BIN  vendor/cache/actionpack-3.0.10.gem
  210. BIN  vendor/cache/activemodel-3.0.10.gem
  211. BIN  vendor/cache/activerecord-3.0.10.gem
  212. BIN  vendor/cache/activeresource-3.0.10.gem
  213. BIN  vendor/cache/activesupport-3.0.10.gem
  214. BIN  vendor/cache/arel-2.0.10.gem
  215. BIN  vendor/cache/builder-2.1.2.gem
  216. BIN  vendor/cache/erubis-2.6.6.gem
  217. BIN  vendor/cache/i18n-0.5.0.gem
  218. BIN  vendor/cache/mail-2.2.19.gem
  219. BIN  vendor/cache/mime-types-1.16.gem
  220. BIN  vendor/cache/multi_json-1.0.3.gem
  221. BIN  vendor/cache/polyglot-0.3.2.gem
  222. BIN  vendor/cache/rack-mount-0.6.14.gem
  223. BIN  vendor/cache/rack-test-0.5.7.gem
  224. BIN  vendor/cache/rails-3.0.10.gem
  225. BIN  vendor/cache/railties-3.0.10.gem
  226. BIN  vendor/cache/rake-0.9.2.gem
  227. BIN  vendor/cache/tzinfo-0.3.29.gem
20  Gemfile
... ...
@@ -1,11 +1,11 @@
1 1
 source 'http://rubygems.org'
2 2
 
3  
-gem 'rails', '3.0.10'
  3
+gem 'rails', '3.1'
4 4
 # Bundle edge Rails instead:
5 5
 #gem 'rails', :git => 'git://github.com/rails/rails.git'
6 6
 #gem 'arel', :git => 'git://github.com/rails/arel.git'
7 7
 #gem 'journey', :git => 'git://github.com/rails/journey.git'
8  
-
  8
+gem 'rails-dev-tweaks'
9 9
 gem 'jquery-rails'
10 10
 gem 'sqlite3'
11 11
 gem 'isbndb'
@@ -16,6 +16,8 @@ gem 'haml-rails'
16 16
 gem 'color'
17 17
 gem 'narray'
18 18
 gem 'formtastic'
  19
+gem 'rails3-jquery-autocomplete'
  20
+gem 'formtastic-bootstrap'
19 21
 gem 'handles_sortable_columns'
20 22
 gem 'gdata'
21 23
 gem 'cancan'
@@ -47,13 +49,23 @@ gem 'statsample'
47 49
 gem 'rails3-jquery-autocomplete'
48 50
 gem 'acts-as-taggable-on', :git => 'git://github.com/mbleigh/acts-as-taggable-on.git'
49 51
 gem 'chronic'
  52
+gem 'acts-as-tree-with-dotted-ids'
  53
+gem 'nifty-generators'
50 54
 #gem 'sparklines'
51 55
 #gem 'sparklines_generator'
52 56
 gem 'workflow'
53 57
 gem 'devise'
54 58
 gem 'web-app-theme'
55 59
 gem 'ruby_parser'
56  
-gem 'sass'
  60
+group :assets do
  61
+  gem 'therubyracer'
  62
+  gem 'sass-rails', "~> 3.1.0.rc"
  63
+  gem 'coffee-rails', "~> 3.1.0.rc"
  64
+  gem 'uglifier'
  65
+  gem 'compass'
  66
+  gem 'compass-bootstrap'
  67
+end
  68
+	
57 69
 gem 'barometer'
58 70
 gem 'mechanize'
59 71
 gem 'rails-settings-cached', :require => 'rails-settings'
@@ -72,8 +84,6 @@ group :development, :test do
72 84
   gem 'forgery'
73 85
   gem 'database_cleaner'
74 86
   gem 'cucumber_factory', :git => 'https://github.com/makandra/cucumber_factory.git'
75  
-  gem 'compass'
76  
-  gem 'compass-bootstrap'
77 87
 end
78 88
 gem 'yaml_db'
79 89
 gem 'email_validator'
162  Gemfile.lock
@@ -21,40 +21,44 @@ GIT
21 21
 GEM
22 22
   remote: http://rubygems.org/
23 23
   specs:
24  
-    abstract (1.0.0)
25  
-    actionmailer (3.0.10)
26  
-      actionpack (= 3.0.10)
27  
-      mail (~> 2.2.19)
28  
-    actionpack (3.0.10)
29  
-      activemodel (= 3.0.10)
30  
-      activesupport (= 3.0.10)
31  
-      builder (~> 2.1.2)
32  
-      erubis (~> 2.6.6)
33  
-      i18n (~> 0.5.0)
34  
-      rack (~> 1.2.1)
35  
-      rack-mount (~> 0.6.14)
36  
-      rack-test (~> 0.5.7)
37  
-      tzinfo (~> 0.3.23)
38  
-    activemodel (3.0.10)
39  
-      activesupport (= 3.0.10)
40  
-      builder (~> 2.1.2)
41  
-      i18n (~> 0.5.0)
42  
-    activerecord (3.0.10)
43  
-      activemodel (= 3.0.10)
44  
-      activesupport (= 3.0.10)
45  
-      arel (~> 2.0.10)
46  
-      tzinfo (~> 0.3.23)
47  
-    activeresource (3.0.10)
48  
-      activemodel (= 3.0.10)
49  
-      activesupport (= 3.0.10)
50  
-    activesupport (3.0.10)
51  
-    arel (2.0.10)
  24
+    actionmailer (3.1.0)
  25
+      actionpack (= 3.1.0)
  26
+      mail (~> 2.3.0)
  27
+    actionpack (3.1.0)
  28
+      activemodel (= 3.1.0)
  29
+      activesupport (= 3.1.0)
  30
+      builder (~> 3.0.0)
  31
+      erubis (~> 2.7.0)
  32
+      i18n (~> 0.6)
  33
+      rack (~> 1.3.2)
  34
+      rack-cache (~> 1.0.3)
  35
+      rack-mount (~> 0.8.2)
  36
+      rack-test (~> 0.6.1)
  37
+      sprockets (~> 2.0.0)
  38
+    activemodel (3.1.0)
  39
+      activesupport (= 3.1.0)
  40
+      bcrypt-ruby (~> 3.0.0)
  41
+      builder (~> 3.0.0)
  42
+      i18n (~> 0.6)
  43
+    activerecord (3.1.0)
  44
+      activemodel (= 3.1.0)
  45
+      activesupport (= 3.1.0)
  46
+      arel (~> 2.2.1)
  47
+      tzinfo (~> 0.3.29)
  48
+    activeresource (3.1.0)
  49
+      activemodel (= 3.1.0)
  50
+      activesupport (= 3.1.0)
  51
+    activesupport (3.1.0)
  52
+      multi_json (~> 1.0)
  53
+    acts-as-tree-with-dotted-ids (1.0.0)
  54
+      activerecord (>= 3.0.0)
  55
+    arel (2.2.1)
52 56
     barometer (0.7.3)
53 57
       httparty (>= 0.4.5)
54 58
       nokogiri
55 59
       tzinfo (>= 0.3.14)
56 60
     bcrypt-ruby (3.0.1)
57  
-    builder (2.1.2)
  61
+    builder (3.0.0)
58 62
     cancan (1.6.7)
59 63
     capybara (1.1.1)
60 64
       mime-types (>= 1.16)
@@ -68,6 +72,13 @@ GEM
68 72
     chronic (0.6.4)
69 73
     chunky_png (1.2.5)
70 74
     clbustos-rtf (0.4.2)
  75
+    coffee-rails (3.1.1)
  76
+      coffee-script (>= 2.2.0)
  77
+      railties (~> 3.1.0)
  78
+    coffee-script (2.2.0)
  79
+      coffee-script-source
  80
+      execjs
  81
+    coffee-script-source (1.2.0)
71 82
     color (1.4.1)
72 83
     compass (0.11.5)
73 84
       chunky_png (~> 1.2)
@@ -95,8 +106,9 @@ GEM
95 106
     distribution (0.7.0)
96 107
     email_validator (1.2.4)
97 108
       activemodel
98  
-    erubis (2.6.6)
99  
-      abstract (>= 1.0.0)
  109
+    erubis (2.7.0)
  110
+    execjs (1.2.13)
  111
+      multi_json (~> 1.0)
100 112
     extendmatrix (0.3.1)
101 113
     factory_girl (2.2.0)
102 114
       activesupport
@@ -108,6 +120,9 @@ GEM
108 120
     forgery (0.5.0)
109 121
     formtastic (2.0.0)
110 122
       rails (~> 3.0)
  123
+    formtastic-bootstrap (1.1.2)
  124
+      formtastic
  125
+      rails (~> 3.1.0)
111 126
     fssm (0.2.7)
112 127
     gdata (1.1.2)
113 128
     gherkin (2.6.2)
@@ -119,11 +134,12 @@ GEM
119 134
       haml (~> 3.0)
120 135
       railties (~> 3.0)
121 136
     handles_sortable_columns (0.1.3)
  137
+    hike (1.2.1)
122 138
     hpricot (0.8.4)
123 139
     httparty (0.8.0)
124 140
       multi_json
125 141
       multi_xml
126  
-    i18n (0.5.0)
  142
+    i18n (0.6.0)
127 143
     isbndb (1.5.5)
128 144
       activesupport
129 145
       i18n
@@ -133,11 +149,11 @@ GEM
133 149
     jquery-rails (1.0.14)
134 150
       railties (~> 3.0)
135 151
       thor (~> 0.14)
136  
-    json (1.6.1)
  152
+    json (1.6.3)
137 153
     json_pure (1.6.1)
  154
+    libv8 (3.3.10.4)
138 155
     libxml-ruby (2.2.2)
139  
-    mail (2.2.19)
140  
-      activesupport (>= 2.3.6)
  156
+    mail (2.3.0)
141 157
       i18n (>= 0.4.0)
142 158
       mime-types (~> 1.16)
143 159
       treetop (~> 1.4.8)
@@ -146,19 +162,20 @@ GEM
146 162
       net-http-persistent (~> 1.8)
147 163
       nokogiri (~> 1.4)
148 164
       webrobots (~> 0.0, >= 0.0.9)
149  
-    mime-types (1.16)
  165
+    mime-types (1.17.2)
150 166
     minimization (0.2.1)
151 167
       text-table (~> 1.2)
152  
-    multi_json (1.0.3)
  168
+    multi_json (1.0.4)
153 169
     multi_xml (0.4.1)
154 170
     mysql (2.8.1)
155 171
     n_gram (0.0.1)
156 172
     narray (0.6.0.1)
157 173
     net-http-digest_auth (1.1.1)
158 174
     net-http-persistent (1.9)
  175
+    nifty-generators (0.4.6)
159 176
     nokogiri (1.5.0)
160 177
     orm_adapter (0.0.5)
161  
-    polyglot (0.3.2)
  178
+    polyglot (0.3.3)
162 179
     prawn (0.8.4)
163 180
       prawn-core (>= 0.8.4, < 0.9)
164 181
       prawn-layout (>= 0.8.4, < 0.9)
@@ -169,32 +186,40 @@ GEM
169 186
     prawn-svg (0.9.1.10)
170 187
       prawn (>= 0.8.4)
171 188
       prawn-core (>= 0.8.4)
172  
-    rack (1.2.4)
173  
-    rack-mount (0.6.14)
  189
+    rack (1.3.5)
  190
+    rack-cache (1.0.3)
  191
+      rack (>= 0.4)
  192
+    rack-mount (0.8.3)
174 193
       rack (>= 1.0.0)
175  
-    rack-test (0.5.7)
  194
+    rack-ssl (1.3.2)
  195
+      rack
  196
+    rack-test (0.6.1)
176 197
       rack (>= 1.0)
177  
-    rails (3.0.10)
178  
-      actionmailer (= 3.0.10)
179  
-      actionpack (= 3.0.10)
180  
-      activerecord (= 3.0.10)
181  
-      activeresource (= 3.0.10)
182  
-      activesupport (= 3.0.10)
  198
+    rails (3.1.0)
  199
+      actionmailer (= 3.1.0)
  200
+      actionpack (= 3.1.0)
  201
+      activerecord (= 3.1.0)
  202
+      activeresource (= 3.1.0)
  203
+      activesupport (= 3.1.0)
183 204
       bundler (~> 1.0)
184  
-      railties (= 3.0.10)
  205
+      railties (= 3.1.0)
  206
+    rails-dev-tweaks (0.5.2)
  207
+      rails (~> 3.1.0)
185 208
     rails-settings-cached (0.1.2)
186 209
       rails (>= 3.0.0)
187 210
     rails3-jquery-autocomplete (1.0.4)
188 211
       rails (~> 3.0)
189  
-    railties (3.0.10)
190  
-      actionpack (= 3.0.10)
191  
-      activesupport (= 3.0.10)
  212
+    railties (3.1.0)
  213
+      actionpack (= 3.1.0)
  214
+      activesupport (= 3.1.0)
  215
+      rack-ssl (~> 1.3.2)
192 216
       rake (>= 0.8.7)
193 217
       rdoc (~> 3.4)
194  
-      thor (~> 0.14.4)
195  
-    rake (0.9.2)
  218
+      thor (~> 0.14.6)
  219
+    rake (0.9.2.2)
196 220
     rcov (0.9.11)
197  
-    rdoc (3.9.4)
  221
+    rdoc (3.12)
  222
+      json (~> 1.4)
198 223
     reportbuilder (1.4.1)
199 224
       clbustos-rtf (~> 0.4.0)
200 225
       prawn (~> 0.8.4)
@@ -220,6 +245,12 @@ GEM
220 245
     rubyvis (0.4.1)
221 246
     rubyzip (0.9.4)
222 247
     sass (3.1.7)
  248
+    sass-rails (3.1.4)
  249
+      actionpack (~> 3.1.0)
  250
+      railties (~> 3.1.0)
  251
+      sass (>= 3.1.4)
  252
+      sprockets (~> 2.0.0)
  253
+      tilt (~> 1.3.2)
223 254
     selenium-webdriver (2.10.0)
224 255
       childprocess (>= 0.2.1)
225 256
       ffi (= 1.0.9)
@@ -228,6 +259,10 @@ GEM
228 259
     sexp_processor (3.0.7)
229 260
     spreadsheet (0.6.5.9)
230 261
       ruby-ole (>= 1.0)
  262
+    sprockets (2.0.3)
  263
+      hike (~> 1.2)
  264
+      rack (~> 1.0)
  265
+      tilt (!= 1.3.0, ~> 1.1)
231 266
     sqlite3 (1.3.4)
232 267
     statsample (1.1.0)
233 268
       dirty-memoize (~> 0.0)
@@ -244,11 +279,17 @@ GEM
244 279
       distribution (~> 0.6)
245 280
     term-ansicolor (1.0.7)
246 281
     text-table (1.2.2)
  282
+    therubyracer (0.9.9)
  283
+      libv8 (~> 3.3.10)
247 284
     thor (0.14.6)
  285
+    tilt (1.3.3)
248 286
     treetop (1.4.10)
249 287
       polyglot
250 288
       polyglot (>= 0.3.1)
251  
-    tzinfo (0.3.29)
  289
+    tzinfo (0.3.31)
  290
+    uglifier (1.2.0)
  291
+      execjs (>= 0.3.0)
  292
+      multi_json (>= 1.0.2)
252 293
     warden (1.0.5)
253 294
       rack (>= 1.0)
254 295
     web-app-theme (0.7.0)
@@ -265,10 +306,12 @@ PLATFORMS
265 306
 
266 307
 DEPENDENCIES
267 308
   acts-as-taggable-on!
  309
+  acts-as-tree-with-dotted-ids
268 310
   barometer
269 311
   cancan
270 312
   capybara
271 313
   chronic
  314
+  coffee-rails (~> 3.1.0.rc)
272 315
   color
273 316
   compass
274 317
   compass-bootstrap
@@ -282,6 +325,7 @@ DEPENDENCIES
282 325
   fastercsv
283 326
   forgery
284 327
   formtastic
  328
+  formtastic-bootstrap
285 329
   gdata
286 330
   haml
287 331
   haml-rails
@@ -293,17 +337,21 @@ DEPENDENCIES
293 337
   mysql
294 338
   n_gram
295 339
   narray
296  
-  rails (= 3.0.10)
  340
+  nifty-generators
  341
+  rails (= 3.1)
  342
+  rails-dev-tweaks
297 343
   rails-settings-cached
298 344
   rails3-jquery-autocomplete
299 345
   rcov
300 346
   rspec
301 347
   rspec-rails
302 348
   ruby_parser
303  
-  sass
  349
+  sass-rails (~> 3.1.0.rc)
304 350
   sqlite3
305 351
   statsample
306 352
   subdomain-fu!
  353
+  therubyracer
  354
+  uglifier
307 355
   web-app-theme
308 356
   will_paginate
309 357
   workflow
9  app/assets/javascripts/application.js
... ...
@@ -0,0 +1,9 @@
  1
+// Place your application-specific JavaScript functions and classes here
  2
+// This file is automatically included by javascript_include_tag :defaults
  3
+//= require jquery
  4
+//= require jquery_ujs
  5
+//= require jquery-ui
  6
+//= require autocomplete-rails
  7
+//= require raphael-min
  8
+//= require jquery.sparkline.min
  9
+//= require_tree .
2  public/javascripts/application.js → app/assets/javascripts/quantified.js
... ...
@@ -1,5 +1,3 @@
1  
-// Place your application-specific JavaScript functions and classes here
2  
-// This file is automatically included by javascript_include_tag :defaults
3 1
 $(document).ready(function() {
4 2
 		$('.datepicker').datepicker({dateFormat: 'yy-m-d'});
5 3
 		$('.sparkline-bar').sparkline('html', {type: 'bar', barColor: '#85acaa', chartRangeMin: 0});
0  app/stylesheets/_forms.sass → app/assets/stylesheets/_forms.sass
File renamed without changes
0  app/stylesheets/_mixins.sass → app/assets/stylesheets/_mixins.sass
File renamed without changes
0  app/stylesheets/_patterns.sass → app/assets/stylesheets/_patterns.sass
File renamed without changes
0  app/stylesheets/_reset.sass → app/assets/stylesheets/_reset.sass
File renamed without changes
0  app/stylesheets/_scaffolding.sass → app/assets/stylesheets/_scaffolding.sass
File renamed without changes
0  app/stylesheets/_tables.sass → app/assets/stylesheets/_tables.sass
File renamed without changes
0  app/stylesheets/_type.sass → app/assets/stylesheets/_type.sass
File renamed without changes
0  app/stylesheets/_variables.sass → app/assets/stylesheets/_variables.sass
File renamed without changes
116  app/assets/stylesheets/application.sass
... ...
@@ -0,0 +1,116 @@
  1
+@import compass_bootstrap
  2
+$lightBackground: #eee
  3
+
  4
+body
  5
+  font-family: Calibri, sans-serif
  6
+  padding-top: 50px
  7
+a
  8
+  text-decoration: none
  9
+.topbar h1
  10
+  font-weight: bold
  11
+  font-size: x-large
  12
+  margin-bottom: 0
  13
+.entry
  14
+  display: inline-block
  15
+  .item
  16
+    display: inline-block
  17
+  margin-right: 10px  
  18
+.image
  19
+  float: right
  20
+  margin-left: 10px
  21
+.auto
  22
+  width: auto
  23
+.formtastic fieldset.inputs ol
  24
+  list-style: none
  25
+li.input
  26
+  margin-left: 0px
  27
+label.label
  28
+  padding-top: 6px
  29
+  font-size: 13px
  30
+  line-height: 18px
  31
+  float: left
  32
+  width: 20%
  33
+  text-align: right
  34
+  color: #404040
  35
+  background: #fff
  36
+  font-weight: normal
  37
+  text-transform: none
  38
+.formtastic li
  39
+  margin-top: 3px
  40
+  margin-bottom: 3px
  41
+  input, textarea, select
  42
+    margin-left: 10px
  43
+.formtastic .actions
  44
+  padding-left: 230px
  45
+  
  46
+input, textarea, select, .uneditable-input
  47
+  width: 50%
  48
+form .clear-fix 
  49
+  margin-bottom: 10px
  50
+  zoom: 1
  51
+.actions .btn
  52
+  margin-right: 10px
  53
+.category
  54
+  @extend .row
  55
+.category_label
  56
+  @extend .span3
  57
+  text-align: right
  58
+  display: block
  59
+  float: left
  60
+.category_detail
  61
+  padding-top: 13px
  62
+  margin-left: 170px
  63
+  @extend .span13
  64
+.contexts .category_detail, .time .category_detail
  65
+  padding-top: 0
  66
+.category_detail .pills
  67
+  margin-bottom: 0px
  68
+a[data-method]
  69
+  color: green
  70
+  font-weight: bold
  71
+.radio legend.label
  72
+  float: left
  73
+.tap_log_record
  74
+  .timestamp
  75
+    width: 150px
  76
+    text-align: right
  77
+  .categories
  78
+    width: 200px	
  79
+  .note
  80
+.status
  81
+  font-weight: normal
  82
+  display: inline
  83
+  @extend .label
  84
+.private
  85
+  font-weight: normal
  86
+  display: inline
  87
+  @extend .label
  88
+.collapsible > legend
  89
+  font-weight: bold
  90
+  margin-bottom: 10px
  91
+td.h
  92
+  font-weight: bold
  93
+.login, .sign_up
  94
+  .inner
  95
+    height: 200px
  96
+.radio legend.label
  97
+  padding-top: 6px
  98
+  font-size: 13px
  99
+  line-height: 18px
  100
+  float: left
  101
+  width: 20%
  102
+  text-align: right
  103
+  color: #404040
  104
+  background: white
  105
+  font-weight: normal
  106
+  text-transform: none
  107
+label.inline
  108
+  padding-top: 0px
  109
+  width: auto
  110
+  text-align: left
  111
+  margin-right: 10px
  112
+  float: none
  113
+.condensed-table
  114
+  font-size: smaller
  115
+.right
  116
+  text-align: right
0  app/stylesheets/compass_bootstrap.sass → app/assets/stylesheets/compass_bootstrap.sass
File renamed without changes
0  app/stylesheets/ie.sass → app/assets/stylesheets/ie.sass
File renamed without changes
0  app/stylesheets/mobile.sass → app/assets/stylesheets/mobile.sass
File renamed without changes
0  app/stylesheets/print.sass → app/assets/stylesheets/print.sass
File renamed without changes
0  app/stylesheets/screen.sass → app/assets/stylesheets/screen.sass
File renamed without changes
14  app/stylesheets/application.sass → app/assets/stylesheets/style.css.sass
... ...
@@ -1,5 +1,4 @@
1 1
 @import compass_bootstrap
2  
- 
3 2
 $lightBackground: #eee
4 3
 
5 4
 body
@@ -93,4 +92,15 @@ td.h
93 92
   font-weight: bold
94 93
 .login, .sign_up
95 94
   .inner
96  
-    height: 200px
  95
+    height: 200px
  96
+.radio legend.label
  97
+  padding-top: 6px
  98
+  font-size: 13px
  99
+  line-height: 18px
  100
+  float: left
  101
+  width: 20%
  102
+  text-align: right
  103
+  color: #404040
  104
+  background: white
  105
+  font-weight: normal
  106
+  text-transform: none
106  app/assets/stylesheets/style.sass
... ...
@@ -0,0 +1,106 @@
  1
+@import compass_bootstrap
  2
+$lightBackground: #eee
  3
+
  4
+body
  5
+  font-family: Calibri, sans-serif
  6
+  padding-top: 50px
  7
+a
  8
+  text-decoration: none
  9
+.topbar h1
  10
+  font-weight: bold
  11
+  font-size: x-large
  12
+  margin-bottom: 0
  13
+.entry
  14
+  display: inline-block
  15
+  .item
  16
+    display: inline-block
  17
+  margin-right: 10px  
  18
+.image
  19
+  float: right
  20
+  margin-left: 10px
  21
+.auto
  22
+  width: auto
  23
+.formtastic fieldset.inputs ol
  24
+  list-style: none
  25
+li.input
  26
+  margin-left: 0px
  27
+label.label
  28
+  padding-top: 6px
  29
+  font-size: 13px
  30
+  line-height: 18px
  31
+  float: left
  32
+  width: 20%
  33
+  text-align: right
  34
+  color: #404040
  35
+  background: #fff
  36
+  font-weight: normal
  37
+  text-transform: none
  38
+.formtastic li
  39
+  margin-top: 3px
  40
+  margin-bottom: 3px
  41
+  input, textarea, select
  42
+    margin-left: 10px
  43
+.formtastic .actions
  44
+  padding-left: 230px
  45
+  
  46
+input, textarea, select, .uneditable-input
  47
+  width: 50%
  48
+form .clear-fix 
  49
+  margin-bottom: 10px
  50
+  zoom: 1
  51
+.actions .btn
  52
+  margin-right: 10px
  53
+.category
  54
+  @extend .row
  55
+.category_label
  56
+  @extend .span3
  57
+  text-align: right
  58
+  display: block
  59
+  float: left
  60
+.category_detail
  61
+  padding-top: 13px
  62
+  margin-left: 170px
  63
+  @extend .span13
  64
+.contexts .category_detail, .time .category_detail
  65
+  padding-top: 0
  66
+.category_detail .pills
  67
+  margin-bottom: 0px
  68
+a[data-method]
  69
+  color: green
  70
+  font-weight: bold
  71
+.radio legend.label
  72
+  float: left
  73
+.tap_log_record
  74
+  .timestamp
  75
+    width: 150px
  76
+    text-align: right
  77
+  .categories
  78
+    width: 200px	
  79
+  .note
  80
+.status
  81
+  font-weight: normal
  82
+  display: inline
  83
+  @extend .label
  84
+.private
  85
+  font-weight: normal
  86
+  display: inline
  87
+  @extend .label
  88
+.collapsible > legend
  89
+  font-weight: bold
  90
+  margin-bottom: 10px
  91
+td.h
  92
+  font-weight: bold
  93
+.login, .sign_up
  94
+  .inner
  95
+    height: 200px
  96
+.radio legend.label
  97
+  padding-top: 6px
  98
+  font-size: 13px
  99
+  line-height: 18px
  100
+  float: left
  101
+  width: 20%
  102
+  text-align: right
  103
+  color: #404040
  104
+  background: white
  105
+  font-weight: normal
  106
+  text-transform: none
31  app/controllers/application_controller.rb
@@ -55,4 +55,35 @@ def filter_sortable_column_order(list)
55 55
     end
56 56
 #     sortable_column_order
57 57
   end
  58
+
  59
+  def go_to(url)
  60
+    if params[:destination].blank?
  61
+      redirect_to url
  62
+    else
  63
+      redirect_to params[:destination]
  64
+    end
  65
+  end
  66
+
  67
+  def add_flash(symbol, value)
  68
+    if flash[symbol].blank?
  69
+      flash[symbol] = value
  70
+    else
  71
+      if flash[symbol].is_a? String
  72
+        flash[symbol] = [flash[symbol]]
  73
+      end
  74
+      flash[symbol] << value
  75
+    end
  76
+  end
  77
+
  78
+  def prepare_filters(symbols)
  79
+    @filters = Hash.new
  80
+    symbols.each do |s|
  81
+      case s
  82
+      when :date_range
  83
+        @filters[:date_range] = t
  84
+        params[:start] ||= current_account.beginning_of_week.strftime('%Y-%m-%d')
  85
+        params[:end] ||= Time.zone.now.strftime('%Y-%m-%d')
  86
+      end
  87
+    end
  88
+  end
58 89
 end
123  app/controllers/record_categories_controller.rb
... ...
@@ -0,0 +1,123 @@
  1
+class RecordCategoriesController < ApplicationController
  2
+  autocomplete :record_category, :full_name, :full => true
  3
+  # GET /record_categories
  4
+  # GET /record_categories.xml
  5
+  def index
  6
+    authorize! :manage_account, current_account
  7
+    @record_categories = current_account.record_categories.where('parent_id IS NULL').order('name')
  8
+    respond_to do |format|
  9
+      format.html # index.html.erb
  10
+      format.xml  { render :xml => @record_categories }
  11
+    end
  12
+  end
  13
+
  14
+  # GET /record_categories/1
  15
+  # GET /record_categories/1.xml
  16
+  def show
  17
+    authorize! :manage_account, current_account
  18
+    @record_category = RecordCategory.find(params[:id])
  19
+    if @record_category.list?
  20
+      @records = @record_category.tree_records.order('timestamp DESC').paginate :page => params[:page], :per_page => 10
  21
+    else
  22
+      @records = @record_category.records.order('timestamp DESC').paginate :page => params[:page], :per_page => 10
  23
+    end
  24
+
  25
+    respond_to do |format|
  26
+      format.html # show.html.erb
  27
+      format.xml  { render :xml => @record_category }
  28
+    end
  29
+  end
  30
+
  31
+  # GET /record_categories/new
  32
+  # GET /record_categories/new.xml
  33
+  def new
  34
+    authorize! :manage_account, current_account
  35
+    @record_category = current_account.record_categories.new
  36
+    @record_category.parent_id = params[:parent_id]
  37
+    
  38
+    respond_to do |format|
  39
+      format.html # new.html.erb
  40
+      format.xml  { render :xml => @record_category }
  41
+    end
  42
+  end
  43
+
  44
+  # GET /record_categories/1/edit
  45
+  def edit
  46
+    authorize! :manage_account, current_account
  47
+    @record_category = current_account.record_categories.find(params[:id])
  48
+  end
  49
+
  50
+  # POST /record_categories
  51
+  # POST /record_categories.xml
  52
+  def create
  53
+    authorize! :manage_account, current_account
  54
+    @record_category = current_account.record_categories.new(params[:record_category])
  55
+
  56
+    respond_to do |format|
  57
+      if @record_category.save
  58
+        format.html { redirect_to(@record_category, :notice => 'Record category was successfully created.') }
  59
+        format.xml  { render :xml => @record_category, :status => :created, :location => @record_category }
  60
+      else
  61
+        format.html { render :action => "new" }
  62
+        format.xml  { render :xml => @record_category.errors, :status => :unprocessable_entity }
  63
+      end
  64
+    end
  65
+  end
  66
+
  67
+  # PUT /record_categories/1
  68
+  # PUT /record_categories/1.xml
  69
+  def update
  70
+    authorize! :manage_account, current_account
  71
+    @record_category = current_account.record_categories.find(params[:id])
  72
+
  73
+    respond_to do |format|
  74
+      if @record_category.update_attributes(params[:record_category])
  75
+        format.html { redirect_to(@record_category, :notice => 'Record category was successfully updated.') }
  76
+        format.xml  { head :ok }
  77
+      else
  78
+        format.html { render :action => "edit" }
  79
+        format.xml  { render :xml => @record_category.errors, :status => :unprocessable_entity }
  80
+      end
  81
+    end
  82
+  end
  83
+
  84
+  # DELETE /record_categories/1
  85
+  # DELETE /record_categories/1.xml
  86
+  def destroy
  87
+    authorize! :manage_account, current_account
  88
+    @record_category = current_account.record_categories.find(params[:id])
  89
+    @record_category.destroy
  90
+
  91
+    respond_to do |format|
  92
+      format.html { redirect_to(record_categories_url) }
  93
+      format.xml  { head :ok }
  94
+    end
  95
+  end
  96
+
  97
+  def track
  98
+    authorize! :manage_account, current_account
  99
+    @record_category = current_account.record_categories.find(params[:id])
  100
+    # Update the latest activity now that we know the ending timestamp
  101
+    now = Time.zone.now
  102
+    if @record_category.activity?
  103
+      Record.update_last(current_account, now)
  104
+      # Create record and allow user to edit it
  105
+    end
  106
+    rec = current_account.records.create(:timestamp => now, :source => 'quantified awesome record categories', :source_id => @record_category.id, :record_category_id => @record_category.id)
  107
+    redirect_to edit_record_path(rec)
  108
+  end
  109
+
  110
+  def bulk_update
  111
+    authorize! :manage_account, current_account
  112
+    params[:category_type].each do |k,v|
  113
+      cat = current_account.record_categories.find(k)
  114
+      cat.category_type = v
  115
+      cat.save!
  116
+    end
  117
+    if params[:commit] == t('records.index.recalculate_durations')
  118
+      Record.recalculate_durations(current_account)
  119
+      add_flash :notice, t('records.index.recalculated_durations')
  120
+    end
  121
+    go_to record_categories_path and return
  122
+  end
  123
+end
122  app/controllers/records_controller.rb
... ...
@@ -0,0 +1,122 @@
  1
+class RecordsController < ApplicationController
  2
+  # GET /records
  3
+  # GET /records.xml
  4
+  def index
  5
+    authorize! :manage_account, current_account
  6
+    @start = (!params[:start].blank? ? Time.zone.parse(params[:start]) : ((current_account.records.minimum('timestamp') || (Time.now - 1.week)))).in_time_zone.midnight
  7
+    @end = (!params[:end].blank? ? Time.zone.parse(params[:end]) : ((current_account.records.maximum('timestamp') || Time.now) + 1.day)).in_time_zone.midnight
  8
+    
  9
+    if params[:commit] == t('records.index.recalculate_durations')
  10
+      Record.recalculate_durations(current_account, @start - 1.day, @end + 1.day)
  11
+      add_flash :notice, t('records.index.recalculated_durations')
  12
+    end
  13
+
  14
+    @records = current_account.records.order('timestamp DESC')
  15
+    @records = @records.where(:timestamp => @start..@end)
  16
+    if cannot? :manage_account, current_account
  17
+      @records = @records.public
  18
+    end
  19
+    unless params[:filter_string].blank?
  20
+      query = "%" + params[:filter_string].downcase + "%"
  21
+      @records = @records.joins(:record_category).where('LOWER(records.data) LIKE ? OR LOWER(record_categories.full_name) LIKE ?', query, query)
  22
+      if cannot? :manage_account, current_account
  23
+        @records = @records.public
  24
+      end
  25
+    end
  26
+    @records = @records.paginate :page => params[:page]
  27
+    respond_to do |format|
  28
+      format.html # index.html.erb
  29
+      format.xml  { render :xml => @records }
  30
+    end
  31
+  end
  32
+
  33
+  # GET /records/1
  34
+  # GET /records/1.xml
  35
+  def show
  36
+    authorize! :manage_account, current_account
  37
+    @record = current_account.records.find(params[:id])
  38
+    @current_activity = @record.current_activity
  39
+    @during_this = @record.during_this
  40
+    @previous_activity = @record.previous.activities.first
  41
+    @previous_entry = @record.previous.first
  42
+    @next_activity = @record.next.activities.first
  43
+    @next_entry = @record.next.first
  44
+
  45
+    respond_to do |format|
  46
+      format.html # show.html.erb
  47
+      format.xml  { render :xml => @record }
  48
+    end
  49
+  end
  50
+
  51
+  # GET /records/new
  52
+  # GET /records/new.xml
  53
+  def new
  54
+    authorize! :manage_account, current_account
  55
+    @record = current_account.records.new
  56
+
  57
+    respond_to do |format|
  58
+      format.html # new.html.erb
  59
+      format.xml  { render :xml => @record }
  60
+    end
  61
+  end
  62
+
  63
+  # GET /records/1/edit
  64
+  def edit
  65
+    authorize! :manage_account, current_account
  66
+    @record = current_account.records.find(params[:id])
  67
+  end
  68
+
  69
+  # POST /records
  70
+  # POST /records.xml
  71
+  def create
  72
+    authorize! :manage_account, current_account
  73
+    @record = current_account.records.new(params[:record])
  74
+
  75
+    respond_to do |format|
  76
+      if @record.save
  77
+        format.html { redirect_to(@record, :notice => 'Record was successfully created.') }
  78
+        format.xml  { render :xml => @record, :status => :created, :location => @record }
  79
+      else
  80
+        format.html { render :action => "new" }
  81
+        format.xml  { render :xml => @record.errors, :status => :unprocessable_entity }
  82
+      end
  83
+    end
  84
+  end
  85
+
  86
+  # PUT /records/1
  87
+  # PUT /records/1.xml
  88
+  def update
  89
+    authorize! :manage_account, current_account
  90
+    @record = current_account.records.find(params[:id])
  91
+
  92
+    respond_to do |format|
  93
+      if @record.update_attributes(params[:record])
  94
+        format.html { redirect_to(@record, :notice => 'Record was successfully updated.') }
  95
+        format.xml  { head :ok }
  96
+      else
  97
+        format.html { render :action => "edit" }
  98
+        format.xml  { render :xml => @record.errors, :status => :unprocessable_entity }
  99
+      end
  100
+    end
  101
+  end
  102
+
  103
+  # DELETE /records/1
  104
+  # DELETE /records/1.xml
  105
+  def destroy
  106
+    authorize! :manage_account, current_account
  107
+    @record = current_account.records.find(params[:id])
  108
+    @record.destroy
  109
+
  110
+    respond_to do |format|
  111
+      format.html { redirect_to(records_url) }
  112
+      format.xml  { head :ok }
  113
+    end
  114
+  end
  115
+
  116
+  def clone
  117
+    authorize! :manage_account, current_account
  118
+    @record = current_account.records.find(params[:id])
  119
+    @record = @record.dup
  120
+    render 'edit'
  121
+  end
  122
+end
220  app/controllers/time_controller.rb
@@ -6,11 +6,9 @@ class TimeController < ApplicationController
6 6
   # POST
7 7
   def refresh_from_csv
8 8
     authorize! :manage_account, current_account
9  
-    @log = TimeTrackerLog.new(current_account)
10  
-    if params[:file]
11  
-      @log.refresh_from_csv(params[:file].tempfile)
12  
-    elsif params[:tap_file]
13  
-      @log.refresh_from_tap_log(params[:tap_file].tempfile.path)
  9
+    if params[:tap_file]
  10
+      Record.refresh_from_tap_log(current_account, params[:tap_file].tempfile.path)
  11
+      add_flash :notice, t('time.refreshed')
14 12
     end
15 13
     redirect_to :action => "graph"
16 14
   end 
@@ -19,180 +17,62 @@ def refresh
19 17
     authorize! :manage_account, current_account
20 18
   end
21 19
 
22  
-  def index
  20
+  def review
23 21
     authorize! :view_time, current_account
24  
-    @log = TimeTrackerLog.new(current_account)
25  
-    base = Chronic.parse("last Saturday").midnight
26  
-    @limits = {"this_week" => [base, base + 1.week],
27  
-      "last_week" => [base - 1.week, base],
28  
-      "other_week" => [base - 2.weeks, base - 1.week]}
29  
-    @summary = Hash.new
30  
-    # Current week
31  
-    @limits.each do |k,l|
32  
-      @summary[k] = @log.summarize(l[0], l[1])
33  
-    end
34  
-    if params[:format] == 'org'
35  
-      render "index_org"
36  
-    else
37  
-      render "index"
  22
+    params[:start] ||= current_account.beginning_of_week.advance(:weeks => -1).strftime('%Y-%m-%d')
  23
+    params[:end] ||= Time.zone.now.strftime('%Y-%m-%d')
  24
+    prepare_filters [:date_range]
  25
+    @summary_start = Date.parse(params[:start])
  26
+    @summary_end = Date.parse(params[:end])
  27
+    # Pick the appropriate level of review
  28
+    @category = params[:parent_id] ? current_account.record_categories.find(params[:parent_id]) : nil
  29
+    range = @summary_start..@summary_end
  30
+    @zoom = Record.choose_zoom_level(range)
  31
+    @summary = RecordCategory.summarize(:user => current_account, :range => range, :zoom => @zoom, :parent => @category, :summarize_children => true)
  32
+    respond_to do |format|
  33
+      format.html # index.html.erb
  34
+      format.xml  { render :xml => @record_categories }
38 35
     end
39 36
   end
40 37
 
41 38
   def graph
42 39
     authorize! :view_time, current_account
43  
-    @day_height = 15;
44  
-    @width = 900
45  
-    @time_bottom = @height
46  
-    @start = (!params[:start].blank? ? Time.zone.parse(params[:start]) : (current_account.time_records.maximum('end_time') || Date.today) - 1.week).in_time_zone.midnight
47  
-    @end = (!params[:end].blank? ? Time.zone.parse(params[:end]) : (current_account.time_records.maximum('end_time') || Date.today)).in_time_zone.midnight
48  
-    @height = (@day_height * (1 + (@end - @start) / 1.day)).to_i
49  
-    entries = current_account.time_records.find(:all, :conditions => ["start_time >= ? AND start_time < ?", @start, @end], :order => "start_time")
50  
-    total_time = (@end - @start).to_f
51  
-    @time_records = Array.new
52  
-    @day_height = (@height * 86400.0) / (@end.midnight - @start.midnight)
53  
-    @second_width = (@width / 2 - 5) / 86400.0
54  
-    days = Hash.new
55  
-    @totals = Hash.new
56  
-    entries.each do |e|
57  
-      x = ((@second_width * (e.start_time - e.start_time.midnight))).to_i
58  
-      y = ((@day_height * (e.start_time.midnight - @start.midnight) / 86400.0)).to_i
59  
-      item_width = @second_width * (e.end_time - e.start_time)
60  
-      class_name = e.name.downcase.gsub(/[^a-z]/, '')
61  
-      if e.name == "A - Sleep" then
62  
-        next
63  
-      elsif e.name == "A - Work" then
64  
-        color = "#85acaa"
65  
-      elsif e.name.match(/^D - /) then
66  
-        color = "#c2d6cb"
67  
-      elsif e.name.match(/^UW - /) then
68  
-        color = "#dd9843"
69  
-      elsif e.name.match(/^P - /) then
70  
-        color = "#acaa85"
71  
-      end
72  
-      title = "#{e.start_time.strftime('%Y-%m-%d %H:%M')} - #{e.end_time.strftime('%H:%M')} #{e.name}" 
73  
-      @time_records << { :x => x, :y => y, :width => item_width, 
74  
-        :color => color,
75  
-        :name => e.name,
76  
-        :class => class_name,
77  
-        :title => title}
78  
-      days[e.start_time.midnight] ||= Hash.new
79  
-      days[e.start_time.midnight][e.name] ||= Hash.new
80  
-      days[e.start_time.midnight][e.name][:title] = e.name
81  
-      days[e.start_time.midnight][e.name][:color] = color
82  
-      days[e.start_time.midnight][e.name][:class] = class_name
83  
-      days[e.start_time.midnight][e.name][:value] ||= 0
84  
-      days[e.start_time.midnight][e.name][:value] += (e.end_time - e.start_time)
85  
-      @totals[e.name] ||= Hash.new
86  
-      @totals[e.name][:value] ||= 0
87  
-      @totals[e.name][:color] = color