viniBaxterDesk 0.13.1
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/Rakefile +32 -0
- data/app/assets/javascripts/administrate/application.js +6 -0
- data/app/assets/javascripts/administrate/components/associative.js +4 -0
- data/app/assets/javascripts/administrate/components/date_time_picker.js +14 -0
- data/app/assets/javascripts/administrate/components/table.js +23 -0
- data/app/assets/stylesheets/administrate/application.scss +30 -0
- data/app/assets/stylesheets/administrate/base/_forms.scss +107 -0
- data/app/assets/stylesheets/administrate/base/_layout.scss +20 -0
- data/app/assets/stylesheets/administrate/base/_lists.scss +19 -0
- data/app/assets/stylesheets/administrate/base/_tables.scss +58 -0
- data/app/assets/stylesheets/administrate/base/_typography.scss +45 -0
- data/app/assets/stylesheets/administrate/components/_app-container.scss +9 -0
- data/app/assets/stylesheets/administrate/components/_attributes.scss +26 -0
- data/app/assets/stylesheets/administrate/components/_buttons.scss +51 -0
- data/app/assets/stylesheets/administrate/components/_cells.scss +47 -0
- data/app/assets/stylesheets/administrate/components/_field-unit.scss +45 -0
- data/app/assets/stylesheets/administrate/components/_flashes.scss +28 -0
- data/app/assets/stylesheets/administrate/components/_form-actions.scss +3 -0
- data/app/assets/stylesheets/administrate/components/_main-content.scss +29 -0
- data/app/assets/stylesheets/administrate/components/_navigation.scss +32 -0
- data/app/assets/stylesheets/administrate/components/_pagination.scss +18 -0
- data/app/assets/stylesheets/administrate/components/_search.scss +46 -0
- data/app/assets/stylesheets/administrate/library/_clearfix.scss +7 -0
- data/app/assets/stylesheets/administrate/library/_data-label.scss +8 -0
- data/app/assets/stylesheets/administrate/library/_variables.scss +63 -0
- data/app/assets/stylesheets/administrate/reset/_normalize.scss +447 -0
- data/app/assets/stylesheets/administrate/utilities/_text-color.scss +3 -0
- data/app/assets/stylesheets/docs.scss +93 -0
- data/app/controllers/administrate/application_controller.rb +189 -0
- data/app/controllers/concerns/administrate/punditize.rb +36 -0
- data/app/helpers/administrate/application_helper.rb +83 -0
- data/app/views/administrate/application/_collection.html.erb +97 -0
- data/app/views/administrate/application/_flashes.html.erb +20 -0
- data/app/views/administrate/application/_form.html.erb +45 -0
- data/app/views/administrate/application/_icons.html.erb +13 -0
- data/app/views/administrate/application/_javascript.html.erb +21 -0
- data/app/views/administrate/application/_navigation.html.erb +20 -0
- data/app/views/administrate/application/_search.html.erb +25 -0
- data/app/views/administrate/application/_stylesheet.html.erb +14 -0
- data/app/views/administrate/application/edit.html.erb +36 -0
- data/app/views/administrate/application/index.html.erb +66 -0
- data/app/views/administrate/application/new.html.erb +37 -0
- data/app/views/administrate/application/show.html.erb +49 -0
- data/app/views/fields/belongs_to/_form.html.erb +26 -0
- data/app/views/fields/belongs_to/_index.html.erb +27 -0
- data/app/views/fields/belongs_to/_show.html.erb +27 -0
- data/app/views/fields/boolean/_form.html.erb +23 -0
- data/app/views/fields/boolean/_index.html.erb +19 -0
- data/app/views/fields/boolean/_show.html.erb +19 -0
- data/app/views/fields/date/_form.html.erb +24 -0
- data/app/views/fields/date/_index.html.erb +21 -0
- data/app/views/fields/date/_show.html.erb +21 -0
- data/app/views/fields/date_time/_form.html.erb +24 -0
- data/app/views/fields/date_time/_index.html.erb +21 -0
- data/app/views/fields/date_time/_show.html.erb +21 -0
- data/app/views/fields/email/_form.html.erb +23 -0
- data/app/views/fields/email/_index.html.erb +18 -0
- data/app/views/fields/email/_show.html.erb +18 -0
- data/app/views/fields/has_many/_form.html.erb +29 -0
- data/app/views/fields/has_many/_index.html.erb +19 -0
- data/app/views/fields/has_many/_show.html.erb +38 -0
- data/app/views/fields/has_one/_form.html.erb +28 -0
- data/app/views/fields/has_one/_index.html.erb +23 -0
- data/app/views/fields/has_one/_show.html.erb +40 -0
- data/app/views/fields/number/_form.html.erb +23 -0
- data/app/views/fields/number/_index.html.erb +19 -0
- data/app/views/fields/number/_show.html.erb +19 -0
- data/app/views/fields/password/_form.html.erb +23 -0
- data/app/views/fields/password/_index.html.erb +18 -0
- data/app/views/fields/password/_show.html.erb +18 -0
- data/app/views/fields/polymorphic/_form.html.erb +29 -0
- data/app/views/fields/polymorphic/_index.html.erb +24 -0
- data/app/views/fields/polymorphic/_show.html.erb +28 -0
- data/app/views/fields/select/_form.html.erb +31 -0
- data/app/views/fields/select/_index.html.erb +16 -0
- data/app/views/fields/select/_show.html.erb +16 -0
- data/app/views/fields/string/_form.html.erb +23 -0
- data/app/views/fields/string/_index.html.erb +18 -0
- data/app/views/fields/string/_show.html.erb +18 -0
- data/app/views/fields/text/_form.html.erb +22 -0
- data/app/views/fields/text/_index.html.erb +18 -0
- data/app/views/fields/text/_show.html.erb +18 -0
- data/app/views/fields/time/_form.html.erb +22 -0
- data/app/views/fields/time/_index.html.erb +17 -0
- data/app/views/fields/time/_show.html.erb +17 -0
- data/app/views/fields/url/_form.html.erb +23 -0
- data/app/views/fields/url/_index.html.erb +20 -0
- data/app/views/fields/url/_show.html.erb +20 -0
- data/app/views/layouts/administrate/application.html.erb +41 -0
- data/config/i18n-tasks.yml +18 -0
- data/config/locales/administrate.ar.yml +28 -0
- data/config/locales/administrate.bs.yml +27 -0
- data/config/locales/administrate.ca.yml +28 -0
- data/config/locales/administrate.da.yml +28 -0
- data/config/locales/administrate.de.yml +28 -0
- data/config/locales/administrate.en.yml +28 -0
- data/config/locales/administrate.es.yml +28 -0
- data/config/locales/administrate.fr.yml +28 -0
- data/config/locales/administrate.id.yml +28 -0
- data/config/locales/administrate.it.yml +28 -0
- data/config/locales/administrate.ja.yml +28 -0
- data/config/locales/administrate.ko.yml +28 -0
- data/config/locales/administrate.nl.yml +28 -0
- data/config/locales/administrate.pl.yml +28 -0
- data/config/locales/administrate.pt-BR.yml +29 -0
- data/config/locales/administrate.pt.yml +29 -0
- data/config/locales/administrate.ru.yml +28 -0
- data/config/locales/administrate.sq.yml +28 -0
- data/config/locales/administrate.sv.yml +28 -0
- data/config/locales/administrate.uk.yml +28 -0
- data/config/locales/administrate.vi.yml +28 -0
- data/config/locales/administrate.zh-CN.yml +28 -0
- data/config/locales/administrate.zh-TW.yml +28 -0
- data/config/routes.rb +2 -0
- data/config/unicorn.rb +30 -0
- data/docs/adding_controllers_without_related_model.md +36 -0
- data/docs/adding_custom_field_types.md +81 -0
- data/docs/authentication.md +63 -0
- data/docs/authorization.md +71 -0
- data/docs/contributing.md +1 -0
- data/docs/customizing_attribute_partials.md +56 -0
- data/docs/customizing_controller_actions.md +58 -0
- data/docs/customizing_dashboards.md +303 -0
- data/docs/customizing_page_views.md +84 -0
- data/docs/getting_started.md +128 -0
- data/docs/rails_api.md +45 -0
- data/lib/administrate/base_dashboard.rb +97 -0
- data/lib/administrate/custom_dashboard.rb +15 -0
- data/lib/administrate/engine.rb +44 -0
- data/lib/administrate/field/associative.rb +33 -0
- data/lib/administrate/field/base.rb +54 -0
- data/lib/administrate/field/belongs_to.rb +38 -0
- data/lib/administrate/field/boolean.rb +15 -0
- data/lib/administrate/field/date.rb +20 -0
- data/lib/administrate/field/date_time.rb +32 -0
- data/lib/administrate/field/deferred.rb +44 -0
- data/lib/administrate/field/email.rb +11 -0
- data/lib/administrate/field/has_many.rb +94 -0
- data/lib/administrate/field/has_one.rb +35 -0
- data/lib/administrate/field/number.rb +35 -0
- data/lib/administrate/field/password.rb +25 -0
- data/lib/administrate/field/polymorphic.rb +51 -0
- data/lib/administrate/field/select.rb +24 -0
- data/lib/administrate/field/string.rb +21 -0
- data/lib/administrate/field/text.rb +21 -0
- data/lib/administrate/field/time.rb +8 -0
- data/lib/administrate/field/url.rb +21 -0
- data/lib/administrate/generator_helpers.rb +13 -0
- data/lib/administrate/namespace/resource.rb +28 -0
- data/lib/administrate/namespace.rb +35 -0
- data/lib/administrate/order.rb +88 -0
- data/lib/administrate/page/base.rb +41 -0
- data/lib/administrate/page/collection.rb +37 -0
- data/lib/administrate/page/form.rb +28 -0
- data/lib/administrate/page/show.rb +24 -0
- data/lib/administrate/page.rb +4 -0
- data/lib/administrate/resource_resolver.rb +43 -0
- data/lib/administrate/search.rb +157 -0
- data/lib/administrate/version.rb +3 -0
- data/lib/administrate/view_generator.rb +36 -0
- data/lib/administrate.rb +4 -0
- data/lib/generators/administrate/assets/assets_generator.rb +12 -0
- data/lib/generators/administrate/assets/javascripts_generator.rb +17 -0
- data/lib/generators/administrate/assets/stylesheets_generator.rb +17 -0
- data/lib/generators/administrate/dashboard/USAGE +9 -0
- data/lib/generators/administrate/dashboard/dashboard_generator.rb +143 -0
- data/lib/generators/administrate/dashboard/templates/controller.rb.erb +46 -0
- data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +68 -0
- data/lib/generators/administrate/field/field_generator.rb +31 -0
- data/lib/generators/administrate/field/templates/_form.html.erb +6 -0
- data/lib/generators/administrate/field/templates/_index.html.erb +1 -0
- data/lib/generators/administrate/field/templates/_show.html.erb +1 -0
- data/lib/generators/administrate/field/templates/field_object.rb.erb +7 -0
- data/lib/generators/administrate/install/install_generator.rb +49 -0
- data/lib/generators/administrate/install/templates/application_controller.rb.erb +21 -0
- data/lib/generators/administrate/routes/routes_generator.rb +96 -0
- data/lib/generators/administrate/routes/templates/routes.rb.erb +5 -0
- data/lib/generators/administrate/views/edit_generator.rb +16 -0
- data/lib/generators/administrate/views/field_generator.rb +50 -0
- data/lib/generators/administrate/views/form_generator.rb +15 -0
- data/lib/generators/administrate/views/index_generator.rb +16 -0
- data/lib/generators/administrate/views/layout_generator.rb +24 -0
- data/lib/generators/administrate/views/navigation_generator.rb +15 -0
- data/lib/generators/administrate/views/new_generator.rb +16 -0
- data/lib/generators/administrate/views/show_generator.rb +15 -0
- data/lib/generators/administrate/views/views_generator.rb +14 -0
- data/lib/tasks/administrate_tasks.rake +4 -0
- metadata +398 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
require "active_support/core_ext/module/delegation"
|
|
2
|
+
require "active_support/core_ext/object/blank"
|
|
3
|
+
|
|
4
|
+
module Administrate
|
|
5
|
+
class Search
|
|
6
|
+
class Query
|
|
7
|
+
attr_reader :filters
|
|
8
|
+
|
|
9
|
+
def blank?
|
|
10
|
+
terms.blank? && filters.empty?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(original_query)
|
|
14
|
+
@original_query = original_query
|
|
15
|
+
@filters, @terms = parse_query(original_query)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def original
|
|
19
|
+
@original_query
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def terms
|
|
23
|
+
@terms.join(" ")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_s
|
|
27
|
+
original
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def filter?(word)
|
|
33
|
+
word.match?(/^\w+:$/)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def parse_query(query)
|
|
37
|
+
filters = []
|
|
38
|
+
terms = []
|
|
39
|
+
query.to_s.split.each do |word|
|
|
40
|
+
if filter?(word)
|
|
41
|
+
filters << word.split(":").first
|
|
42
|
+
else
|
|
43
|
+
terms << word
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
[filters, terms]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def initialize(scoped_resource, dashboard_class, term)
|
|
51
|
+
@dashboard_class = dashboard_class
|
|
52
|
+
@scoped_resource = scoped_resource
|
|
53
|
+
@query = Query.new(term)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def run
|
|
57
|
+
if query.blank?
|
|
58
|
+
@scoped_resource.all
|
|
59
|
+
else
|
|
60
|
+
results = search_results(@scoped_resource)
|
|
61
|
+
results = filter_results(results)
|
|
62
|
+
results
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def apply_filter(filter, resources)
|
|
69
|
+
return resources unless filter
|
|
70
|
+
filter.call(resources)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def filter_results(resources)
|
|
74
|
+
query.filters.each do |filter_name|
|
|
75
|
+
filter = valid_filters[filter_name]
|
|
76
|
+
resources = apply_filter(filter, resources)
|
|
77
|
+
end
|
|
78
|
+
resources
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def query_template
|
|
82
|
+
search_attributes.map do |attr|
|
|
83
|
+
table_name = query_table_name(attr)
|
|
84
|
+
attr_name = column_to_query(attr)
|
|
85
|
+
|
|
86
|
+
"LOWER(CAST(#{table_name}.#{attr_name} AS CHAR(256))) LIKE ?"
|
|
87
|
+
end.join(" OR ")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def query_values
|
|
91
|
+
["%#{term.mb_chars.downcase}%"] * search_attributes.count
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def search_attributes
|
|
95
|
+
attribute_types.keys.select do |attribute|
|
|
96
|
+
attribute_types[attribute].searchable?
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def search_results(resources)
|
|
101
|
+
resources.
|
|
102
|
+
joins(tables_to_join).
|
|
103
|
+
where(query_template, *query_values)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def valid_filters
|
|
107
|
+
if @dashboard_class.const_defined?(:COLLECTION_FILTERS)
|
|
108
|
+
@dashboard_class.const_get(:COLLECTION_FILTERS).stringify_keys
|
|
109
|
+
else
|
|
110
|
+
{}
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def attribute_types
|
|
115
|
+
@dashboard_class::ATTRIBUTE_TYPES
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def query_table_name(attr)
|
|
119
|
+
if association_search?(attr)
|
|
120
|
+
provided_class_name = attribute_types[attr].options[:class_name]
|
|
121
|
+
if provided_class_name
|
|
122
|
+
provided_class_name.constantize.table_name
|
|
123
|
+
else
|
|
124
|
+
ActiveRecord::Base.connection.quote_table_name(attr.to_s.pluralize)
|
|
125
|
+
end
|
|
126
|
+
else
|
|
127
|
+
ActiveRecord::Base.connection.
|
|
128
|
+
quote_table_name(@scoped_resource.table_name)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def column_to_query(attr)
|
|
133
|
+
if association_search?(attr)
|
|
134
|
+
ActiveRecord::Base.connection.
|
|
135
|
+
quote_column_name(attribute_types[attr].searchable_field)
|
|
136
|
+
else
|
|
137
|
+
ActiveRecord::Base.connection.quote_column_name(attr)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def tables_to_join
|
|
142
|
+
attribute_types.keys.select do |attribute|
|
|
143
|
+
attribute_types[attribute].searchable? && association_search?(attribute)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def association_search?(attribute)
|
|
148
|
+
attribute_types[attribute].associative?
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def term
|
|
152
|
+
query.terms
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
attr_reader :resolver, :query
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require "rails/generators/base"
|
|
2
|
+
require "administrate/generator_helpers"
|
|
3
|
+
|
|
4
|
+
module Administrate
|
|
5
|
+
class ViewGenerator < Rails::Generators::Base
|
|
6
|
+
include Administrate::GeneratorHelpers
|
|
7
|
+
|
|
8
|
+
def self.template_source_path
|
|
9
|
+
File.expand_path(
|
|
10
|
+
"../../../app/views/administrate/application",
|
|
11
|
+
__FILE__,
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def copy_resource_template(template_name)
|
|
18
|
+
template_file = "#{template_name}.html.erb"
|
|
19
|
+
|
|
20
|
+
copy_file(
|
|
21
|
+
template_file,
|
|
22
|
+
"app/views/admin/#{resource_path}/#{template_file}",
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def resource_path
|
|
27
|
+
args.first.try(:underscore).try(:pluralize) || BaseResourcePath.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class BaseResourcePath
|
|
31
|
+
def to_s
|
|
32
|
+
"application"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/administrate.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "administrate/view_generator"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Generators
|
|
5
|
+
class AssetsGenerator < Administrate::ViewGenerator
|
|
6
|
+
def copy_assets
|
|
7
|
+
call_generator("administrate:assets:javascripts")
|
|
8
|
+
call_generator("administrate:assets:stylesheets")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "rails/generators/base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Generators
|
|
5
|
+
module Assets
|
|
6
|
+
class JavascriptsGenerator < Rails::Generators::Base
|
|
7
|
+
JAVASCRIPTS_PATH = "app/assets/javascripts/administrate"
|
|
8
|
+
|
|
9
|
+
source_root File.expand_path("../../../../../", __FILE__)
|
|
10
|
+
|
|
11
|
+
def copy_javascripts
|
|
12
|
+
directory JAVASCRIPTS_PATH, JAVASCRIPTS_PATH
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "rails/generators/base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Generators
|
|
5
|
+
module Assets
|
|
6
|
+
class StylesheetsGenerator < Rails::Generators::Base
|
|
7
|
+
STYLESHEETS_PATH = "app/assets/stylesheets/administrate"
|
|
8
|
+
|
|
9
|
+
source_root File.expand_path("../../../../../", __FILE__)
|
|
10
|
+
|
|
11
|
+
def copy_stylesheets
|
|
12
|
+
directory STYLESHEETS_PATH, STYLESHEETS_PATH
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require "rails/generators/named_base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Generators
|
|
5
|
+
class DashboardGenerator < Rails::Generators::NamedBase
|
|
6
|
+
ATTRIBUTE_TYPE_MAPPING = {
|
|
7
|
+
boolean: "Field::Boolean",
|
|
8
|
+
date: "Field::Date",
|
|
9
|
+
datetime: "Field::DateTime",
|
|
10
|
+
enum: "Field::String",
|
|
11
|
+
float: "Field::Number",
|
|
12
|
+
integer: "Field::Number",
|
|
13
|
+
time: "Field::Time",
|
|
14
|
+
text: "Field::Text",
|
|
15
|
+
string: "Field::String",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
ATTRIBUTE_OPTIONS_MAPPING = {
|
|
19
|
+
enum: { searchable: false },
|
|
20
|
+
float: { decimals: 2 },
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
DEFAULT_FIELD_TYPE = "Field::String.with_options(searchable: false)"
|
|
24
|
+
COLLECTION_ATTRIBUTE_LIMIT = 4
|
|
25
|
+
READ_ONLY_ATTRIBUTES = %w[id created_at updated_at]
|
|
26
|
+
|
|
27
|
+
class_option :namespace, type: :string, default: "admin"
|
|
28
|
+
|
|
29
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
30
|
+
|
|
31
|
+
def create_dashboard_definition
|
|
32
|
+
template(
|
|
33
|
+
"dashboard.rb.erb",
|
|
34
|
+
Rails.root.join("app/dashboards/#{file_name}_dashboard.rb"),
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create_resource_controller
|
|
39
|
+
destination = Rails.root.join(
|
|
40
|
+
"app/controllers/#{namespace}/#{file_name.pluralize}_controller.rb",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
template("controller.rb.erb", destination)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def namespace
|
|
49
|
+
options[:namespace]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def attributes
|
|
53
|
+
klass.reflections.keys +
|
|
54
|
+
klass.columns.map(&:name) -
|
|
55
|
+
redundant_attributes
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def form_attributes
|
|
59
|
+
attributes - READ_ONLY_ATTRIBUTES
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def redundant_attributes
|
|
63
|
+
klass.reflections.keys.flat_map do |relationship|
|
|
64
|
+
redundant_attributes_for(relationship)
|
|
65
|
+
end.compact
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def redundant_attributes_for(relationship)
|
|
69
|
+
case association_type(relationship)
|
|
70
|
+
when "Field::Polymorphic"
|
|
71
|
+
[relationship + "_id", relationship + "_type"]
|
|
72
|
+
when "Field::BelongsTo"
|
|
73
|
+
relationship + "_id"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def field_type(attribute)
|
|
78
|
+
type = column_type_for_attribute(attribute.to_s)
|
|
79
|
+
|
|
80
|
+
if type
|
|
81
|
+
ATTRIBUTE_TYPE_MAPPING.fetch(type, DEFAULT_FIELD_TYPE) +
|
|
82
|
+
options_string(ATTRIBUTE_OPTIONS_MAPPING.fetch(type, {}))
|
|
83
|
+
else
|
|
84
|
+
association_type(attribute)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def column_type_for_attribute(attr)
|
|
89
|
+
if enum_column?(attr)
|
|
90
|
+
:enum
|
|
91
|
+
else
|
|
92
|
+
column_types(attr)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def enum_column?(attr)
|
|
97
|
+
klass.respond_to?(:defined_enums) &&
|
|
98
|
+
klass.defined_enums.keys.include?(attr)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def column_types(attr)
|
|
102
|
+
klass.columns.find { |column| column.name == attr }.try(:type)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def association_type(attribute)
|
|
106
|
+
relationship = klass.reflections[attribute.to_s]
|
|
107
|
+
if relationship.has_one?
|
|
108
|
+
"Field::HasOne"
|
|
109
|
+
elsif relationship.collection?
|
|
110
|
+
"Field::HasMany" + relationship_options_string(relationship)
|
|
111
|
+
elsif relationship.polymorphic?
|
|
112
|
+
"Field::Polymorphic"
|
|
113
|
+
else
|
|
114
|
+
"Field::BelongsTo" + relationship_options_string(relationship)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def klass
|
|
119
|
+
@klass ||= Object.const_get(class_name)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def relationship_options_string(relationship)
|
|
123
|
+
if relationship.class_name != relationship.name.to_s.classify
|
|
124
|
+
options_string(class_name: relationship.class_name)
|
|
125
|
+
else
|
|
126
|
+
""
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def options_string(options)
|
|
131
|
+
if options.any?
|
|
132
|
+
".with_options(#{inspect_hash_as_ruby(options)})"
|
|
133
|
+
else
|
|
134
|
+
""
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def inspect_hash_as_ruby(hash)
|
|
139
|
+
hash.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module <%= namespace.classify %>
|
|
2
|
+
class <%= class_name.pluralize %>Controller < <%= namespace.classify %>::ApplicationController
|
|
3
|
+
# Overwrite any of the RESTful controller actions to implement custom behavior
|
|
4
|
+
# For example, you may want to send an email after a foo is updated.
|
|
5
|
+
#
|
|
6
|
+
# def update
|
|
7
|
+
# super
|
|
8
|
+
# send_foo_updated_email(requested_resource)
|
|
9
|
+
# end
|
|
10
|
+
|
|
11
|
+
# Override this method to specify custom lookup behavior.
|
|
12
|
+
# This will be used to set the resource for the `show`, `edit`, and `update`
|
|
13
|
+
# actions.
|
|
14
|
+
#
|
|
15
|
+
# def find_resource(param)
|
|
16
|
+
# Foo.find_by!(slug: param)
|
|
17
|
+
# end
|
|
18
|
+
|
|
19
|
+
# The result of this lookup will be available as `requested_resource`
|
|
20
|
+
|
|
21
|
+
# Override this if you have certain roles that require a subset
|
|
22
|
+
# this will be used to set the records shown on the `index` action.
|
|
23
|
+
#
|
|
24
|
+
# def scoped_resource
|
|
25
|
+
# if current_user.super_admin?
|
|
26
|
+
# resource_class
|
|
27
|
+
# else
|
|
28
|
+
# resource_class.with_less_stuff
|
|
29
|
+
# end
|
|
30
|
+
# end
|
|
31
|
+
|
|
32
|
+
# Override `resource_params` if you want to transform the submitted
|
|
33
|
+
# data before it's persisted. For example, the following would turn all
|
|
34
|
+
# empty values into nil values. It uses other APIs such as `resource_class`
|
|
35
|
+
# and `dashboard`:
|
|
36
|
+
#
|
|
37
|
+
# def resource_params
|
|
38
|
+
# params.require(resource_class.model_name.param_key).
|
|
39
|
+
# permit(dashboard.permitted_attributes).
|
|
40
|
+
# transform_values { |value| value == "" ? nil : value }
|
|
41
|
+
# end
|
|
42
|
+
|
|
43
|
+
# See https://administrate-prototype.herokuapp.com/customizing_controller_actions
|
|
44
|
+
# for more information
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require "administrate/base_dashboard"
|
|
2
|
+
|
|
3
|
+
class <%= class_name %>Dashboard < Administrate::BaseDashboard
|
|
4
|
+
# ATTRIBUTE_TYPES
|
|
5
|
+
# a hash that describes the type of each of the model's fields.
|
|
6
|
+
#
|
|
7
|
+
# Each different type represents an Administrate::Field object,
|
|
8
|
+
# which determines how the attribute is displayed
|
|
9
|
+
# on pages throughout the dashboard.
|
|
10
|
+
ATTRIBUTE_TYPES = {
|
|
11
|
+
<% attributes.each do |attr| -%>
|
|
12
|
+
<%= attr %>: <%= field_type(attr) %>,
|
|
13
|
+
<% end -%>
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
# COLLECTION_ATTRIBUTES
|
|
17
|
+
# an array of attributes that will be displayed on the model's index page.
|
|
18
|
+
#
|
|
19
|
+
# By default, it's limited to four items to reduce clutter on index pages.
|
|
20
|
+
# Feel free to add, remove, or rearrange items.
|
|
21
|
+
COLLECTION_ATTRIBUTES = [
|
|
22
|
+
<%=
|
|
23
|
+
attributes.first(COLLECTION_ATTRIBUTE_LIMIT).map do |attr|
|
|
24
|
+
" :#{attr},"
|
|
25
|
+
end.join("\n")
|
|
26
|
+
%>
|
|
27
|
+
].freeze
|
|
28
|
+
|
|
29
|
+
# SHOW_PAGE_ATTRIBUTES
|
|
30
|
+
# an array of attributes that will be displayed on the model's show page.
|
|
31
|
+
SHOW_PAGE_ATTRIBUTES = [
|
|
32
|
+
<%=
|
|
33
|
+
attributes.map do |attr|
|
|
34
|
+
" :#{attr},"
|
|
35
|
+
end.join("\n")
|
|
36
|
+
%>
|
|
37
|
+
].freeze
|
|
38
|
+
|
|
39
|
+
# FORM_ATTRIBUTES
|
|
40
|
+
# an array of attributes that will be displayed
|
|
41
|
+
# on the model's form (`new` and `edit`) pages.
|
|
42
|
+
FORM_ATTRIBUTES = [
|
|
43
|
+
<%=
|
|
44
|
+
form_attributes.map do |attr|
|
|
45
|
+
" :#{attr},"
|
|
46
|
+
end.join("\n")
|
|
47
|
+
%>
|
|
48
|
+
].freeze
|
|
49
|
+
|
|
50
|
+
# COLLECTION_FILTERS
|
|
51
|
+
# a hash that defines filters that can be used while searching via the search
|
|
52
|
+
# field of the dashboard.
|
|
53
|
+
#
|
|
54
|
+
# For example to add an option to search for open resources by typing "open:"
|
|
55
|
+
# in the search field:
|
|
56
|
+
#
|
|
57
|
+
# COLLECTION_FILTERS = {
|
|
58
|
+
# open: ->(resources) { resources.where(open: true) }
|
|
59
|
+
# }.freeze
|
|
60
|
+
COLLECTION_FILTERS = {}.freeze
|
|
61
|
+
|
|
62
|
+
# Overwrite this method to customize how <%= file_name.pluralize.humanize.downcase %> are displayed
|
|
63
|
+
# across all pages of the admin dashboard.
|
|
64
|
+
#
|
|
65
|
+
# def display_resource(<%= file_name %>)
|
|
66
|
+
# "<%= class_name %> ##{<%= file_name %>.id}"
|
|
67
|
+
# end
|
|
68
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Administrate
|
|
2
|
+
module Generators
|
|
3
|
+
class FieldGenerator < Rails::Generators::NamedBase
|
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
5
|
+
|
|
6
|
+
def template_field_object
|
|
7
|
+
template(
|
|
8
|
+
"field_object.rb.erb",
|
|
9
|
+
"app/fields/#{file_name}_field.rb",
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def copy_partials
|
|
14
|
+
copy_partial(:show)
|
|
15
|
+
copy_partial(:index)
|
|
16
|
+
copy_partial(:form)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def copy_partial(partial_name)
|
|
22
|
+
partial = "_#{partial_name}.html.erb"
|
|
23
|
+
|
|
24
|
+
copy_file(
|
|
25
|
+
partial,
|
|
26
|
+
"app/views/fields/#{file_name}_field/#{partial}",
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= field.to_s %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= field.to_s %>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require "rails/generators/base"
|
|
2
|
+
require "administrate/generator_helpers"
|
|
3
|
+
require "administrate/namespace"
|
|
4
|
+
|
|
5
|
+
module Administrate
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
include Administrate::GeneratorHelpers
|
|
9
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
10
|
+
|
|
11
|
+
class_option :namespace, type: :string, default: "admin"
|
|
12
|
+
|
|
13
|
+
def run_routes_generator
|
|
14
|
+
if dashboard_resources.none?
|
|
15
|
+
call_generator("administrate:routes", "--namespace", namespace)
|
|
16
|
+
load Rails.root.join("config/routes.rb")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def create_dashboard_controller
|
|
21
|
+
template(
|
|
22
|
+
"application_controller.rb.erb",
|
|
23
|
+
"app/controllers/#{namespace}/application_controller.rb",
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def run_dashboard_generators
|
|
28
|
+
singular_dashboard_resources.each do |resource|
|
|
29
|
+
call_generator "administrate:dashboard", resource,
|
|
30
|
+
"--namespace", namespace
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def namespace
|
|
37
|
+
options[:namespace]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def singular_dashboard_resources
|
|
41
|
+
dashboard_resources.map(&:to_s).map(&:singularize)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def dashboard_resources
|
|
45
|
+
Administrate::Namespace.new(namespace).resources
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# All Administrate controllers inherit from this
|
|
2
|
+
# `Administrate::ApplicationController`, making it the ideal place to put
|
|
3
|
+
# authentication logic or other before_actions.
|
|
4
|
+
#
|
|
5
|
+
# If you want to add pagination or other controller-level concerns,
|
|
6
|
+
# you're free to overwrite the RESTful controller actions.
|
|
7
|
+
module <%= namespace.classify %>
|
|
8
|
+
class ApplicationController < Administrate::ApplicationController
|
|
9
|
+
before_action :authenticate_admin
|
|
10
|
+
|
|
11
|
+
def authenticate_admin
|
|
12
|
+
# TODO Add authentication logic here.
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Override this value to specify the number of elements to display at a time
|
|
16
|
+
# on index pages. Defaults to 20.
|
|
17
|
+
# def records_per_page
|
|
18
|
+
# params[:per_page] || 20
|
|
19
|
+
# end
|
|
20
|
+
end
|
|
21
|
+
end
|