tawork 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (239) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +16 -0
  4. data/Gemfile +91 -0
  5. data/Gemfile.lock +295 -0
  6. data/MIT-LICENSE +20 -0
  7. data/Procfile +2 -0
  8. data/README.md +1 -0
  9. data/Rakefile +6 -0
  10. data/app/assets/images/.keep +0 -0
  11. data/app/assets/javascripts/application.js +31 -0
  12. data/app/assets/javascripts/backbone/models/.gitkeep +0 -0
  13. data/app/assets/javascripts/backbone/routers/.gitkeep +0 -0
  14. data/app/assets/javascripts/backbone/tawork.js.coffee +11 -0
  15. data/app/assets/javascripts/backbone/templates/.gitkeep +0 -0
  16. data/app/assets/javascripts/backbone/views/.gitkeep +0 -0
  17. data/app/assets/javascripts/backbone/views/page.js.coffee +75 -0
  18. data/app/assets/javascripts/backbone/views/ticket.js.coffee +110 -0
  19. data/app/assets/javascripts/backbone/views/tree_node_page.js.coffee +16 -0
  20. data/app/assets/javascripts/backbone/views/tree_node_ticket.js.coffee +14 -0
  21. data/app/assets/javascripts/wiki/pages.js.coffee +3 -0
  22. data/app/assets/stylesheets/application.css +22 -0
  23. data/app/assets/stylesheets/bootstrap_and_overrides.sass +208 -0
  24. data/app/assets/stylesheets/diff.css +14 -0
  25. data/app/assets/stylesheets/wiki/pages.css.scss +3 -0
  26. data/app/controllers/application_controller.rb +15 -0
  27. data/app/controllers/assignments_controller.rb +30 -0
  28. data/app/controllers/attachments_controller.rb +10 -0
  29. data/app/controllers/comments_controller.rb +24 -0
  30. data/app/controllers/concerns/.keep +0 -0
  31. data/app/controllers/home_controller.rb +7 -0
  32. data/app/controllers/projects_controller.rb +31 -0
  33. data/app/controllers/search_controller.rb +49 -0
  34. data/app/controllers/sink_controller.rb +10 -0
  35. data/app/controllers/tickets_controller.rb +147 -0
  36. data/app/controllers/users/omniauth_callbacks_controller.rb +23 -0
  37. data/app/controllers/wiki/pages_controller.rb +115 -0
  38. data/app/controllers/wiki/spaces_controller.rb +37 -0
  39. data/app/helpers/application_helper.rb +20 -0
  40. data/app/helpers/wiki/pages_helper.rb +2 -0
  41. data/app/inputs/fake_input.rb +6 -0
  42. data/app/mailers/.keep +0 -0
  43. data/app/models/.keep +0 -0
  44. data/app/models/assignment.rb +5 -0
  45. data/app/models/attachment.rb +54 -0
  46. data/app/models/bug.rb +2 -0
  47. data/app/models/comment.rb +6 -0
  48. data/app/models/concerns/.keep +0 -0
  49. data/app/models/page.rb +68 -0
  50. data/app/models/project.rb +2 -0
  51. data/app/models/space.rb +2 -0
  52. data/app/models/story.rb +29 -0
  53. data/app/models/story_detail.rb +3 -0
  54. data/app/models/task.rb +2 -0
  55. data/app/models/ticket.rb +127 -0
  56. data/app/models/user.rb +36 -0
  57. data/app/models/user_verifier.rb +2 -0
  58. data/app/views/comments/_comment.html.haml +6 -0
  59. data/app/views/comments/_form.html.haml +4 -0
  60. data/app/views/comments/create.js.coffee +7 -0
  61. data/app/views/devise/confirmations/new.html.erb +12 -0
  62. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  63. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  64. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  65. data/app/views/devise/passwords/edit.html.erb +16 -0
  66. data/app/views/devise/passwords/new.html.erb +12 -0
  67. data/app/views/devise/registrations/edit.html.erb +29 -0
  68. data/app/views/devise/registrations/new.html.erb +18 -0
  69. data/app/views/devise/sessions/new.html.erb +17 -0
  70. data/app/views/devise/shared/_links.erb +25 -0
  71. data/app/views/devise/unlocks/new.html.erb +12 -0
  72. data/app/views/home/index.html.haml +4 -0
  73. data/app/views/layouts/_activity_wrapper.html.haml +17 -0
  74. data/app/views/layouts/_nav_header.html.haml +26 -0
  75. data/app/views/layouts/_spaces.html.haml +34 -0
  76. data/app/views/layouts/application.html.haml +39 -0
  77. data/app/views/layouts/minimal.html.haml +22 -0
  78. data/app/views/projects/index.html.haml +16 -0
  79. data/app/views/projects/new.html.haml +6 -0
  80. data/app/views/public_activity/ticket/_assignment.html.haml +14 -0
  81. data/app/views/public_activity/ticket/_create_comment.html.haml +10 -0
  82. data/app/views/public_activity/ticket/_created.html.haml +3 -0
  83. data/app/views/public_activity/ticket/_reorder.html.haml +2 -0
  84. data/app/views/public_activity/ticket/_state_change.html.haml +2 -0
  85. data/app/views/public_activity/ticket/_update_details.html.haml +13 -0
  86. data/app/views/tickets/_activity.html.haml +3 -0
  87. data/app/views/tickets/_breadcrumb.html.haml +7 -0
  88. data/app/views/tickets/_bug_form.html.haml +1 -0
  89. data/app/views/tickets/_events_dropdown.html.haml +4 -0
  90. data/app/views/tickets/_form.html.haml +28 -0
  91. data/app/views/tickets/_project_form.html.haml +1 -0
  92. data/app/views/tickets/_story_form.html.haml +15 -0
  93. data/app/views/tickets/_task_form.html.haml +8 -0
  94. data/app/views/tickets/_tickets_listing.html.haml +5 -0
  95. data/app/views/tickets/_title_and_description.html.haml +8 -0
  96. data/app/views/tickets/_tree_node.html.haml +28 -0
  97. data/app/views/tickets/assignment.js.coffee +3 -0
  98. data/app/views/tickets/create.js.coffee +7 -0
  99. data/app/views/tickets/new.html.haml +1 -0
  100. data/app/views/tickets/show.html.haml +64 -0
  101. data/app/views/tickets/trigger_event.js.coffee +12 -0
  102. data/app/views/tickets/update.js.coffee +12 -0
  103. data/app/views/wiki/pages/_attachment.html.haml +5 -0
  104. data/app/views/wiki/pages/_attachments.html.haml +22 -0
  105. data/app/views/wiki/pages/_breadcrumb.html.haml +9 -0
  106. data/app/views/wiki/pages/_child_menu.html.haml +9 -0
  107. data/app/views/wiki/pages/_display.html.haml +138 -0
  108. data/app/views/wiki/pages/_page_header.html.haml +13 -0
  109. data/app/views/wiki/pages/_subpages_dropdown.html.haml +6 -0
  110. data/app/views/wiki/pages/_subtree.html.haml +7 -0
  111. data/app/views/wiki/pages/_tree_node.html.haml +21 -0
  112. data/app/views/wiki/pages/attach.js.coffee +2 -0
  113. data/app/views/wiki/pages/combined.html.haml +8 -0
  114. data/app/views/wiki/pages/create.js.coffee +5 -0
  115. data/app/views/wiki/pages/edit.html.haml +2 -0
  116. data/app/views/wiki/pages/history.html.haml +13 -0
  117. data/app/views/wiki/pages/index.html.haml +2 -0
  118. data/app/views/wiki/pages/new.html.haml +13 -0
  119. data/app/views/wiki/pages/show.html.haml +14 -0
  120. data/app/views/wiki/pages/update.html.haml +2 -0
  121. data/app/views/wiki/spaces/_page_list_item.html.haml +11 -0
  122. data/app/views/wiki/spaces/_space_list.html.haml +4 -0
  123. data/app/views/wiki/spaces/new.html.haml +5 -0
  124. data/app/views/wiki/spaces/space_list.html.haml +1 -0
  125. data/bin/bundle +3 -0
  126. data/bin/rails +4 -0
  127. data/bin/rake +4 -0
  128. data/config/application.rb +30 -0
  129. data/config/boot.rb +4 -0
  130. data/config/database.yml +39 -0
  131. data/config/environment.rb +5 -0
  132. data/config/environments/development.rb +35 -0
  133. data/config/environments/production.rb +80 -0
  134. data/config/environments/test.rb +36 -0
  135. data/config/initializers/backtrace_silencers.rb +7 -0
  136. data/config/initializers/config.rb +4 -0
  137. data/config/initializers/devise.rb +257 -0
  138. data/config/initializers/elasticsearch.rb +9 -0
  139. data/config/initializers/filter_parameter_logging.rb +4 -0
  140. data/config/initializers/gollum.rb +31 -0
  141. data/config/initializers/haml_gfm.rb +66 -0
  142. data/config/initializers/inflections.rb +16 -0
  143. data/config/initializers/mime_types.rb +5 -0
  144. data/config/initializers/secret_token.rb +12 -0
  145. data/config/initializers/session_store.rb +3 -0
  146. data/config/initializers/simple_form.rb +145 -0
  147. data/config/initializers/simple_form_bootstrap.rb +73 -0
  148. data/config/initializers/wrap_parameters.rb +14 -0
  149. data/config/locales/devise.en.yml +59 -0
  150. data/config/locales/en.yml +23 -0
  151. data/config/locales/simple_form.en.yml +26 -0
  152. data/config/routes.rb +101 -0
  153. data/config/tinymce.yml +10 -0
  154. data/config.ru +4 -0
  155. data/db/migrate/20131209041251_create_tickets.rb +13 -0
  156. data/db/migrate/20131210041050_devise_create_users.rb +42 -0
  157. data/db/migrate/20131210043014_add_username_to_users.rb +5 -0
  158. data/db/migrate/20131210045348_add_creator_to_ticket.rb +5 -0
  159. data/db/migrate/20131211034104_create_comments.rb +11 -0
  160. data/db/migrate/20131212073014_create_assignments.rb +12 -0
  161. data/db/migrate/20131215220825_add_position_to_ticket.rb +5 -0
  162. data/db/migrate/20131216044331_create_story_details.rb +12 -0
  163. data/db/migrate/20131218060557_create_activities.rb +23 -0
  164. data/db/migrate/20140109235844_create_pages.rb +14 -0
  165. data/db/migrate/20140112004346_create_attachments.rb +13 -0
  166. data/db/migrate/20140120030547_add_name_to_users.rb +5 -0
  167. data/db/schema.rb +125 -0
  168. data/db/seeds.rb +7 -0
  169. data/init.rb +1 -0
  170. data/lib/assets/.keep +0 -0
  171. data/lib/tasks/.keep +0 -0
  172. data/lib/tawork/engine.rb +13 -0
  173. data/lib/tawork/version.rb +3 -0
  174. data/lib/tawork.rb +4 -0
  175. data/lib/templates/haml/scaffold/_form.html.haml +10 -0
  176. data/lib/ticket_assignment.rb +25 -0
  177. data/log/.keep +0 -0
  178. data/public/401.html +57 -0
  179. data/public/404.html +58 -0
  180. data/public/422.html +58 -0
  181. data/public/500.html +57 -0
  182. data/public/favicon.ico +0 -0
  183. data/public/robots.txt +5 -0
  184. data/tags +279 -0
  185. data/tawork.gemspec +24 -0
  186. data/vendor/.DS_Store +0 -0
  187. data/vendor/assets/.DS_Store +0 -0
  188. data/vendor/assets/javascripts/.keep +0 -0
  189. data/vendor/assets/javascripts/bootstrap-tagsinput.js +503 -0
  190. data/vendor/assets/javascripts/bootstrap-tree.js +15 -0
  191. data/vendor/assets/javascripts/bootstrap-typeahead.js +335 -0
  192. data/vendor/assets/javascripts/hallo.js +2949 -0
  193. data/vendor/assets/javascripts/highlight.pack.js +1 -0
  194. data/vendor/assets/javascripts/jquery.autosize.js +250 -0
  195. data/vendor/assets/javascripts/jquery.mjs.nestedSortable.js +613 -0
  196. data/vendor/assets/javascripts/rangy-core.js +94 -0
  197. data/vendor/assets/javascripts/tinymce/mention/plugin.js +358 -0
  198. data/vendor/assets/stylesheets/.keep +0 -0
  199. data/vendor/assets/stylesheets/bootflat-extensions.css +356 -0
  200. data/vendor/assets/stylesheets/bootflat-square.css +69 -0
  201. data/vendor/assets/stylesheets/bootflat.css +1556 -0
  202. data/vendor/assets/stylesheets/bootstrap-tagsinput.css +45 -0
  203. data/vendor/assets/stylesheets/bootstrap-tree.sass +82 -0
  204. data/vendor/assets/stylesheets/highlight/arta.css +160 -0
  205. data/vendor/assets/stylesheets/highlight/ascetic.css +50 -0
  206. data/vendor/assets/stylesheets/highlight/brown_paper.css +105 -0
  207. data/vendor/assets/stylesheets/highlight/brown_papersq.png +0 -0
  208. data/vendor/assets/stylesheets/highlight/dark.css +105 -0
  209. data/vendor/assets/stylesheets/highlight/default.css +153 -0
  210. data/vendor/assets/stylesheets/highlight/docco.css +132 -0
  211. data/vendor/assets/stylesheets/highlight/far.css +113 -0
  212. data/vendor/assets/stylesheets/highlight/foundation.css +133 -0
  213. data/vendor/assets/stylesheets/highlight/github.css +130 -0
  214. data/vendor/assets/stylesheets/highlight/googlecode.css +146 -0
  215. data/vendor/assets/stylesheets/highlight/idea.css +122 -0
  216. data/vendor/assets/stylesheets/highlight/ir_black.css +105 -0
  217. data/vendor/assets/stylesheets/highlight/magula.css +123 -0
  218. data/vendor/assets/stylesheets/highlight/mono-blue.css +62 -0
  219. data/vendor/assets/stylesheets/highlight/monokai.css +127 -0
  220. data/vendor/assets/stylesheets/highlight/monokai_sublime.css +102 -0
  221. data/vendor/assets/stylesheets/highlight/obsidian.css +154 -0
  222. data/vendor/assets/stylesheets/highlight/pojoaque.css +105 -0
  223. data/vendor/assets/stylesheets/highlight/pojoaque.jpg +0 -0
  224. data/vendor/assets/stylesheets/highlight/railscasts.css +182 -0
  225. data/vendor/assets/stylesheets/highlight/rainbow.css +115 -0
  226. data/vendor/assets/stylesheets/highlight/school_book.css +113 -0
  227. data/vendor/assets/stylesheets/highlight/school_book.png +0 -0
  228. data/vendor/assets/stylesheets/highlight/solarized_dark.css +92 -0
  229. data/vendor/assets/stylesheets/highlight/solarized_light.css +92 -0
  230. data/vendor/assets/stylesheets/highlight/sunburst.css +160 -0
  231. data/vendor/assets/stylesheets/highlight/tomorrow-night-blue.css +52 -0
  232. data/vendor/assets/stylesheets/highlight/tomorrow-night-bright.css +51 -0
  233. data/vendor/assets/stylesheets/highlight/tomorrow-night-eighties.css +51 -0
  234. data/vendor/assets/stylesheets/highlight/tomorrow-night.css +52 -0
  235. data/vendor/assets/stylesheets/highlight/tomorrow.css +49 -0
  236. data/vendor/assets/stylesheets/highlight/vs.css +89 -0
  237. data/vendor/assets/stylesheets/highlight/xcode.css +157 -0
  238. data/vendor/assets/stylesheets/highlight/zenburn.css +117 -0
  239. metadata +299 -0
