tawork 0.0.24 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
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