para 0.5.0 → 0.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c04310b282e123cc4d2f5329d495d6133aaf8bfd
4
- data.tar.gz: 3f5658e207ad84fd1820dc4428bc4a65b95635a8
3
+ metadata.gz: 732caede63e764554d7a140b937d9b2c22ca9c85
4
+ data.tar.gz: 2cf5c7b7351487eb7b6c73de119fe8e0b17a79af
5
5
  SHA512:
6
- metadata.gz: 2553622ee949ea75a6c1de1db3c08af4058a41e134cf7b4c5d453dc83b20c03ab14e78144b3f9fa95ce0ea66efa8c8082e50feee00e26d28f53f09070dc9c65e
7
- data.tar.gz: 6031a27defab3bbd0254dead9a8620009e43efe10ad2af914cf5bef8bc0f989c45c11f10cb0c79c8163afcf96ebe6455faabd93c09cd13934ad6afc8001d5d4b
6
+ metadata.gz: abf828d53004049d831e19fb4125cc5ab54c254decc1f28a30a06bf8866f5bae76ca287d2e2b5664a28685c278106bd9ce269c51c1f6822be0984beab3a47148
7
+ data.tar.gz: c271d48d9883fd0f5268efddddf48efa61a3b77cc8ca4309896aeb8ec3c18f17f60a59522d746e04b94b34fb84c7fc1683b6147bc24fec5780015197796a88b0
@@ -21,7 +21,7 @@
21
21
  display: block
22
22
  &.fileinput-exists
23
23
  .fileinput-placeholder
24
- display: none
24
+ display: none
25
25
 
26
26
  .input-group-addon
27
27
  font-size: 13px
@@ -128,8 +128,7 @@ label.valid
128
128
 
129
129
  legend
130
130
  font-weight: 600
131
- padding: 10px 12px 15px 12px
132
- margin-top: 10px
131
+ padding: 15px 12px 15px 12px
133
132
  margin-bottom: 0
134
133
  width: auto
135
134
  margin-left: 0
@@ -22,3 +22,7 @@
22
22
  line-height: 28px
23
23
  .progress-small
24
24
  margin: 7px 0 8px
25
+
26
+ .panel-body
27
+ &.page-entries-info
28
+ padding: 0 20px
@@ -9,13 +9,13 @@
9
9
  outline: none
10
10
  outline-offset: 0
11
11
 
12
- @mixin button-hover-focus-active($color-border, $color-bg)
12
+ @mixin button-hover-focus-active($color-border, $color-bg)
13
13
  position: relative
14
- box-shadow: 0px 2px darken($color-border, 10%)
14
+ box-shadow: 0px 2px darken($color-border, 10%)
15
15
  transition: none
16
16
  &:hover
17
17
  top: 1px
18
- box-shadow: 0px 1px darken($color-border, 10%)
18
+ box-shadow: 0px 1px darken($color-border, 10%)
19
19
  background-color: $color-bg
20
20
  border-color: $color-border
21
21
  &:focus,
@@ -29,7 +29,7 @@
29
29
  &:hover
30
30
  background-color: darken($color-bg, 7%)
31
31
 
32
- @mixin button-variant-inverse($color-border, $color-bg)
32
+ @mixin button-variant-inverse($color-border, $color-bg)
33
33
  color: $color-border
34
34
  background-color: transparent
35
35
  box-shadow: none
@@ -51,8 +51,8 @@
51
51
  background-color: darken($color-bg, 7%)
52
52
  outline: none
53
53
  outline: 0
54
-
55
- .btn,
54
+
55
+ .btn,
56
56
  input,
57
57
  textarea,
58
58
  select,
@@ -61,15 +61,15 @@ button
61
61
  &,
62
62
  &:active,
63
63
  &.active
64
- &:focus
64
+ &:focus
65
65
  +tab-focus()
66
66
  &:hover,
67
67
  &:focus
68
68
  +tab-focus()
69
-
69
+
70
70
 
71
71
  .btn-default
72
- +button-hover-focus-active($btn-default-border, $btn-default-bg)
72
+ +button-hover-focus-active($btn-default-border, $btn-default-bg)
73
73
  &.btn-inverse
74
74
  +button-variant-inverse($btn-default-border, $btn-default-bg)
75
75
  color: $btn-default-color
@@ -111,25 +111,25 @@ button
111
111
  background-color: $brand-primary
112
112
 
113
113
  .label-success,
114
- .badge-success
114
+ .badge-success
115
115
  background-color: $brand-success
116
116
 
117
117
  .label-info,
118
- .badge-info
118
+ .badge-info
119
119
  background-color: $brand-info
120
120
 
121
121
  .label-warning,
122
- .badge-warning
122
+ .badge-warning
123
123
  background-color: $brand-warning
124
124
 
