hydra-batch-edit 0.0.6 → 0.0.7

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