para 0.6.9 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/para/admin/tangram-mosaic.png +0 -0
  3. data/app/assets/images/para/admin/template-section.svg +23 -0
  4. data/app/assets/javascripts/para/admin.coffee +20 -0
  5. data/app/assets/javascripts/para/admin/tabs.coffee +22 -5
  6. data/app/assets/javascripts/para/admin/theme_actions.coffee +3 -3
  7. data/app/assets/javascripts/para/inputs/material-input.coffee +4 -0
  8. data/app/assets/javascripts/para/inputs/multi-select-input.coffee +173 -0
  9. data/app/assets/javascripts/para/inputs/nested_many.coffee +9 -9
  10. data/app/assets/stylesheets/para/admin.sass +5 -5
  11. data/app/assets/stylesheets/para/admin/main.sass +32 -0
  12. data/app/assets/stylesheets/para/admin/src/_alert.sass +17 -0
  13. data/app/assets/stylesheets/para/admin/src/_base.sass +51 -0
  14. data/app/assets/stylesheets/para/admin/src/_bootstrap-variables.scss +874 -0
  15. data/app/assets/stylesheets/para/admin/src/_breadcrumb.sass +22 -0
  16. data/app/assets/stylesheets/para/admin/src/_buttons.sass +107 -0
  17. data/app/assets/stylesheets/para/admin/src/_checkable.sass +94 -0
  18. data/app/assets/stylesheets/para/admin/src/_common.sass +203 -0
  19. data/app/assets/stylesheets/para/admin/src/_dropdown.sass +40 -0
  20. data/app/assets/stylesheets/para/admin/src/_form.sass +271 -0
  21. data/app/assets/stylesheets/para/admin/src/_list.sass +61 -0
  22. data/app/assets/stylesheets/para/admin/src/_mixins.sass +113 -0
  23. data/app/assets/stylesheets/para/admin/src/_multi-select.sass +91 -0
  24. data/app/assets/stylesheets/para/admin/src/_navigation.sass +150 -0
  25. data/app/assets/stylesheets/para/admin/src/_navtabs.sass +41 -0
  26. data/app/assets/stylesheets/para/admin/src/_nested-many.sass +69 -0
  27. data/app/assets/stylesheets/para/admin/src/_nested_one.sass +13 -0
  28. data/app/assets/stylesheets/para/admin/src/_orderable.sass +44 -0
  29. data/app/assets/stylesheets/para/admin/src/_page-loading.sass +39 -0
  30. data/app/assets/stylesheets/para/admin/src/_pagination.sass +34 -0
  31. data/app/assets/stylesheets/para/admin/src/_panel.sass +55 -0
  32. data/app/assets/stylesheets/para/admin/src/_responsive.sass +100 -0
  33. data/app/assets/stylesheets/para/admin/{theme → src}/_sorting.sass +11 -3
  34. data/app/assets/stylesheets/para/admin/src/_statcard.sass +41 -0
  35. data/app/assets/stylesheets/para/admin/src/_table.sass +33 -0
  36. data/app/assets/stylesheets/para/admin/src/_tree.sass +52 -0
  37. data/app/assets/stylesheets/para/admin/src/_variables.sass +37 -0
  38. data/app/assets/stylesheets/para/admin/src/_well.sass +12 -0
  39. data/app/assets/stylesheets/para/{admin/src → lib}/datetimepicker.sass +1 -3
  40. data/app/assets/stylesheets/para/{admin/src → lib}/fuelux.sass +3 -5
  41. data/app/assets/stylesheets/para/lib/jasny-bootstrap.sass +97 -0
  42. data/app/assets/stylesheets/para/{admin/src → lib}/redactor.sass +2 -5
  43. data/app/assets/stylesheets/para/lib/selectize.sass +112 -0
  44. data/app/assets/stylesheets/para/lib/slider.sass +12 -0
  45. data/app/controllers/concerns/para/admin/resource_controller_concerns.rb +14 -2
  46. data/app/controllers/para/admin/base_controller.rb +7 -0
  47. data/app/controllers/para/admin/crud_resources_controller.rb +13 -6
  48. data/app/controllers/para/admin/form_resources_controller.rb +5 -3
  49. data/app/controllers/para/admin/resources_controller.rb +9 -3
  50. data/app/controllers/para/admin/search_controller.rb +15 -0
  51. data/app/controllers/para/application_controller.rb +10 -2
  52. data/app/helpers/para/admin/page_helper.rb +9 -9
  53. data/app/helpers/para/application_helper.rb +1 -10
  54. data/app/helpers/para/form_helper.rb +5 -6
  55. data/app/helpers/para/model_helper.rb +13 -3
  56. data/app/helpers/para/ordering_helper.rb +1 -1
  57. data/app/helpers/para/search_results_helper.rb +16 -0
  58. data/app/helpers/para/tree_helper.rb +10 -6
  59. data/app/models/para/page.rb +5 -0
  60. data/app/models/para/page/section.rb +42 -0
  61. data/app/models/para/page/section_resource.rb +12 -0
  62. data/app/views/layouts/para/admin.html.haml +5 -8
  63. data/app/views/para/admin/dashboard.html.haml +21 -8
  64. data/app/views/para/admin/form_resources/show.html.haml +1 -1
  65. data/app/views/para/admin/imports/new.html.haml +2 -2
  66. data/app/views/para/admin/resources/_actions.html.haml +3 -3
  67. data/app/views/para/admin/resources/_add_button.html.haml +1 -1
  68. data/app/views/para/admin/resources/_exports_menu.html.haml +6 -6
  69. data/app/views/para/admin/resources/_filters.html.haml +7 -8
  70. data/app/views/para/admin/resources/_imports_menu.html.haml +6 -6
  71. data/app/views/para/admin/resources/_list.html.haml +14 -15
  72. data/app/views/para/admin/resources/_per_page_select.html.haml +4 -3
  73. data/app/views/para/admin/resources/_subclassable_add_button.html.haml +3 -3
  74. data/app/views/para/admin/resources/_tree.html.haml +7 -9
  75. data/app/views/para/admin/resources/_tree_item.html.haml +5 -6
  76. data/app/views/para/admin/resources/edit.html.haml +1 -1
  77. data/app/views/para/admin/resources/new.html.haml +1 -1
  78. data/app/views/para/admin/search/_result.html.haml +7 -0
  79. data/app/views/para/admin/search/index.html.haml +1 -0
  80. data/app/views/para/admin/settings_component/show.html.haml +1 -1
  81. data/app/views/para/admin/shared/_breadcrumbs.html.haml +2 -3
  82. data/app/views/para/admin/shared/_header.html.haml +16 -27
  83. data/app/views/para/admin/shared/_navigation.html.haml +20 -19
  84. data/app/views/para/form/_tabs.html.haml +6 -7
  85. data/app/views/para/inputs/_multi_select.html.haml +40 -0
  86. data/app/views/para/inputs/_nested_many.html.haml +4 -4
  87. data/app/views/para/inputs/multi_select/_no_items.html.haml +6 -0
  88. data/app/views/para/inputs/nested_many/_add.html.haml +1 -2
  89. data/app/views/para/inputs/nested_many/_add_with_subclasses.html.haml +4 -5
  90. data/app/views/para/inputs/nested_many/_container.html.haml +7 -8
  91. data/app/views/shared/_breadcrumbs.html.haml +4 -0
  92. data/config/locales/fr.yml +29 -4
  93. data/db/migrate/20170324125547_create_para_page_section_resources.rb +15 -0
  94. data/lib/generators/para/filters/templates/_filters.html.haml +3 -5
  95. data/lib/generators/para/install/templates/initializer.rb +12 -0
  96. data/lib/generators/para/page/section/section_generator.rb +13 -2
  97. data/lib/generators/para/page/section/templates/section.html.haml.erb +3 -0
  98. data/lib/generators/para/resource/resource_generator.rb +1 -1
  99. data/lib/para.rb +25 -21
  100. data/lib/para/attribute_field.rb +2 -0
  101. data/lib/para/attribute_field/base.rb +1 -1
  102. data/lib/para/attribute_field/belongs_to.rb +1 -1
  103. data/lib/para/attribute_field/boolean.rb +1 -1
  104. data/lib/para/attribute_field/friendly_id.rb +19 -0
  105. data/lib/para/attribute_field/has_many.rb +43 -4
  106. data/lib/para/attribute_field/nested_field.rb +46 -0
  107. data/lib/para/attribute_field/nested_many.rb +30 -9
  108. data/lib/para/attribute_field/nested_one.rb +28 -9
  109. data/lib/para/attribute_field/password.rb +1 -1
  110. data/lib/para/attribute_field/relation.rb +19 -1
  111. data/lib/para/attribute_field_mappings.rb +9 -3
  112. data/lib/para/breadcrumbs/breadcrumb.rb +57 -10
  113. data/lib/para/breadcrumbs/controller.rb +19 -6
  114. data/lib/para/breadcrumbs/manager.rb +9 -1
  115. data/lib/para/config.rb +3 -0
  116. data/lib/para/controller_resource.rb +34 -0
  117. data/lib/para/engine.rb +33 -14
  118. data/lib/para/exporter/base.rb +1 -1
  119. data/lib/para/ext.rb +1 -1
  120. data/lib/para/ext/active_record_nested_attributes.rb +51 -0
  121. data/lib/para/ext/paperclip.rb +2 -6
  122. data/lib/para/form_builder.rb +3 -0
  123. data/lib/para/form_builder/attributes_mappings_tracker.rb +45 -0
  124. data/lib/para/form_builder/containers.rb +13 -17
  125. data/lib/para/form_builder/nested_form.rb +2 -3
  126. data/lib/para/helpers.rb +8 -0
  127. data/lib/para/helpers/attributes_mappings.rb +13 -0
  128. data/lib/para/helpers/resource_name.rb +14 -0
  129. data/lib/para/inputs.rb +1 -0
  130. data/lib/para/inputs/multi_select_input.rb +90 -0
  131. data/lib/para/inputs/nested_many_input.rb +6 -1
  132. data/lib/para/markup/resources_table.rb +15 -11
  133. data/lib/para/model_field_parsers.rb +3 -2
  134. data/lib/para/model_field_parsers/base.rb +7 -2
  135. data/lib/para/model_field_parsers/friendly_id.rb +19 -0
  136. data/lib/para/model_field_parsers/relations.rb +20 -1
  137. data/lib/para/page/model.rb +3 -1
  138. data/lib/para/routes.rb +1 -0
  139. data/lib/para/simple_form_config.rb +85 -0
  140. data/lib/para/version.rb +1 -1
  141. data/lib/rails/routing_mapper.rb +5 -8
  142. data/vendor/assets/javascripts/jasny-bootstrap.js +577 -0
  143. data/vendor/assets/stylesheets/animate.css +3340 -0
  144. data/vendor/assets/stylesheets/hint.css +649 -0
  145. data/vendor/assets/stylesheets/jasny-bootstrap.css +287 -0
  146. metadata +114 -67
  147. data/app/assets/images/para/admin/bg.png +0 -0
  148. data/app/assets/javascripts/para/admin.js +0 -20
  149. data/app/assets/stylesheets/admin/theme.sass +0 -0
  150. data/app/assets/stylesheets/para/admin/src/jasny.bootstrap.sass +0 -40
  151. data/app/assets/stylesheets/para/admin/src/nested_many.sass +0 -5
  152. data/app/assets/stylesheets/para/admin/src/page-loading.sass +0 -24
  153. data/app/assets/stylesheets/para/admin/src/page-top-bar.sass +0 -9
  154. data/app/assets/stylesheets/para/admin/src/selectize.sass +0 -46
  155. data/app/assets/stylesheets/para/admin/src/slider.sass +0 -12
  156. data/app/assets/stylesheets/para/admin/theme.sass +0 -22
  157. data/app/assets/stylesheets/para/admin/theme/_base.sass +0 -176
  158. data/app/assets/stylesheets/para/admin/theme/_breadcrumb.sass +0 -75
  159. data/app/assets/stylesheets/para/admin/theme/_buttons.sass +0 -27
  160. data/app/assets/stylesheets/para/admin/theme/_checkable.sass +0 -108
  161. data/app/assets/stylesheets/para/admin/theme/_commonds.sass +0 -210
  162. data/app/assets/stylesheets/para/admin/theme/_dropdown.sass +0 -52
  163. data/app/assets/stylesheets/para/admin/theme/_form.sass +0 -150
  164. data/app/assets/stylesheets/para/admin/theme/_list.sass +0 -139
  165. data/app/assets/stylesheets/para/admin/theme/_navigation.sass +0 -229
  166. data/app/assets/stylesheets/para/admin/theme/_navtabs.sass +0 -151
  167. data/app/assets/stylesheets/para/admin/theme/_orderable.sass +0 -45
  168. data/app/assets/stylesheets/para/admin/theme/_panel.sass +0 -264
  169. data/app/assets/stylesheets/para/admin/theme/_responsive.sass +0 -123
  170. data/app/assets/stylesheets/para/admin/theme/_table.sass +0 -28
  171. data/app/assets/stylesheets/para/admin/theme/_tree.sass +0 -74
  172. data/app/assets/stylesheets/para/admin/theme/_variables.sass +0 -31
  173. data/app/assets/stylesheets/para/application.css +0 -15
  174. data/app/assets/stylesheets/para/lib/_variables.scss +0 -646
  175. data/app/assets/stylesheets/para/overrides/responsive.sass +0 -62
  176. data/app/assets/stylesheets/para/overrides/theme.sass +0 -172
  177. data/lib/para/ext/cancan.rb +0 -26
  178. data/vendor/assets/javascripts/jasny.bootstrap.min.js +0 -7
  179. data/vendor/assets/stylesheets/animate.min.css +0 -6
  180. data/vendor/assets/stylesheets/jasny.bootstrap.min.css +0 -7
