curation_concerns 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +1 -1
- data/Rakefile +3 -11
- data/VERSION +1 -1
- data/app/assets/javascripts/curation_concerns/application.js +3 -0
- data/app/assets/javascripts/curation_concerns/curation_concerns.js +5 -0
- data/app/assets/javascripts/curation_concerns/file_manager/affix.es6 +13 -0
- data/app/assets/javascripts/curation_concerns/file_manager/list_toggle.es6 +6 -0
- data/app/assets/javascripts/curation_concerns/file_manager/member.es6 +82 -0
- data/app/assets/javascripts/curation_concerns/file_manager/save_manager.es6 +70 -0
- data/app/assets/javascripts/curation_concerns/file_manager/sorting.es6 +82 -0
- data/app/assets/stylesheets/curation_concerns/_modules.scss +1 -1
- data/app/assets/stylesheets/curation_concerns/_typography.scss +0 -11
- data/app/assets/stylesheets/curation_concerns/modules/file_manager.scss +115 -0
- data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +1 -1
- data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +5 -1
- data/app/forms/curation_concerns/forms/work_form.rb +3 -1
- data/app/views/catalog/_document_list.html.erb +1 -1
- data/app/views/collections/_search_collection_dashboard_form.html.erb +1 -1
- data/app/views/collections/_search_form.html.erb +1 -1
- data/app/views/collections/show.html.erb +24 -17
- data/app/views/curation_concerns/base/_file_manager_actions.html.erb +3 -0
- data/app/views/curation_concerns/base/_file_manager_attributes.html.erb +0 -0
- data/app/views/curation_concerns/base/_file_manager_extra_tools.html.erb +0 -0
- data/app/views/curation_concerns/base/_file_manager_member.html.erb +31 -0
- data/app/views/curation_concerns/base/_file_manager_thumbnail.html.erb +1 -0
- data/app/views/curation_concerns/base/_show_actions.html.erb +1 -0
- data/app/views/curation_concerns/base/file_manager.html.erb +34 -0
- data/app/views/shared/_site_search.html.erb +3 -3
- data/config/locales/curation_concerns.en.yml +2 -0
- data/curation_concerns.gemspec +2 -0
- data/lib/curation_concerns/engine.rb +1 -0
- data/lib/curation_concerns/rails/routes.rb +5 -0
- data/lib/curation_concerns/version.rb +1 -1
- data/spec/actors/curation_concerns/work_actor_spec.rb +21 -5
- data/spec/controllers/curation_concerns/collections_controller_spec.rb +9 -0
- data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +24 -4
- data/spec/javascripts/file_manager_member_spec.coffee +87 -0
- data/spec/javascripts/fixtures/.gitkeep +0 -0
- data/spec/javascripts/fixtures/file_manager_member.html +40 -0
- data/spec/javascripts/fixtures/save_button.html +3 -0
- data/spec/javascripts/helpers/jasmine-jquery.js +841 -0
- data/spec/javascripts/helpers/mock-ajax.js +736 -0
- data/spec/javascripts/helpers/test_responses.js +12 -0
- data/spec/javascripts/jasmine_spec.rb +25 -0
- data/spec/javascripts/save_manager_spec.coffee +84 -0
- data/spec/javascripts/support/jasmine.yml +136 -0
- data/spec/javascripts/support/jasmine_helper.rb +15 -0
- data/spec/routing/route_spec.rb +4 -0
- data/spec/support/rake_support.rb +41 -0
- data/spec/views/catalog/index.html.erb_spec.rb +2 -2
- data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +72 -0
- data/tasks/jasmine.rake +18 -0
- metadata +71 -4
@@ -0,0 +1,34 @@
|
|
1
|
+
<h1><%= t("file_manager.link_text") %></h1>
|
2
|
+
<ul class="breadcrumb">
|
3
|
+
<li>
|
4
|
+
Back to <%= link_to @presenter.to_s, [main_app, @presenter] %>
|
5
|
+
</li>
|
6
|
+
</ul>
|
7
|
+
|
8
|
+
<% if !@presenter.file_presenters.empty? %>
|
9
|
+
<div data-action="file-manager">
|
10
|
+
<div class="col-md-3" id="file-manager-tools">
|
11
|
+
<h2>Toolbar</h2>
|
12
|
+
<%= render "file_manager_actions" %>
|
13
|
+
</div>
|
14
|
+
<div class="col-md-3" id="label-tools-spacer" class="fixed"></div>
|
15
|
+
<div class="col-md-9" id="order-grid">
|
16
|
+
<div class="btn-group" role="group" data-action="list-toggle">
|
17
|
+
<button type="button" class="btn btn-default list" aria-label="List">
|
18
|
+
<span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
|
19
|
+
</button>
|
20
|
+
<button type="button" class="btn btn-default active grid" aria-label="Grid">
|
21
|
+
<span class="glyphicon glyphicon-th" aria-hidden="true"></span>
|
22
|
+
</button>
|
23
|
+
</div>
|
24
|
+
<ul id="sortable" data-id="<%= @presenter.id %>" data-class-name="<%= @presenter.model_name.plural %>" data-singular-class-name="<%= @presenter.model_name.singular %>" class="list-unstyled grid">
|
25
|
+
<% @presenter.file_presenters.each do |member| %>
|
26
|
+
<%= render "file_manager_member", node: member %>
|
27
|
+
<% end %>
|
28
|
+
</ul>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
32
|
+
<div id="file-manager-extra-tools">
|
33
|
+
<%= render "file_manager_extra_tools" %>
|
34
|
+
</div>
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<%= form_tag main_app.search_catalog_path, method: :get, class: "search-form" do %>
|
2
2
|
<fieldset>
|
3
|
-
<legend class="
|
4
|
-
<%= label_tag :catalog_search, t('curation_concerns.search.form.q.label'), class: "
|
3
|
+
<legend class="sr-only">Search <%= t('curation_concerns.product_name') %></legend>
|
4
|
+
<%= label_tag :catalog_search, t('curation_concerns.search.form.q.label'), class: "sr-only" %>
|
5
5
|
<%= render_hash_as_hidden_fields(search_state.params_for_search.except(:q, :search_field, :qt, :page, :utf8)) %>
|
6
6
|
<%= text_field_tag(:q, params[:q], class: "q search-query", id: "catalog_search",
|
7
7
|
placeholder: t('curation_concerns.search.form.q.placeholder'), tabindex: "1", type: "search") %>
|
8
8
|
<button type="submit" class="search-submit btn btn-primary" id="keyword-search-submit" tabindex="2">
|
9
|
-
<i class="glyphicon glyphicon-search"></i><span class="
|
9
|
+
<i class="glyphicon glyphicon-search"></i><span class="sr-only">Search</span>
|
10
10
|
</button>
|
11
11
|
</fieldset>
|
12
12
|
<% end %>
|
data/curation_concerns.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency 'hydra-editor', '~> 1.1'
|
26
26
|
spec.add_dependency 'blacklight_advanced_search', '~> 6.0'
|
27
27
|
spec.add_dependency 'rails_autolink'
|
28
|
+
spec.add_dependency 'sprockets-es6'
|
28
29
|
|
29
30
|
spec.add_development_dependency 'solr_wrapper', '~> 0.4'
|
30
31
|
spec.add_development_dependency 'fcrepo_wrapper', '~> 0.1'
|
@@ -42,4 +43,5 @@ Gem::Specification.new do |spec|
|
|
42
43
|
spec.add_development_dependency "factory_girl"
|
43
44
|
spec.add_development_dependency "database_cleaner", "< 1.1.0"
|
44
45
|
spec.add_development_dependency 'mida', '~> 0.3.4'
|
46
|
+
spec.add_development_dependency 'jasmine'
|
45
47
|
end
|
@@ -12,6 +12,11 @@ module ActionDispatch::Routing
|
|
12
12
|
namespace :curation_concerns, path: :concern do
|
13
13
|
concerns_to_route.each do |curation_concern_name|
|
14
14
|
namespaced_resources curation_concern_name, except: [:index], &block
|
15
|
+
namespaced_resources curation_concern_name, only: [] do
|
16
|
+
member do
|
17
|
+
get :file_manager
|
18
|
+
end
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
resources :permissions, only: [] do
|
@@ -247,15 +247,31 @@ describe CurationConcerns::GenericWorkActor do
|
|
247
247
|
context 'with multiple file sets' do
|
248
248
|
let(:file_set1) { create(:file_set) }
|
249
249
|
let(:file_set2) { create(:file_set) }
|
250
|
-
let(:curation_concern) { FactoryGirl.create(:generic_work, user: user,
|
250
|
+
let(:curation_concern) { FactoryGirl.create(:generic_work, user: user, ordered_members: [file_set1, file_set2]) }
|
251
251
|
let(:attributes) do
|
252
|
-
FactoryGirl.attributes_for(:generic_work,
|
252
|
+
FactoryGirl.attributes_for(:generic_work, ordered_member_ids: [file_set2.id, file_set1.id])
|
253
253
|
end
|
254
|
-
|
255
|
-
expect(curation_concern.ordered_members).to eq [file_set1, file_set2]
|
254
|
+
it 'updates the order of file sets' do
|
255
|
+
expect(curation_concern.ordered_members.to_a).to eq [file_set1, file_set2]
|
256
|
+
|
256
257
|
expect(subject.update).to be true
|
258
|
+
|
257
259
|
curation_concern.reload
|
258
|
-
expect(curation_concern.ordered_members).to eq [file_set2, file_set1]
|
260
|
+
expect(curation_concern.ordered_members.to_a).to eq [file_set2, file_set1]
|
261
|
+
end
|
262
|
+
## Is this something we want to support?
|
263
|
+
context "when told to stop ordering a file set" do
|
264
|
+
let(:attributes) do
|
265
|
+
FactoryGirl.attributes_for(:generic_work, ordered_member_ids: [file_set2.id])
|
266
|
+
end
|
267
|
+
it "works" do
|
268
|
+
expect(curation_concern.ordered_members.to_a).to eq [file_set1, file_set2]
|
269
|
+
|
270
|
+
expect(subject.update).to be true
|
271
|
+
|
272
|
+
curation_concern.reload
|
273
|
+
expect(curation_concern.ordered_members.to_a).to eq [file_set2]
|
274
|
+
end
|
259
275
|
end
|
260
276
|
end
|
261
277
|
end
|
@@ -163,6 +163,15 @@ describe CollectionsController do
|
|
163
163
|
expect(assigns[:presenter].title).to eq collection.title
|
164
164
|
expect(assigns[:member_docs].map(&:id)).to match_array [asset1, asset2, asset3].map(&:id)
|
165
165
|
end
|
166
|
+
|
167
|
+
context 'when the q parameter is passed' do
|
168
|
+
it 'loads the collection (paying no attention to the q param)' do
|
169
|
+
get :show, id: collection, q: 'no matches'
|
170
|
+
expect(response).to be_successful
|
171
|
+
expect(assigns[:presenter]).to be_kind_of CurationConcerns::CollectionPresenter
|
172
|
+
expect(assigns[:presenter].title).to eq collection.title
|
173
|
+
end
|
174
|
+
end
|
166
175
|
end
|
167
176
|
|
168
177
|
context 'not signed in' do
|
@@ -122,7 +122,7 @@ describe CurationConcerns::GenericWorksController do
|
|
122
122
|
describe '#update' do
|
123
123
|
let(:a_work) { create(:private_generic_work, user: user) }
|
124
124
|
before do
|
125
|
-
allow(
|
125
|
+
allow(CurationConcerns::CurationConcern).to receive(:actor).and_return(actor)
|
126
126
|
end
|
127
127
|
let(:actor) { double(update: true, visibility_changed?: false) }
|
128
128
|
|
@@ -131,6 +131,13 @@ describe CurationConcerns::GenericWorksController do
|
|
131
131
|
expect(response).to redirect_to main_app.curation_concerns_generic_work_path(a_work)
|
132
132
|
end
|
133
133
|
|
134
|
+
it "can update file membership" do
|
135
|
+
file = create(:file_set, user: user)
|
136
|
+
|
137
|
+
patch :update, id: a_work, generic_work: { ordered_member_ids: [file.id] }
|
138
|
+
expect(CurationConcerns::CurationConcern).to have_received(:actor).with(anything, anything, ordered_member_ids: [file.id])
|
139
|
+
end
|
140
|
+
|
134
141
|
describe 'changing rights' do
|
135
142
|
let(:actor) { double(update: true, visibility_changed?: true) }
|
136
143
|
|
@@ -138,14 +145,14 @@ describe CurationConcerns::GenericWorksController do
|
|
138
145
|
let(:a_work) { create(:work_with_one_file, user: user) }
|
139
146
|
|
140
147
|
it 'prompts to change the files access' do
|
141
|
-
patch :update, id: a_work
|
148
|
+
patch :update, id: a_work, generic_work: {}
|
142
149
|
expect(response).to redirect_to main_app.confirm_curation_concerns_permission_path(controller.curation_concern)
|
143
150
|
end
|
144
151
|
end
|
145
152
|
|
146
153
|
context 'without children' do
|
147
154
|
it "doesn't prompt to change the files access" do
|
148
|
-
patch :update, id: a_work
|
155
|
+
patch :update, id: a_work, generic_work: {}
|
149
156
|
expect(response).to redirect_to main_app.curation_concerns_generic_work_path(a_work)
|
150
157
|
end
|
151
158
|
end
|
@@ -155,7 +162,7 @@ describe CurationConcerns::GenericWorksController do
|
|
155
162
|
let(:actor) { double(update: false, visibility_changed?: false) }
|
156
163
|
|
157
164
|
it 'renders the form' do
|
158
|
-
patch :update, id: a_work
|
165
|
+
patch :update, id: a_work, generic_work: {}
|
159
166
|
expect(assigns[:form]).to be_kind_of CurationConcerns::GenericWorkForm
|
160
167
|
expect(response).to render_template('edit')
|
161
168
|
end
|
@@ -207,4 +214,17 @@ describe CurationConcerns::GenericWorksController do
|
|
207
214
|
end
|
208
215
|
end
|
209
216
|
end
|
217
|
+
|
218
|
+
describe '#file_manager' do
|
219
|
+
let(:work) { create(:private_generic_work, user: user) }
|
220
|
+
before do
|
221
|
+
sign_in user
|
222
|
+
end
|
223
|
+
it "is successful" do
|
224
|
+
get :file_manager, id: work.id
|
225
|
+
|
226
|
+
expect(response).to be_success
|
227
|
+
expect(assigns(:presenter)).not_to be_blank
|
228
|
+
end
|
229
|
+
end
|
210
230
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
describe "FileManagerMember", ->
|
2
|
+
file_manager_member = null
|
3
|
+
save_manager = null
|
4
|
+
beforeEach () ->
|
5
|
+
loadFixtures('file_manager_member.html')
|
6
|
+
save_manager = {
|
7
|
+
push_changed: () -> {},
|
8
|
+
mark_unchanged: () -> {}
|
9
|
+
}
|
10
|
+
file_manager_member = new FileManagerMember($("li"), save_manager)
|
11
|
+
describe "#is_changed", ->
|
12
|
+
it "is true when the form's label input is changed", ->
|
13
|
+
$("#file_set_title").val("testing")
|
14
|
+
$("#file_set_title").change()
|
15
|
+
|
16
|
+
expect(file_manager_member.is_changed).toEqual(true)
|
17
|
+
it "is false when the form's label input isn't changed", ->
|
18
|
+
$("#file_set_title").change()
|
19
|
+
|
20
|
+
expect(file_manager_member.is_changed).toEqual(false)
|
21
|
+
it "is false when the form's label input returns", ->
|
22
|
+
initial_val = $("#file_set_title").val()
|
23
|
+
$("#file_set_title").val("testing")
|
24
|
+
$("#file_set_title").change()
|
25
|
+
$("#file_set_title").val(initial_val)
|
26
|
+
$("#file_set_title").change()
|
27
|
+
|
28
|
+
expect(file_manager_member.is_changed).toEqual(false)
|
29
|
+
it "triggers save_manager's push_changed when changed", ->
|
30
|
+
spyOn(save_manager, "push_changed")
|
31
|
+
$("#file_set_title").val("testing")
|
32
|
+
$("#file_set_title").change()
|
33
|
+
|
34
|
+
expect(save_manager.push_changed).toHaveBeenCalledWith(file_manager_member)
|
35
|
+
it "triggers save_manager's mark_unchanged when no longer changed", ->
|
36
|
+
spyOn(save_manager, "mark_unchanged")
|
37
|
+
initial_val = $("#file_set_title").val()
|
38
|
+
$("#file_set_title").val("testing")
|
39
|
+
$("#file_set_title").change()
|
40
|
+
$("#file_set_title").val(initial_val)
|
41
|
+
$("#file_set_title").change()
|
42
|
+
|
43
|
+
expect(save_manager.mark_unchanged).toHaveBeenCalledWith(file_manager_member)
|
44
|
+
it "doesn't trigger save_manager's mark_unchanged when there are still changed elements", ->
|
45
|
+
spyOn(save_manager, "mark_unchanged")
|
46
|
+
file_manager_member.elements.push {}
|
47
|
+
initial_val = $("#file_set_title").val()
|
48
|
+
$("#file_set_title").val("testing")
|
49
|
+
$("#file_set_title").change()
|
50
|
+
$("#file_set_title").val(initial_val)
|
51
|
+
$("#file_set_title").change()
|
52
|
+
|
53
|
+
expect(save_manager.mark_unchanged).not.toHaveBeenCalled()
|
54
|
+
describe "#persist", ->
|
55
|
+
describe "when nothing has changed", ->
|
56
|
+
it "returns a resolved deferred object", ->
|
57
|
+
expect(file_manager_member.persist().state()).toEqual("resolved")
|
58
|
+
describe "when updates need to be sent", ->
|
59
|
+
request = null
|
60
|
+
beforeEach () ->
|
61
|
+
jasmine.Ajax.install()
|
62
|
+
afterEach () ->
|
63
|
+
jasmine.Ajax.uninstall()
|
64
|
+
it "returns a deferred object which is resolved with the ajax request", ->
|
65
|
+
$("#file_set_title").val("testing")
|
66
|
+
$("#file_set_title").change()
|
67
|
+
result = file_manager_member.persist()
|
68
|
+
request = jasmine.Ajax.requests.mostRecent()
|
69
|
+
|
70
|
+
expect(result.state()).toEqual("pending")
|
71
|
+
|
72
|
+
request.respondWith(TestResponses.file_manager_member.success)
|
73
|
+
|
74
|
+
expect(result.state()).toEqual("resolved")
|
75
|
+
expect(file_manager_member.is_changed).toEqual(false)
|
76
|
+
it "rejects the deferred object when the ajax request fails", ->
|
77
|
+
$("#file_set_title").val("testing")
|
78
|
+
$("#file_set_title").change()
|
79
|
+
result = file_manager_member.persist()
|
80
|
+
request = jasmine.Ajax.requests.mostRecent()
|
81
|
+
|
82
|
+
expect(result.state()).toEqual("pending")
|
83
|
+
|
84
|
+
request.respondWith(TestResponses.file_manager_member.failure)
|
85
|
+
|
86
|
+
expect(result.state()).toEqual("rejected")
|
87
|
+
expect(file_manager_member.is_changed).toEqual(true)
|
File without changes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<li data-reorder-id="j38606956">
|
2
|
+
<form accept-charset="UTF-8" action="/concern/file_sets/j38606956" class=
|
3
|
+
"simple_form edit_file_set" data-remote="true" id="edit_file_set_j38606956"
|
4
|
+
method="post" name="edit_file_set_j38606956">
|
5
|
+
<input name="utf8" type="hidden" value="✓"><input name="_method" type=
|
6
|
+
"hidden" value="patch">
|
7
|
+
<div class="panel panel-default">
|
8
|
+
<div class="panel-heading ui-sortable-handle">
|
9
|
+
<div class="order-title">
|
10
|
+
<div class="form-group string required file_set_title">
|
11
|
+
<div>
|
12
|
+
<input aria-required="true" class=
|
13
|
+
"string required title form-control" id="file_set_title" name=
|
14
|
+
"file_set[title][]" required="required" type="text" value=
|
15
|
+
"01.tif">
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
<div class="file-set-link pull-right">
|
20
|
+
<a href="/concern/file_sets/j38606956" title=
|
21
|
+
"Edit file"><span aria-hidden="true" class=
|
22
|
+
"glyphicon glyphicon-edit"></span></a>
|
23
|
+
</div>
|
24
|
+
<div class="order-filename">
|
25
|
+
<em title="01.tif">(01.tif)</em>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
<div class="panel-body">
|
29
|
+
<div class="text-center thumbnail">
|
30
|
+
<a data-context-href="/catalog/j38606956/track?search_id=1" href=
|
31
|
+
"/concern/file_sets/j38606956"><img alt="J38606956?file=thumbnail"
|
32
|
+
class="thumbnail-inner" src=
|
33
|
+
"/downloads/j38606956?file=thumbnail"></a>
|
34
|
+
</div>
|
35
|
+
<div class="attributes"></div>
|
36
|
+
<div class="spacer"></div>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</form>
|
40
|
+
</li>
|