para 0.8.3 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 932450574c9f0ae3df18f694ec0e85292fae9c13e89bae9e0c4e3170acf31b5e
4
- data.tar.gz: affb81684ce4e7f0fba86a8e6f31c31e40aa5a43bcb400a6cf6e0effd964a0d6
2
+ SHA1:
3
+ metadata.gz: 8f7d2729a7b4605f42e736da01ed85636b39232c
4
+ data.tar.gz: 42a119d77586ef8db3eee57231c3a46154141e1c
5
5
  SHA512:
6
- metadata.gz: ecb83cf77fa7d9ac72461a9537e936bc72c890a755a36f6ad4441235dfdf9c7c9bc561aa17fd3352920d177bbf8e00909498c3e3548c7814b7393369bd739052
7
- data.tar.gz: 1728f4c124e70866df8eb0d83ede63a63c194eff93d3941361d62d7a43493b6126789187fc9de12f0523ad38c5af7239d3c734f17da515ce8eb5f2800952237c
6
+ metadata.gz: 44f44a2d7340fa890359d5f259f90b591f2436609399028bb77a54237f1e49b95d81435a807c452234cc58904a2a7773bd469be58b373d4074244a540a325442
7
+ data.tar.gz: 25280f88dd481faf6882df01416d85b31cc0a3fcc7204487ad53d7837bd7220463b0280141e1cdc203c577960ac103977abbd7d560ca9570fb00dd76325ec166
@@ -18,20 +18,20 @@ class Para.NestedManyField
18
18
  @$fieldsList.on('sortupdate', $.proxy(@sortUpdate, this))
19
19
 
20
20
  sortUpdate: ->
21
- @$fieldsList.find('.form-fields').each (i, el) ->
21
+ @$fieldsList.find('.form-fields:visible').each (i, el) ->
22
22
  $(el).find('.resource-position-field').val(i)
23
23
 
24
24
  initializeCocoon: ->
25
25
  @$fieldsList.on 'cocoon:after-insert', $.proxy(@afterInsertField, this)
26
26
  @$fieldsList.on 'cocoon:before-remove', $.proxy(@beforeRemoveField, this)
27
+ @$fieldsList.on 'cocoon:after-remove', $.proxy(@afterRemoveField, this)
27
28
 
28
29
  afterInsertField: (e, $element) ->
29
30
  if ($collapsible = $element.find('[data-open-on-insert="true"]')).length
30
31
  @openInsertedField($collapsible)
31
32
 
32
33
  if @orderable
33
- @$fieldsList.sortable('destroy')
34
- @initializeOrderable()
34
+ @$fieldsList.sortable('reload')
35
35
  @sortUpdate()
36
36
 
37
37
  $element.simpleForm()
@@ -42,6 +42,10 @@ class Para.NestedManyField
42
42
  # create an empty nested resource otherwise
43
43
  $nextEl.remove() if $nextEl.is('[data-attributes-mappings]') and not $element.is('[data-persisted]')
44
44
 
45
+ # When a sub field is removed, update every sub field position
46
+ afterRemoveField: ->
47
+ @sortUpdate();
48
+
45
49
  openInsertedField: ($field) ->
46
50
  $target = $($field.attr('href'))
47
51
  $target.collapse('show')
@@ -1,6 +1,8 @@
1
1
  module Para
2
2
  module Admin
3
3
  class SearchController < ApplicationController
4
+ include Para::Helpers::ResourceName
5
+
4
6
  def index
5
7
  # Parse ids that are provided as string into array
6
8
  if params[:q] && params[:q][:id_in].is_a?(String)
@@ -9,8 +11,16 @@ module Para
9
11
 
10
12
  model = params[:model_name].constantize
11
13
  @results = model.ransack(params[:q]).result
14
+ @results = @results.limit(params[:limit]) if params[:limit]
12
15
 
13
- render layout: false
16
+ case params[:mode]
17
+ when "selectize"
18
+ render json: @results.map { |res|
19
+ { text: resource_name(res), value: res.id }
20
+ }
21
+ else
22
+ render layout: false
23
+ end
14
24
  end
15
25
  end
16
26
  end
@@ -21,7 +21,7 @@ module Para
21
21
  allow_adding_resource = options.fetch(:addable, true)
22
22
 
23
23
  partial = :list
24
- partial = :tree if model.respond_to? :roots
24
+ partial = :tree if model.respond_to?(:roots) && can?(:tree, model)
25
25
 
