slash_admin 0.1.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/README.md +95 -0
- data/app/assets/config/relax_admin_manifest.js +2 -0
- data/app/assets/images/slash_admin/en.png +0 -0
- data/app/assets/images/slash_admin/favicon.png +0 -0
- data/app/assets/images/slash_admin/fr.png +0 -0
- data/app/assets/javascripts/slash_admin/application.js +344 -0
- data/app/assets/javascripts/slash_admin/custom.js +0 -0
- data/app/assets/stylesheets/slash_admin/alert.scss +29 -0
- data/app/assets/stylesheets/slash_admin/application.scss +1469 -0
- data/app/assets/stylesheets/slash_admin/colors.scss +17 -0
- data/app/assets/stylesheets/slash_admin/custom.scss +0 -0
- data/app/controllers/slash_admin/application_controller.rb +17 -0
- data/app/controllers/slash_admin/base_controller.rb +45 -0
- data/app/controllers/slash_admin/batch_actions_controller.rb +17 -0
- data/app/controllers/slash_admin/dashboard_controller.rb +11 -0
- data/app/controllers/slash_admin/models_controller.rb +325 -0
- data/app/controllers/slash_admin/security/sessions_controller.rb +29 -0
- data/app/controllers/slash_admin/selectize_controller.rb +49 -0
- data/app/helpers/slash_admin/application_helper.rb +212 -0
- data/app/helpers/slash_admin/menu_helper.rb +14 -0
- data/app/helpers/slash_admin/widgets_helper.rb +7 -0
- data/app/jobs/slash_admin/application_job.rb +4 -0
- data/app/mailers/slash_admin/application_mailer.rb +6 -0
- data/app/models/slash_admin/admin.rb +46 -0
- data/app/models/slash_admin/admin_ability.rb +11 -0
- data/app/models/slash_admin/application_record.rb +5 -0
- data/app/views/layouts/slash_admin/admin_user.html.erb +16 -0
- data/app/views/layouts/slash_admin/application.html.erb +40 -0
- data/app/views/slash_admin/base/_data_belongs_to.html.erb +37 -0
- data/app/views/slash_admin/base/_data_list.html.erb +276 -0
- data/app/views/slash_admin/base/_data_nestable.html.erb +33 -0
- data/app/views/slash_admin/base/_data_new.html.erb +16 -0
- data/app/views/slash_admin/base/_data_show.html.erb +72 -0
- data/app/views/slash_admin/base/_filters.html.erb +60 -0
- data/app/views/slash_admin/base/_translatable_fields.html.erb +23 -0
- data/app/views/slash_admin/base/edit.html.erb +26 -0
- data/app/views/slash_admin/base/index.html.erb +47 -0
- data/app/views/slash_admin/base/index.xls.erb +27 -0
- data/app/views/slash_admin/base/nestable.html.erb +28 -0
- data/app/views/slash_admin/base/new.html.erb +26 -0
- data/app/views/slash_admin/base/show.html.erb +22 -0
- data/app/views/slash_admin/custom_fields/_color.html.erb +2 -0
- data/app/views/slash_admin/custom_fields/_email.html.erb +2 -0
- data/app/views/slash_admin/custom_fields/_google_map.html.erb +72 -0
- data/app/views/slash_admin/custom_fields/_nested_belongs_to.html.erb +55 -0
- data/app/views/slash_admin/custom_fields/_password.html.erb +2 -0
- data/app/views/slash_admin/custom_fields/_select.html.erb +2 -0
- data/app/views/slash_admin/custom_fields/_tags.html.erb +2 -0
- data/app/views/slash_admin/custom_fields/_wysiwyg.html.erb +2 -0
- data/app/views/slash_admin/dashboard/home.html.erb +5 -0
- data/app/views/slash_admin/dashboard/widgets/_statistic_chart.html.erb +0 -0
- data/app/views/slash_admin/dashboard/widgets/_statistic_progress_tile.html.erb +29 -0
- data/app/views/slash_admin/fields/_belongs_to.html.erb +9 -0
- data/app/views/slash_admin/fields/_boolean.html.erb +2 -0
- data/app/views/slash_admin/fields/_carrierwave.html.erb +15 -0
- data/app/views/slash_admin/fields/_date.html.erb +2 -0
- data/app/views/slash_admin/fields/_decimal.html.erb +2 -0
- data/app/views/slash_admin/fields/_form_group.html.erb +12 -0
- data/app/views/slash_admin/fields/_has_many.html.erb +12 -0
- data/app/views/slash_admin/fields/_has_many_row.html.erb +18 -0
- data/app/views/slash_admin/fields/_has_one.html.erb +24 -0
- data/app/views/slash_admin/fields/_integer.html.erb +2 -0
- data/app/views/slash_admin/fields/_json.html.erb +14 -0
- data/app/views/slash_admin/fields/_nested_has_many.html.erb +14 -0
- data/app/views/slash_admin/fields/_number.html.erb +2 -0
- data/app/views/slash_admin/fields/_string.html.erb +2 -0
- data/app/views/slash_admin/fields/_text.html.erb +2 -0
- data/app/views/slash_admin/security/sessions/new.html.erb +30 -0
- data/app/views/slash_admin/shared/_batch_actions.html.erb +21 -0
- data/app/views/slash_admin/shared/_better_paginate.html.erb +30 -0
- data/app/views/slash_admin/shared/_breadcrumb.html.erb +30 -0
- data/app/views/slash_admin/shared/_debug.html.erb +24 -0
- data/app/views/slash_admin/shared/_errors_data_new.html.erb +12 -0
- data/app/views/slash_admin/shared/_header.html.erb +38 -0
- data/app/views/slash_admin/shared/_menu.html.erb +57 -0
- data/app/views/slash_admin/shared/_new_form_buttons.html.erb +9 -0
- data/app/views/slash_admin/shared/_sub_header.html.erb +11 -0
- data/config/initializers/validators.rb +13 -0
- data/config/locales/slash_admin.en.yml +67 -0
- data/config/locales/slash_admin.fr.yml +72 -0
- data/config/routes.rb +16 -0
- data/db/migrate/20170512104248_create_slash_admin_admins.rb +19 -0
- data/lib/batch_translation.rb +19 -0
- data/lib/generators/slash_admin/controllers/controllers_generator.rb +16 -0
- data/lib/generators/slash_admin/controllers/templates/controllers.erb +9 -0
- data/lib/generators/slash_admin/install/install_generator.rb +13 -0
- data/lib/generators/slash_admin/install/templates/install.erb +14 -0
- data/lib/generators/slash_admin/override_admin/override_admin_generator.rb +13 -0
- data/lib/generators/slash_admin/override_admin/templates/admin.erb +46 -0
- data/lib/generators/slash_admin/override_session/override_session_generator.rb +13 -0
- data/lib/generators/slash_admin/override_session/templates/session.erb +27 -0
- data/lib/generators/slash_admin/permissions/permissions_generator.rb +13 -0
- data/lib/generators/slash_admin/permissions/templates/permissions.erb +11 -0
- data/lib/slash_admin.rb +29 -0
- data/lib/slash_admin/engine.rb +8 -0
- data/lib/slash_admin/version.rb +3 -0
- data/lib/tasks/slash_admin_tasks.rake +4 -0
- data/vendor/assets/javascripts/bootstrap-material-datetimepicker.js +1295 -0
- data/vendor/assets/javascripts/codemirror/codemirror.js +9657 -0
- data/vendor/assets/javascripts/codemirror/lint/json-lint.js +37 -0
- data/vendor/assets/javascripts/codemirror/lint/jsonlint.js +432 -0
- data/vendor/assets/javascripts/codemirror/lint/lint.js +252 -0
- data/vendor/assets/javascripts/codemirror/mode/javascript.js +865 -0
- data/vendor/assets/javascripts/jquery.nestable.js +910 -0
- data/vendor/assets/javascripts/jquery.tagsinput-revisited.min.js +5 -0
- data/vendor/assets/javascripts/toastr.js +6 -0
- data/vendor/assets/stylesheets/animate.css +1579 -0
- data/vendor/assets/stylesheets/bootstrap-material-datetimepicker.css +82 -0
- data/vendor/assets/stylesheets/codemirror/codemirror.css +346 -0
- data/vendor/assets/stylesheets/codemirror/lint/lint.css +73 -0
- data/vendor/assets/stylesheets/codemirror/theme/relax-seti.css +41 -0
- data/vendor/assets/stylesheets/jquery.nestable.css +121 -0
- data/vendor/assets/stylesheets/jquery.tagsinput-revisited.min.css +1 -0
- data/vendor/assets/stylesheets/sweetalert.css +935 -0
- data/vendor/assets/stylesheets/toastr.css +1 -0
- metadata +509 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :params
|
|
4
|
+
# :model_class
|
|
5
|
+
# :field
|
|
6
|
+
# :q
|
|
7
|
+
module SlashAdmin
|
|
8
|
+
class SelectizeController < SlashAdmin::BaseController
|
|
9
|
+
def search
|
|
10
|
+
model_class = model
|
|
11
|
+
if model_class.respond_to? :translated_attribute_names
|
|
12
|
+
results = model_class.with_translations(I18n.locale).all
|
|
13
|
+
else
|
|
14
|
+
results = model_class.all
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
duplicate_for_orwhere = results
|
|
18
|
+
|
|
19
|
+
params[:fields].each_with_index do |f, index|
|
|
20
|
+
if model_class.respond_to? :translated_attribute_names
|
|
21
|
+
if model_class.translated_attribute_names.include?(f.to_sym)
|
|
22
|
+
f = "#{params[:model_class].singularize.underscore}_translations.#{f}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if index == 0
|
|
27
|
+
results = results.where("lower(#{f}) LIKE lower(:query)", query: "%#{params[:q]}%")
|
|
28
|
+
else
|
|
29
|
+
results = results.or(duplicate_for_orwhere.where("lower(#{f}) LIKE lower(:query)", query: "%#{params[:q]}%"))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
formatted_result = []
|
|
34
|
+
results.each do |r|
|
|
35
|
+
formatted_result << { id: r.id, name: helpers.show_object(r) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
render json: formatted_result
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def model
|
|
42
|
+
ActiveRecord::Base.connection.tables.map do |klass|
|
|
43
|
+
testing_class = klass.capitalize.singularize.camelize
|
|
44
|
+
return testing_class.constantize if testing_class == params[:model_class].capitalize.singularize.camelize
|
|
45
|
+
end
|
|
46
|
+
raise Exception.new("Can't find model #{params[:model_class]}")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module SlashAdmin
|
|
3
|
+
module ApplicationHelper
|
|
4
|
+
def page_title(content)
|
|
5
|
+
content_for :page_title, content
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def page_sub_title(content)
|
|
9
|
+
content_for :page_sub_title, content
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# is the current has access to at least one node
|
|
13
|
+
def access?(s)
|
|
14
|
+
access = false
|
|
15
|
+
if s[:sub_menu].present?
|
|
16
|
+
s[:sub_menu].each do |sub|
|
|
17
|
+
access = true if access_model?(sub)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Direct Link temp TODO
|
|
22
|
+
if s[:path].present?
|
|
23
|
+
access = true
|
|
24
|
+
end
|
|
25
|
+
access
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# is the current has access to model
|
|
29
|
+
def access_model?(sub)
|
|
30
|
+
return false if cannot? :index, sub[:model]
|
|
31
|
+
true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def class_name_from_association(obj, field_name)
|
|
35
|
+
[:belongs_to, :has_many, :has_one].each do |relation|
|
|
36
|
+
obj.class.reflect_on_all_associations(relation).each do |association|
|
|
37
|
+
return association.class_name if association.name == field_name.to_sym
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
raise Exception.new("Unable to guess association for attribute: #{field_name} in model: #{obj}")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def required?(obj, field_name)
|
|
45
|
+
if field_name.is_a?(Hash)
|
|
46
|
+
field_hash = field_name
|
|
47
|
+
field_name = field_hash.keys.first
|
|
48
|
+
|
|
49
|
+
if field_hash[field_name].key?(:required)
|
|
50
|
+
return field_hash[field_name][:required]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
obj.class.validators_on(field_name.to_s).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def show_hidden_errors
|
|
58
|
+
@model.errors.messages.except(*@update_params)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def show_errors(form, field_name)
|
|
62
|
+
object = form.object
|
|
63
|
+
if field_name.is_a?(Hash)
|
|
64
|
+
field_name = field_name.keys.first
|
|
65
|
+
end
|
|
66
|
+
return [] if object.errors.empty?
|
|
67
|
+
unless object.errors.messages[field_name].blank?
|
|
68
|
+
return object.errors.messages[field_name]
|
|
69
|
+
end
|
|
70
|
+
[]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def errors?(form, field_name)
|
|
74
|
+
object = form.object
|
|
75
|
+
if field_name.is_a?(Hash)
|
|
76
|
+
field_name = field_name.keys.first
|
|
77
|
+
end
|
|
78
|
+
return false if object.errors.empty?
|
|
79
|
+
return true unless object.errors.messages[field_name].blank?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def toastr_bootstrap
|
|
83
|
+
flash_messages = []
|
|
84
|
+
flash.each do |type, message|
|
|
85
|
+
text = '<script data-turbolinks-eval="false">toastr.' + type + '("' + message + '");</script>'
|
|
86
|
+
flash_messages << text.html_safe if message
|
|
87
|
+
end
|
|
88
|
+
flash_messages.join("\n").html_safe
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Default available field_type handeled
|
|
92
|
+
def orderable?(object, attr)
|
|
93
|
+
field_type = guess_field_type(object, attr)
|
|
94
|
+
%w(boolean integer number decimal string text date datetime).include?(field_type)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# By default all sortable fields are orderable
|
|
98
|
+
def sortable?(object, attr)
|
|
99
|
+
orderable?(object, attr)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def object_label_methods
|
|
103
|
+
[:title, :name]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Default label for object to string, title and name
|
|
107
|
+
# can be an attribute, a string or the model_class
|
|
108
|
+
def object_label(a)
|
|
109
|
+
if a.is_a? Hash
|
|
110
|
+
constantized_model = a.keys.first.to_s.singularize.classify.constantize
|
|
111
|
+
elsif a.is_a? ActiveRecord::Base
|
|
112
|
+
constantized_model = a
|
|
113
|
+
else
|
|
114
|
+
constantized_model = a.to_s.singularize.classify.constantize
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
constantized_model = constantized_model.new
|
|
118
|
+
|
|
119
|
+
method = 'to_s'
|
|
120
|
+
object_label_methods.each do |m|
|
|
121
|
+
method = m if constantized_model.respond_to?(m)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
method
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def show_object(a)
|
|
128
|
+
method = 'to_s'
|
|
129
|
+
|
|
130
|
+
unless a.blank?
|
|
131
|
+
object_label_methods.each do |m|
|
|
132
|
+
method = m if a.respond_to?(m)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
a.send(method)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Automatic retrieve of field type
|
|
140
|
+
# object params can be a Model Class or a Model Instance
|
|
141
|
+
# boolean integer number decimal string text date datetime has_many belongs_to
|
|
142
|
+
def guess_field_type(object, attr)
|
|
143
|
+
if object.class === Class
|
|
144
|
+
object_class = object
|
|
145
|
+
else
|
|
146
|
+
object_class = object.class
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
belongs_to_fields = object_class.reflect_on_all_associations(:belongs_to).map(&:name)
|
|
150
|
+
has_many_fields = object_class.reflect_on_all_associations(:has_many).map(&:name)
|
|
151
|
+
has_one_fields = object_class.reflect_on_all_associations(:has_one).map(&:name)
|
|
152
|
+
|
|
153
|
+
type = if object_class&.uploaders&.key?(attr.to_sym)
|
|
154
|
+
'image'
|
|
155
|
+
elsif belongs_to_fields.include?(attr.to_sym)
|
|
156
|
+
'belongs_to'
|
|
157
|
+
elsif has_many_fields.include?(attr.to_sym)
|
|
158
|
+
'has_many'
|
|
159
|
+
elsif has_one_fields.include?(attr.to_sym)
|
|
160
|
+
'has_one'
|
|
161
|
+
else
|
|
162
|
+
object_class.type_for_attribute(attr.to_s).type.to_s
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Virtual field default string eg password
|
|
166
|
+
return 'string' if object_class.new.respond_to?(attr) && type.blank?
|
|
167
|
+
|
|
168
|
+
# Raise exception if no type fouded
|
|
169
|
+
raise Exception.new("Unable to guess field_type for attribute: #{attr} in model: #{object_class}") if type.blank?
|
|
170
|
+
type
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def admin_custom_field(form, attribute)
|
|
174
|
+
type = attribute[attribute.keys.first][:type].to_s
|
|
175
|
+
render partial: "slash_admin/custom_fields/#{type}", locals: { f: form, a: attribute }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Form helper for generic field
|
|
179
|
+
def admin_field(form, attribute)
|
|
180
|
+
object_class = form.object.class
|
|
181
|
+
belongs_to_fields = object_class.reflect_on_all_associations(:belongs_to).map(&:name)
|
|
182
|
+
has_many_fields = object_class.reflect_on_all_associations(:has_many).map(&:name)
|
|
183
|
+
has_one_fields = object_class.reflect_on_all_associations(:has_one).map(&:name)
|
|
184
|
+
|
|
185
|
+
# Handle custom field first and default after
|
|
186
|
+
if attribute.is_a?(Hash)
|
|
187
|
+
admin_custom_field(form, attribute)
|
|
188
|
+
elsif belongs_to_fields.include?(attribute.to_sym)
|
|
189
|
+
render partial: 'slash_admin/fields/belongs_to', locals: { f: form, a: attribute }
|
|
190
|
+
elsif has_many_fields.include?(attribute.to_sym)
|
|
191
|
+
# if has nested_attributes_options for has_many field
|
|
192
|
+
if form.object.class.nested_attributes_options.key?(attribute.to_sym)
|
|
193
|
+
render partial: 'slash_admin/fields/nested_has_many', locals: { f: form, a: attribute }
|
|
194
|
+
else
|
|
195
|
+
render partial: 'slash_admin/fields/has_many', locals: { f: form, a: attribute }
|
|
196
|
+
end
|
|
197
|
+
elsif has_one_fields.include?(attribute.to_sym)
|
|
198
|
+
render partial: 'slash_admin/fields/has_one', locals: { f: form, a: attribute }
|
|
199
|
+
elsif form.object.class&.uploaders&.key?(attribute.to_sym)
|
|
200
|
+
render partial: 'slash_admin/fields/carrierwave', locals: { f: form, a: attribute }
|
|
201
|
+
else
|
|
202
|
+
type = form.object.class.type_for_attribute(attribute.to_s).type.to_s
|
|
203
|
+
if type == 'date' || type == 'datetime'
|
|
204
|
+
render partial: 'slash_admin/fields/date', locals: { f: form, a: attribute }
|
|
205
|
+
else
|
|
206
|
+
raise Exception.new("Unable to guess field_type for attribute: #{attribute} in model: #{object_class}") if type.blank?
|
|
207
|
+
render partial: "slash_admin/fields/#{type}", locals: { f: form, a: attribute }
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module SlashAdmin
|
|
3
|
+
class Admin < ApplicationRecord
|
|
4
|
+
include CanCan::Ability
|
|
5
|
+
|
|
6
|
+
has_secure_password
|
|
7
|
+
|
|
8
|
+
attr_accessor :login
|
|
9
|
+
|
|
10
|
+
EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
|
|
11
|
+
USERNAME_REGEX = /^[a-zA-Z0-9_\.]*$/
|
|
12
|
+
validates :username, presence: true, uniqueness: true, length: { in: 3..20 }
|
|
13
|
+
validates :email, presence: true, uniqueness: true
|
|
14
|
+
validates_length_of :password, in: 6..20, on: :create
|
|
15
|
+
validates_format_of :email, with: EMAIL_REGEX, multiline: true
|
|
16
|
+
validates_format_of :username, with: USERNAME_REGEX, multiline: true
|
|
17
|
+
|
|
18
|
+
before_create :handle_default_role
|
|
19
|
+
|
|
20
|
+
serialize :roles, JSON
|
|
21
|
+
|
|
22
|
+
def has_role?(role)
|
|
23
|
+
if roles.blank?
|
|
24
|
+
false
|
|
25
|
+
else
|
|
26
|
+
roles.include?(role)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def handle_default_role
|
|
31
|
+
self.roles = 'superadmin' unless roles.present?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def login=(login)
|
|
35
|
+
@login = login
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def login
|
|
39
|
+
@login || self.username || self.email
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def identicon
|
|
43
|
+
RubyIdenticon.create_base64(email, grid_size: 5, border_size: 150, square_size: 50, background_color: 0xf0f0f0ff)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= t('slash_admin.view.administration_login') %></title>
|
|
5
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
7
|
+
<%= stylesheet_link_tag "slash_admin/application", media: "all", 'data-turbolinks-track' => true %>
|
|
8
|
+
<%= javascript_include_tag "slash_admin/application", 'data-turbolinks-track' => true %>
|
|
9
|
+
<%= favicon_link_tag 'slash_admin/favicon.png' %>
|
|
10
|
+
<%= csrf_meta_tags %>
|
|
11
|
+
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet" type="text/css"/>
|
|
12
|
+
</head>
|
|
13
|
+
<body id="admin-user">
|
|
14
|
+
<%= yield %>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= yield(:page_title) ? yield(:page_title) : t('slash_admin.view.administration') %></title>
|
|
5
|
+
<%= stylesheet_link_tag "slash_admin/application", media: "all", 'data-turbolinks-track' => true %>
|
|
6
|
+
<%= javascript_include_tag "slash_admin/application", 'data-turbolinks-track' => true %>
|
|
7
|
+
<%= favicon_link_tag 'slash_admin/favicon.png' %>
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
9
|
+
<script type="text/javascript">
|
|
10
|
+
I18n.defaultLocale = "<%= I18n.default_locale %>";
|
|
11
|
+
I18n.locale = "<%= I18n.locale %>";
|
|
12
|
+
</script>
|
|
13
|
+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/2.6.0/js/froala_editor.pkgd.min.js"></script>
|
|
14
|
+
<%= csrf_meta_tags %>
|
|
15
|
+
</head>
|
|
16
|
+
<body id="admin-dashboard" class="<% if session[:compact].present? %>page-sidebar-closed<% end %>">
|
|
17
|
+
<noscript>
|
|
18
|
+
<%= t('slash_admin.view.enable_javascript_html') %>
|
|
19
|
+
</noscript>
|
|
20
|
+
|
|
21
|
+
<%= render 'slash_admin/shared/header' %>
|
|
22
|
+
|
|
23
|
+
<div class="page-container">
|
|
24
|
+
<%= render 'slash_admin/shared/menu' %>
|
|
25
|
+
<div class="page-content">
|
|
26
|
+
<%= render 'slash_admin/shared/sub_header' %>
|
|
27
|
+
<%= render 'slash_admin/shared/breadcrumb' %>
|
|
28
|
+
<%= yield %>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="scroll-to-top">
|
|
33
|
+
<i class="icon-arrow-up"></i>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<%= toastr_bootstrap %>
|
|
37
|
+
</body>
|
|
38
|
+
|
|
39
|
+
</body>
|
|
40
|
+
</html>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<div class="modal-dialog modal-lg" role="document">
|
|
2
|
+
<div class="modal-content">
|
|
3
|
+
<%= form_for [:slash_admin, class_name_from_association(f.object, a).constantize.new], remote: true, html: {'data-type': 'json'} do |fs| %>
|
|
4
|
+
<div class="modal-header">
|
|
5
|
+
<%= t('slash_admin.view.create') %>
|
|
6
|
+
<%= class_name_from_association(f.object, a).constantize.model_name.human.downcase %>
|
|
7
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
8
|
+
<span aria-hidden="true">×</span>
|
|
9
|
+
</button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
<div class="errors-json"></div>
|
|
13
|
+
<%= render 'slash_admin/shared/errors_data_new' %>
|
|
14
|
+
<% if @model.id.blank? %>
|
|
15
|
+
<% if a.is_a?(Hash) %>
|
|
16
|
+
<% params_assoc = "SlashAdmin::Models::#{class_name_from_association(f.object, a).pluralize}Controller".constantize.new.create_params(from: @model_class).each %>
|
|
17
|
+
<% else %>
|
|
18
|
+
<% params_assoc = "SlashAdmin::Models::#{a.to_s.classify.pluralize}Controller".constantize.new.create_params(from: @model_class).each %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% else %>
|
|
21
|
+
<% if a.is_a?(Hash) %>
|
|
22
|
+
<% params_assoc = "SlashAdmin::Models::#{class_name_from_association(f.object, a).pluralize}Controller".constantize.new.update_params(from: @model_class).each %>
|
|
23
|
+
<% else %>
|
|
24
|
+
<% params_assoc = "SlashAdmin::Models::#{a.to_s.classify.pluralize}Controller".constantize.new.update_params(from: @model_class).each %>
|
|
25
|
+
<% end %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% params_assoc.each do |attribute| %>
|
|
28
|
+
<%= render 'slash_admin/fields/form_group', f: fs, a: attribute %>
|
|
29
|
+
<% end %>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="modal-footer">
|
|
32
|
+
<a href="#" data-dismiss="modal"><%= t('slash_admin.view.cancel') %></a>
|
|
33
|
+
<button type="submit" class="btn btn-primary pull-right"><%= t('slash_admin.view.save') %></button>
|
|
34
|
+
</div>
|
|
35
|
+
<% end %>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|