tawork 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/application.js +1 -0
  3. data/app/assets/javascripts/bootstrap-confirmation-delete.js.coffee +46 -0
  4. data/app/assets/stylesheets/bootstrap_and_overrides.sass +8 -0
  5. data/app/controllers/attachments_controller.rb +1 -1
  6. data/app/controllers/wiki/pages_controller.rb +10 -0
  7. data/app/helpers/application_helper.rb +6 -0
  8. data/app/models/attachment.rb +25 -4
  9. data/app/models/deleted_item.rb +14 -0
  10. data/app/models/page.rb +29 -3
  11. data/app/models/space.rb +2 -0
  12. data/app/views/layouts/_spaces.html.haml +2 -4
  13. data/app/views/layouts/application.html.haml +6 -4
  14. data/app/views/public_activity/page/_attachment.html.haml +1 -1
  15. data/app/views/public_activity/page/_created.html.haml +1 -1
  16. data/app/views/public_activity/page/_reorder.html.haml +1 -1
  17. data/app/views/public_activity/page/_update_details.html.haml +1 -1
  18. data/app/views/tickets/_form.html.haml +4 -3
  19. data/app/views/tickets/_tree_node.html.haml +4 -3
  20. data/app/views/wiki/pages/_attachment.html.haml +5 -4
  21. data/app/views/wiki/pages/_display.html.haml +14 -9
  22. data/app/views/wiki/pages/_tree_node.html.haml +4 -3
  23. data/app/views/wiki/pages/show.html.haml +8 -4
  24. data/app/views/wiki/pages/update.js.coffee +1 -0
  25. data/db/migrate/20140319050456_add_version_count_to_attachment.rb +5 -0
  26. data/db/migrate/20140319052313_create_deleted_items.rb +13 -0
  27. data/db/schema.rb +12 -1
  28. data/lib/searcher.rb +55 -1
  29. data/lib/tawork/version.rb +1 -1
  30. data/vendor/assets/javascripts/bootstrap-confirmation.js +240 -0
  31. metadata +7 -2
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjhmMzgxMzNlYjA5OGY4NzJhZmI4NDU2YTVmYmVkMTljZDczM2I0ZQ==
4
+ YzExZmU4ZDZmZjZlZTVlZjgxZGVkN2UwNjI2MTc2ODBlZWNjMzRjOA==
5
5
  data.tar.gz: !binary |-
6
- M2U1MjczODA5OTM0YjZiNTdmYzkwN2E2MWVhOTlhNTFlNmNiNzMzMA==
6
+ MGVmYzZkZmFkZjUwMDcyMDA5ZGRlN2Y5YWExNTUxZWU2ZGE3Y2RmOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NjQyMjhiODJmOGZmNTY3YTdlZGFjMDc0OTI3NTM0MDY0ZmRiZTM0Yjk2NDI3
10
- YzhhYmE2ZjhkMDdiMzIwYzlhODQ2ZGQ0OTc0YzUxZDBkY2QxOGIyM2ZmYWM5
11
- MWEyYzJmMTU0NWRiOGY3N2E0NTYyMWM1ZmQyZWM1M2NjYmUyZmM=
9
+ YmZhMTEyZmU4ZmUzNzMxNDY2Mjc2Y2NhYmJkZjc1MmYwYjUyNWZmMWM1NmJj
10
+ OTY5ZTJmOTNmYTI5MGU4MzE3MTZhNTVlYjJiZmRhODllNWEzYjFhNGUzZGY2
11
+ NTU4OWUwNWRiNGRlZDYwZDVmYTNhNDlkZjg4YzU0NTQzZDNhMWQ=
12
12
  data.tar.gz: !binary |-
13
- YjE5M2IzMDJmZTRjMzE5ODFkY2RkYzNmYzBmYTRlMjVhNWE2MmQwOTc4NTM5
14
- NmQxOTllODY2ZWNmYzNmYmM1YzI0ZDk3YTU2ZTBiY2RhYzU2YTEzYmViYTNi
15
- YTQwNWNjNDRiMDIyMGU5Mjg1MWRlYmY5YjdkZjViMGUwYThhMTE=
13
+ MjYzOTJiZmViY2JjMjEyZjcyM2Y5Zjk3ZmRjNjU1ODBlZWNkZTZlOTc4NmFj
14
+ MGExYTUxODNiN2M3OTczNDFiNzNmYjg1ZmNjM2U2ZjMzZmIwYWQzNTQ3YTVk
15
+ NWY1YjM2OGU3ZTdiNmI1NGQ4MDI4YTUxNDdkMmJlNDZiMTIyOGU=
@@ -20,6 +20,7 @@
20
20
  // require bootstrap-tree
