curation_concerns 2.0.0.rc1 → 2.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -12
- data/.travis.yml +6 -1
- data/CONTRIBUTING.md +68 -20
- data/app/actors/curation_concerns/actors/add_as_member_of_collections_actor.rb +3 -0
- data/app/actors/curation_concerns/actors/add_to_work_actor.rb +16 -4
- data/app/actors/curation_concerns/actors/apply_order_actor.rb +16 -5
- data/app/actors/curation_concerns/optimistic_lock_validator.rb +28 -0
- data/app/assets/javascripts/curation_concerns/file_manager/sorting.es6 +17 -7
- data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +11 -1
- data/app/controllers/concerns/curation_concerns/download_behavior.rb +6 -0
- data/app/forms/curation_concerns/forms/file_manager_form.rb +27 -0
- data/app/forms/curation_concerns/forms/work_form.rb +8 -0
- data/app/indexers/curation_concerns/file_set_indexer.rb +2 -2
- data/app/jobs/characterize_job.rb +12 -5
- data/app/jobs/create_derivatives_job.rb +10 -5
- data/app/jobs/ingest_file_job.rb +13 -9
- data/app/models/concerns/curation_concerns/ability.rb +1 -0
- data/app/models/concerns/curation_concerns/collection_behavior.rb +1 -1
- data/app/models/concerns/curation_concerns/work_behavior.rb +6 -0
- data/app/presenters/curation_concerns/admin/workflow_role_presenter.rb +4 -0
- data/app/presenters/curation_concerns/member_presenter_factory.rb +70 -0
- data/app/presenters/curation_concerns/work_show_presenter.rb +7 -47
- data/app/services/curation_concerns/actors/actor_factory.rb +2 -1
- data/app/services/curation_concerns/workflow/grant_edit_to_depositor.rb +1 -1
- data/app/services/curation_concerns/workflow/permission_query.rb +4 -1
- data/app/services/curation_concerns/workflow/workflow_importer.rb +1 -0
- data/app/services/curation_concerns/workflow/workflow_schema.rb +1 -0
- data/app/views/curation_concerns/admin/workflow_roles/index.html.erb +1 -2
- data/app/views/curation_concerns/base/_file_manager_member_resource_options.html.erb +2 -2
- data/app/views/curation_concerns/base/_file_manager_members.html.erb +13 -5
- data/app/views/curation_concerns/base/_file_manager_resource_form.html.erb +1 -1
- data/app/views/curation_concerns/base/_form.html.erb +5 -0
- data/app/views/curation_concerns/base/_form_in_works_error.html.erb +3 -0
- data/app/views/curation_concerns/base/_form_ordered_members_error.html.erb +3 -0
- data/app/views/curation_concerns/base/file_manager.html.erb +2 -2
- data/app/views/curation_concerns/base/show.json.jbuilder +2 -1
- data/config/locales/curation_concerns.en.yml +4 -0
- data/curation_concerns.gemspec +1 -1
- data/db/migrate/20170308175556_add_allows_access_grant_to_workflow.rb +5 -0
- data/lib/curation_concerns/data_migration/collections_migration.rb +16 -0
- data/lib/curation_concerns/version.rb +1 -1
- data/lib/generators/curation_concerns/templates/workflow.json.erb +1 -0
- data/lib/tasks/curation_concerns.rake +12 -0
- data/spec/actors/curation_concerns/add_as_member_of_collections_actor_spec.rb +58 -0
- data/spec/actors/curation_concerns/apply_order_actor_spec.rb +20 -0
- data/spec/actors/curation_concerns/optimistic_lock_validator_spec.rb +50 -0
- data/spec/actors/curation_concerns/work_actor_spec.rb +9 -6
- data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +2 -1
- data/spec/controllers/downloads_controller_spec.rb +5 -6
- data/spec/features/create_child_work_spec.rb +16 -2
- data/spec/forms/curation_concerns/forms/file_manager_form_spec.rb +19 -0
- data/spec/forms/work_form_spec.rb +8 -0
- data/spec/lib/curation_concerns/data_migration/collections_migration_spec.rb +34 -0
- data/spec/presenters/curation_concerns/member_presenter_factory_spec.rb +25 -0
- data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +11 -21
- data/spec/services/curation_concerns/workflow/grant_edit_to_depositor_spec.rb +15 -4
- data/spec/services/curation_concerns/workflow/permission_query_spec.rb +7 -1
- data/spec/services/curation_concerns/workflow/workflow_importer_spec.rb +5 -2
- data/spec/services/curation_concerns/workflow/workflow_schema_spec.rb +1 -0
- data/spec/views/curation_concerns/admin/workflow_roles/index.html.erb_spec.rb +33 -0
- data/spec/views/curation_concerns/base/_form.html.erb_spec.rb +35 -0
- data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +10 -8
- data/spec/views/curation_concerns/base/show.json.jbuilder_spec.rb +3 -1
- metadata +26 -5
@@ -27,6 +27,10 @@ module CurationConcerns
|
|
27
27
|
super(model)
|
28
28
|
end
|
29
29
|
|
30
|
+
def version
|
31
|
+
model.etag
|
32
|
+
end
|
33
|
+
|
30
34
|
# The value for embargo_relase_date and lease_expiration_date should not
|
31
35
|
# be initialized to empty string
|
32
36
|
def initialize_field(key)
|
@@ -59,6 +63,10 @@ module CurationConcerns
|
|
59
63
|
super
|
60
64
|
end
|
61
65
|
end
|
66
|
+
|
67
|
+
def build_permitted_params
|
68
|
+
super + [:version]
|
69
|
+
end
|
62
70
|
end
|
63
71
|
|
64
72
|
private
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module CurationConcerns
|
2
2
|
class FileSetIndexer < ActiveFedora::IndexingService
|
3
3
|
include IndexesThumbnails
|
4
|
-
|
4
|
+
STORED_LONG = Solrizer::Descriptor.new(:long, :stored)
|
5
5
|
|
6
6
|
def generate_solr_document
|
7
7
|
super.tap do |solr_doc|
|
@@ -12,7 +12,7 @@ module CurationConcerns
|
|
12
12
|
solr_doc[Solrizer.solr_name('label', :stored_sortable)] = object.label
|
13
13
|
solr_doc[Solrizer.solr_name('file_format')] = file_format
|
14
14
|
solr_doc[Solrizer.solr_name('file_format', :facetable)] = file_format
|
15
|
-
solr_doc[Solrizer.solr_name(:file_size,
|
15
|
+
solr_doc[Solrizer.solr_name(:file_size, STORED_LONG)] = object.file_size[0]
|
16
16
|
solr_doc['all_text_timv'] = object.extracted_text.content if object.extracted_text.present?
|
17
17
|
solr_doc['height_is'] = Integer(object.height.first) if object.height.present?
|
18
18
|
solr_doc['width_is'] = Integer(object.width.first) if object.width.present?
|
@@ -1,4 +1,6 @@
|
|
1
1
|
class CharacterizeJob < ActiveJob::Base
|
2
|
+
include CurationConcerns::Lockable
|
3
|
+
|
2
4
|
queue_as CurationConcerns.config.ingest_queue_name
|
3
5
|
|
4
6
|
# @param [FileSet] file_set
|
@@ -7,11 +9,16 @@ class CharacterizeJob < ActiveJob::Base
|
|
7
9
|
def perform(file_set, file_id, filepath = nil)
|
8
10
|
filename = CurationConcerns::WorkingDirectory.find_or_retrieve(file_id, file_set.id, filepath)
|
9
11
|
raise LoadError, "#{file_set.class.characterization_proxy} was not found" unless file_set.characterization_proxy?
|
10
|
-
|
11
|
-
|
12
|
-
file_set.
|
13
|
-
|
14
|
-
|
12
|
+
|
13
|
+
# Prevent other jobs from trying to modify the FileSet at the same time
|
14
|
+
acquire_lock_for(file_set.id) do
|
15
|
+
Hydra::Works::CharacterizationService.run(file_set.characterization_proxy, filename)
|
16
|
+
Rails.logger.debug "Ran characterization on #{file_set.characterization_proxy.id} (#{file_set.characterization_proxy.mime_type})"
|
17
|
+
file_set.characterization_proxy.save!
|
18
|
+
file_set.update_index
|
19
|
+
file_set.parent.in_collections.each(&:update_index) if file_set.parent
|
20
|
+
end
|
21
|
+
|
15
22
|
CreateDerivativesJob.perform_later(file_set, file_id, filename)
|
16
23
|
end
|
17
24
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
class CreateDerivativesJob < ActiveJob::Base
|
2
|
+
include CurationConcerns::Lockable
|
3
|
+
|
2
4
|
queue_as CurationConcerns.config.ingest_queue_name
|
3
5
|
|
4
6
|
# @param [FileSet] file_set
|
@@ -8,12 +10,15 @@ class CreateDerivativesJob < ActiveJob::Base
|
|
8
10
|
return if file_set.video? && !CurationConcerns.config.enable_ffmpeg
|
9
11
|
filename = CurationConcerns::WorkingDirectory.find_or_retrieve(file_id, file_set.id, filepath)
|
10
12
|
|
11
|
-
|
13
|
+
# Prevent other jobs from trying to modify the FileSet at the same time
|
14
|
+
acquire_lock_for(file_set.id) do
|
15
|
+
file_set.create_derivatives(filename)
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
# Reload from Fedora and reindex for thumbnail and extracted text
|
18
|
+
file_set.reload
|
19
|
+
file_set.update_index
|
20
|
+
file_set.parent.update_index if parent_needs_reindex?(file_set)
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
# If this file_set is the thumbnail for the parent work,
|
data/app/jobs/ingest_file_job.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
class IngestFileJob < ActiveJob::Base
|
2
|
+
include CurationConcerns::Lockable
|
3
|
+
|
2
4
|
queue_as CurationConcerns.config.ingest_queue_name
|
3
5
|
|
4
6
|
# @param [FileSet] file_set
|
@@ -15,15 +17,17 @@ class IngestFileJob < ActiveJob::Base
|
|
15
17
|
local_file.mime_type = opts.fetch(:mime_type, nil)
|
16
18
|
local_file.original_name = opts.fetch(:filename, File.basename(filepath))
|
17
19
|
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
# Prevent other jobs from trying to modify the FileSet at the same time
|
21
|
+
acquire_lock_for(file_set.id) do
|
22
|
+
# Tell AddFileToFileSet service to skip versioning because versions will be minted by
|
23
|
+
# VersionCommitter when necessary during save_characterize_and_record_committer.
|
24
|
+
Hydra::Works::AddFileToFileSet.call(file_set,
|
25
|
+
local_file,
|
26
|
+
relation,
|
27
|
+
versioning: false)
|
28
|
+
# Persist changes to the file_set
|
29
|
+
file_set.save!
|
30
|
+
end
|
27
31
|
|
28
32
|
repository_file = file_set.send(relation)
|
29
33
|
|
@@ -50,7 +50,7 @@ module CurationConcerns
|
|
50
50
|
# Field name to look up when locating the size of each file in Solr.
|
51
51
|
# Override for your own installation if using something different
|
52
52
|
def file_size_field
|
53
|
-
Solrizer.solr_name(:file_size, CurationConcerns::FileSetIndexer::
|
53
|
+
Solrizer.solr_name(:file_size, CurationConcerns::FileSetIndexer::STORED_LONG)
|
54
54
|
end
|
55
55
|
|
56
56
|
# Solr field name collections and works use to index member ids
|
@@ -24,6 +24,12 @@ module CurationConcerns::WorkBehavior
|
|
24
24
|
self.indexer = CurationConcerns::WorkIndexer
|
25
25
|
end
|
26
26
|
|
27
|
+
# TODO: Move this into ActiveFedora
|
28
|
+
def etag
|
29
|
+
raise "Unable to produce an etag for a unsaved object" unless persisted?
|
30
|
+
ldp_source.head.etag
|
31
|
+
end
|
32
|
+
|
27
33
|
module ClassMethods
|
28
34
|
# This governs which partial to draw when you render this type of object
|
29
35
|
def _to_partial_path #:nodoc:
|
@@ -16,6 +16,10 @@ module CurationConcerns
|
|
16
16
|
@agent = agent
|
17
17
|
end
|
18
18
|
|
19
|
+
def responsibilities_present?
|
20
|
+
@agent.workflow_responsibilities.any?
|
21
|
+
end
|
22
|
+
|
19
23
|
def responsibilities
|
20
24
|
@agent.workflow_responsibilities.each do |responsibility|
|
21
25
|
yield ResponsibilityPresenter.new(responsibility)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module CurationConcerns
|
2
|
+
# Creates the presenters of the members (member works and file sets) of a specific object
|
3
|
+
class MemberPresenterFactory
|
4
|
+
class_attribute :file_presenter_class, :work_presenter_class
|
5
|
+
# modify this attribute to use an alternate presenter class for the files
|
6
|
+
self.file_presenter_class = FileSetPresenter
|
7
|
+
|
8
|
+
# modify this attribute to use an alternate presenter class for the child works
|
9
|
+
self.work_presenter_class = WorkShowPresenter
|
10
|
+
|
11
|
+
def initialize(work, ability, request = nil)
|
12
|
+
@work = work
|
13
|
+
@current_ability = ability
|
14
|
+
@request = request
|
15
|
+
end
|
16
|
+
|
17
|
+
delegate :id, to: :@work
|
18
|
+
attr_reader :current_ability, :request
|
19
|
+
|
20
|
+
# @param [Array<String>] ids a list of ids to build presenters for
|
21
|
+
# @param [Class] presenter_class the type of presenter to build
|
22
|
+
# @return [Array<presenter_class>] presenters for the ordered_members (not filtered by class)
|
23
|
+
def member_presenters(ids = ordered_ids, presenter_class = composite_presenter_class)
|
24
|
+
PresenterFactory.build_presenters(ids, presenter_class, *presenter_factory_arguments)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Array<FileSetPresenter>] presenters for the orderd_members that are FileSets
|
28
|
+
def file_set_presenters
|
29
|
+
@file_set_presenters ||= member_presenters(ordered_ids & file_set_ids)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Array<WorkShowPresenter>] presenters for the ordered_members that are not FileSets
|
33
|
+
def work_presenters
|
34
|
+
@work_presenters ||= member_presenters(ordered_ids - file_set_ids, work_presenter_class)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# TODO: Extract this to ActiveFedora::Aggregations::ListSource
|
40
|
+
def ordered_ids
|
41
|
+
@ordered_ids ||= begin
|
42
|
+
ActiveFedora::SolrService.query("proxy_in_ssi:#{id}",
|
43
|
+
rows: 10_000,
|
44
|
+
fl: "ordered_targets_ssim")
|
45
|
+
.flat_map { |x| x.fetch("ordered_targets_ssim", []) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# These are the file sets that belong to this work, but not necessarily
|
50
|
+
# in order.
|
51
|
+
# Arbitrarily maxed at 10 thousand; had to specify rows due to solr's default of 10
|
52
|
+
def file_set_ids
|
53
|
+
@file_set_ids ||= begin
|
54
|
+
ActiveFedora::SolrService.query("{!field f=has_model_ssim}FileSet",
|
55
|
+
rows: 10_000,
|
56
|
+
fl: ActiveFedora.id_field,
|
57
|
+
fq: "{!join from=ordered_targets_ssim to=id}id:\"#{id}/list_source\"")
|
58
|
+
.flat_map { |x| x.fetch(ActiveFedora.id_field, []) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def presenter_factory_arguments
|
63
|
+
[current_ability, request]
|
64
|
+
end
|
65
|
+
|
66
|
+
def composite_presenter_class
|
67
|
+
CompositePresenterFactory.new(file_presenter_class, work_presenter_class, ordered_ids & file_set_ids)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -4,17 +4,11 @@ module CurationConcerns
|
|
4
4
|
include PresentsAttributes
|
5
5
|
attr_accessor :solr_document, :current_ability, :request
|
6
6
|
|
7
|
-
class_attribute :collection_presenter_class
|
7
|
+
class_attribute :collection_presenter_class
|
8
8
|
|
9
9
|
# modify this attribute to use an alternate presenter class for the collections
|
10
10
|
self.collection_presenter_class = CollectionPresenter
|
11
11
|
|
12
|
-
# modify this attribute to use an alternate presenter class for the files
|
13
|
-
self.file_presenter_class = FileSetPresenter
|
14
|
-
|
15
|
-
# modify this attribute to use an alternate presenter class for the child works
|
16
|
-
self.work_presenter_class = self
|
17
|
-
|
18
12
|
# Methods used by blacklight helpers
|
19
13
|
delegate :has?, :first, :fetch, :export_formats, :export_as, to: :solr_document
|
20
14
|
|
@@ -41,11 +35,6 @@ module CurationConcerns
|
|
41
35
|
:lease_expiration_date, :rights, :source, :thumbnail_id, :representative_id,
|
42
36
|
:member_of_collection_ids, to: :solr_document
|
43
37
|
|
44
|
-
# @return [Array<FileSetPresenter>] presenters for the orderd_members that are FileSets
|
45
|
-
def file_set_presenters
|
46
|
-
@file_set_presenters ||= member_presenters(ordered_ids & file_set_ids)
|
47
|
-
end
|
48
|
-
|
49
38
|
def workflow
|
50
39
|
@workflow ||= WorkflowPresenter.new(solr_document, current_ability)
|
51
40
|
end
|
@@ -68,22 +57,6 @@ module CurationConcerns
|
|
68
57
|
end
|
69
58
|
end
|
70
59
|
|
71
|
-
# @return [Array<WorkShowPresenter>] presenters for the ordered_members that are not FileSets
|
72
|
-
def work_presenters
|
73
|
-
@work_presenters ||= member_presenters(ordered_ids - file_set_ids, work_presenter_class)
|
74
|
-
end
|
75
|
-
|
76
|
-
# @param [Array<String>] ids a list of ids to build presenters for
|
77
|
-
# @param [Class] presenter_class the type of presenter to build
|
78
|
-
# @return [Array<presenter_class>] presenters for the ordered_members (not filtered by class)
|
79
|
-
def member_presenters(ids = ordered_ids, presenter_class = composite_presenter_class)
|
80
|
-
PresenterFactory.build_presenters(ids, presenter_class, *presenter_factory_arguments)
|
81
|
-
end
|
82
|
-
|
83
|
-
def composite_presenter_class
|
84
|
-
CompositePresenterFactory.new(file_presenter_class, work_presenter_class, ordered_ids & file_set_ids)
|
85
|
-
end
|
86
|
-
|
87
60
|
# Get presenters for the collections this work is a member of via the member_of_collections association.
|
88
61
|
# @return [Array<CollectionPresenter>] presenters
|
89
62
|
def member_of_collection_presenters
|
@@ -107,33 +80,20 @@ module CurationConcerns
|
|
107
80
|
graph.dump(:ttl)
|
108
81
|
end
|
109
82
|
|
110
|
-
|
83
|
+
delegate :member_presenters, :file_set_presenters, :work_presenters, to: :member_presenter_factory
|
111
84
|
|
112
|
-
|
113
|
-
GraphExporter.new(solr_document, request).fetch
|
114
|
-
end
|
85
|
+
private
|
115
86
|
|
116
87
|
def presenter_factory_arguments
|
117
88
|
[current_ability, request]
|
118
89
|
end
|
119
90
|
|
120
|
-
|
121
|
-
|
122
|
-
@ordered_ids ||= begin
|
123
|
-
ActiveFedora::SolrService.query("proxy_in_ssi:#{id}", fl: "ordered_targets_ssim")
|
124
|
-
.flat_map { |x| x.fetch("ordered_targets_ssim", []) }
|
125
|
-
end
|
91
|
+
def member_presenter_factory
|
92
|
+
MemberPresenterFactory.new(solr_document, current_ability, request)
|
126
93
|
end
|
127
94
|
|
128
|
-
|
129
|
-
|
130
|
-
def file_set_ids
|
131
|
-
@file_set_ids ||= begin
|
132
|
-
ActiveFedora::SolrService.query("{!field f=has_model_ssim}FileSet",
|
133
|
-
fl: ActiveFedora.id_field,
|
134
|
-
fq: "{!join from=ordered_targets_ssim to=id}id:\"#{id}/list_source\"")
|
135
|
-
.flat_map { |x| x.fetch(ActiveFedora.id_field, []) }
|
136
|
-
end
|
95
|
+
def graph
|
96
|
+
GraphExporter.new(solr_document, request).fetch
|
137
97
|
end
|
138
98
|
end
|
139
99
|
end
|
@@ -257,7 +257,10 @@ module CurationConcerns
|
|
257
257
|
.and(entity_responsibilities[:entity_id].eq(entity.id))
|
258
258
|
)
|
259
259
|
|
260
|
-
|
260
|
+
# PostgreSQL requires an explicit cast from string to integer
|
261
|
+
cast = Arel::Nodes::NamedFunction.new "CAST", [agent_table[:proxy_for_id].as("integer")]
|
262
|
+
|
263
|
+
sub_query_for_user = agent_table.project(cast).where(
|
261
264
|
agent_table[:id].in(workflow_agent_id_subquery)
|
262
265
|
.or(agent_table[:id].in(entity_agent_id_subquery))
|
263
266
|
).where(
|
@@ -72,6 +72,7 @@ module CurationConcerns
|
|
72
72
|
workflow = Sipity::Workflow.find_or_initialize_by(name: configuration.fetch(:name)) do |wf|
|
73
73
|
wf.label = configuration.fetch(:label, nil)
|
74
74
|
wf.description = configuration.fetch(:description, nil)
|
75
|
+
wf.allows_access_grant = configuration.fetch(:allows_access_grant, nil)
|
75
76
|
wf.save!
|
76
77
|
end
|
77
78
|
|
@@ -34,6 +34,7 @@ module CurationConcerns
|
|
34
34
|
required(:name).filled(:str?) # Sipity::Workflow#name
|
35
35
|
optional(:label).filled(:str?) # Sipity::Workflow#label
|
36
36
|
optional(:description).filled(:str?) # Sipity::Workflow#description
|
37
|
+
optional(:allows_access_grant).filled(:bool?) # Sipity::Workflow#allows_access_grant?
|
37
38
|
required(:actions).each do
|
38
39
|
required(:name).filled(:str?) # Sipity::WorkflowAction#name
|
39
40
|
required(:from_states).each do
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<tr>
|
12
12
|
<td><%= user.user_key %></td>
|
13
13
|
<% agent_presenter = @presenter.presenter_for(user) %>
|
14
|
-
<% if agent_presenter %>
|
14
|
+
<% if agent_presenter && agent_presenter.responsibilities_present? %>
|
15
15
|
<td>
|
16
16
|
<ul>
|
17
17
|
<% agent_presenter.responsibilities do |responsibility_presenter| %>
|
@@ -42,4 +42,3 @@
|
|
42
42
|
</div>
|
43
43
|
</div>
|
44
44
|
</div>
|
45
|
-
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<div class="form-group radio_buttons member_resource_options">
|
2
2
|
<span class="radio">
|
3
|
-
<%= radio_button_tag "thumbnail_id", node.id, @
|
3
|
+
<%= radio_button_tag "thumbnail_id", node.id, @form.thumbnail_id == node.id, id: "thumbnail_id_#{node.id}", class: "radio_buttons" %>
|
4
4
|
<%= label_tag "thumbnail_id_#{node.id}", "Thumbnail" %>
|
5
5
|
</span>
|
6
6
|
<span class="radio">
|
7
|
-
<%= radio_button_tag "representative_id", node.id, @
|
7
|
+
<%= radio_button_tag "representative_id", node.id, @form.representative_id == node.id, id: "representative_id_#{node.id}", class: "radio_buttons" %>
|
8
8
|
<%= label_tag "representative_id_#{node.id}", "Representative Media" %>
|
9
9
|
</span>
|
10
10
|
</div>
|
@@ -1,5 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
<%= content_tag :ul,
|
2
|
+
id: "sortable",
|
3
|
+
class: "list-unstyled grid clearfix",
|
4
|
+
data: {
|
5
|
+
id: @form.id,
|
6
|
+
"class-name" => @form.model_name.plural,
|
7
|
+
"singular-class-name" => @form.model_name.singular,
|
8
|
+
version: @form.version
|
9
|
+
} do %>
|
10
|
+
<% @form.member_presenters.each do |member| %>
|
11
|
+
<%= render "file_manager_member", node: member %>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="resource-form-container">
|
2
|
-
<%= simple_form_for [main_app, @
|
2
|
+
<%= simple_form_for [main_app, @form], remote: true, html: { id: 'resource-form', 'data-type': 'json' } do |f| %>
|
3
3
|
<%= f.input :thumbnail_id, as: :hidden, input_html: { data: {member_link: 'thumbnail_id'}} %>
|
4
4
|
<%= f.input :representative_id, as: :hidden, input_html: { data: {member_link: 'representative_id'}} %>
|
5
5
|
<% end %>
|