para 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|