21
21
  //= require bootstrap-tagsinput
22
22
  //= require bootstrap-tokenfield
23
+ //= require bootstrap-confirmation-delete
23
24
  //
24
25
  //= require moxie
25
26
  //= require plupload.dev
@@ -0,0 +1,46 @@
1
+ # Override Rails handling of confirmation
2
+
3
+ $.rails.allowAction = (element) ->
4
+ # The message is something like "Are you sure?"
5
+ message = element.data('confirm')
6
+ description = element.data('description')
7
+ # If there's no message, there's no data-confirm attribute,
8
+ # which means there's nothing to confirm
9
+ return true unless message
10
+ # Clone the clicked element (probably a delete link) so we can use it in the dialog box.
11
+ $link = element.clone()
12
+ # We don't necessarily want the same styling as the original link/button.
13
+ .removeAttr('class')
14
+ # We don't want to pop up another confirmation (recursion)
15
+ .removeAttr('data-confirm')
16
+ # We want a button
17
+ .addClass('btn').addClass('btn-danger')
18
+ # We want it to sound confirmy
19
+ .html("Yes, I'm positively certain.")
20
+
21
+ # Create the modal box with the message
22
+ modal_html = """
23
+ <div id="delete-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
24
+ <div class="modal-dialog">
25
+ <div class="modal-content">
26
+ <div class="modal-header">
27
+ <a class="close" data-dismiss="modal">×</a>
28
+ <h3>#{message}</h3>
29
+ </div>
30
+ <div class="modal-body">
31
+ <p>#{description}</p>
32
+ </div>
33
+ <div class="modal-footer">
34
+ <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ """
40
+ $modal_html = $(modal_html)
41
+ # Add the new button to the modal box
42
+ $modal_html.find('.modal-footer').append($link)
43
+ # Pop it up
44
+ $modal_html.modal()
45
+ # Prevent the original link from working
46
+ return false
@@ -296,3 +296,11 @@ div.tokenfield.form-control
296
296
  text-decoration: none
297
297
  i
298
298
  padding-right: 4px
299
+
300
+
301
+ .nav-list .nav-header.with-link
302
+ padding: 0
303
+
304
+ .delete-link
305
+ font-size: .75em
306
+ color: lighten(red, 15)
@@ -15,7 +15,7 @@ class AttachmentsController < ApplicationController
15
15
 
16
16
  def destroy
17
17
  @attachment = Attachment.find params[:id]
18
- @attachment.destroy
18
+ @attachment.save_and_destroy
19
19
 
20
20
  render json: {}
21
21
  end
@@ -117,6 +117,16 @@ class Wiki::PagesController < ApplicationController
117
117
  render json: {}
118
118
  end
119
119
 
120
+ def destroy
121
+ parent = @page.parent
122
+ @page.save_and_destroy(current_user)
123
+
124
+ link = root_url
125
+ link = wiki_page_path(parent) if parent
126
+
127
+ redirect_to link, notice: "Page was deleted.", status: :see_other
128
+ end
129
+
120
130
  protected
121
131
  def load_page
122
132
  @page = Page.find(params[:id]) if params[:id]
@@ -17,4 +17,10 @@ module ApplicationHelper
17
17
  )
18
18
  end
19
19
  end
20
+
21
+ def link_to_trackable activity, path
22
+ link = send(:"#{path}_path", (activity.trackable || "deleted-#{activity.trackable_id}"))
23
+
24
+ link_to((activity.trackable.try(:title) || "[Deleted Page]"), link)
25
+ end
20
26
  end
@@ -5,12 +5,26 @@ class Attachment < ActiveRecord::Base
5
5
  # after_save :save_to_git
6
6
  belongs_to :attachable, :polymorphic => true
7
7
  validates_presence_of :attachable
8
-
9
- settings do
10
- mappings dynamic: 'false' do
8
+ after_update :update_version_count
9
+
10
+ settings analysis: {
11
+ filter: {
12
+ nGram_filter: Searcher::Filters.ngram
13
+ },
14
+ analyzer: {
15
+ email_tokenizer: {
16
+ tokenizer: "uax_url_email",
17
+ filter: "lowercase"
18
+ },
19
+ nGram_analyzer: Searcher::Analyzers.ngram,
20
+ email_ngram_analyzer: Searcher::Analyzers.email_ngram,
21
+ whitespace_analyzer: Searcher::Analyzers.whitespace
22
+ },
23
+ } do
24
+ mapping dynamic: 'false', index_analyzer: "nGram_analyzer", search_analyzer: "whitespace_analyzer" do
11
25
  indexes :id, :index => :not_analyzed