@@ -0,0 +1,16 @@
1
+ class Tawork.Views.TreeNodePageView extends Tawork.Views.PageView
2
+ events: ->
3
+ _.extend {}, Tawork.Views.PageView.events, {
4
+ "click .node-handle": "toggle_tree_node"
5
+ }
6
+
7
+ toggle_tree_node: (event) ->
8
+ $node_handle = $(event.target).closest(".node-handle")
9
+ return if @$(".node-handle:first").get(0) != $node_handle.get(0)
10
+ return if @$("> ol").length == 0
11
+ @$el.toggleClass('mjs-nestedSortable-collapsed').toggleClass('mjs-nestedSortable-expanded')
12
+
13
+
14
+ setup_uploader: ->
15
+
16
+
@@ -0,0 +1,14 @@
1
+ class Tawork.Views.TreeNodeTicketView extends Tawork.Views.TicketView
2
+ events: ->
3
+ _.extend {}, Tawork.Views.TicketView.prototype.events, {
4
+ "click .node-handle": "toggle_tree_node"
5
+ }
6
+
7
+ toggle_tree_node: (event) ->
8
+ $node_handle = $(event.target).closest(".node-handle")
9
+ return if @$(".node-handle:first").get(0) != $node_handle.get(0)
10
+ return if @$("> ol").length == 0
11
+ @$el.toggleClass('mjs-nestedSortable-collapsed').toggleClass('mjs-nestedSortable-expanded')
12
+
13
+
14
+
@@ -0,0 +1,3 @@
1
+ # Place all the behaviors and hooks related to the matching controller here.
2
+ # All this logic will automatically be available in application.js.
3
+ # You can use CoffeeScript in this file: http://coffeescript.org/
@@ -0,0 +1,22 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require bootstrap_and_overrides
13
+ *= require bootflat
14
+ *= require bootflat-extensions
15
+ *= require bootflat-square
16
+ *= require_tree .
17
+ */
18
+
19
+ .main-navbar {
20
+ border-radius: 0px !important;
21
+ }
22
+
@@ -0,0 +1,208 @@
1
+ @import bootstrap
2
+ @import bootstrap-tree
3
+ @import bootstrap-tagsinput
4
+ @import components-font-awesome
5
+
6
+
7
+ body
8
+ font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif
9
+ font-size: 15px
10
+ line-height: 1.428571429
11
+
12
+ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6
13
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif
14
+
15
+ .label.title
16
+ display: table-caption
17
+ margin: 0
18
+ margin-bottom: .25em
19
+
20
+ .label.label-task
21
+ @extend .label-warning
22
+
23
+ .btn.btn-task
24
+ @extend .btn-warning
25
+
26
+ .label.label-bug
27
+ @extend .label-danger
28
+
29
+ .btn.btn-bug
30
+ @extend .btn-danger
31
+
32
+ .label.label-story
33
+ @extend .label-primary
34
+
35
+ .btn.btn-story
36
+ @extend .btn-primary
37
+
38
+ .label.label-project
39
+ @extend .label-info
40
+
41
+ .btn.btn-project
42
+ @extend .btn-info
43
+
44
+ .bootstrap-tagsinput
45
+ width: 100% !important
46
+
47
+ .ticket-placeholder, .page-placeholder
48
+ outline: 1px dashed #4183C4
49
+ border-radius: 3px
50
+
51
+ .tree > ol
52
+ padding: 0
53
+
54
+ li.mjs-nestedSortable-collapsed
55
+ > ol
56
+ display: none
57
+
58
+ > .panel > .panel-body > .node-handle > .node-toggle > i.fa
59
+ @extend .fa-plus-circle
60
+ cursor: pointer
61
+
62
+ // .node-handle:last > .node > i.fa
63
+ // content: ''
64
+
65
+ li.mjs-nestedSortable-expanded
66
+ > .panel > .panel-body > .node-handle > .node-toggle > i.fa
67
+ @extend .fa-minus-circle
68
+ cursor: pointer
69
+
70
+ // .node-handle:last-of-type > .node > i.fa
71
+ // cursor: ''
72
+
73
+ .story_who, .story_what, .story_why
74
+ display: inline
75
+
76
+ input
77
+ display: inline
78
+
79
+ .story_who input
80
+ width: 20%
81
+
82
+ .story_what input
83
+ width: 62%
84
+
85
+ .story_why input
86
+ width: 87%
87
+
88
+ // .breadcrumb li a
89
+ // width: 110px
90
+ // overflow: hidden
91
+ // text-overflow: ellipsis
92
+ // white-space: nowrap
93
+ // display: inline-block
94
+
95
+ // &:hover
96
+ // display: inline
97
+
98
+ .ticket-description
99
+
100
+ table
101
+ @extend .table
102
+
103
+ .ticket-state
104
+ position: relative
105
+
106
+ .mce-content-body
107
+ outline: 1px dotted #333
108
+
109
+ .node-handle
110
+ cursor: move
111
+
112
+ .tree
113
+ .tree-node
114
+ margin: 3px 0
115
+
116
+ .panel
117
+ margin-bottom: 5px
118
+
119
+ .node-title
120
+ padding-left: 85px
121
+ padding-right: 80px
122
+
123
+ .panel-body
124
+ padding: 5px
125
+
126
+ .node-handle
127
+ position: absolute
128
+ top: 0
129
+ left: 0
130
+ height: 100%
131
+
132
+ border: none
133
+ height: 100%
134
+ border-top-right-radius: 0
135
+ border-bottom-right-radius: 0
136
+ border-bottom-left-radius: 3px
137
+ border-top-left-radius: 3px
138
+ width: 75px
139
+ padding: 5px 10px
140
+ color: white
141
+ background-color: #aeb1b1
142
+
143
+ &.node-story
144
+ background-color: $brand-primary
145
+
146
+ &.node-task
147
+ background-color: $brand-warning
148
+
149
+ &.node-bug
150
+ background-color: $brand-danger
151
+
152
+ .details
153
+ width: 110px
154
+ position: absolute
155
+ top: 0
156
+ right: 0
157
+ height: 100%
158
+
159
+ .ticket-state
160
+ height: 100%
161
+
162
+ button.btn
163
+ padding-right: 5px
164
+ padding-top: 4px
165
+ text-align: right
166
+ width: 100px
167
+ height: 100%
168
+ border-top-right-radius: 3px
169
+ border-bottom-right-radius: 3px
170
+ border-bottom-left-radius: 0px
171
+ border-top-left-radius: 0px
172
+
173
+ &[data-state=open]
174
+ border-color: $brand-primary
175
+ background-color: $brand-primary
176
+
177
+ &[data-state=completed]
178
+ border-color: $brand-info
179
+ background-color: $brand-info
180
+
181
+ &[data-state=current]
182
+ border-color: #aeb1b1
183
+ background-color: #aeb1b1
184
+
185
+ &[data-state=verified]
186
+ border-color: $brand-success
187
+ background-color: $brand-success
188
+
189
+ i.fa
190
+ margin-left: 3px
191
+
192
+ .page.tree-node
193
+ .node-handle
194
+ width: 35px
195
+ .node-title
196
+ padding-left: 45px
197
+
198
+ .page-list-item ul.nav-list-sub
199
+ padding-left: 10px
200
+ li a
201
+ padding-left: 15px
202
+
203
+ .nav-list-panel .selected > a,
204
+ .nav-list-panel .selected > a:hover,
205
+ .nav-list-panel .selected > a:focus
206
+ color: #fff
207
+ background-color: #2986b9
208
+ text-decoration: none
@@ -0,0 +1,14 @@
1
+ .diff{overflow:auto;}
2
+ .diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0;display:table;width:100%;}
3
+ .diff del, .diff ins{display:block;text-decoration:none;}
4
+ .diff li{padding:0; display:table-row;margin: 0;height:1em;}
5
+ .diff li.ins{background:#dfd; color:#080}
6
+ .diff li.ins ins{background:#dfd; color:#080}
7
+ .diff li.del{background:#fee; color:#b00}
8
+ .diff li:hover{background:#ffc}
9
+ /* try 'whitespace:pre;' if you don't want lines to wrap */
10
+ .diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;}
11
+ .diff del strong{font-weight:normal;background:#fcc;}
12
+ .diff ins strong{font-weight:normal;background:#9f9;}
13
+ .diff li.diff-comment { display: none; }
14
+ .diff li.diff-block-info { background: none repeat scroll 0 0 gray; }
@@ -0,0 +1,3 @@
1
+ // Place all the styles related to the wiki/pages controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,15 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+
6
+ before_filter :profiler_check
7
+
8
+ protected
9
+
10
+ def profiler_check
11
+ if params[:profile].present?
12
+ Rack::MiniProfiler.authorize_request
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ class AssignmentsController < ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def create
5
+ @ticket = Ticket.find params[:ticket_id]
6
+ @assignment = @ticket.assignments.build(
7
+ assignment_params.merge(assigner: current_user)
8
+ )
9
+
10
+ respond_to do |format|
11
+ format.js
12
+ end
13
+ end
14
+
15
+ def update
16
+ # as one would have it
17
+ end
18
+
19
+ def destroy
20
+ assignment = Assignment.find params[:id]
21
+ assignment.destroy
22
+ end
23
+
24
+ private
25
+
26
+ def assignment_params
27
+ params.require(params[:assignment]).permit(:user_id, :priority)
28
+ end
29
+
30
+ end
@@ -0,0 +1,10 @@
1
+ class AttachmentsController < ApplicationController
2
+ def show
3
+ attachment = Attachment.find params[:id]
4
+
5
+ send_data attachment.file_data,
6
+ type: attachment.content_type,
7
+ filename: attachment.filename,
8
+ disposition: 'inline'
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ class CommentsController < ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def create
5
+ @comment = Comment.new(
6
+ comment_params.merge(user: current_user)
7
+ )
8
+ if @comment.save
9
+ @ticket = @comment.ticket
10
+ @activity = @ticket.create_activity key: "ticket.create_comment", owner: current_user, recipient: @comment
11
+ end
12
+
13
+ respond_to do |format|
14
+ format.js
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def comment_params
21
+ params.require(:comment).permit(:body, :ticket_id)
22
+ end
23
+ end
24
+
File without changes
@@ -0,0 +1,7 @@
1
+ class HomeController < ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def index
5
+ @activities = PublicActivity::Activity.limit(15)
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ class ProjectsController < ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def index
5
+ @projects = Project.all
6
+ end
7
+
8
+ def new
9
+ @project = current_user.projects.build
10
+ end
11
+
12
+ def create
13
+ @project = current_user.projects.build(project_params)
14
+
15
+ if @project.save
16
+ redirect_to root_path
17
+ else
18
+ render :new
19
+ end
20
+ end
21
+
22
+ def show
23
+ @project = Project.find params[:id]
24
+ end
25
+
26
+ private
27
+
28
+ def project_params
29
+ params.require(:project).permit(:title, :description)
30
+ end
31
+ end
@@ -0,0 +1,49 @@
1
+ class SearchController < ApplicationController
2
+ def mentions
3
+ q = params[:query]
4
+ delimiter = params[:delimiter]
5
+ search_group = "spaces,pages,projects,bugs,tasks,stories,users,attachments"
6
+
7
+ if delimiter == "!"
8
+ search_group = "attachments"
9
+ end
10
+
11
+ query = Tire.search(search_group) do
12
+ query do
13
+ boolean do
14
+ should { string "title:#{q}*" }
15
+ should { string "filename:#{q}*" }
16
+ should { string "name:#{q}*" }
17
+ should { string "email:#{q}*" }
18
+ end
19
+ end
20
+ end
21
+
22
+ render json: query.results.map{|result| process_result(result) }
23
+ end
24
+
25
+ protected
26
+
27
+ #TODO: dirty. fix.
28
+ def process_result(result)
29
+ json = {}
30
+ json[:type] = result._type
31
+ if ["space", "page"].include?(result._type)
32
+ json[:name] = result.title
33
+ json[:url] = wiki_page_url(result.id)
34
+ json[:space] = result.load.root.title
35
+ elsif ["project", "bug", "task", "story"].include?(result._type)
36
+ json[:name] = result.title
37
+ json[:url] = ticket_url(result.id)
38
+ json[:project] = result.load.root.title
39
+ elsif result._type == "attachment"
40
+ json[:name] = result.filename
41
+ json[:url] = attachment_url(result.id)
42
+ elsif result._type == "user"
43
+ json[:name] = result.name
44
+ json[:email] = result.email
45
+ end
46
+
47
+ json
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ class SinkController < ApplicationController
2
+
3
+ def index
4
+
5
+ end
6
+
7
+ def components
8
+
9
+ end
10
+ end
@@ -0,0 +1,147 @@
1
+ require 'ticket_assignment'
2
+ class TicketsController < ApplicationController
3
+ before_filter :authenticate_user!
4
+ before_filter :load_ticket
5
+
6
+ def index
7
+ @tickets = Ticket.all
8
+ end
9
+
10
+ def new
11
+ @ticket_types = ticket_types(parent_id: params[:parent_id])
12
+ end
13
+
14
+ def create
15
+ @ticket = Ticket.filtered_type_class(params[:type]).new(
16
+ ticket_params.merge(creator: current_user)
17
+ )
18
+ if @ticket.save
19
+ @ticket.create_activity key: "ticket.created", owner: current_user
20
+ end
21
+
22
+ @ticket_types = ticket_types(parent_id: @ticket.parent_id)
23
+
24
+ respond_to do |format|
25
+ format.js
26
+ end
27
+ end
28
+
29
+ def show
30
+ @ticket_types = ticket_types(parent_id: @ticket.id)
31
+ @subtree = @ticket.subtree.includes(:assignments).group_by(&:parent_id)
32
+ @comments = @ticket.comments.group_by(&:id)
33
+ end
34
+
35
+ def trigger_event
36
+ old_state = @ticket.state
37
+ if @ticket.trigger_event!(params[:event])
38
+ @activity = @ticket.create_activity key: "ticket.state_change", owner: current_user, parameters: {
39
+ event: params[:event],
40
+ to: @ticket.state,
41
+ from: old_state
42
+ }
43
+ end
44
+ end
45
+
46
+ # only for title/description
47
+ def update
48
+ update_params = params.require(params[:type]).permit(
49
+ :title, :description,
50
+ :who, :what, :why
51
+ )
52
+ old_title = @ticket.title
53
+ old_description = @ticket.description
54
+ if @ticket.update_attributes(update_params)
55
+ parameters = {}
56
+ if old_title != @ticket.title
57
+ parameters[:title_diff] = generate_diff(old_title, @ticket.title)
58
+ parameters[:title_html_diff] = generate_html_diff(old_title, @ticket.title)
59
+ end
60
+ if old_description != @ticket.description
61
+ parameters[:description_diff] = generate_diff(old_description, @ticket.description)
62
+ parameters[:description_html_diff] = generate_html_diff(old_description, @ticket.description)
63
+ end
64
+
65
+ @activity = @ticket.create_activity key: "ticket.update_details", owner: current_user, parameters: parameters
66
+ end
67
+ end
68
+
69
+ def assignment
70
+ assignment = TicketAssignment.new @ticket, params[:assignment_user_ids]
71
+
72
+ if assignment.assign!
73
+ @activity = @ticket.create_activity key: "ticket.assignment",
74
+ owner: current_user,
75
+ parameters: {
76
+ assigned_ids: assignment.assigned_ids,
77
+ unassigned_ids: assignment.unassigned_ids
78
+ }
79
+ end
80
+ end
81
+
82
+ def reorder
83
+ old_parent_id = @ticket.parent_id
84
+ old_position = @ticket.position
85
+ if @ticket.reorder!(
86
+ parent_id: params[:parent_id],
87
+ position: params[:position]
88
+ )
89
+ @activity = @ticket.create_activity key: "ticket.reorder",
90
+ owner: current_user,
91
+ parameters: {
92
+ from_parent_id: old_parent_id,
93
+ old_position: old_position,
94
+ parent_id: params[:parent_id],
95
+ position: params[:position]
96
+ }
97
+ end
98
+
99
+ render json: {}
100
+ end
101
+
102
+ # FIXME: this is fake right now, need to filter.
103
+ def user_search
104
+ render json: User.all.map { |user|
105
+ {
106
+ name: user.display_name,
107
+ id: user.id,
108
+ value: "#{user.display_name} - #{user.email}"
109
+ }
110
+ }
111
+ end
112
+
113
+ private
114
+
115
+ def ticket_params
116
+ params.require(params[:type]).permit(
117
+ :title, :description, :parent_id,
118
+ :assignment_user_ids, :who, :what, :why
119
+ )
120
+ end
121
+
122
+ def ticket_types(options = {})
123
+ Ticket::ALLOWED_TYPES.each_with_object({}) do |type, hash|
124
+ hash[type] = Ticket.filtered_type_class(type).new(
125
+ creator: current_user,
126
+ parent_id: options[:parent_id]
127
+ )
128
+ end
129
+ end
130
+
131
+ def load_ticket
132
+ @ticket = Ticket.find(params[:id]) if params[:id]
133
+ end
134
+
135
+ def generate_diff(old_text, new_text)
136
+ Diffy::Diff.new(
137
+ old_text, new_text,
138
+ include_diff_info: true,
139
+ include_plus_and_minus_in_html: true,
140
+ context: 2
141
+ )
142
+ end
143
+
144
+ def generate_html_diff(old_text, new_text)
145
+ generate_diff(old_text, new_text).to_s(:html)
146
+ end
147
+ end
@@ -0,0 +1,23 @@
1
+ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
2
+ skip_before_filter :verify_authenticity_token, only: [:google_apps]
3
+
4
+ def google_apps
5
+ if UserVerifier.respond_to?(:verified?)
6
+ if !UserVerifier.verified?(request.env["omniauth.auth"])
7
+ render file: File.join(Tawork::Engine.root, "public/401.html"),
8
+ layout: false
9
+ return
10
+ end
11
+ end
12
+
13
+ @user = User.find_for_open_id(request.env["omniauth.auth"], current_user)
14
+
15
+ if @user.persisted?
16
+ flash[:notice] = I18n.t "devise.omniauth_callbacks.success", kind: "Google"
17
+ sign_in_and_redirect @user, event: :authentication
18
+ else
19
+ session["devise.google_data"] = request.env["omniauth.auth"]
20
+ redirect_to new_user_registration_url
21
+ end
22
+ end
23
+ end