26
26
  render(
27
27
  partial: find_partial_for(relation, partial),
@@ -48,6 +48,8 @@ module Para
48
48
  end
49
49
 
50
50
  def add_button_for(component, relation, model)
51
+ return unless can?(:create, model)
52
+
51
53
  partial_name = if component.subclassable?
52
54
  :subclassable_add_button
53
55
  else
@@ -4,6 +4,10 @@
4
4
  = render partial: find_partial_for(relation, :actions), locals: { relation: relation, component: component, model: model, allow_adding_resource: allow_adding_resource }
5
5
 
6
6
  - if resources.length > 0
7
+ - if resources.total_count > 100
8
+ .page-entries-info
9
+ = page_entries(resources)
10
+
7
11
  %ul.tree.root-tree{ data: { url: component.relation_path(model.model_name.route_key, action: :tree), :"max-depth" => max_depth_for(model) } }
8
12
  = render partial: find_partial_for(model, 'tree_item'), collection: resources.roots, as: :root, locals: { model: model}
9
13
 
@@ -1,10 +1,10 @@
1
1
  .nested-many-field{ class: [('orderable' if orderable), ('nested-many-field-inset' if inset)] }
2
2
  .fields-list{ id: dom_identifier }
3
3
  = form.simple_fields_for attribute_name, resources, nested_attribute_name: attribute_name, orderable: orderable, track_attribute_mappings: render_partial do |nested_form|
4
- = render partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), locals: { form: nested_form, model: nested_form.object.class, subclass: subclass, nested_locals: nested_locals, inset: inset, render_partial: render_partial, remote_partial_params: remote_partial_params }
4
+ = render partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), locals: { form: nested_form, model: nested_form.object.class, subclass: subclass, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, render_partial: render_partial, remote_partial_params: remote_partial_params }
5
5
  -# Add button
6
6
  - if add_button
7
7
  - if subclass
8
- = render partial: 'para/inputs/nested_many/add_with_subclasses', locals: { form: form, model: model, dom_identifier: dom_identifier, nested_locals: nested_locals, attribute_name: attribute_name, orderable: orderable, subclasses: subclasses, inset: inset, add_button_label: add_button_label, add_button_class: add_button_class, render_partial: render_partial, remote_partial_params: remote_partial_params }
8
+ = render partial: 'para/inputs/nested_many/add_with_subclasses', locals: { form: form, model: model, dom_identifier: dom_identifier, nested_locals: nested_locals, attribute_name: attribute_name, orderable: orderable, subclasses: subclasses, inset: inset, uncollapsed: uncollapsed, add_button_label: add_button_label, add_button_class: add_button_class, render_partial: render_partial, remote_partial_params: remote_partial_params }
9
9
  - else
10
- = render partial: 'para/inputs/nested_many/add', locals: { form: form, model: model, dom_identifier: dom_identifier, nested_locals: nested_locals, attribute_name: attribute_name, orderable: orderable, inset: inset, add_button_label: add_button_label, add_button_class: add_button_class, render_partial: render_partial, remote_partial_params: remote_partial_params }
10
+ = render partial: 'para/inputs/nested_many/add', locals: { form: form, model: model, dom_identifier: dom_identifier, nested_locals: nested_locals, attribute_name: attribute_name, orderable: orderable, inset: inset, uncollapsed: uncollapsed, add_button_label: add_button_label, add_button_class: add_button_class, render_partial: render_partial, remote_partial_params: remote_partial_params }
@@ -1,2 +1,2 @@
1
- = link_to_add_association form, attribute_name, partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: "btn btn-shadow add-button nested-many-inset-add-button #{add_button_class}", data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: model, nested_locals: nested_locals, inset: inset, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
1
+ = link_to_add_association form, attribute_name, partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: "btn btn-shadow add-button nested-many-inset-add-button #{add_button_class}", data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: model, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
2
2
  = add_button_label
@@ -5,5 +5,5 @@
5
5
  %ul.dropdown-menu
6
6
  - subclasses.each do |submodel|
7
7
  %li
8
- = link_to_add_association form, attribute_name, wrap_object: proc { submodel.new }, partial: find_partial_for(submodel, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: 'dropdown-link', data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: submodel, nested_locals: nested_locals, inset: inset, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
8
+ = link_to_add_association form, attribute_name, wrap_object: proc { submodel.new }, partial: find_partial_for(submodel, 'nested_many/container', partial_dir: 'inputs'), form_name: 'form', class: 'dropdown-link', data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: submodel, nested_locals: nested_locals, inset: inset, uncollapsed: uncollapsed, render_partial: render_partial, remote_partial_params: remote_partial_params } } do
9
9
  = submodel.model_name.human