12
26
  indexes :type, :as => :type, :boost => 100
13
- indexes :filename, :analyzer => 'snowball', :boost => 100
27
+ indexes :filename, :analyzer => 'stop', :boost => 100
14
28
  indexes :content_type, :analyzer => 'snowball'
15
29
  indexes :body, :analyzer => 'snowball'
16
30
  indexes :created_at, :type => 'date', :include_in_all => false
@@ -122,6 +136,10 @@ class Attachment < ActiveRecord::Base
122
136
  Rails.logger.info "document not extractable."
123
137
  end
124
138
 
139
+ def save_and_destroy(deleted_by)
140
+ DeletedItem.save_and_destroy(self, deleted_by)
141
+ end
142
+
125
143
  protected
126
144
 
127
145
  def wiki_attachment_data
@@ -132,4 +150,7 @@ class Attachment < ActiveRecord::Base
132
150
  "/attachments/#{id}"
133
151
  end
134
152
 
153
+ def update_version_count
154
+ update_column(:version_count, versions.count)
155
+ end
135
156
  end
@@ -0,0 +1,14 @@
1
+ class DeletedItem < ActiveRecord::Base
2
+
3
+ def self.save_and_destroy(item, deleted_by)
4
+ DeletedItem.create(
5
+ item_type: item.class.to_s,
6
+ item_id: item.id,
7
+ yaml: item.to_yaml,
8
+ json: item.to_json,
9
+ deleted_by_id: deleted_by.id
10
+ )
11
+
12
+ item.destroy
13
+ end
14
+ end
data/app/models/page.rb CHANGED
@@ -4,8 +4,21 @@ class Page < ActiveRecord::Base
4
4
  include Elasticsearch::Model
5
5
  include Elasticsearch::Model::Callbacks
6
6
 
7
- settings do
8
- mappings dynamic: 'false' do
7
+ settings analysis: {
8
+ filter: {
9
+ nGram_filter: Searcher::Filters.ngram
10
+ },
11
+ analyzer: {
12
+ email_tokenizer: {
13
+ tokenizer: "uax_url_email",
14
+ filter: "lowercase"
15
+ },
16
+ nGram_analyzer: Searcher::Analyzers.ngram,
17
+ email_ngram_analyzer: Searcher::Analyzers.email_ngram,
18
+ whitespace_analyzer: Searcher::Analyzers.whitespace
19
+ },
20
+ } do
21
+ mapping dynamic: 'false', index_analyzer: "nGram_analyzer", search_analyzer: "whitespace_analyzer" do
9
22
  indexes :id, :index => :not_analyzed
10
23
  indexes :type, :as => :type, :boost => 100
11
24
  indexes :ancestry, :index => :not_analyzed
@@ -93,6 +106,19 @@ class Page < ActiveRecord::Base
93
106
  json
94
107
  end
95
108
 
96
- private
109
+ def save_and_destroy(deleted_by)
110
+ # let's get this page and all child pages and attachments
111
+ # let's save them to deleted_items
112
+ # let's delete them all
97
113
 
114
+ self.children.each do |child|
115
+ child.save_and_destroy(deleted_by)
116
+ end
117
+
118
+ self.attachments.each do |attachment|
119
+ attachment.save_and_destroy(deleted_by)
120
+ end
121
+
122
+ DeletedItem.save_and_destroy(self, deleted_by)
123
+ end
98
124
  end
data/app/models/space.rb CHANGED
@@ -1,2 +1,4 @@
1
1
  class Space < Page
2
+ index_name Page.index_name
3
+ document_type Page.document_type
2
4
  end
@@ -6,8 +6,8 @@
6
6
  %li.divider
7
7
 
8
8
  - if @space.present? && @space.persisted?
9
- %li.nav-header
10
- = @space.title
9
+ %li.nav-header.with-link
10
+ = link_to @space.title, wiki_page_path(@space)
11
11
  - @space.children.each do |page|
12
12
  = render 'wiki/spaces/page_list_item', page: page, end_page: @page
13
13
  -# %li.page-list-item{data: {page_id: page.id}}
@@ -33,12 +33,10 @@
33
33
  url: "/wiki/spaces/" + page_id + "/space_list"
