hydra-batch-edit 0.0.6 → 0.0.7

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.
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ RSpec::Core::RakeTask.new(:spec => :generate) do |t|
13
13
  end
14
14
 
15
15
 
16
- describe "Create the test rails app"
16
+ desc "Create the test rails app"
17
17
  task :generate do
18
18
  unless File.exists?('spec/internal/Rakefile')
19
19
  puts "Generating rails app"
@@ -36,7 +36,7 @@ task :generate do
36
36
  puts "Running specs"
37
37
  end
38
38
 
39
- describe "Clean out the test rails app"
39
+ desc "Clean out the test rails app"
40
40
  task :clean do
41
41
  puts "Removing sample rails app"
42
42
  `rm -rf spec/internal`
@@ -17,8 +17,8 @@ module BatchEditHelper
17
17
  end
18
18
 
19
19
  # Displays the button that users click when they are done selecting items for a batch. Put this in your search result page template. We put it in catalog/index.html
20
- def batch_edit_continue
21
- render :partial => '/batch_edits/next_page'
20
+ def batch_edit_continue(label = 'Update Selected')
21
+ render :partial => '/batch_edits/next_page', :locals=>{:label=>label}
22
22
  end
23
23
 
24
24
  # Displays the button to select/deselect items for your batch. Call this in the index partial that's rendered for each search result.
@@ -28,7 +28,12 @@ module BatchEditHelper
28
28
  end
29
29
 
30
30
  # Displays the check all button to select/deselect items for your batch. Put this in your search result page template. We put it in catalog/index.html
31
- def batch_check_all
32
- render :partial=>'/batch_edits/check_all'
31
+ def batch_check_all(label = 'Use all results')
32
+ render :partial=>'/batch_edits/check_all', :locals=>{:label=>label}
33
+ end
34
+
35
+ # Displays the button that users click when they are done selecting items for a batch to Remove those items from the repository. Put this in your search result page template. We put it in catalog/index.html
36
+ def batch_edit_delete_batch(label = 'Delete Selected', confirm = 'Are you sure?')
37
+ render :partial => '/batch_edits/delete_batch', :locals=>{:label=>label, :confirm=>confirm}
33
38
  end
34
39
  end
@@ -4,17 +4,19 @@
4
4
  <%-
5
5
  # pass in local :document with a SolrDocument
6
6
  if item_in_batch?(document.id)
7
- method = "delete"
7
+ method = :delete
8
8
  label = 'remove from batch'
9
9
  cssClass = "deleteBatch"
10
+ action = "destroy"
10
11
  else
11
- method = "put"
12
+ method = :put
12
13
  label = 'add to batch'
13
14
  cssClass = "addBatch"
15
+ action = "add"
14
16
  end
15
17
  -%>
16
18
 
17
- <%= form_tag(batch_edit_path(document), :method => method, :class=> "batch_toggle #{cssClass}", "data-doc-id" => document.id, "data-behavior" => 'batch-add-form', :title=>h(document[document_show_link_field])) do -%>
19
+ <%= form_tag({:controller => "batch_edits", :action => action, :id => document.id}, :method => method, :class=> "batch_toggle #{cssClass}", "data-doc-id" => document.id, "data-behavior" => 'batch-add-form', :title=>h(document[document_show_link_field])) do -%>
18
20
  <%= hidden_field(:bookmark, :title, :value => document[document_show_link_field]) %>
19
21
  <%= submit_tag(label, :class=>"batch_submit", :id => "batch_submit_#{document.id}") %>
20
22
  <% end %>
@@ -1,4 +1,4 @@
1
1
  <%= form_tag(all_batch_edits_path, :method => :put, :class=> "batch-select-all hidden", "data-behavior" => 'batch-select-all') do -%>
2
- <%= submit_tag("Use all results", :class=>'batch-all-button btn') %>
2
+ <%= submit_tag(label, :class=>'batch-all-button btn') %>
3
3
  <% end %>
4
4
 
@@ -0,0 +1 @@
1
+ <%= button_to label, batch_edit, :confirm => confirm, :method=>:delete, :class=>"btn btn-primary btn-delete hidden", 'data-behavior'=>'batch-edit', :id=>'batch-edit-delete' %>
@@ -1 +1 @@
1
- <%= button_to "Update Selected", edit_batch_edits_path, :method=>:get, :class=>"btn btn-primary hidden", 'data-behavior'=>'batch-edit', :id=>'batch-edit' %>
1
+ <%= button_to label, edit_batch_edits_path, :method=>:get, :class=>"btn btn-update btn-primary hidden", 'data-behavior'=>'batch-edit', :id=>'batch-edit' %>
@@ -15,6 +15,7 @@ module Hydra
15
15
  delete :destroy
