para 0.4.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +65 -0
- data/Rakefile +21 -0
- data/app/assets/images/para/admin/bg.png +0 -0
- data/app/assets/javascripts/admin/app.coffee +1 -0
- data/app/assets/javascripts/para/admin/table.coffee +46 -0
- data/app/assets/javascripts/para/admin/theme_actions.coffee +26 -0
- data/app/assets/javascripts/para/admin/tree.coffee +53 -0
- data/app/assets/javascripts/para/admin.coffee +18 -0
- data/app/assets/javascripts/para/application.js +13 -0
- data/app/assets/javascripts/para/inputs/nested_many.coffee +57 -0
- data/app/assets/javascripts/para/lib/ajax.coffee +11 -0
- data/app/assets/stylesheets/admin/app.sass +0 -0
- data/app/assets/stylesheets/admin/theme.sass +0 -0
- data/app/assets/stylesheets/para/admin/theme/_base.sass +170 -0
- data/app/assets/stylesheets/para/admin/theme/_breadcrumb.sass +29 -0
- data/app/assets/stylesheets/para/admin/theme/_buttons.sass +24 -0
- data/app/assets/stylesheets/para/admin/theme/_checkable.sass +107 -0
- data/app/assets/stylesheets/para/admin/theme/_commonds.sass +213 -0
- data/app/assets/stylesheets/para/admin/theme/_dropdown.sass +53 -0
- data/app/assets/stylesheets/para/admin/theme/_form.sass +141 -0
- data/app/assets/stylesheets/para/admin/theme/_list.sass +138 -0
- data/app/assets/stylesheets/para/admin/theme/_navigation.sass +287 -0
- data/app/assets/stylesheets/para/admin/theme/_navtabs.sass +127 -0
- data/app/assets/stylesheets/para/admin/theme/_orderable.sass +44 -0
- data/app/assets/stylesheets/para/admin/theme/_panel.sass +288 -0
- data/app/assets/stylesheets/para/admin/theme/_responsive.sass +123 -0
- data/app/assets/stylesheets/para/admin/theme/_sorting.sass +30 -0
- data/app/assets/stylesheets/para/admin/theme/_table.sass +24 -0
- data/app/assets/stylesheets/para/admin/theme/_tree.sass +74 -0
- data/app/assets/stylesheets/para/admin/theme/_variables.sass +31 -0
- data/app/assets/stylesheets/para/admin/theme.sass +22 -0
- data/app/assets/stylesheets/para/admin.sass +10 -0
- data/app/assets/stylesheets/para/application.css +15 -0
- data/app/assets/stylesheets/para/lib/_variables.scss +646 -0
- data/app/assets/stylesheets/para/overrides/datetimepicker.sass +17 -0
- data/app/assets/stylesheets/para/overrides/fuelux.sass +43 -0
- data/app/assets/stylesheets/para/overrides/jasny.bootstrap.sass +41 -0
- data/app/assets/stylesheets/para/overrides/redactor.sass +88 -0
- data/app/assets/stylesheets/para/overrides/responsive.sass +63 -0
- data/app/assets/stylesheets/para/overrides/selectize.sass +45 -0
- data/app/assets/stylesheets/para/overrides/slider.sass +13 -0
- data/app/assets/stylesheets/para/overrides/theme.sass +172 -0
- data/app/controllers/concerns/para/admin/resource_controller_concerns.rb +17 -0
- data/app/controllers/para/admin/base_controller.rb +46 -0
- data/app/controllers/para/admin/component_controller.rb +9 -0
- data/app/controllers/para/admin/crud_component_controller.rb +17 -0
- data/app/controllers/para/admin/crud_resources_controller.rb +71 -0
- data/app/controllers/para/admin/main_controller.rb +8 -0
- data/app/controllers/para/admin/resources_controller.rb +163 -0
- data/app/controllers/para/admin/settings_component_controller.rb +11 -0
- data/app/controllers/para/admin/settings_form_controller.rb +21 -0
- data/app/controllers/para/admin/singleton_resource_component_controller.rb +14 -0
- data/app/controllers/para/admin/singleton_resources_controller.rb +30 -0
- data/app/controllers/para/application_controller.rb +7 -0
- data/app/decorators/para/component/base_decorator.rb +48 -0
- data/app/decorators/para/component/crud_decorator.rb +32 -0
- data/app/decorators/para/component/settings_decorator.rb +11 -0
- data/app/decorators/para/component/singleton_resource_decorator.rb +11 -0
- data/app/decorators/para/component_section_decorator.rb +4 -0
- data/app/helpers/para/admin/base_helper.rb +57 -0
- data/app/helpers/para/admin/component_groups_helper.rb +4 -0
- data/app/helpers/para/admin/components_helper.rb +4 -0
- data/app/helpers/para/admin/resources_helper.rb +27 -0
- data/app/helpers/para/application_helper.rb +14 -0
- data/app/helpers/para/exports_helper.rb +11 -0
- data/app/helpers/para/flash_helper.rb +48 -0
- data/app/helpers/para/form_helper.rb +28 -0
- data/app/helpers/para/markup_helper.rb +15 -0
- data/app/helpers/para/model_helper.rb +38 -0
- data/app/helpers/para/navigation_helper.rb +8 -0
- data/app/helpers/para/ordering_helper.rb +20 -0
- data/app/helpers/para/search_helper.rb +22 -0
- data/app/helpers/para/tag_helper.rb +50 -0
- data/app/helpers/para/tree_helper.rb +41 -0
- data/app/models/para/component/base.rb +70 -0
- data/app/models/para/component/crud.rb +45 -0
- data/app/models/para/component/resource.rb +33 -0
- data/app/models/para/component/settings.rb +17 -0
- data/app/models/para/component/singleton_resource.rb +25 -0
- data/app/models/para/component_resource.rb +6 -0
- data/app/models/para/component_section.rb +18 -0
- data/app/views/layouts/para/admin.html.haml +32 -0
- data/app/views/layouts/para/application.html.erb +14 -0
- data/app/views/para/admin/component_sections/_form.html.haml +10 -0
- data/app/views/para/admin/component_sections/edit.html.haml +5 -0
- data/app/views/para/admin/component_sections/new.html.haml +5 -0
- data/app/views/para/admin/components/_form.html.haml +15 -0
- data/app/views/para/admin/components/new.html.haml +4 -0
- data/app/views/para/admin/crud_component/show.html.haml +4 -0
- data/app/views/para/admin/dashboard.html.haml +10 -0
- data/app/views/para/admin/main/index.html.haml +1 -0
- data/app/views/para/admin/resources/_exports_menu.html.haml +12 -0
- data/app/views/para/admin/resources/_fields.html.haml +5 -0
- data/app/views/para/admin/resources/_filters.html.haml +9 -0
- data/app/views/para/admin/resources/_form.html.haml +6 -0
- data/app/views/para/admin/resources/_list.html.haml +22 -0
- data/app/views/para/admin/resources/_table.html.haml +8 -0
- data/app/views/para/admin/resources/_tree.html.haml +15 -0
- data/app/views/para/admin/resources/_tree_item.html.haml +16 -0
- data/app/views/para/admin/resources/edit.html.haml +6 -0
- data/app/views/para/admin/resources/new.html.haml +6 -0
- data/app/views/para/admin/settings_component/show.html.haml +12 -0
- data/app/views/para/admin/shared/_breadcrumb.html.haml +3 -0
- data/app/views/para/admin/shared/_header.html.haml +27 -0
- data/app/views/para/admin/shared/_navigation.html.haml +21 -0
- data/app/views/para/admin/singleton_resource_component/show.html.haml +5 -0
- data/app/views/para/inputs/_nested_many.html.haml +10 -0
- data/app/views/para/inputs/_nested_many_container.html.haml +19 -0
- data/app/views/para/inputs/_nested_one.html.haml +3 -0
- data/config/locales/en.yml +86 -0
- data/config/locales/fr.yml +101 -0
- data/db/migrate/20140911091225_create_para_components.rb +19 -0
- data/db/migrate/20140911112150_add_slug_to_para_components.rb +6 -0
- data/db/migrate/20140929125733_create_para_component_sections.rb +8 -0
- data/db/migrate/20140929131111_add_identifier_to_para_component_sections.rb +5 -0
- data/db/migrate/20140930121822_add_position_to_para_component_section.rb +5 -0
- data/db/migrate/20150129170710_create_para_component_resources.rb +13 -0
- data/db/migrate/20150203173219_add_identifier_to_para_components.rb +5 -0
- data/lib/generators/para/admin_user/admin_user_generator.rb +16 -0
- data/lib/generators/para/component/component_generator.rb +59 -0
- data/lib/generators/para/component/templates/component.rb +3 -0
- data/lib/generators/para/component/templates/component_controller.rb +7 -0
- data/lib/generators/para/component/templates/show.html.haml +2 -0
- data/lib/generators/para/exporter/exporter_generator.rb +42 -0
- data/lib/generators/para/exporter/templates/base_exporter.rb +15 -0
- data/lib/generators/para/exporter/templates/csv_exporter.rb +13 -0
- data/lib/generators/para/form/form_generator.rb +15 -0
- data/lib/generators/para/form/templates/_form.html.haml +7 -0
- data/lib/generators/para/install/install_generator.rb +112 -0
- data/lib/generators/para/install/templates/components.rb +13 -0
- data/lib/generators/para/install/templates/initializer.rb +23 -0
- data/lib/generators/para/nested_fields/nested_fields_generator.rb +15 -0
- data/lib/generators/para/nested_fields/templates/_nested_fields.html.haml +3 -0
- data/lib/generators/para/orderable/orderable_generator.rb +53 -0
- data/lib/generators/para/orderable/templates/orderable_migration.rb +6 -0
- data/lib/generators/para/resource/resource_generator.rb +71 -0
- data/lib/generators/para/resource/templates/resource_controller.rb +5 -0
- data/lib/generators/para/table/table_generator.rb +34 -0
- data/lib/generators/para/table/templates/_table.html.haml +10 -0
- data/lib/para/attribute_field/base.rb +77 -0
- data/lib/para/attribute_field/belongs_to.rb +29 -0
- data/lib/para/attribute_field/boolean.rb +15 -0
- data/lib/para/attribute_field/datetime.rb +9 -0
- data/lib/para/attribute_field/file.rb +20 -0
- data/lib/para/attribute_field/has_many.rb +31 -0
- data/lib/para/attribute_field/image.rb +25 -0
- data/lib/para/attribute_field/nested_many.rb +26 -0
- data/lib/para/attribute_field/nested_one.rb +27 -0
- data/lib/para/attribute_field/password.rb +18 -0
- data/lib/para/attribute_field/redactor.rb +20 -0
- data/lib/para/attribute_field/relation.rb +52 -0
- data/lib/para/attribute_field/translation.rb +9 -0
- data/lib/para/attribute_field_mappings.rb +82 -0
- data/lib/para/cloneable.rb +20 -0
- data/lib/para/component/exportable.rb +25 -0
- data/lib/para/component.rb +27 -0
- data/lib/para/components_configuration.rb +156 -0
- data/lib/para/config.rb +21 -0
- data/lib/para/engine.rb +59 -0
- data/lib/para/errors.rb +15 -0
- data/lib/para/exporter/base.rb +27 -0
- data/lib/para/exporter/csv.rb +49 -0
- data/lib/para/exporter.rb +57 -0
- data/lib/para/ext/cancan.rb +26 -0
- data/lib/para/ext/paperclip.rb +67 -0
- data/lib/para/ext.rb +13 -0
- data/lib/para/form_builder/containers.rb +70 -0
- data/lib/para/form_builder/field_mappings.rb +9 -0
- data/lib/para/form_builder/nested_form.rb +80 -0
- data/lib/para/form_builder/ordering.rb +15 -0
- data/lib/para/form_builder/settings.rb +24 -0
- data/lib/para/form_builder.rb +22 -0
- data/lib/para/generators/field_helpers.rb +32 -0
- data/lib/para/generators/name_helpers.rb +9 -0
- data/lib/para/generators/named_base.rb +7 -0
- data/lib/para/generators.rb +11 -0
- data/lib/para/inputs/nested_many_input.rb +40 -0
- data/lib/para/inputs/nested_one_input.rb +24 -0
- data/lib/para/inputs.rb +11 -0
- data/lib/para/markup/alert.rb +37 -0
- data/lib/para/markup/component.rb +20 -0
- data/lib/para/markup/modal.rb +52 -0
- data/lib/para/markup/panel.rb +41 -0
- data/lib/para/markup/resources_table.rb +178 -0
- data/lib/para/markup.rb +10 -0
- data/lib/para/model_field_parsers/base.rb +20 -0
- data/lib/para/model_field_parsers/devise.rb +37 -0
- data/lib/para/model_field_parsers/globalize.rb +23 -0
- data/lib/para/model_field_parsers/orderable.rb +15 -0
- data/lib/para/model_field_parsers/paperclip.rb +51 -0
- data/lib/para/model_field_parsers/redactor.rb +19 -0
- data/lib/para/model_field_parsers/relations.rb +67 -0
- data/lib/para/model_field_parsers.rb +22 -0
- data/lib/para/orderable.rb +44 -0
- data/lib/para/routes.rb +49 -0
- data/lib/para/version.rb +3 -0
- data/lib/para.rb +65 -0
- data/lib/rails/relation_length_validator.rb +45 -0
- data/lib/rails/routing_mapper.rb +27 -0
- data/lib/tasks/para_tasks.rake +22 -0
- metadata +595 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require_dependency "para/application_controller"
|
|
2
|
+
|
|
3
|
+
module Para
|
|
4
|
+
module Admin
|
|
5
|
+
class ResourcesController < Para::Admin::BaseController
|
|
6
|
+
include Para::ModelHelper
|
|
7
|
+
|
|
8
|
+
class_attribute :resource_name, :resource_class
|
|
9
|
+
load_and_authorize_component
|
|
10
|
+
helper_method :resource
|
|
11
|
+
|
|
12
|
+
def new
|
|
13
|
+
render 'para/admin/resources/new'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create
|
|
17
|
+
# Assign component the resource belongs to it
|
|
18
|
+
resource.component = @component if resource.respond_to?(:component=)
|
|
19
|
+
|
|
20
|
+
if resource.save
|
|
21
|
+
flash_message(:success, resource)
|
|
22
|
+
redirect_to after_form_submit_path
|
|
23
|
+
else
|
|
24
|
+
flash_message(:error, resource)
|
|
25
|
+
render 'new'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def edit
|
|
30
|
+
render 'para/admin/resources/edit'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update
|
|
34
|
+
if resource.update_attributes(resource_params)
|
|
35
|
+
flash_message(:success, resource)
|
|
36
|
+
redirect_to after_form_submit_path
|
|
37
|
+
else
|
|
38
|
+
flash_message(:error, resource)
|
|
39
|
+
render 'edit'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def destroy
|
|
44
|
+
resource.destroy
|
|
45
|
+
flash_message(:success, resource)
|
|
46
|
+
redirect_to @component.path
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def order
|
|
50
|
+
ActiveRecord::Base.transaction do
|
|
51
|
+
resources_data.each do |resource_params|
|
|
52
|
+
resource = resources_hash[resource_params[:id]]
|
|
53
|
+
resource.position = resource_params[:position].to_i
|
|
54
|
+
resource.save(validate: false)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
head 200
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def tree
|
|
62
|
+
ActiveRecord::Base.transaction do
|
|
63
|
+
resources_data.each do |resource_params|
|
|
64
|
+
resource = resources_hash[resource_params[:id]]
|
|
65
|
+
resource.assign_attributes(
|
|
66
|
+
position: resource_params[:position].to_i,
|
|
67
|
+
parent_id: resource_params[:parent_id]
|
|
68
|
+
)
|
|
69
|
+
resource.save(validate: false)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
head 200
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def after_form_submit_path
|
|
79
|
+
if params[:_save_and_edit]
|
|
80
|
+
{ action: 'edit', id: resource.to_param }
|
|
81
|
+
elsif params[:_save_and_add_another]
|
|
82
|
+
{ action: 'new' }
|
|
83
|
+
else
|
|
84
|
+
params.delete(:return_to).presence || @component.path
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def resource_model
|
|
89
|
+
self.class.resource_model
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def resource
|
|
93
|
+
@resource ||= begin
|
|
94
|
+
self.class.ensure_resource_name_defined!
|
|
95
|
+
instance_variable_get(:"@#{ self.class.resource_name }")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def resource_params
|
|
100
|
+
@resource_params ||= parse_resource_params(
|
|
101
|
+
params.require(:resource).permit!
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def parse_resource_params(hash)
|
|
106
|
+
model_field_mappings(resource_model).fields.each do |field|
|
|
107
|
+
field.parse_input(hash)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
hash
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.resource(name, options = {})
|
|
114
|
+
default_options = {
|
|
115
|
+
class: name.to_s.camelize,
|
|
116
|
+
through: :component,
|
|
117
|
+
parent: false
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
default_options.each do |key, value|
|
|
121
|
+
options[key] = value unless options.key?(key)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
self.resource_name = name
|
|
125
|
+
self.resource_class = options[:class]
|
|
126
|
+
|
|
127
|
+
load_and_authorize_resource(name, options)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def self.resource_model
|
|
131
|
+
@resource_model ||= begin
|
|
132
|
+
ensure_resource_name_defined!
|
|
133
|
+
Para.const_get(resource_class)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def self.ensure_resource_name_defined!
|
|
138
|
+
unless resource_name.presence
|
|
139
|
+
raise "Resource not defined in your controller. " \
|
|
140
|
+
"You can define the resource of your controller with the " \
|
|
141
|
+
"`resource :resource_name` macro when subclassing " \
|
|
142
|
+
"Para::Admin::ResourcesController"
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def resources_data
|
|
147
|
+
@resources_data ||= params[:resources].values
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def resources_hash
|
|
151
|
+
@resources_hash ||= begin
|
|
152
|
+
|
|
153
|
+
ids = resources_data.map { |resource| resource[:id] }
|
|
154
|
+
|
|
155
|
+
resources = resource_model.where(id: ids)
|
|
156
|
+
resources.each_with_object({}) do |resource, hash|
|
|
157
|
+
hash[resource.id.to_s] = resource
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Admin
|
|
3
|
+
class SettingsFormController < Para::Admin::BaseController
|
|
4
|
+
load_and_authorize_component
|
|
5
|
+
|
|
6
|
+
def update
|
|
7
|
+
form = SettingsRails::Form.new
|
|
8
|
+
form.settings_attributes = settings_params[:settings_attributes]
|
|
9
|
+
form.save
|
|
10
|
+
flash_message(:success, form)
|
|
11
|
+
redirect_to admin_settings_path(@component)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def settings_params
|
|
17
|
+
params.require(:resource).permit(settings_attributes: [:key, :_type, :value])
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Admin
|
|
3
|
+
class SingletonResourceComponentController < Para::Admin::BaseController
|
|
4
|
+
load_and_authorize_component
|
|
5
|
+
|
|
6
|
+
attr_accessor :resource
|
|
7
|
+
helper_method :resource
|
|
8
|
+
|
|
9
|
+
def show
|
|
10
|
+
self.resource = @component.resource
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_dependency "para/application_controller"
|
|
2
|
+
|
|
3
|
+
module Para
|
|
4
|
+
module Admin
|
|
5
|
+
class SingletonResourcesController < Para::Admin::ResourcesController
|
|
6
|
+
include Para::Admin::ResourceControllerConcerns
|
|
7
|
+
|
|
8
|
+
before_filter :load_and_authorize_singleton_resource
|
|
9
|
+
after_filter :attach_resource_to_component, only: [:create]
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def attach_resource_to_component
|
|
14
|
+
return unless resource.persisted?
|
|
15
|
+
@component.resource = resource
|
|
16
|
+
@component.save
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load_and_authorize_singleton_resource
|
|
20
|
+
loader = self.class.cancan_resource_class.new(
|
|
21
|
+
self, :resource, parent: false, class: resource_model.name,
|
|
22
|
+
singleton: true, through: :component
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
loader.load_and_authorize_resource
|
|
26
|
+
instance_variable_set(:"@#{ resource_name }", @resource)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Component
|
|
3
|
+
module BaseDecorator
|
|
4
|
+
include Rails.application.routes.mounted_helpers
|
|
5
|
+
include ActionDispatch::Routing::PolymorphicRoutes
|
|
6
|
+
|
|
7
|
+
def path(options = {})
|
|
8
|
+
find_path([:admin, self], options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def relation_path(controller_or_resource, options = {})
|
|
12
|
+
find_path([:admin, self, controller_or_resource], options)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# Try to find a polymorphic path for the given arguments
|
|
18
|
+
#
|
|
19
|
+
# If no route exist, we try all the existing engines too
|
|
20
|
+
# This is quite dirty but for now should work as desired
|
|
21
|
+
# The only problem is if we have engines that declare the same routes
|
|
22
|
+
#
|
|
23
|
+
def find_path(path, options)
|
|
24
|
+
polymorphic_path(path, options)
|
|
25
|
+
rescue NoMethodError, NameError => original_error
|
|
26
|
+
mounted_proxy_methods.each do |proxy_method|
|
|
27
|
+
begin
|
|
28
|
+
proxy = send(proxy_method)
|
|
29
|
+
return polymorphic_path(([proxy] + path), options)
|
|
30
|
+
rescue NoMethodError, NameError => e
|
|
31
|
+
next
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
raise original_error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def mounted_proxy_methods
|
|
39
|
+
@mounted_proxy_methods ||= begin
|
|
40
|
+
routes = Rails.application.routes
|
|
41
|
+
routes.mounted_helpers.instance_methods.select do |name|
|
|
42
|
+
/^[^_]/ =~ name
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Component
|
|
3
|
+
module CrudDecorator
|
|
4
|
+
include Para::Component::BaseDecorator
|
|
5
|
+
|
|
6
|
+
def relation_path(controller_or_resource, options = {})
|
|
7
|
+
if (id = extract_id_from(controller_or_resource))
|
|
8
|
+
options[:id] = id
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
route_key = route_key_for(options[:id], options)
|
|
12
|
+
options[:model] = model.model_name.singular_route_key
|
|
13
|
+
|
|
14
|
+
polymorphic_path([:admin, self, route_key].compact, options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def extract_id_from(object)
|
|
20
|
+
object.id if object.respond_to?(:persisted?) && object.persisted?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def route_key_for(id, options)
|
|
24
|
+
if id || options[:action].presence && options[:action].to_sym == :new
|
|
25
|
+
:crud_resource
|
|
26
|
+
else
|
|
27
|
+
:crud_resources
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Component
|
|
3
|
+
module SingletonResourceDecorator
|
|
4
|
+
include Para::Component::BaseDecorator
|
|
5
|
+
|
|
6
|
+
def relation_path(controller_or_resource, options = {})
|
|
7
|
+
polymorphic_path([:admin, self, :singleton_resource].compact, options)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Admin
|
|
3
|
+
module BaseHelper
|
|
4
|
+
include Para::ApplicationHelper
|
|
5
|
+
|
|
6
|
+
def find_partial_for(relation, partial)
|
|
7
|
+
if relation.kind_of? ActiveRecord::Base
|
|
8
|
+
relation = relation.class
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
relation = relation.to_s.underscore.pluralize
|
|
12
|
+
|
|
13
|
+
if lookup_context.find_all("admin/#{relation}/_#{ partial }").any?
|
|
14
|
+
"admin/#{ relation }/#{ partial }"
|
|
15
|
+
else
|
|
16
|
+
"para/admin/resources/#{ partial }"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def template_path_lookup(*paths)
|
|
21
|
+
paths.find do |path|
|
|
22
|
+
lookup_context.find_all(path).any?
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def resource_title_for(resource)
|
|
27
|
+
resource.try(:title) || resource.try(:name) ||
|
|
28
|
+
t('para.form.shared.edit.title', model: resource.class.model_name.human)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def registered_components_options
|
|
32
|
+
Para::Component.registered_components.keys.map do |identifier|
|
|
33
|
+
[
|
|
34
|
+
t("para.component.#{ identifier }.name", default: identifier.to_s.humanize),
|
|
35
|
+
identifier
|
|
36
|
+
]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def flash_message(type, resource = nil)
|
|
41
|
+
key = "#{ flash_shared_key }.#{ params[:action] }.#{ type }"
|
|
42
|
+
|
|
43
|
+
translation = if resource
|
|
44
|
+
I18n.t(key, model: resource.class.model_name.human)
|
|
45
|
+
else
|
|
46
|
+
I18n.t(key)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
flash[type] = translation
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def flash_shared_key
|
|
53
|
+
'para.flash.shared'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module Admin
|
|
3
|
+
module ResourcesHelper
|
|
4
|
+
def resource_form_path(resource)
|
|
5
|
+
if resource.new_record?
|
|
6
|
+
resource_path(resource, :index)
|
|
7
|
+
else
|
|
8
|
+
resource_path(resource, :show)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resource_path(resource, action =:index)
|
|
13
|
+
resource = resource.kind_of?(Class) ? resource.new : resource
|
|
14
|
+
route_key = resource.class.model_name.route_key
|
|
15
|
+
|
|
16
|
+
component_path = @component && @component.to_param
|
|
17
|
+
id = resource.id
|
|
18
|
+
|
|
19
|
+
if [:index, :show, :create, :update, :destroy].include?(action)
|
|
20
|
+
action = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
["", "admin", component_path, route_key, id, action].compact.join('/')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
include Para::SearchHelper
|
|
4
|
+
include Para::ModelHelper
|
|
5
|
+
include Para::OrderingHelper
|
|
6
|
+
include Para::NavigationHelper
|
|
7
|
+
include Para::FormHelper
|
|
8
|
+
include Para::MarkupHelper
|
|
9
|
+
include Para::TagHelper
|
|
10
|
+
include Para::TreeHelper
|
|
11
|
+
include Para::FlashHelper
|
|
12
|
+
include Para::ExportsHelper
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module FlashHelper
|
|
3
|
+
def display_admin_flash
|
|
4
|
+
# Render empty string if no flash
|
|
5
|
+
return "" if flash.empty?
|
|
6
|
+
|
|
7
|
+
# Make a div.alert for each message and join the whole
|
|
8
|
+
messages = flash.map do |type, message|
|
|
9
|
+
flash.delete(type)
|
|
10
|
+
type = homogenize_flash_type(type)
|
|
11
|
+
|
|
12
|
+
icon = content_tag(:div, class: "alert-icon-container pull-left") do
|
|
13
|
+
content_tag(:i, "", class: "fa #{ icon_class_for(type) }") +
|
|
14
|
+
' '.html_safe
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
alert(type: type) do
|
|
18
|
+
icon + content_tag(:p, message.html_safe)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Join the messages and make sure markup is correctly displayed
|
|
23
|
+
messages.join.html_safe
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# Converts flash types to :success or :error to conform to what
|
|
29
|
+
# twitter bootstrap can handle
|
|
30
|
+
#
|
|
31
|
+
def homogenize_flash_type type
|
|
32
|
+
case type.to_sym
|
|
33
|
+
when :notice then :success
|
|
34
|
+
when :alert then :warning
|
|
35
|
+
when :error then :danger
|
|
36
|
+
else type
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def icon_class_for type
|
|
41
|
+
case type
|
|
42
|
+
when :success then "fa-check"
|
|
43
|
+
when :error then "fa-warning"
|
|
44
|
+
else "fa-exclamation-triangle"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module FormHelper
|
|
3
|
+
def para_form_for(resource, options = {}, &block)
|
|
4
|
+
default_options = {
|
|
5
|
+
as: :resource,
|
|
6
|
+
wrapper: :horizontal_form,
|
|
7
|
+
html: { class: '' }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
options = default_options.deep_merge(options)
|
|
11
|
+
|
|
12
|
+
options[:html][:class] = [
|
|
13
|
+
options[:html][:class].presence,
|
|
14
|
+
'form-horizontal form-group-separated'
|
|
15
|
+
].compact.join(' ')
|
|
16
|
+
|
|
17
|
+
unless options.key?(:url)
|
|
18
|
+
options[:url] = @component.relation_path(resource)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if options.fetch(:fixed_actions, true)
|
|
22
|
+
default_options[:html][:class] << ' form-fixed-actions'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
simple_form_for(resource, options, &block)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module MarkupHelper
|
|
3
|
+
def alert(message, options = {}, &block)
|
|
4
|
+
Para::Markup::Alert.new(self).container(message, options, &block)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def resources_table(options = {}, &block)
|
|
8
|
+
Para::Markup::ResourcesTable.new(self).container(options, &block)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def panel(options = {}, &block)
|
|
12
|
+
Para::Markup::Panel.new(self).container(options, &block)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module ModelHelper
|
|
3
|
+
def attribute_field_mappings_for(component, relation)
|
|
4
|
+
model = relation_klass_for(component, relation)
|
|
5
|
+
model_field_mappings(model).fields
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def model_field_mappings(model, attributes = nil)
|
|
9
|
+
store_key = ['model', 'mappings', model.name.underscore].join(':')
|
|
10
|
+
|
|
11
|
+
Para.store[store_key] ||= Para::AttributeFieldMappings.new(
|
|
12
|
+
model, whitelist_attributes: attributes
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def relation_klass_for(component, relation)
|
|
17
|
+
component.class.reflect_on_association(relation).klass
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def field_value_for(object, field_name, type = nil)
|
|
21
|
+
field = model_field_mappings(object.class).field_for(field_name, type)
|
|
22
|
+
value = field.value_for(object)
|
|
23
|
+
excerpt_value_for(value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def excerpt_value_for(value)
|
|
27
|
+
return value unless value.kind_of?(String)
|
|
28
|
+
|
|
29
|
+
value = sanitize(value, tags: [])
|
|
30
|
+
|
|
31
|
+
if (truncated = value[0..100]) != value
|
|
32
|
+
"#{ truncated }..."
|
|
33
|
+
else
|
|
34
|
+
value
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module OrderingHelper
|
|
3
|
+
def reorder_anchor(options = {})
|
|
4
|
+
options[:class] ||= ''
|
|
5
|
+
options[:class] = [options[:class], 'order-anchor'].join(' ')
|
|
6
|
+
|
|
7
|
+
field = if (form = options.delete(:form))
|
|
8
|
+
form.hidden_field(:position, class: 'resource-position-field')
|
|
9
|
+
else
|
|
10
|
+
value = options.delete(:value) || 0
|
|
11
|
+
hidden_field_tag(:position, value, class: 'resource-position-field')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
content_tag(:span, options) do
|
|
15
|
+
content_tag(:i, '', class: 'fa fa-bars') +
|
|
16
|
+
field
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Para
|
|
2
|
+
module SearchHelper
|
|
3
|
+
def fulltext_search_param_for(attributes)
|
|
4
|
+
"#{ searchable_attributes(attributes) }_cont"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def filtered?(attributes)
|
|
8
|
+
params[:q] && params[:q][fulltext_search_param_for(attributes)].present?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def searchable_attributes(attributes)
|
|
12
|
+
whitelist = attributes.select do |attribute|
|
|
13
|
+
[:string, :text].include?(attribute.type.to_sym) &&
|
|
14
|
+
!attribute.name.match(/password/)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
whitelist.map do |attribute|
|
|
18
|
+
attribute.attribute_column_path.join('_')
|
|
19
|
+
end.join('_or_')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|