@@ -11,7 +11,7 @@
11
11
 
12
12
  = form.remove_association_button
13
13
 
14
- .panel-collapse.form-inputs.collapse{ id: form.nested_resource_dom_id, class: ('in' if inset && form.object.persisted?), data: { rendered: render_partial, render_path: @component.path(remote_partial_params), id: form.object.id, :"object-name" => form.object_name, :"model-name" => model.name } }
14
+ .panel-collapse.form-inputs.collapse{ id: form.nested_resource_dom_id, class: ('in' if uncollapsed && form.object.persisted?), data: { rendered: render_partial, render_path: @component.path(remote_partial_params), id: form.object.id, :"object-name" => form.object_name, :"model-name" => model.name } }
15
15
  .panel-body{ data: { :"nested-form-container" => true } }
16
16
  - if render_partial
17
17
  = render partial: find_partial_for(model, :fields), locals: { form: form }.merge(nested_locals)
@@ -27,9 +27,17 @@ Para.config do |config|
27
27
  # config.resource_name_methods += [:full_name]
28
28
 
29
29
  # Configure the theme navigation bar color not gray but blue darker
30
- #
30
+ #
31
31
  # config.dark_theme = true
32
32
 
33
+ # Do not uncollapse by default "inset" nested fields, which makes all such nested field
34
+ # blocks get collapsed on page load, and can be easier to read for big blocks.
35
+ #
36
+ # This also speeds up page loading when used in conjunction to remote partial loading
37
+ # for nested fields
38
+ #
39
+ # config.uncollapse_inset_nested_fields = false
40
+
33
41
  # Set if the Para::Breadcrumb::Controller module should be included into the
34
42
  # app, allowing easy breadcrumbs management in the app.
35
43
  #
@@ -43,8 +43,12 @@ module Para
43
43
  end
44
44
 
45
45
  # Takes an array of ids and a block. Check for each id if model exists
46
- # and create one if not. E.g: [12, "foo"] will try to create a model with
47
- # 'foo'
46
+ # and create one if not.
47
+ #
48
+ # Example : [12, "foo"] will try to create a model with
49
+ # 'foo' as a name, title or any other attribute referenced in
50
+ # the `Para.config.resource_name_methods` configuration param.
51
+ #
48
52
  def on_the_fly_creation ids, &block
49
53
  Array.wrap(ids).each do |id|
50
54
  if !reflection.klass.exists?(id: id)
@@ -56,7 +60,14 @@ module Para
56
60
  if resource.respond_to?(setter_name)
57
61
  resource.send(setter_name, id)
58
62
 
59
- if resource.save
63
+ # This check avoids multiple creation of the same resource with
64
+ # a given attribute value and ensure all resources from the form
65
+ # that reference that new resource name are associated to the
66
+ # same parent resource.
67
+ if (existing_resource = reflection.klass.find_by(method_name => id))
68
+ block.call(existing_resource, id)
69
+ break
70
+ elsif resource.save
60
71
  block.call(resource, id)
61
72
  break
62
73
  end
@@ -42,6 +42,9 @@ module Para
42
42
  mattr_accessor :dark_theme
43
43
  @@dark_theme = false
44
44
 
45
+ mattr_accessor :uncollapse_inset_nested_fields
46
+ @@uncollapse_inset_nested_fields = true
47
+
45
48
  # Allows changing default cache store used by Para to store jobs through
46
49
  # the ActiveJob::Status gem
47
50
  #
@@ -26,6 +26,9 @@ module Para
26
26
  file.save!
27
27
 
28
28
  store(:file_gid, file.to_global_id)
29
+
30
+ # Ensure that `.perform_now` returns the exporter
31
+ self
29
32
  end
30
33
 
31
34
  def file
@@ -27,7 +27,9 @@ module Para
27
27
  end
28
28
 
29
29
  def actions_buttons_for(options)
30
- names = [:submit, :submit_and_edit, :submit_and_add_another, :cancel]
30
+ names = [:submit, :submit_and_edit]
31
+ names << :submit_and_add_another if template.can?(:create, object.class)
32
+ names << :cancel
31
33
 
32
34
  names.select! { |name| Array.wrap(options[:only]).include?(name) } if options[:only]
33
35
  names.reject! { |name| Array.wrap(options[:except]).include?(name) } if options[:except]
@@ -26,6 +26,9 @@ module Para
26
26
  end
27
27
 
28
28
  save_errors!