125
125
  .label-danger,
126
- .badge-danger
126
+ .badge-danger
127
127
  background-color: $brand-danger
128
128
 
129
129
  // Table
130
130
  .para-component-relation-table
131
131
  td > img
132
- height: 50px
132
+ height: 50px
133
133
 
134
134
  .pull-right.btn-group
135
135
  min-width: 97px
@@ -148,9 +148,9 @@ button
148
148
  clear: both
149
149
  content: " "
150
150
  display: table
151
-
151
+
152
152
  .block.form-inputs
153
- margin-bottom: 20px
153
+ margin-bottom: 0
154
154
  padding: 0px 10px
155
155
  background-color: $body-bg
156
156
 
@@ -96,9 +96,18 @@ module Para
96
96
  end
97
97
  end
98
98
 
99
+ # We check for the existance of `params[:resource]` to avoid rails'
100
+ # params sanitizer to raise if no `:resource` key is found. We prefer
101
+ # to let the model handle validations instead of asking the controller
102
+ # to validate some params presence
103
+ #
104
+ # Note : This also created a bug with cancan which tried to build the
105
+ # params on a `new` action, that did not contain the `:resource`
106
+ # key in the params, which made the `#new` action form raise
107
+ #
99
108
  def resource_params
100
109
  @resource_params ||= parse_resource_params(
101
- params.require(:resource).permit!
110
+ (params[:resource] && params.require(:resource).permit!) || {}
102
111
  )
103
112
  end
104
113
 
@@ -4,6 +4,7 @@ module Para
4
4
  include Para::Component::BaseDecorator
5
5
 
6
6
  def path(options = {})
7
+ options[:model] ||= model_singular_route_key
7
8
  find_path([:admin, self, :resources], options)
8
9
  end
9
10
 
@@ -13,7 +14,7 @@ module Para
13
14
  end
14
15
 
15
16
  route_key = route_key_for(options[:id], options)
16
- options[:model] = model.model_name.singular_route_key
17
+ options[:model] = model_singular_route_key
17
18
 
18
19
  polymorphic_path([:admin, self, route_key].compact, options)
19
20
  end
@@ -31,6 +32,10 @@ module Para
31
32
  :resources
32
33
  end
33
34
  end
35
+
36
+ def model_singular_route_key
37
+ @model_singular_route_key ||= model.model_name.singular_route_key
38
+ end
34
39
  end
35
40
  end
36
41
  end
@@ -4,19 +4,39 @@ module Para
4
4
  include Para::ApplicationHelper
5
5
 
6
6
  def find_partial_for(relation, partial, partial_dir: 'admin/resources')
7
- if relation.kind_of? ActiveRecord::Base
7
+ relation_class = if relation.kind_of?(ActiveRecord::Base)
8
8
  relation = relation.class
9
+ elsif model?(relation)
10
+ relation
9
11
  end
10
12
 
11
- relation = relation.to_s.underscore.pluralize
13
+ relation_name = find_relation_name_for(
14
+ 'admin', plural_file_path_for(relation), partial,
15
+ relation_class: relation_class
16
+ )
12
17
 
13
- if lookup_context.find_all("admin/#{relation}/_#{ partial }").any?
14
- "admin/#{ relation }/#{ partial }"
18
+ if relation_name
19
+ "admin/#{ relation_name }/#{ partial }"
15
20
  else
16
21
  "para/#{ partial_dir }/#{ partial }"
17
22
  end
18
23
  end
19
24
 
25
+ def find_relation_name_for(namespace, relation, partial, options = {})
26
+ return relation if partial_exists?(relation, partial)
27
+ return nil unless options[:relation_class]
28
+
29
+ relation = options[:relation_class].ancestors.find do |ancestor|
30
+ next unless model?(ancestor)
31
+ break if ancestor == ActiveRecord::Base
32
+
33
+ ancestor_name = plural_file_path_for(ancestor.name)
34
+ partial_exists?(ancestor_name, partial)
35
+ end
36
+
37
+ plural_file_path_for(relation) if relation
38
+ end
39
+
20
40
  def template_path_lookup(*paths)
21
41
  paths.find do |path|
22
42
  lookup_context.find_all(path).any?
@@ -57,6 +77,20 @@ module Para
57
77
  def flash_shared_key
58
78
  'para.flash.shared'
59
79
  end
80
+
81
+ private
82
+
83
+ def plural_file_path_for(class_name)
84
+ class_name.to_s.underscore.pluralize
85
+ end
86
+
87
+ def model?(object)
88
+ object.respond_to?(:model_name)
89
+ end
90
+
91
+ def partial_exists?(relation, partial)
92
+ lookup_context.find_all("admin/#{relation}/_#{ partial }").any?
93
+ end
60
94
  end
61
95
  end
62
96
  end