34
34
  success: (data) ->
35
35
  $i.closest("a").after data
36
- console.log "lalla"
37
36
  false
38
37
 
39
38
  $(document).on "click", ".page-list-item a i.fa-minus-square", ->
40
39
  $i = $(this)
41
40
  $i.toggleClass("fa-plus-square").toggleClass('fa-minus-square')
42
41
  $i.closest(".page-list-item").find("ul.nav-list-sub").remove()
43
- console.log "lalla"
44
42
  false
@@ -17,10 +17,12 @@
17
17
  = render 'layouts/nav_header'
18
18
 
19
19
  .container-fluid
20
- - if notice.present?
21
- .alert.alert-success= notice
22
- - if alert.present?
23
- .alert.alert-error= alert
20
+ .row
21
+ .col-md-9.col-md-offset-3
22
+ - if notice.present?
23
+ .alert.alert-success= notice
24
+ - if alert.present?
25
+ .alert.alert-error= alert
24
26
 
25
27
  .container-fluid
26
28
  .row
@@ -1,4 +1,4 @@
1
1
  - content_for :action, flush: true do
2
- added attachment to page #{link_to activity.trackable.title, wiki_page_path(activity.trackable)}
2
+ added attachment to page #{link_to_trackable activity, "wiki_page"}
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
1
  - content_for :action, flush: true do
2
- created page #{link_to activity.trackable.title, wiki_page_path(activity.trackable)}
2
+ created page #{link_to_trackable activity, "wiki_page"}
3
3
 
4
4
 
@@ -1,2 +1,2 @@
1
1
  - content_for :action, flush: true do
2
- reordered the page: #{link_to activity.trackable.title, wiki_page_path(activity.trackable)}
2
+ reordered the page: #{link_to_trackable activity, "wiki_page"}
@@ -1,4 +1,4 @@
1
1
  - content_for :action, flush: true do
2
- updated page #{link_to activity.trackable.title, wiki_page_path(activity.trackable)}
2
+ updated page #{link_to_trackable activity, "wiki_page"}
3
3
 
4
4
 
@@ -14,9 +14,10 @@
14
14
  = render "#{type.underscore}_form", ticket: @ticket_types[type]
15
15
 
16
16
  - if tab.present?
17
- :coffeescript
18
- $ ->
19
- $('#new_ticket_tabs a.#{tab}-tab').tab('show')
17
+ :javascript
18
+ $(function() {
19
+ $('#new_ticket_tabs a.#{tab}-tab').tab('show');
20
+ });
20
21
  - else
21
22
  :coffeescript
22
23
  $ ->
@@ -23,6 +23,7 @@
23
23
  - @subtree[ticket.id].sort_by(&:position).each do |child|
24
24
  = render 'tree_node', ticket: child
25
25
 
26
- :coffeescript
27
- $ ->
28
- ticket_view = new Tawork.Views.TreeNodeTicketView el: $("#ticket_#{ticket.id}").get(0)
26
+ :javascript
27
+ $(function() {
28
+ ticket_view = new Tawork.Views.TreeNodeTicketView({el: $("#ticket_#{ticket.id}").get(0)});
29
+ });
@@ -1,12 +1,13 @@
1
1
  %tr.attachment{data: {attachment_id: attachment.id}}
2
2
  %td.filename= link_to attachment.filename, attachment_path(attachment)
3
3
  %td.size= number_to_human_size(attachment.size)
4
- %td.versions= attachment.versions.count
4
+ %td.versions= attachment.version_count
5
5
  %td.actions
6
6
  %a.upload{href: "#", title: "Upload", id: "upload_attachment_#{attachment.id}"}
7
7
  %i.fa.fa-upload
8
8
  %a.delete{href: "#", title: "Delete"}
9
9
  %i.fa.fa-times
10
- :coffeescript
11
- $ ->
12
- view = new Tawork.Views.AttachmentView el: $(".attachment[data-attachment-id=#{attachment.id}]").get(0)
10
+ :javascript
11
+ $(function() {
12
+ var view = new Tawork.Views.AttachmentView({el: $(".attachment[data-attachment-id=#{attachment.id}]").get(0)});
13
+ });
@@ -1,4 +1,5 @@
1
- .page-article{class: "page_#{@page.id}"}
1
+ .page-article{class: "page_#{@page.id}",
2
+ data: {parent_id: params[:parent_id], type: @page.type.parameterize}}
2
3
  %h3.edit-helper.hide Title
3
4
  %h1#wiki-title.wiki-title= @page.title