16
16
  end
17
17
  collection do
18
+ match 'destroy' => 'batch_edits#destroy_collection', :via=>:delete
18
19
  get :edit
19
20
  put :update
20
21
  delete :clear
@@ -1,5 +1,5 @@
1
1
  module Hydra
2
2
  module BatchEdit
3
- VERSION = "0.0.6"
3
+ VERSION = "0.0.7"
4
4
  end
5
5
  end
@@ -1,112 +1,147 @@
1
- module Hydra::BatchEditBehavior
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- before_filter :filter_docs_with_access!, :only=>[:edit, :update]
6
- before_filter :check_for_empty!, :only=>[:edit, :update]
7
- end
1
+ module Hydra
2
+ module BatchEditBehavior
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_filter :filter_docs_with_access!, :only=>[:edit, :update, :destroy_collection]
7
+ before_filter :check_for_empty!, :only=>[:edit, :update, :destroy_collection]
8
+ end
8
9
 
9
-
10
- # fetch the documents that match the ids in the folder
11
- def index
12
- @response, @documents = get_solr_response_for_field_values("id", batch)
13
- end
10
+
11
+ # fetch the documents that match the ids in the folder
12
+ def index
13
+ @response, @documents = get_solr_response_for_field_values("id", batch)
14
+ end
14
15
 
15
- def state
16
- session[:batch_edit_state] = params[:state]
17
- render :json => {"OK" => "OK"}
18
- end
16
+ def state
17
+ session[:batch_edit_state] = params[:state]
18
+ render :json => {"OK" => "OK"}
19
+ end
19
20
 
20
- # add a document_id to the batch. :id of action is solr doc id
21
- def add
22
- batch << params[:id]
23
- respond_to do |format|
24
- format.html do
25
- redirect_to :back, :notice => "#{params[:title] || "Item"} successfully added to batch"
21
+ # add a document_id to the batch. :id of action is solr doc id
22
+ def add
23
+ id = params[:id]
24
+ raise "Too many items in batch!" if ((batch.to_s.length+id.to_s.length) > 2200) # we are going to overflow our cookie
25
+ batch << id if ! batch.include? id
26
+ respond_to do |format|
27
+ format.html do
28
+ redirect_to :back, :notice => "#{params[:title] || "Item"} successfully added to batch"
29
+ end
30
+ format.js { render :json => batch }
26
31
  end
27
- format.js { render :json => batch }
28
32
  end
29
- end
30
-
31
- # remove a document_id from the batch. :id of action is solr_doc_id
32
- def destroy
33
- batch.delete(params[:id])
34
- respond_to do |format|
35
- format.html do
36
- redirect_to :back, :notice => "#{params[:title] || "Item"} successfully removed from batch"
33
+
34
+ # remove a document_id from the batch. :id of action is solr_doc_id
35
+ def destroy
36
+ batch.delete(params[:id])
37
+ respond_to do |format|
38
+ format.html do
39
+ redirect_to :back, :notice => "#{params[:title] || "Item"} successfully removed from batch"
40
+ end
41
+ format.js do
42
+ render :json => {"OK" => "OK"}
43
+ end
37
44
  end
38
- format.js do
39
- render :json => {"OK" => "OK"}
45
+
46
+ end
47
+
48
+ # get rid of the items in the batch
49
+ def clear
50
+ clear_batch!
51
+ respond_to do |format|
52
+ format.html { redirect_to :back, :notice=> "Batch has been cleared" }
53
+ format.js { render :json => batch }
40
54
  end
41
55
  end
42
-
43
- end
44
-
45
- # get rid of the items in the batch
46
- def clear
47
- clear_batch!
48
- respond_to do |format|
49
- format.html { redirect_to :back, :notice=> "Batch has been cleared" }
50
- format.js { render :json => batch }
56
+
57
+ def edit
51
58
  end
52
- end
53
59
 
54
- def edit
55
- end
60
+ #pulled out to allow a user to override the default redirect
61
+ def after_update
62
+ redirect_to catalog_index_path
63
+ end
64
+
65
+ #called before the save of the document on update to do addition processes on the document beyond update_attributes
66
+ def update_document(obj)
67
+ type = obj.class.to_s.underscore.to_sym
68
+ obj.update_attributes(params[type].reject{|k, v| v.blank?})
69
+ end
56
70
 