@@ -3,8 +3,16 @@ module Para
3
3
  class Manager
4
4
  include Enumerable
5
5
 
6
+ attr_reader :controller
7
+
8
+ delegate :length, to: :breadcrumbs
9
+
10
+ def initialize(controller)
11
+ @controller = controller
12
+ end
13
+
6
14
  def add(identifier, path = nil, *args)
7
- breadcrumbs << Breadcrumb.new(identifier, path, *args)
15
+ breadcrumbs << Breadcrumb.new(identifier, path, controller, *args)
8
16
  end
9
17
 
10
18
  def breadcrumbs
@@ -18,6 +18,9 @@ module Para
18
18
  mattr_accessor :resource_name_methods
19
19
  @@resource_name_methods = [:admin_name, :admin_title, :name, :title]
20
20
 
21
+ mattr_accessor :enable_app_breadcrumbs
22
+ @@enable_app_breadcrumbs = true
23
+
21
24
  mattr_reader :plugins
22
25
  @@plugins = Para::Plugins::Set.new
23
26
 
@@ -0,0 +1,34 @@
1
+ module Para
2
+ class ControllerResource < CanCan::ControllerResource
3
+ # Todo : Document why this extension was added ?
4
+ def assign_attributes(resource)
5
+ if @options[:singleton] && parent_resource && resource.respond_to?(:"#{ parent_name }=")
6
+ resource.send(:"#{ parent_name }=", parent_resource)
7
+ end
8
+
9
+ initial_attributes.each do |attr_name, value|
10
+ resource.send(:"#{ attr_name }=", value)
11
+ end
12
+
13
+ resource
14
+ end
15
+
16
+ # Remove automatic params assignation and let our controllers do it
17
+ # manually, letting our attribute fields to parse the params with a
18
+ # reference to the current resource.
19
+ #
20
+ # Before this override, some attribute fields raised during #parse_input
21
+ # because of the controller resource that was missing at the time it
22
+ # was called (during the resource instanciation ...)
23
+ #
24
+ def build_resource
25
+ resource = resource_base.new
26
+
27
+ unless @options[:bypass_params_assignation]
28
+ resource.assign_attributes(resource_params || {})
29
+ end
30
+
31
+ assign_attributes(resource)
32
+ end
33
+ end
34
+ end
@@ -32,25 +32,13 @@ module Para
32
32
  next unless Kernel.const_defined?('Paperclip')