4
5
  .meta.row
@@ -153,9 +154,20 @@
153
154
  $(".save").click ->
154
155
  title = tinyMCE.get("wiki-title").getContent()
155
156
  body = tinyMCE.get("wiki-content").getContent()
157
+ type = $(".page-article").attr("data-type")
156
158
  markdown_body = $("#markdown_body").val()
157
159
  $.blockUI(message: "")
158
160
 
161
+ data =
162
+ timestamp: $(".time").data("timestamp")
163
+ markdown_body: markdown_body
164
+ type: type
165
+ parent_id: $(".page-article").attr("data-parent-id")
166
+
167
+ data[type] =
168
+ title: title
169
+ body: body
170
+
159
171
  $.ajax
160
172
  type: $(this).data("type")
161
173
  url: $(this).data("url")
@@ -163,12 +175,5 @@
163
175
  complete: ->
164
176
  $.unblockUI()
165
177
 
166
- data:
167
- timestamp: $(".time").data("timestamp")
168
- markdown_body: markdown_body
169
- type: #{@page.type.parameterize.to_json}
170
- parent_id: #{params[:parent_id].to_json}
171
- #{@page.type.parameterize}:
172
- title: title
173
- body: body
178
+ data: data
174
179
  false
@@ -16,6 +16,7 @@
16
16
  - @subtree[page.id].sort_by(&:position).each do |child|
17
17
  = render 'tree_node', page: child
18
18
 
19
- :coffeescript
20
- $ ->
21
- page_view = new Tawork.Views.TreeNodePageView el: $("#page_#{page.id}").get(0)
19
+ :javascript
20
+ $(function() {
21
+ var page_view = new Tawork.Views.TreeNodePageView({el: $("#page_#{page.id}").get(0)});
22
+ });
@@ -7,8 +7,12 @@
7
7
  = render 'display'
8
8
  = render 'subtree'
9
9
  = render 'attachments'
10
+ .row
11
+ .col-md-12{style: "text-align: right;"}
12
+ %hr
13
+ = link_to "Delete Page", wiki_page_path(@page), class: 'delete-link', data: {confirm: "Really?", description: "This will also delete all child pages and attachments.", method: :delete}
10
14
 
11
- :coffeescript
12
- $ ->
13
- page_view = new Tawork.Views.PageView el: $("#page_#{@page.id}").get(0)
14
-
15
+ :javascript
16
+ $(function() {
17
+ var page_view = new Tawork.Views.PageView({ el: $("#page_#{@page.id}").get(0)});
18
+ });
@@ -6,6 +6,7 @@
6
6
  $(".page_<%= @page.id %> .last-updated time").timeago()
7
7
  $(".edit-helper").toggleClass("hide")
8
8
  $(".save").hide()
9
+ $(".cancel").hide()
9
10
  $(".edit").show()
10
11
  tinyMCE.remove('div');
11
12
  <% end %>
@@ -0,0 +1,5 @@
1
+ class AddVersionCountToAttachment < ActiveRecord::Migration
2
+ def change
3
+ add_column :attachments, :version_count, :integer, default: 1
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class CreateDeletedItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :deleted_items do |t|
4
+ t.string :item_type
5
+ t.integer :item_id
6
+ t.text :yaml
7
+ t.text :json
8
+ t.integer :deleted_by_id
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
data/db/schema.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20140314014649) do
14
+ ActiveRecord::Schema.define(version: 20140319052313) do
15
15
 
16
16
  create_table "activities", force: true do |t|
17
17
  t.integer "trackable_id"
@@ -51,6 +51,7 @@ ActiveRecord::Schema.define(version: 20140314014649) do
51
51
  t.integer "attachable_id"
52
52
  t.datetime "created_at"
53
53
  t.datetime "updated_at"
54
+ t.integer "version_count", default: 1
54
55
  end
55
56
 
56
57
  create_table "comments", force: true do |t|
@@ -64,6 +65,16 @@ ActiveRecord::Schema.define(version: 20140314014649) do
64
65
  add_index "comments", ["ticket_id"], name: "index_comments_on_ticket_id", using: :btree
65
66
  add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
66
67
 
68
+ create_table "deleted_items", force: true do |t|
69
+ t.string "item_type"
70
+ t.integer "item_id"
71
+ t.text "yaml"
72
+ t.text "json"
73
+ t.integer "deleted_by_id"
74
+ t.datetime "created_at"
75
+ t.datetime "updated_at"
76
+ end
77
+
67
78
  create_table "pages", force: true do |t|