57
- def update
58
- batch.each do |doc_id|
59
- obj = ActiveFedora::Base.find(doc_id, :cast=>true)
60
- type = obj.class.to_s.underscore.to_sym
61
- obj.update_attributes(params[type].reject{|k, v| v.blank?})
62
- obj.save
71
+ def update
72
+ batch.each do |doc_id|
73
+ obj = ActiveFedora::Base.find(doc_id, :cast=>true)
74
+ update_document(obj)
75
+ obj.save
76
+ end
77
+ flash[:notice] = "Batch update complete"
78
+ clear_batch!
79
+ after_update
80
+ end
81
+
82
+ def all
83
+ self.batch = Hydra::BatchEdit::SearchService.new(session, current_user.user_key).last_search_documents.map(&:id)
84
+ respond_to do |format|
85
+ format.html { redirect_to edit_batch_edits_path }
86
+ format.js { render :json => batch }
87
+ end
63
88
  end
64
- flash[:notice] = "Batch update complete"
65
- clear_batch!
66
- redirect_to catalog_index_path
67
89
 
68
- end
90
+ #pulled out to allow a user to override the default redirect
91
+ def after_destroy_collection
92
+ redirect_to catalog_index_path
93
+ end
69
94
 
70
- def all
71
- self.batch = Hydra::BatchEdit::SearchService.new(session, current_user.user_key).last_search_documents.map(&:id)
72
- redirect_to edit_batch_edits_path
73
- end
95
+ def destroy_collection
96
+ batch.each do |doc_id|
97
+ obj = ActiveFedora::Base.find(doc_id, :cast=>true)
98
+ obj.destroy
99
+ end
100
+ flash[:notice] = "Batch delete complete"
101
+ clear_batch!
102
+ after_destroy_collection
103
+ end
74
104
 
75
- protected
105
+ def check_for_empty?
106
+ return batch.empty?
107
+ end
76
108
 
77
- def batch
78
- session[:batch_document_ids] ||= []
79
- end
109
+ protected
80
110
 
81
- def batch=(val)
82
- session[:batch_document_ids] = val
83
- end
111
+ def batch
112
+ session[:batch_document_ids] ||= []
113
+ end
84
114
 
115
+ def batch=(val)
116
+ session[:batch_document_ids] = val
117
+ end
85
118
 
86
- def clear_batch!
87
- self.batch = []
88
- end
89
119
 
90
- def check_for_empty!
91
- if batch.empty?
92
- redirect_to :back
93
- return false
120
+ def clear_batch!
121
+ self.batch = []
94
122
  end
95
- end
96
-
97
- def filter_docs_with_access!
98
- no_permissions = []
99
- if batch.empty?
100
- flash[:notice] = "Select something first"
101
- else
102
- batch.dup.each do |doc_id|
103
- unless can?(:edit, doc_id)
104
- session[:batch_document_ids].delete(doc_id)
105
- no_permissions << doc_id
123
+
124
+ def check_for_empty!
125
+ if batch.empty?
126
+ redirect_to :back
127
+ return false
128
+ end
129
+ end
130
+
131
+ def filter_docs_with_access!
132
+ no_permissions = []
133
+ if batch.empty?
134
+ flash[:notice] = "Select something first"
135
+ else
136
+ batch.dup.each do |doc_id|
137
+ unless can?(:edit, doc_id)
138
+ session[:batch_document_ids].delete(doc_id)
139
+ no_permissions << doc_id
140
+ end
106
141
  end
142
+ flash[:notice] = "You do not have permission to edit the documents: #{no_permissions.join(', ')}" unless no_permissions.empty?
107
143
  end
108
- flash[:notice] = "You do not have permission to edit the documents: #{no_permissions.join(', ')}" unless no_permissions.empty?
109
144
  end
145
+
110
146
  end
111
-
112
147
  end
@@ -9,7 +9,15 @@ describe BatchEditsController do
9
9
  before(:each) do
10
10
  request.env["HTTP_REFERER"] = "/"
11
11
  end
12
-
12
+ it "should respond to after_update" do
13
+ controller.respond_to? "after_update"
14
+ end
15
+ it "should respond to update_document" do
16
+ controller.respond_to? "update_document"
17
+ end
18
+ it "should respond to after_delete" do
19
+ controller.respond_to? "after_delete"
20
+ end
13
21
  it "should add items to list" do
14
22
  @mock_response = mock()
15
23
  @mock_document = mock()