33
33
 
34
34
  ActiveSupport.on_load(:active_record) do
35
- ::Paperclip::HasAttachedFile.send(
36
- :include, Para::Ext::Paperclip::HasAttachedFileMixin
37
- )
38
- end
39
- end
40
-
41
- initializer 'Extend cancan ControllerResource class' do
42
- next unless Kernel.const_defined?('CanCan')
43
-
44
- ActiveSupport.on_load(:active_record) do
45
- ::CanCan::ControllerResource.send(
46
- :include, Para::Ext::Cancan::ControllerResource
47
- )
35
+ ::Paperclip::HasAttachedFile.prepend Para::Ext::Paperclip::HasAttachedFileMixin
48
36
  end
49
37
  end
50
38
 
51
39
  initializer 'Add resource name methods to simple form extension' do
52
40
  ::SimpleFormExtension.resource_name_methods = (
53
- Para.config.resource_name_methods +
41
+ Para.config.resource_name_methods +
54
42
  ::SimpleFormExtension.resource_name_methods
55
43
  ).uniq
56
44
  end
@@ -63,6 +51,13 @@ module Para
63
51
  end
64
52
  end
65
53
 
54
+ initializer 'Override ActiveRecord::NestedAttributes' do
55
+ ActiveSupport.on_load(:active_record) do
56
+ prepend Para::Ext::ActiveRecord::NestedAttributes
57
+ extend Para::Ext::ActiveRecord::NestedAttributesClassMethods
58
+ end
59
+ end
60
+
66
61
  initializer 'Build components tree' do |app|