68
79
  t.string "type"
69
80
  t.string "ancestry"
data/lib/searcher.rb CHANGED
@@ -25,7 +25,7 @@ class Searcher
25
25
  if @q
26
26
  q = @q
27
27
  else
28
- q = q.split(" ").collect{|x| "_all:" + x + "*"}.join(" #{@comparator} ")
28
+ q = q.split(" ").join(" #{@comparator} ")
29
29
  end
30
30
 
31
31
  if @type
@@ -58,4 +58,58 @@ class Searcher
58
58
  def search_group
59
59
  @search_group
60
60
  end
61
+
62
+ class Filters
63
+ def self.ngram
64
+ {
65
+ type: "edgeNGram",
66
+ min_gram: 2,
67
+ max_gram: 20,
68
+ token_chars: [
69
+ "letter",
70
+ "digit",
71
+ "punctuation",
72
+ "symbol"
73
+ ]
74
+ }
75
+ end
76
+ end
77
+
78
+ class Analyzers
79
+
80
+ def self.ngram
81
+ {
82
+ type: "custom",
83
+ tokenizer: "whitespace",
84
+ filter: [
85
+ "lowercase",
86
+ "asciifolding",
87
+ "nGram_filter"
88
+ ]
89
+ }
90
+ end
91
+
92
+ def self.email_ngram
93
+ {
94
+ type: "custom",
95
+ tokenizer: "uax_url_email",
96
+ filter: [
97
+ "lowercase",
98
+ "asciifolding",
99
+ "nGram_filter"
100
+ ]
101
+ }
102
+ end
103
+
104
+ def self.whitespace
105
+ {
106
+ type: "custom",
107
+ tokenizer: "whitespace",
108
+ filter: [
109
+ "lowercase",
110
+ "asciifolding"
111
+ ]
112
+ }
113
+ end
114
+ end
61
115
  end
@@ -1,3 +1,3 @@
1
1
  module Tawork
2
- VERSION = '0.0.24'
2
+ VERSION = '0.0.25'
3
3
  end