@@ -48,6 +56,14 @@ describe BatchEditsController do
48
56
  xhr :put, :add, :id => "77826928"
49
57
  flash[:notice].should == nil
50
58
  end
59
+
60
+ it "should check for empty" do
61
+ put :add, :id =>"77826928"
62
+ put :add, :id => "94120425"
63
+ controller.check_for_empty?.should == false
64
+ put :clear
65
+ controller.check_for_empty?.should == true
66
+ end
51
67
 
52
68
  describe "edit" do
53
69
  before do
@@ -119,6 +135,49 @@ describe BatchEditsController do
119
135
  end
120
136
  end
121
137
 
138
+ describe "delete_collection" do
139
+ before :all do
140
+ @one = Sample.create
141
+ @two = Sample.create
142
+ end
143
+ before do
144
+ controller.stub(:catalog_index_path).and_return('/catalog')
145
+ request.env["HTTP_REFERER"] = "where_i_came_from"
146
+ end
147
+ it "should complain when none are in the batch " do
148
+ delete :destroy_collection
149
+ response.should redirect_to 'where_i_came_from'
150
+ flash[:notice].should == "Select something first"
151
+ end
152
+ it "should not update when the user doesn't have permissions" do
153
+ put :add, :id =>@one.pid
154
+ put :add, :id => @two.pid
155
+ controller.should_receive(:can?).with(:edit, @one.pid).and_return(false)
156
+ controller.should_receive(:can?).with(:edit, @two.pid).and_return(false)
157
+ delete :destroy_collection
158
+ response.should redirect_to 'where_i_came_from'
159
+ flash[:notice].should == "You do not have permission to edit the documents: #{@one.pid}, #{@two.pid}"
160
+ end
161
+ describe "when current user has access to the documents" do
162
+ before do
163
+ @one.save
164
+ @two.save
165
+ put :add, :id =>@one.pid
166
+ put :add, :id => @two.pid
167
+ controller.should_receive(:can?).with(:edit, @one.pid).and_return(true)
168
+ controller.should_receive(:can?).with(:edit, @two.pid).and_return(true)
169
+ ActiveFedora::Base.should_receive(:find).with( @one.pid, :cast=>true).and_return(@one)
170
+ ActiveFedora::Base.should_receive(:find).with( @two.pid, :cast=>true).and_return(@two)
171
+ end
172
+ it "should update all the field" do
173
+ delete :destroy_collection
174
+ response.should redirect_to '/catalog'
175
+ flash[:notice].should == "Batch delete complete"
176
+ Sample.find(@one.pid).should be_nil
177
+ Sample.find(@two.pid).should be_nil
178
+ end
179
+ end
180
+ end
122
181
 
123
182
  describe "state" do
124
183
  it "should save state on" do
@@ -145,6 +204,11 @@ describe BatchEditsController do
145
204
  response.should redirect_to edit_batch_edits_path
146
205
  session[:batch_document_ids].should == [123, 456]
147
206
  end
207
+ it "ajax should add every document in the current resultset to the batch but not redirect" do
208
+ xhr :put, :all
209
+ response.should_not redirect_to edit_batch_edits_path
210
+ session[:batch_document_ids].should == [123, 456]
211
+ end
148
212
  end
149
213
 
150
214
  describe "clear" do
@@ -10,6 +10,9 @@ describe "Routes for batch_update" do
10
10
  it "should route update" do
11
11
  { :put => batch_edits_path }.should route_to( :controller => "batch_edits", :action => "update")
12
12
  end
13
+ it "should route delete batch" do
14
+ { :delete => batch_edits_path }.should route_to( :controller => "batch_edits", :action => "destroy_collection")
15
+ end
13
16
  it "should route add" do
14
17
  { :put => '/batch_edits/7'}.should route_to( :controller => "batch_edits", :action => "add", :id=>'7')
15
18
  end
data/spec/support/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '3.2.6'
3
+ gem 'rails'
4
4
 
5
5
  # Bundle edge Rails instead:
6
6
  # gem 'rails', :git => 'git://github.com/rails/rails.git'
@@ -15,7 +15,7 @@ group :assets do
15
15
  gem 'coffee-rails', '~> 3.2.1'
16
16
 
17
17
  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
18
- # gem 'therubyracer', :platforms => :ruby
18
+ gem 'therubyracer', :platforms => :ruby
19
19
 
20
20
  gem 'uglifier', '>= 1.0.3'
21
21
  end
@@ -30,4 +30,8 @@ class Sample
30
30
  def pid