67
62
  components_config_path = Rails.root.join('config', 'components.rb')
68
63
 
@@ -75,6 +70,10 @@ module Para
75
70
  Para::PostgresExtensionsChecker.check_all
76
71
  end
77
72
 
73
+ initializer 'Initialize simple form wrappers' do
74
+ Para::SimpleFormConfig.configure
75
+ end
76
+
78
77
  initializer 'Configure ActiveJob' do
79
78
  if ActiveSupport::Cache::NullStore === ActiveJob::Status.store ||
80
79
  ActiveSupport::Cache::MemoryStore === ActiveJob::Status.store
@@ -85,6 +84,26 @@ module Para
85
84
  Para::Logging::ActiveJobLogSubscriber.attach_to :active_job
86
85
  end
87
86
 
87
+ # Allow any view or helper to check wether it is rendered inside the
88
+ # para admin by defaulting to false, and being overriden in
89
+ # Para::ApplicationController with true
90
+ #
91
+ initializer 'Add #admin? method to ActionController::Base' do
92
+ ActiveSupport.on_load(:action_controller) do
93
+ define_method(:admin?) { false }
94
+ end
95
+ end
96
+
97
+ initializer 'Include breadcrumbs manager in app ApplicationController' do
98
+ ActiveSupport.on_load(:action_controller) do
99
+ if Para.config.enable_app_breadcrumbs
100
+ include Para::Breadcrumbs::Controller
101
+ else
102
+ Para::ApplicationController.send(:include, Para::Breadcrumbs::Controller)
103
+ end
104
+ end
105
+ end
106
+
88
107
  # Allow generating resources in the gem without having all the unnecessary
