curation_concerns 2.0.0.rc1 → 2.0.0.rc2

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -12
  3. data/.travis.yml +6 -1
  4. data/CONTRIBUTING.md +68 -20
  5. data/app/actors/curation_concerns/actors/add_as_member_of_collections_actor.rb +3 -0
  6. data/app/actors/curation_concerns/actors/add_to_work_actor.rb +16 -4
  7. data/app/actors/curation_concerns/actors/apply_order_actor.rb +16 -5
  8. data/app/actors/curation_concerns/optimistic_lock_validator.rb +28 -0
  9. data/app/assets/javascripts/curation_concerns/file_manager/sorting.es6 +17 -7
  10. data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +11 -1
  11. data/app/controllers/concerns/curation_concerns/download_behavior.rb +6 -0
  12. data/app/forms/curation_concerns/forms/file_manager_form.rb +27 -0
  13. data/app/forms/curation_concerns/forms/work_form.rb +8 -0
  14. data/app/indexers/curation_concerns/file_set_indexer.rb +2 -2
  15. data/app/jobs/characterize_job.rb +12 -5
  16. data/app/jobs/create_derivatives_job.rb +10 -5
  17. data/app/jobs/ingest_file_job.rb +13 -9
  18. data/app/models/concerns/curation_concerns/ability.rb +1 -0
  19. data/app/models/concerns/curation_concerns/collection_behavior.rb +1 -1
  20. data/app/models/concerns/curation_concerns/work_behavior.rb +6 -0
  21. data/app/presenters/curation_concerns/admin/workflow_role_presenter.rb +4 -0
  22. data/app/presenters/curation_concerns/member_presenter_factory.rb +70 -0
  23. data/app/presenters/curation_concerns/work_show_presenter.rb +7 -47
  24. data/app/services/curation_concerns/actors/actor_factory.rb +2 -1
  25. data/app/services/curation_concerns/workflow/grant_edit_to_depositor.rb +1 -1
  26. data/app/services/curation_concerns/workflow/permission_query.rb +4 -1
  27. data/app/services/curation_concerns/workflow/workflow_importer.rb +1 -0
  28. data/app/services/curation_concerns/workflow/workflow_schema.rb +1 -0
  29. data/app/views/curation_concerns/admin/workflow_roles/index.html.erb +1 -2
  30. data/app/views/curation_concerns/base/_file_manager_member_resource_options.html.erb +2 -2
  31. data/app/views/curation_concerns/base/_file_manager_members.html.erb +13 -5
  32. data/app/views/curation_concerns/base/_file_manager_resource_form.html.erb +1 -1
  33. data/app/views/curation_concerns/base/_form.html.erb +5 -0
  34. data/app/views/curation_concerns/base/_form_in_works_error.html.erb +3 -0
  35. data/app/views/curation_concerns/base/_form_ordered_members_error.html.erb +3 -0
  36. data/app/views/curation_concerns/base/file_manager.html.erb +2 -2
  37. data/app/views/curation_concerns/base/show.json.jbuilder +2 -1
  38. data/config/locales/curation_concerns.en.yml +4 -0
  39. data/curation_concerns.gemspec +1 -1
  40. data/db/migrate/20170308175556_add_allows_access_grant_to_workflow.rb +5 -0
  41. data/lib/curation_concerns/data_migration/collections_migration.rb +16 -0
  42. data/lib/curation_concerns/version.rb +1 -1
  43. data/lib/generators/curation_concerns/templates/workflow.json.erb +1 -0
  44. data/lib/tasks/curation_concerns.rake +12 -0
  45. data/spec/actors/curation_concerns/add_as_member_of_collections_actor_spec.rb +58 -0
  46. data/spec/actors/curation_concerns/apply_order_actor_spec.rb +20 -0
  47. data/spec/actors/curation_concerns/optimistic_lock_validator_spec.rb +50 -0
  48. data/spec/actors/curation_concerns/work_actor_spec.rb +9 -6
  49. data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +2 -1
  50. data/spec/controllers/downloads_controller_spec.rb +5 -6
  51. data/spec/features/create_child_work_spec.rb +16 -2
  52. data/spec/forms/curation_concerns/forms/file_manager_form_spec.rb +19 -0
  53. data/spec/forms/work_form_spec.rb +8 -0
  54. data/spec/lib/curation_concerns/data_migration/collections_migration_spec.rb +34 -0
  55. data/spec/presenters/curation_concerns/member_presenter_factory_spec.rb +25 -0
  56. data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +11 -21
  57. data/spec/services/curation_concerns/workflow/grant_edit_to_depositor_spec.rb +15 -4
  58. data/spec/services/curation_concerns/workflow/permission_query_spec.rb +7 -1
  59. data/spec/services/curation_concerns/workflow/workflow_importer_spec.rb +5 -2
  60. data/spec/services/curation_concerns/workflow/workflow_schema_spec.rb +1 -0
  61. data/spec/views/curation_concerns/admin/workflow_roles/index.html.erb_spec.rb +33 -0
  62. data/spec/views/curation_concerns/base/_form.html.erb_spec.rb +35 -0
  63. data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +10 -8
  64. data/spec/views/curation_concerns/base/show.json.jbuilder_spec.rb +3 -1
  65. 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