31
31
  @pid
32
32
  end
33
+
34
+ def destroy
35
+ self.class.objects.delete(@pid)
36
+ end
33
37
  end
@@ -1,11 +1,15 @@
1
1
  $ ->
2
2
  $("[data-behavior='batch-tools']").removeClass('hidden')
3
3
 
4
- $("[data-behavior='batch-add-form']").bl_checkbox_submit({
4
+ window.batch_edits_options = {} if typeof window.batch_edits_options is "undefined"
5
+ default_options =
5
6
  checked_label: "Selected",
6
7
  unchecked_label: "Select",
7
- css_class: "batch_toggle"
8
- })
8
+ css_class: "batch_toggle"
9
+
10
+ options = $.extend({}, default_options, window.batch_edits_options)
11
+
12
+ $("[data-behavior='batch-add-form']").bl_checkbox_submit(options)
9
13
 
10
14
  setState = (obj) ->
11
15
  activate = ->
@@ -45,3 +49,80 @@ $ ->
45
49
  });
46
50
  # TODO check-all
47
51
 
52
+ # ajax manager to queue ajax calls so all adds or removes are done in sequence
53
+ queue = ->
54
+ requests = []
55
+ addReq: (opt) ->
56
+ requests.push opt
57
+
58
+ removeReq: (opt) ->
59
+ requests.splice $.inArray(opt, requests), 1 if $.inArray(opt, requests) > -1
60
+
61
+ run: ->
62
+ self = this
63
+ orgSuc = undefined
64
+ if requests.length
65
+ oriSuc = requests[0].complete
66
+ requests[0].complete = ->
67
+ oriSuc() if typeof oriSuc is "function"
68
+ requests.shift()
69
+ self.run.apply self, []
70
+
71
+ $.ajax requests[0]
72
+ else
73
+ self.tid = setTimeout(->
74
+ self.run.apply self, []
75
+ , 1000)
76
+
77
+ stop: ->
78
+ requests = []
79
+ clearTimeout @tid
80
+
81
+ ajaxManager = (queue())
82
+
83
+ ajaxManager.run()
84
+
85
+ #override the default blacklight checkbox behavior to queue ajax calls
86
+ $("input[type='checkbox'].batch_toggle").click ->
87
+ checked = not this["checked"]
88
+ checkbox = $(this)
89
+ form = $(checkbox.parent()[0])
90
+ label = $(checkbox.parent().children("label")[0])
91
+ label.text(options.progress_label).attr "disabled", "disabled"
92
+ checkbox.attr "disabled", "disabled"
93
+ ajaxManager.addReq
94
+ queue: "add_doc"
95
+ url: form.attr("action")
96
+ dataType: "json"
97
+ type: form.attr("method").toUpperCase()
98
+ data: form.serialize()
99
+ error: ->
100
+ alert "Error Too Many results Selected"
101
+ update_state_for checked, checkbox, label, form
102
+ label.removeAttr "disabled"
103
+ checkbox.removeAttr "disabled"
104
+
105
+ success: (data, status, xhr) ->
106
+ unless xhr.status is 0
107
+ checked = not checked
108
+ update_state_for checked, checkbox, label, form
109
+ label.removeAttr "disabled"
110
+ checkbox.removeAttr "disabled"
111
+ else
112
+ alert "Error Too Many results Selected"
113
+ update_state_for checked, checkbox, label, form
114
+ label.removeAttr "disabled"
115
+ checkbox.removeAttr "disabled"
116
+
117
+ false
118
+
119
+ # complete the override by overriding update_state_for
120
+ update_state_for = (state, checkbox, label, form) ->
121
+ checkbox.attr "checked", state
122
+ label.toggleClass "checked", state
123
+ if state
124
+ form.find("input[name=_method]").val "delete"
125
+ label.text options.progress_label
126
+ else
127
+ form.find("input[name=_method]").val "put"
128
+ label.text options.progress_label
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-batch-edit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-20 00:00:00.000000000 Z
13
+ date: 2012-11-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: blacklight
@@ -92,6 +92,7 @@ files:
92
92
  - app/helpers/batch_edit_helper.rb
93
93
  - app/views/batch_edits/_add_button.html.erb
94
94
  - app/views/batch_edits/_check_all.html.erb
95
+ - app/views/batch_edits/_delete_batch.html.erb
95
96
  - app/views/batch_edits/_next_page.html.erb
96
97
  - app/views/batch_edits/_tools.html.erb
97
98
  - app/views/batch_edits/edit.html.erb