89
108
  # files generated
90
109
  #
@@ -54,7 +54,7 @@ module Para
54
54
  @resources ||= if options[:resources]
55
55
  options[:resources]
56
56
  elsif options[:search]
57
- model.search(options[:search]).result
57
+ model.ransack(options[:search]).result
58
58
  else
59
59
  model.all
60
60
  end
@@ -9,6 +9,6 @@ module Para
9
9
  end
10
10
  end
11
11
 
12
- require 'para/ext/cancan'
13
12
  require 'para/ext/paperclip'
14
13
  require 'para/ext/active_job_status'
14
+ require 'para/ext/active_record_nested_attributes'
@@ -0,0 +1,51 @@
1
+ # This extension is needed because of Para's params input parsing which creates
2
+ # empty placeholder records for nested attributes before their params are
3
+ # assigned.
4
+ #
5
+ # This patch hooks into Rails nested attributes logic to clean all placeholder
6
+ # data during the params assignation process.
7
+ #
8
+ module Para
9
+ module Ext
10
+ module ActiveRecord
11
+ module NestedAttributes
12
+ # Handle rejected nested records that have a fake id, which means that
13
+ # the resource was nevertheless created by Para during input params
14
+ # parsing. Therefore, we clean those records when they're rejected.
15
+ #
16
+ def call_reject_if(association_name, attributes)
17
+ super.tap do |rejected|
18
+ if rejected && attributes['id'].to_s.match(/\A__/)
19
+ records = association(association_name).target
20
+
21
+ if ::ActiveRecord::Base === records
22
+ records.destroy
23
+ elsif (record = records.find { |res| res.id == attributes['id'] })
24
+ records.delete(record)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ module NestedAttributesClassMethods
32
+ # Override default :reject_all proc to handle fake ids as empty keys,
33
+ # avoiding the model to be created with only its fake id.
34
+ PARA_REJECT_ALL_BLANK_PROC = proc { |attributes|
35
+ attributes.all? { |key, value|
36
+ (key == 'id' && value.to_s.match(/\A__/)) || key == '_destroy' || value.blank?
37
+ }
38
+ }
39
+
40
+ # Intercept the `reject_if: :all_blank` option to also consider fake
41
+ # ids as blank fields and avoid empty params assignation
42
+ #
43
+ def accepts_nested_attributes_for(*attr_names)
44
+ options = attr_names.extract_options!
45
+ options[:reject_if] = PARA_REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
46
+ super(*attr_names, options)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -4,12 +4,8 @@ module Para
4
4
  module HasAttachedFileMixin