@@ -3,9 +3,9 @@ module Para
3
3
  def ordered_components
4
4
  @component_sections.each_with_object([]) do |section, components|
5
5
  section.components.each do |component|
6
- components << component
6
+ components << component if can?(:read, component)
7
7
  end
8
- end.sort_by(&:updated_at)
8
+ end.sort_by(&:name)
9
9
  end
10
10
  end
11
11
  end
@@ -7,6 +7,9 @@
7
7
  = render partial: find_partial_for(relation, :filters), locals: { attributes: attributes }
8
8
 
9
9
  - if resources.length > 0
10
+ = panel.body class: 'page-entries-info' do
11
+ = page_entries_info(resources)
12
+
10
13
  = panel.body class: '' do
11
14
  = table_for(resources: resources, model: model, component: component, attributes: attributes)
12
15
 
@@ -1,10 +1,11 @@
1
1
  .nested-many-field{ class: ('orderable' if orderable) }
2
2
  .fields-list{ id: dom_identifier }
3
3
  = form.simple_fields_for attribute_name, resources, nested_attribute_name: attribute_name, orderable: orderable do |nested_form|
4
- = render partial: find_partial_for(model, :nested_many_container, partial_dir: 'inputs'), locals: { form: nested_form, model: model }
4
+ = render partial: find_partial_for(model, 'nested_many/container', partial_dir: 'inputs'), locals: { form: nested_form, model: model, subclass: subclass, nested_locals: nested_locals }
5
5
 
6
6
  -# Add button
7
7
  - if add_button
8
- = link_to_add_association form, attribute_name, partial: find_partial_for(model, :nested_many_container, partial_dir: 'inputs'), form_name: 'form', class: 'btn btn-primary', data: { :'association-insertion-node' => "##{ dom_identifier }", :'association-insertion-method' => 'append' }, render_options: { nested_attribute_name: attribute_name, orderable: orderable, locals: { model: model } } do
9
- %i.fa.fa-plus
10
- = t('para.form.nested.add')
8
+ - if subclass
9
+ = 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 }
10
+ - else
11
+ = 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 }
@@ -0,0 +1,3 @@
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-primary', 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 } } do
2
+ %i.fa.fa-plus
3
+ = t('para.form.nested.add')
@@ -0,0 +1,10 @@
1
+ .add-button.dropdown
2
+ %button.btn.btn-primary{ type: 'button', data: { toggle: 'dropdown' } }
3
+ %i.fa.fa-plus
4
+ = t('para.form.nested.add')
5
+ %span.caret
6
+ %ul.dropdown-menu
7
+ - model.descendants.sort_by { |m| m.model_name.human }.each do |submodel|
8
+ %li
9
+ = 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 } } do
10
+ = submodel.model_name.human
@@ -1,3 +1,5 @@
1
+ - nested_locals ||= {}
2
+
1
3
  .panel.panel-default.form-fields
2
4
  .panel-heading
3
5
  = form.reorder_anchor
@@ -12,6 +14,8 @@
12
14
  .clearfix
13
15
 
14
16
  .panel-body.form-inputs.collapse{ id: form.nested_resource_dom_id }
15
- = render partial: find_partial_for(model, :fields), locals: { form: form }
17
+ = render partial: find_partial_for(model, :fields), locals: { form: form }.merge(nested_locals)
18
+
19
+ = form.hidden_field :type if form.object.class.column_names.include?(form.object.class.inheritance_column)
16
20
 
17
21
  .clearfix
@@ -114,3 +114,21 @@ fr:
114
114
  time:
115
115
  formats:
116
116
  admin: '%d/%m/%Y %H:%M'
117
+
118
+ # Kaminari translations
119
+ views:
120
+ pagination:
121
+ first: "&laquo; Première"
122
+ last: "Dernière &raquo;"
123
+ previous: "&lsaquo; Précédente"
124
+ next: "Suivante &rsaquo;"
125
+ truncate: "&hellip;"
126
+ helpers:
127
+ page_entries_info:
128
+ one_page:
129
+ display_entries:
130
+ zero: "Aucune entrée trouvée"
131
+ one: "Affichage des entrées <b>1&nbsp;-&nbsp;1</b> sur <b>1</b> au total"
132
+ other: "Affichage des entrées <b>1&nbsp;-&nbsp;%{count}</b> sur <b>%{count}</b> au total"
133
+ more_pages:
134
+ display_entries: "Affichage des entrées <b>%{first}&nbsp;-&nbsp;%{last}</b> sur <b>%{total}</b> au total"
@@ -3,9 +3,15 @@ module Para
3
3
  class DatetimeField < AttributeField::Base
4
4
  register :datetime, :date, self
5
5
 
6
+ field_option :wrapper, :wrapper_name
7
+
6
8
  def value_for(instance)