29
+
30
+ # Ensure that `.perform_now` returns the importer
31
+ self
29
32
  end
30
33
 
31
34
  protected
@@ -32,6 +32,7 @@ module Para
32
32
  add_button_label: add_button_label,
33
33
  add_button_class: add_button_class,
34
34
  inset: inset?,
35
+ uncollapsed: uncollapsed?,
35
36
  render_partial: render_partial?,
36
37
  remote_partial_params: remote_partial_params
37
38
  }
@@ -50,9 +51,13 @@ module Para
50
51
  def inset?
51
52
  options.fetch(:inset, false)
52
53
  end
53
-
54
+
55
+ def uncollapsed?
56
+ inset? && Para.config.uncollapse_inset_nested_fields
57
+ end
58
+
54
59
  def render_partial?
55
- options[:render_partial] || object.errors.any? || (object.persisted? && inset?)
60
+ options[:render_partial] || object.errors.any? || (object.persisted? && uncollapsed?)
56
61
  end
57
62
 
58
63
  def remote_partial_params
@@ -2,14 +2,14 @@ module Para
2
2
  module Markup
3
3
  class ResourcesButtons < Para::Markup::Component
4
4
  attr_reader :component
5
-
5
+
6
6
  def initialize(component, view)
7
7
  @component = component
8
8
  super(view)
9
9
  end
10
10
 
11
11
  def clone_button(resource)
12
- return unless resource.class.cloneable?
12
+ return unless resource.class.cloneable? && view.can?(:clone, resource)
13
13
 
14
14
  path = component.relation_path(
15
15
  resource, action: :clone, return_to: view.request.fullpath
@@ -29,6 +29,8 @@ module Para
29
29
  end
30
30
 
31
31
  def edit_button(resource)
32
+ return unless view.can?(:edit, resource)
33
+
32
34
  path = component.relation_path(
33
35
  resource, action: :edit, return_to: view.request.fullpath
34
36
  )
@@ -39,6 +41,8 @@ module Para
39
41
  end
40
42
 
41
43
  def delete_button(resource)
44
+ return unless view.can?(:delete, resource)
45
+
42
46
  path = component.relation_path(resource, return_to: view.request.fullpath)
43
47
 
44
48
  options = {
@@ -5,7 +5,7 @@ module Para
5
5
  self.default_actions = [:edit, :clone, :delete]
6
6
 
7
7
  attr_reader :component, :model, :orderable, :actions
8
-
8
+
9
9
  def initialize(component, view)
10
10
  @component = component
11
11
  super(view)
@@ -15,7 +15,7 @@ module Para
15
15
  @model = options.delete(:model)
16
16
 
17
17
  if !options.key?(:orderable) || options.delete(:orderable)
18
- @orderable = model.orderable?
18
+ @orderable = model.orderable? && view.can?(:order, model)
19
19
  end
20
20
 
21
21
  @actions = build_actions(options.delete(:actions))
@@ -93,7 +93,7 @@ module Para
93
93
 
94
94
  content_tag(:th, options) do
95
95
  if (sort = options.delete(:sort))
96
- view.sort_link(search, *sort, label, hide_indicator: true)
96
+ view.sort_link(search, *sort, label, hide_indicator: true)
97
97
  elsif searchable?(field_name)
98
98
  view.sort_link(search, field_name, label, hide_indicator: true)
99
99
  else
@@ -1,3 +1,3 @@
1
1
  module Para
2
- VERSION = '0.8.3'
2
+ VERSION = '0.8.7'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: para
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valentin Ballestrino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-23 00:00:00.000000000 Z
11
+ date: 2020-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -168,14 +168,14 @@ dependencies:
168
168
  requirements:
169
169
  - - "~>"
170
170
  - !ruby/object:Gem::Version
171
- version: '1.9'
171
+ version: '3.0'
172
172
  type: :runtime
173
173
  prerelease: false
174
174
  version_requirements: !ruby/object:Gem::Requirement
175
175
  requirements:
176
176
  - - "~>"
177
177
  - !ruby/object:Gem::Version
178
- version: '1.9'
178
+ version: '3.0'
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: kaminari
181
181
  requirement: !ruby/object:Gem::Requirement
@@ -849,7 +849,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
849
849
  - !ruby/object:Gem::Version
850
850
  version: '0'
851
851
  requirements: []
852
- rubygems_version: 3.0.3
852
+ rubyforge_project:
853
+ rubygems_version: 2.6.11
853
854
  signing_key:
854
855
  specification_version: 4
855
856
  summary: Rails admin engine