para 0.5.0 → 0.5.1

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
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