7
9
  (value = instance.send(name)) && I18n.l(value)
8
10
  end
11
+
12
+ def wrapper_name
13
+ :horizontal_form
14
+ end
9
15
  end
10
16
  end
11
17
  end
@@ -1,9 +1,17 @@
1
1
  module Para
2
2
  module FormBuilder
3
3
  module Containers
4
- def fieldset(&block)
4
+ def fieldset(options = {}, &block)
5
5
  template.content_tag(:div, class: 'block form-inputs') do
6
- template.capture(&block)
6
+ buffer = if (title = options[:title])
7
+ template.content_tag(:div, class: 'form-group') do
8
+ template.content_tag(:legend, title)
9
+ end
10
+ else
11
+ ''.html_safe
12
+ end
13
+
14
+ buffer + template.capture(&block)
7
15
  end
8
16
  end
9
17
 
@@ -1,6 +1,10 @@
1
1
  module Para
2
2
  module FormBuilder
3
3
  module NestedForm
4
+ # FIXME : When we have a nested field that maps to an STI model, the _id
5
+ # field is passed instead of the relation, and the inverse_of
6
+ # guard doesn't work
7
+ #
4
8
  def nested_fields
5
9
  @nested_fields ||= fields.reject do |field|
6
10
  inverse_of?(field.name)
@@ -4,8 +4,6 @@ module Para
4
4
  def input(wrapper_options = nil)
5
5
  input_html_options[:class] << "nested-many"
6
6
 
7
- parent_model = @builder.object.class
8
- model = parent_model.reflect_on_association(attribute_name).klass
9
7
  orderable = options.fetch(:orderable, model.orderable?)
10
8
  add_button = options.fetch(:add_button, true)
11
9
  # Load existing resources
@@ -13,6 +11,8 @@ module Para
13
11
  # Order them if the list should be orderable
14
12
  resources = resources.order(:position) if orderable
15
13
 
14
+ locals = options.fetch(:locals, {})
15
+
16
16
  template.render(
17
17
  partial: 'para/inputs/nested_many',
18
18
  locals: {
@@ -22,11 +22,21 @@ module Para
22
22
  orderable: orderable,
23
23
  add_button: add_button,
24
24
  dom_identifier: dom_identifier,
25
- resources: resources
25
+ resources: resources,
26
+ nested_locals: locals,
27
+ subclass: subclass
26
28
  }
27
29
  )
28
30
  end
29
31
 
32
+ def parent_model
33
+ @parent_model ||= @builder.object.class
34
+ end
35
+
36
+ def model
37
+ @model ||= parent_model.reflect_on_association(attribute_name).klass
38
+ end
39
+
30
40
  def dom_identifier
31
41
  @dom_identifier ||= begin
32
42
  name = attribute_name
@@ -35,6 +45,13 @@ module Para
35
45
  [name, time, random].join('-')
36
46
  end
37
47
  end
48
+
49
+ def subclass
50
+ @subclass ||= options.fetch(
51
+ :subclass,
52
+ model.respond_to?(:descendants) && model.descendants.length > 0
53
+ )
54
+ end
38
55
  end
39
56
  end
40
57
  end
@@ -14,7 +14,7 @@ module Para
14
14
 
15
15
  router.instance_eval do
16
16
  namespace :admin do
17
- scope module: :acl do
17
+ scope module: [:para, identifier].join('/').to_sym, as: identifier do
18
18
  router.instance_eval(&block)
19
19
  end
20
20
  end
data/lib/para/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Para
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
@@ -31,8 +31,8 @@ module ActionDispatch
31
31
  controller = [component_name.to_s.singularize, 'resources'].join('_')
32
32
 
33
33
  scope endpoint, as: as do
34
- resources :resources, controller: controller do
35
- scope options[:scope] do
34
+ scope options[:scope] do
35
+ resources :resources, controller: controller do
36
36
  collection do
37
37
  patch :order
38
38
  patch :tree
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.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valentin Ballestrino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-18 00:00:00.000000000 Z
11
+ date: 2016-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -437,8 +437,10 @@ files:
437
437
  - app/views/para/admin/singleton_resources/show.html.haml
438
438
  - app/views/para/form/_tabs.html.haml
439
439
  - app/views/para/inputs/_nested_many.html.haml
440
- - app/views/para/inputs/_nested_many_container.html.haml
441
440
  - app/views/para/inputs/_nested_one.html.haml
441
+ - app/views/para/inputs/nested_many/_add.html.haml
442
+ - app/views/para/inputs/nested_many/_add_with_subclasses.html.haml
443
+ - app/views/para/inputs/nested_many/_container.html.haml
442
444
  - config/locales/en.yml
443
445
  - config/locales/fr.yml
444
446
  - db/migrate/20140911091225_create_para_components.rb