@@ -0,0 +1,240 @@
1
+ +function ($) {
2
+ 'use strict';
3
+
4
+ //var for check event at body can have only one.
5
+ var event_body = false;
6
+
7
+ // CONFIRMATION PUBLIC CLASS DEFINITION
8
+ // ===============================
9
+ var Confirmation = function (element, options) {
10
+ var that = this;
11
+
12
+ this.init('confirmation', element, options);
13
+
14
+
15
+ $(element).on('show.bs.confirmation', function(e) {
16
+ that.options.onShow(e, this);
17
+
18
+ $(this).addClass('open');
19
+
20
+ var options = that.options;
21
+ var all = options.all_selector;
22
+
23
+ if(options.singleton) {
24
+ $(all+'.in').not(that.$element).confirmation('hide');
25
+ }
26
+ });
27
+
28
+ $(element).on('hide.bs.confirmation', function(e) {
29
+ that.options.onHide(e, this);
30
+
31
+ $(this).removeClass('open');
32
+ });
33
+
34
+ $(element).on('shown.bs.confirmation', function(e) {
35
+ var options = that.options;
36
+ var all = options.all_selector;
37
+
38
+ that.$element.on('click.dismiss.bs.confirmation', '[data-dismiss="confirmation"]', $.proxy(that.hide, that));
39
+
40
+ if(that.isPopout()) {
41
+ if(!event_body) {
42
+ event_body = $('body').on('click', function (e) {
43
+ if(that.$element.is(e.target)) return;
44
+ if(that.$element.has(e.target).length) return;
45
+ if($('.popover').has(e.target).length) return;
46
+
47
+ that.$element.confirmation('hide');
48
+
49
+ $('body').unbind(e);
50
+
51
+ event_body = false;
52
+
53
+ return;
54
+ });
55
+ }
56
+ }
57
+ });
58
+
59
+ $(element).on('click', function(e) {
60
+ e.preventDefault();
61
+ });
62
+ }
63
+
64
+ if (!$.fn.popover || !$.fn.tooltip) throw new Error('Confirmation requires popover.js and tooltip.js');
65
+
66
+ Confirmation.DEFAULTS = $.extend({}, $.fn.popover.Constructor.DEFAULTS, {
67
+ placement : 'right',
68
+ title : 'Are you sure?',
69
+ btnOkClass : 'btn btn-sm btn-danger',
70
+ btnOkLabel : 'Delete',
71
+ btnOkIcon : 'glyphicon glyphicon-ok',
72
+ btnCancelClass : 'btn btn-sm btn-default',
73
+ btnCancelLabel : 'Cancel',
74
+ btnCancelIcon : 'glyphicon glyphicon-remove',
75
+ href : '#',
76
+ target : '_self',
77
+ singleton : true,
78
+ popout : true,
79
+ onShow : function(event, element){},
80
+ onHide : function(event, element){},
81
+ onConfirm : function(event, element){},
82
+ onCancel : function(event, element){},
83
+ template : '<div class="popover"><div class="arrow"></div>'
84
+ + '<h3 class="popover-title"></h3>'
85
+ + '<div class="popover-content">'
86
+ + '<a data-apply="confirmation">Yes</a>'
87
+ + ' <a data-dismiss="confirmation">No</a>'
88
+ + '</div>'
89
+ + '</div>'
90
+ });
91
+
92
+
93
+ // NOTE: CONFIRMATION EXTENDS popover.js
94
+ // ================================
95
+ Confirmation.prototype = $.extend({}, $.fn.popover.Constructor.prototype);
96
+
97
+ Confirmation.prototype.constructor = Confirmation;
98
+
99
+ Confirmation.prototype.getDefaults = function () {
100
+ return Confirmation.DEFAULTS;
101
+ }
102
+
103
+ Confirmation.prototype.setContent = function () {
104
+ var that = this;
105
+ var $tip = this.tip();
106
+ var title = this.getTitle();
107
+ var $btnOk = $tip.find('[data-apply="confirmation"]');
108
+ var $btnCancel = $tip.find('[data-dismiss="confirmation"]');
109
+ var options = this.options
110
+
111
+ $btnOk.addClass(this.getBtnOkClass())
112
+ .html(this.getBtnOkLabel())
113
+ .prepend($('<i></i>').addClass(this.getBtnOkIcon()), " ")
114
+ .attr('href', this.getHref())
115
+ .attr('target', this.getTarget())
116
+ .off('click').on('click', function(event) {
117
+ options.onConfirm(event, that.$element);
118
+
119
+ that.$element.confirmation('hide');
120
+ });
121
+
122
+ $btnCancel.addClass(this.getBtnCancelClass())
123
+ .html(this.getBtnCancelLabel())
124
+ .prepend($('<i></i>').addClass(this.getBtnCancelIcon()), " ")
125
+ .off('click').on('click', function(event){
126
+ options.onCancel(event, that.$element);
127
+
128
+ that.$element.confirmation('hide');
129
+ });
130
+
131
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title);
132
+
133
+ $tip.removeClass('fade top bottom left right in');
134
+
135
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
136
+ // this manually by checking the contents.
137
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide();
138
+ }
139
+
140
+ Confirmation.prototype.getBtnOkClass = function () {
141
+ var $e = this.$element;
142
+ var o = this.options;
143
+
144
+ return $e.attr('data-btnOkClass') || (typeof o.btnOkClass == 'function' ? o.btnOkClass.call($e[0]) : o.btnOkClass);
145
+ }
146
+
147
+ Confirmation.prototype.getBtnOkLabel = function () {
148
+ var $e = this.$element;
149
+ var o = this.options;
150
+
151
+ return $e.attr('data-btnOkLabel') || (typeof o.btnOkLabel == 'function' ? o.btnOkLabel.call($e[0]) : o.btnOkLabel);
152
+ }
153
+
154
+ Confirmation.prototype.getBtnOkIcon = function () {
155
+ var $e = this.$element;
156
+ var o = this.options;
157
+
158
+ return $e.attr('data-btnOkIcon') || (typeof o.btnOkIcon == 'function' ? o.btnOkIcon.call($e[0]) : o.btnOkIcon);
159
+ }
160
+
161
+ Confirmation.prototype.getBtnCancelClass = function () {
162
+ var $e = this.$element;
163
+ var o = this.options;
164
+
165
+ return $e.attr('data-btnCancelClass') || (typeof o.btnCancelClass == 'function' ? o.btnCancelClass.call($e[0]) : o.btnCancelClass);
166
+ }
167
+
168
+ Confirmation.prototype.getBtnCancelLabel = function () {
169
+ var $e = this.$element;
170
+ var o = this.options;
171
+
172
+ return $e.attr('data-btnCancelLabel') || (typeof o.btnCancelLabel == 'function' ? o.btnCancelLabel.call($e[0]) : o.btnCancelLabel);
173
+ }
174
+
175
+ Confirmation.prototype.getBtnCancelIcon = function () {
176
+ var $e = this.$element;
177
+ var o = this.options;
178
+
179
+ return $e.attr('data-btnCancelIcon') || (typeof o.btnCancelIcon == 'function' ? o.btnCancelIcon.call($e[0]) : o.btnCancelIcon);
180
+ }
181
+
182
+ Confirmation.prototype.getHref = function () {
183
+ var $e = this.$element;
184
+ var o = this.options;
185
+
186
+ return $e.attr('data-href') || (typeof o.href == 'function' ? o.href.call($e[0]) : o.href);
187
+ }
188
+
189
+ Confirmation.prototype.getTarget = function () {
190
+ var $e = this.$element;
191
+ var o = this.options;
192
+
193
+ return $e.attr('data-target') || (typeof o.target == 'function' ? o.target.call($e[0]) : o.target);
194
+ }
195
+
196
+ Confirmation.prototype.isPopout = function () {
197
+ var popout;
198
+ var $e = this.$element;
199
+ var o = this.options;
200
+
201
+ popout = $e.attr('data-popout') || (typeof o.popout == 'function' ? o.popout.call($e[0]) : o.popout);
202
+
203
+ if(popout == 'false') popout = false;
204
+
205
+ return popout
206
+ }
207
+
208
+
209
+ // CONFIRMATION PLUGIN DEFINITION
210
+ // =========================
211
+ var old = $.fn.confirmation;
212
+
213
+ $.fn.confirmation = function (option) {
214
+ var that = this;
215
+
216
+ return this.each(function () {
217
+ var $this = $(this);
218
+ var data = $this.data('bs.confirmation');
219
+ var options = typeof option == 'object' && option;
220
+
221
+ options = options || {};
222
+ options.all_selector = that.selector;
223
+
224
+ if (!data && option == 'destroy') return;
225
+ if (!data) $this.data('bs.confirmation', (data = new Confirmation(this, options)));
226
+ if (typeof option == 'string') data[option]();
227
+ });
228
+ }
229
+
230
+ $.fn.confirmation.Constructor = Confirmation
231
+
232
+
233
+ // CONFIRMATION NO CONFLICT
234
+ // ===================
235
+ $.fn.confirmation.noConflict = function () {
236
+ $.fn.confirmation = old;
237
+
238
+ return this;
239
+ }
240
+ }(jQuery);
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tawork
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.24
4
+ version: 0.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adnan Ali
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-17 00:00:00.000000000 Z
11
+ date: 2014-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -54,6 +54,7 @@ files:
54
54
  - app/assets/javascripts/backbone/views/ticket.js.coffee