- STORED_INTEGER = Solrizer::Descriptor.new(:integer, :stored)
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, STORED_INTEGER)] = object.file_size[0]
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
- Hydra::Works::CharacterizationService.run(file_set.characterization_proxy, filename)
11
- Rails.logger.debug "Ran characterization on #{file_set.characterization_proxy.id} (#{file_set.characterization_proxy.mime_type})"
12
- file_set.characterization_proxy.save!
13
- file_set.update_index
14
- file_set.parent.in_collections.each(&:update_index) if file_set.parent
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
- file_set.create_derivatives(filename)
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
- # Reload from Fedora and reindex for thumbnail and extracted text
14
- file_set.reload
15
- file_set.update_index
16
- file_set.parent.update_index if parent_needs_reindex?(file_set)
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,
@@ -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
- # Tell AddFileToFileSet service to skip versioning because versions will be minted by
19
- # VersionCommitter when necessary during save_characterize_and_record_committer.
20
- Hydra::Works::AddFileToFileSet.call(file_set,
21
- local_file,
22
- relation,
23
- versioning: false)
24
-
25
- # Persist changes to the file_set
26
- file_set.save!
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
 
@@ -14,6 +14,7 @@ module CurationConcerns
14
14
 
15
15
  # user can version if they can edit
16
16
  alias_action :versions, to: :update
17
+ alias_action :file_manager, to: :update
17
18
 
18
19
  if admin?
19
20
  admin_permissions
@@ -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::STORED_INTEGER)
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, :file_presenter_class, :work_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
- private
83
+ delegate :member_presenters, :file_set_presenters, :work_presenters, to: :member_presenter_factory
111
84
 
112
- def graph
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
- # TODO: Extract this to ActiveFedora::Aggregations::ListSource
121
- def ordered_ids
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
- # These are the file sets that belong to this work, but not necessarily
129
- # in order.
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
@@ -8,7 +8,8 @@ module CurationConcerns
8
8
  end
9
9
 
10
10
  def self.stack_actors(curation_concern)
11
- [AddAsMemberOfCollectionsActor,
11
+ [OptimisticLockValidator,
12
+ AddAsMemberOfCollectionsActor,
12
13
  AddToWorkActor,
13
14
  AssignRepresentativeActor,
14
15
  AttachFilesActor,
@@ -4,7 +4,7 @@ module CurationConcerns
4
4
  # grants the creator the ability to alter it.
5
5
  class GrantEditToDepositor
6
6
  def self.call(target:, **)
7
- target.edit_users = [target.depositor]
7
+ target.edit_users += [target.depositor]
8
8
  end
9
9
  end
10
10
  end
@@ -257,7 +257,10 @@ module CurationConcerns
257
257
  .and(entity_responsibilities[:entity_id].eq(entity.id))
258
258
  )
259
259
 
260
- sub_query_for_user = agent_table.project(agent_table[:proxy_for_id]).where(
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, @presenter.thumbnail_id == node.id, id: "thumbnail_id_#{node.id}", class: "radio_buttons" %>
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, @presenter.representative_id == node.id, id: "representative_id_#{node.id}", class: "radio_buttons" %>
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
- <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 clearfix">
2
- <% @presenter.member_presenters.each do |member| %>
3
- <%= render "file_manager_member", node: member %>
4
- <% end %>
5
- </ul>
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, @presenter], remote: true, html: { id: 'resource-form', 'data-type': 'json' } do |f| %>
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 %>