5
5
  extend ActiveSupport::Concern
6
6
 
7
- included do
8
- alias_method_chain :define, :removeable_management
9
- end
10
-
11
- def define_with_removeable_management
12
- define_without_removeable_management
7
+ def define
8
+ super
13
9
  define_removeable
14
10
  end
15
11
 
@@ -1,5 +1,6 @@
1
1
  require 'simple_form/form_builder'
2
2
 
3
+ require 'para/form_builder/attributes_mappings_tracker'
3
4
  require 'para/form_builder/containers'
4
5
  require 'para/form_builder/field_mappings'
5
6
  require 'para/form_builder/nested_form'
@@ -13,6 +14,8 @@ require 'para/form_builder/tabs'
13
14
  # explicitly
14
15
  #
15
16
  SimpleForm::FormBuilder.class_eval do
17
+ prepend Para::FormBuilder::AttributesMappingsTracker
18
+
16
19
  include Para::FormBuilder::Containers
17
20
  include Para::FormBuilder::FieldMappings
18
21
  include Para::FormBuilder::NestedForm
@@ -0,0 +1,45 @@
1
+ module Para
2
+ module FormBuilder
3
+ module AttributesMappingsTracker
4
+ def initialize(*) #:nodoc:
5
+ @attributes_mappings = {}
6
+
7
+ super
8
+ end
9
+
10
+ def input(attribute_name, options = {}, &block)
11
+ store_attribute_mapping_for(attribute_name, options, &block)
12
+
13
+ super(attribute_name, options, &block)
14
+ end
15
+
16
+ def input_field(attribute_name, options = {})
17
+ store_attribute_mapping_for(attribute_name, options)
18
+
19
+ super(attribute_name, options)
20
+ end
21
+
22
+ def fields_for(*args, options, &block)
23
+ super(*args, options) do |fields|
24
+ fields_html = @template.capture { block.call(fields) }
25
+
26
+ fields_html + fields.attributes_mappings_field_for(fields)
27
+ end
28
+ end
29
+
30
+ def attributes_mappings_field_for(fields)
31
+ hidden_field :_attributes_mappings, value: @attributes_mappings.to_json,
32
+ data: { :'attributes-mappings' => fields.options[:child_index] }
33
+ end
34
+
35
+ private
36
+
37
+ def store_attribute_mapping_for(attribute_name, options, &block)
38
+ input = find_input(attribute_name, options, &block)
39
+ type = input.class.name.demodulize.underscore.gsub(/_input\z/, '')
40
+
41
+ @attributes_mappings[attribute_name] = type
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,11 +2,9 @@ module Para
2
2
  module FormBuilder