55
55
  - app/assets/javascripts/backbone/views/tree_node_page.js.coffee
56
56
  - app/assets/javascripts/backbone/views/tree_node_ticket.js.coffee
57
+ - app/assets/javascripts/bootstrap-confirmation-delete.js.coffee
57
58
  - app/assets/javascripts/global_search.js.coffee
58
59
  - app/assets/javascripts/wiki/pages.js.coffee
59
60
  - app/assets/stylesheets/application.css
@@ -85,6 +86,7 @@ files:
85
86
  - app/models/bug.rb
86
87
  - app/models/comment.rb
87
88
  - app/models/concerns/.keep
89
+ - app/models/deleted_item.rb
88
90
  - app/models/page.rb
89
91
  - app/models/project.rb
90
92
  - app/models/space.rb
@@ -221,6 +223,8 @@ files:
221
223
  - db/migrate/20140313052226_create_starreds.rb
222
224
  - db/migrate/20140314014648_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb
223
225
  - db/migrate/20140314014649_add_missing_unique_indices.acts_as_taggable_on_engine.rb
226
+ - db/migrate/20140319050456_add_version_count_to_attachment.rb
227
+ - db/migrate/20140319052313_create_deleted_items.rb
224
228
  - db/schema.rb
225
229
  - db/seeds.rb
226
230
  - init.rb
@@ -244,6 +248,7 @@ files:
244
248
  - vendor/.DS_Store
245
249
  - vendor/assets/.DS_Store
246
250
  - vendor/assets/javascripts/.keep
251
+ - vendor/assets/javascripts/bootstrap-confirmation.js
247
252
  - vendor/assets/javascripts/bootstrap-tagsinput.js
248
253
  - vendor/assets/javascripts/bootstrap-tokenfield.js
249
254
  - vendor/assets/javascripts/bootstrap-tree.js