para 0.6.9 → 0.7.0

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