3
3
  module Containers
4
4
  def fieldset(options = {}, &block)
5
- template.content_tag(:div, class: 'block form-inputs') do
5
+ template.content_tag(:div, class: 'form-inputs') do
6
6
  buffer = if (title = options[:title])
7
- template.content_tag(:div, class: 'form-group') do
8
- template.content_tag(:legend, title)
9
- end
7
+ template.content_tag(:legend, title)
10
8
  else
11
9
  ''.html_safe
12
10
  end
@@ -16,16 +14,14 @@ module Para
16
14
  end
17
15
 
18
16
  def actions(options = {}, &block)
19
- template.content_tag(:div, class: 'block form-actions form-group') do
20
- template.content_tag(:div, class: 'col-sm-9 col-sm-offset-3') do
21
- if block
22
- template.capture(&block)
23
- else
24
- if options.empty?
25
- options[:only] = template.instance_variable_get(:@component).default_form_actions
26
- end
27
- actions_buttons_for(options).join("\n").html_safe
17
+ template.content_tag(:div, class: 'form-actions') do
18
+ if block
19
+ template.capture(&block)
20
+ else
21
+ if options.empty?
22
+ options[:only] = template.instance_variable_get(:@component).default_form_actions
28
23
  end
24
+ actions_buttons_for(options).join("\n").html_safe
29
25
  end
30
26
  end
31
27
  end
@@ -45,7 +41,7 @@ module Para
45
41
  end
46
42
 
47
43
  def para_submit_button(options = {})
48
- button(:submit, ::I18n.t('para.shared.save'), name: '_save', class: 'btn-success')
44
+ button(:submit, ::I18n.t('para.shared.save'), name: '_save', class: 'btn-success btn-shadow')
49
45
  end
50
46
 
51
47
  def para_submit_and_edit_button
@@ -59,21 +55,21 @@ module Para
59
55
  button_tag = button(
60
56
  :submit,
61
57
  ::I18n.t('para.shared.save_and_edit'),
62
- name: '_save_and_edit', class: 'btn-primary'
58
+ name: '_save_and_edit', class: 'btn-primary btn-shadow'
63
59
  )
64
60
 
65
61
  current_anchor_tag + button_tag
66
62
  end
67
63
 
68
64
  def para_submit_and_add_another_button
69
- button(:submit, ::I18n.t('para.shared.save_and_add_another_button'), name: '_save_and_add_another', class: 'btn-primary')
65
+ button(:submit, ::I18n.t('para.shared.save_and_add_another_button'), name: '_save_and_add_another', class: 'btn-primary btn-shadow')
70
66
  end
71
67
 
72
68
  def para_cancel_button
73
69
  template.link_to(
74
70
  ::I18n.t('para.shared.cancel'),
75
71
  return_to_path,
76
- class: 'btn btn-danger'
72
+ class: 'btn btn-danger btn-shadow'
77
73
  )
78
74
  end
79
75
 
@@ -34,11 +34,10 @@ module Para
34
34
  def remove_association_button
35
35
  return "" unless allow_destroy?
36
36
 
37
- template.content_tag(:div, class: 'panel-btns pull-right') do
37
+ template.content_tag(:div, class: 'panel-btns') do
38
38
  template.link_to_remove_association(
39
- self, wrapper_class: 'form-fields', class: 'btn btn-danger'
39
+ self, wrapper_class: 'form-fields', class: 'btn btn-danger btn-xs'
40
40
  ) do
41
- template.content_tag(:i, '', class: 'fa fa-trash') +
42
41
  ::I18n.t('para.form.nested.remove')
43
42
  end
44
43
  end
@@ -0,0 +1,8 @@
1
+ module Para
2
+ module Helpers
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :AttributesMappings
6
+ autoload :ResourceName
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Para
2
+ module Helpers
3
+ module AttributesMappings
4
+ def attributes_mappings_for(params)
5
+ if (data = params.delete('_attributes_mappings'))
6
+ JSON.parse(data)
7
+ else
8
+ {}
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Para
2
+ module Helpers
3
+ module ResourceName
4
+ def resource_name(resource)
5
+ Para.config.resource_name_methods.each do |method|
6
+ return resource.send(method) if resource.respond_to?(method)
7
+ end
8
+
9
+ model_name = resource.class.model_name.human
10
+ "#{ model_name } - #{ resource.id }"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -4,6 +4,7 @@ module Para
4
4
 
5
5
  autoload :NestedOneInput
6
6
  autoload :NestedManyInput
7
+ autoload :MultiSelectInput
7
8
  autoload :HasOneInput
8
9
  end
9
10
  end
@@ -0,0 +1,90 @@
1
+ module Para
2
+ module Inputs
3
+ class MultiSelectInput < SimpleForm::Inputs::Base
4
+ include Para::Helpers::ResourceName
5
+
6
+ attr_reader :resource
7
+
8
+ def input(wrapper_options = nil)
9
+ input_html_options[:class] << "multi-select"
10
+
11
+ # Load existing resources
12
+ resources = object.send(attribute_name)
13
+ # Order them if the list should be orderable
14
+ resources = resources.sort_by(&method(:resource_position)) if orderable?
15
+
16
+ template.render(
17
+ partial: 'para/inputs/multi_select',
18
+ locals: {
19
+ form: @builder,
20
+ model: model,
21
+ attribute_name: foreign_key,
22
+ orderable: orderable?,
23
+ resources: resources,
24
+ option_resources: option_resources
25
+ }
26
+ )
27
+ end
28
+
29
+ def option_resources
30
+ @option_resources ||= if model.orderable?
31
+ model.ordered
32
+ else
33
+ model.all.sort_by { |resource| resource_name(resource) }
34
+ end
35
+ end
36
+
37
+ def parent_model
38
+ @parent_model ||= @builder.object.class
39
+ end
40
+
41
+ def model
42
+ @model ||= reflection.klass
43
+ end
44
+
45
+ def reflection
46
+ @reflection ||= parent_model.reflect_on_association(attribute_name)
47
+ end
48
+
49
+ def foreign_key
50
+ :"#{ reflection.name.to_s.singularize }_ids"
51
+ end
52
+
53
+ def attribute_field
54
+ @attribute_field ||= AttributeField::HasManyField.new(object.class, name: attribute_name)
55
+ end
56
+
57
+ def orderable?
58
+ @orderable ||= options.fetch(:orderable) do
59
+ if attribute_field.through_reflection
60
+ attribute_field.through_reflection.klass.orderable?
61
+ else
62
+ model.orderable?
63
+ end
64
+ end
65
+ end
66
+
67
+ def resource_position(resource)
68
+ if attribute_field.through_reflection
69
+ resource = join_resources.find do |res|
70
+ res.send(attribute_field.through_relation_source_foreign_key) == resource.id
71
+ end
72
+ end
73
+
74
+ resource.position
75
+ end
76
+
77
+ def orderable_association
78
+ @orderable_association ||= if attribute_field.through_reflection
79
+ object.association(attribute_field.through_reflection.name)
80
+ else
81
+ object.association(attribute_name)
82
+ end
83
+ end
84
+
85
+ def join_resources
86
+ @join_resources ||= orderable_association.load_target
87
+ end
88
+ end
89
+ end
90
+ end