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,94 @@
|
|
|
1
|
+
require_relative "associative"
|
|
2
|
+
require "administrate/page/collection"
|
|
3
|
+
require "administrate/order"
|
|
4
|
+
|
|
5
|
+
module Administrate
|
|
6
|
+
module Field
|
|
7
|
+
class HasMany < Associative
|
|
8
|
+
DEFAULT_LIMIT = 5
|
|
9
|
+
|
|
10
|
+
def self.permitted_attribute(attr, _options = nil)
|
|
11
|
+
{ "#{attr.to_s.singularize}_ids".to_sym => [] }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def associated_collection(order = self.order)
|
|
15
|
+
Administrate::Page::Collection.new(associated_dashboard, order: order)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def attribute_key
|
|
19
|
+
permitted_attribute.keys.first
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def associated_resource_options
|
|
23
|
+
candidate_resources.map do |resource|
|
|
24
|
+
[display_candidate_resource(resource), resource.send(primary_key)]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def selected_options
|
|
29
|
+
return if data.empty?
|
|
30
|
+
|
|
31
|
+
data.map { |object| object.send(primary_key) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def limit
|
|
35
|
+
options.fetch(:limit, DEFAULT_LIMIT)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def permitted_attribute
|
|
39
|
+
self.class.permitted_attribute(attribute)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def resources(page = 1, order = self.order)
|
|
43
|
+
resources = order.apply(data).page(page).per(limit)
|
|
44
|
+
includes.any? ? resources.includes(*includes) : resources
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def more_than_limit?
|
|
48
|
+
data.count(:all) > limit
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def data
|
|
52
|
+
@data ||= associated_class.none
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def order_from_params(params)
|
|
56
|
+
Administrate::Order.new(
|
|
57
|
+
params.fetch(:order, sort_by),
|
|
58
|
+
params.fetch(:direction, direction),
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def order
|
|
63
|
+
@order ||= Administrate::Order.new(sort_by, direction)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def includes
|
|
69
|
+
associated_dashboard.collection_includes
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def candidate_resources
|
|
73
|
+
if options.key?(:includes)
|
|
74
|
+
includes = options.fetch(:includes)
|
|
75
|
+
associated_class.includes(*includes).all
|
|
76
|
+
else
|
|
77
|
+
associated_class.all
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def display_candidate_resource(resource)
|
|
82
|
+
associated_dashboard.display_resource(resource)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def sort_by
|
|
86
|
+
options[:sort_by]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def direction
|
|
90
|
+
options[:direction]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative "associative"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class HasOne < Associative
|
|
6
|
+
def self.permitted_attribute(attr, options = nil)
|
|
7
|
+
associated_class_name =
|
|
8
|
+
if options
|
|
9
|
+
options.fetch(:class_name, attr.to_s.singularize.camelcase)
|
|
10
|
+
else
|
|
11
|
+
attr
|
|
12
|
+
end
|
|
13
|
+
related_dashboard_attributes =
|
|
14
|
+
Administrate::ResourceResolver.new("admin/#{associated_class_name}").
|
|
15
|
+
dashboard_class.new.permitted_attributes + [:id]
|
|
16
|
+
|
|
17
|
+
{ "#{attr}_attributes": related_dashboard_attributes }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def nested_form
|
|
21
|
+
@nested_form ||= Administrate::Page::Form.new(
|
|
22
|
+
resolver.dashboard_class.new,
|
|
23
|
+
data || resolver.resource_class.new,
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def resolver
|
|
30
|
+
@resolver ||=
|
|
31
|
+
Administrate::ResourceResolver.new("admin/#{associated_class_name}")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class Number < Field::Base
|
|
6
|
+
def to_s
|
|
7
|
+
data.nil? ? "-" : format_string % value
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def format_string
|
|
13
|
+
prefix + "%.#{decimals}f" + suffix
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def prefix
|
|
17
|
+
options[:prefix].to_s
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def suffix
|
|
21
|
+
options[:suffix].to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def decimals
|
|
25
|
+
_left, right = data.to_s.split(".")
|
|
26
|
+
default = right.nil? ? 0 : right.size
|
|
27
|
+
options.fetch(:decimals, default)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def value
|
|
31
|
+
data * options.fetch(:multiplier, 1)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class Password < Field::Base
|
|
6
|
+
def self.searchable?
|
|
7
|
+
false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def truncate
|
|
11
|
+
data.to_s.gsub(/./, character)[0...truncation_length]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def truncation_length
|
|
17
|
+
options.fetch(:truncate, 50)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def character
|
|
21
|
+
options.fetch(:character, "•")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require_relative "associative"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class Polymorphic < BelongsTo
|
|
6
|
+
def self.permitted_attribute(attr, _options = nil)
|
|
7
|
+
{ attr => %i{type value} }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def associated_resource_grouped_options
|
|
11
|
+
classes.map do |klass|
|
|
12
|
+
[klass.to_s, candidate_resources_for(klass).map do |resource|
|
|
13
|
+
[display_candidate_resource(resource), resource.to_global_id]
|
|
14
|
+
end]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def permitted_attribute
|
|
19
|
+
{ attribute => %i{type value} }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def selected_global_id
|
|
23
|
+
data ? data.to_global_id : nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
def associated_dashboard(klass = data.class)
|
|
29
|
+
"#{klass.name}Dashboard".constantize.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def classes
|
|
33
|
+
options.fetch(:classes, [])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def order
|
|
39
|
+
@_order ||= options.delete(:order)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def candidate_resources_for(klass)
|
|
43
|
+
order ? klass.order(order) : klass.all
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def display_candidate_resource(resource)
|
|
47
|
+
associated_dashboard(resource.class).display_resource(resource)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class Select < Field::Base
|
|
6
|
+
def self.searchable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def selectable_options
|
|
11
|
+
collection
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def collection
|
|
17
|
+
maybe_proc = options.fetch(:collection, [])
|
|
18
|
+
return maybe_proc.call if maybe_proc.respond_to? :call
|
|
19
|
+
|
|
20
|
+
@collection ||= maybe_proc
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class String < Field::Base
|
|
6
|
+
def self.searchable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def truncate
|
|
11
|
+
data.to_s[0...truncation_length]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def truncation_length
|
|
17
|
+
options.fetch(:truncate, 50)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class Text < Administrate::Field::Base
|
|
6
|
+
def self.searchable?
|
|
7
|
+
false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def truncate
|
|
11
|
+
data.to_s[0...truncation_length]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def truncation_length
|
|
17
|
+
options.fetch(:truncate, 50)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Field
|
|
5
|
+
class Url < Field::Base
|
|
6
|
+
def self.searchable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def truncate
|
|
11
|
+
data.to_s[0...truncation_length]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def truncation_length
|
|
17
|
+
options.fetch(:truncate, 50)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Administrate
|
|
2
|
+
class Namespace
|
|
3
|
+
class Resource
|
|
4
|
+
attr_reader :namespace, :resource
|
|
5
|
+
|
|
6
|
+
def initialize(namespace, resource)
|
|
7
|
+
@namespace = namespace
|
|
8
|
+
@resource = resource
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_s
|
|
12
|
+
name.to_s
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_sym
|
|
16
|
+
name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name
|
|
20
|
+
resource.to_s.gsub(/^#{namespace}\//, "").to_sym
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def path
|
|
24
|
+
name.to_s.gsub("/", "_")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Administrate
|
|
2
|
+
class Namespace
|
|
3
|
+
def initialize(namespace)
|
|
4
|
+
@namespace = namespace
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def resources
|
|
8
|
+
@resources ||= routes.map(&:first).uniq.map do |path|
|
|
9
|
+
Resource.new(namespace, path)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def routes
|
|
14
|
+
@routes ||= all_routes.select do |controller, _action|
|
|
15
|
+
controller.starts_with?("#{namespace}/")
|
|
16
|
+
end.map do |controller, action|
|
|
17
|
+
[controller.gsub(/^#{namespace}\//, ""), action]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def resources_with_index_route
|
|
22
|
+
routes.select { |_resource, route| route == "index" }.map(&:first).uniq
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :namespace
|
|
28
|
+
|
|
29
|
+
def all_routes
|
|
30
|
+
Rails.application.routes.routes.map do |route|
|
|
31
|
+
route.defaults.values_at(:controller, :action).map(&:to_s)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module Administrate
|
|
2
|
+
class Order
|
|
3
|
+
def initialize(attribute = nil, direction = nil)
|
|
4
|
+
@attribute = attribute
|
|
5
|
+
@direction = sanitize_direction(direction)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def apply(relation)
|
|
9
|
+
return order_by_association(relation) unless
|
|
10
|
+
reflect_association(relation).nil?
|
|
11
|
+
|
|
12
|
+
order = "#{relation.table_name}.#{attribute} #{direction}"
|
|
13
|
+
|
|
14
|
+
return relation.reorder(Arel.sql(order)) if
|
|
15
|
+
relation.columns_hash.keys.include?(attribute.to_s)
|
|
16
|
+
|
|
17
|
+
relation
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ordered_by?(attr)
|
|
21
|
+
attr.to_s == attribute.to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def order_params_for(attr)
|
|
25
|
+
{
|
|
26
|
+
order: attr,
|
|
27
|
+
direction: reversed_direction_param_for(attr)
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
attr_reader :direction
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
attr_reader :attribute
|
|
36
|
+
|
|
37
|
+
def sanitize_direction(direction)
|
|
38
|
+
%w[asc desc].include?(direction.to_s) ? direction.to_sym : :asc
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def reversed_direction_param_for(attr)
|
|
42
|
+
if ordered_by?(attr)
|
|
43
|
+
opposite_direction
|
|
44
|
+
else
|
|
45
|
+
:asc
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def opposite_direction
|
|
50
|
+
direction == :asc ? :desc : :asc
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def order_by_association(relation)
|
|
54
|
+
return order_by_count(relation) if has_many_attribute?(relation)
|
|
55
|
+
|
|
56
|
+
return order_by_id(relation) if belongs_to_attribute?(relation)
|
|
57
|
+
|
|
58
|
+
relation
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def order_by_count(relation)
|
|
62
|
+
relation.
|
|
63
|
+
left_joins(attribute.to_sym).
|
|
64
|
+
group(:id).
|
|
65
|
+
reorder("COUNT(#{attribute}.id) #{direction}")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def order_by_id(relation)
|
|
69
|
+
relation.reorder("#{foreign_key(relation)} #{direction}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def has_many_attribute?(relation)
|
|
73
|
+
reflect_association(relation).macro == :has_many
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def belongs_to_attribute?(relation)
|
|
77
|
+
reflect_association(relation).macro == :belongs_to
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def reflect_association(relation)
|
|
81
|
+
relation.klass.reflect_on_association(attribute.to_s)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def foreign_key(relation)
|
|
85
|
+
reflect_association(relation).foreign_key
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Administrate
|
|
2
|
+
module Page
|
|
3
|
+
class Base
|
|
4
|
+
def initialize(dashboard, options = {})
|
|
5
|
+
@dashboard = dashboard
|
|
6
|
+
@options = options
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def resource_name
|
|
10
|
+
@resource_name ||=
|
|
11
|
+
dashboard.class.to_s.scan(/(.+)Dashboard/).first.first.underscore
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def resource_path
|
|
15
|
+
@resource_path ||= resource_name.gsub("/", "_")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def collection_includes
|
|
19
|
+
dashboard.try(:collection_includes) || []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def item_includes
|
|
23
|
+
dashboard.try(:item_includes) || []
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
def attribute_field(dashboard, resource, attribute_name, page)
|
|
29
|
+
value = get_attribute_value(resource, attribute_name)
|
|
30
|
+
field = dashboard.attribute_type_for(attribute_name)
|
|
31
|
+
field.new(attribute_name, value, page, resource: resource)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_attribute_value(resource, attribute_name)
|
|
35
|
+
resource.public_send(attribute_name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
attr_reader :dashboard, :options
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Page
|
|
5
|
+
class Collection < Page::Base
|
|
6
|
+
def attribute_names
|
|
7
|
+
dashboard.collection_attributes
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def attributes_for(resource)
|
|
11
|
+
attribute_names.map do |attr_name|
|
|
12
|
+
attribute_field(dashboard, resource, attr_name, :index)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def attribute_types
|
|
17
|
+
dashboard.attribute_types_for(attribute_names)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ordered_html_class(attr)
|
|
21
|
+
ordered_by?(attr) && order.direction
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
delegate :ordered_by?, to: :order
|
|
25
|
+
|
|
26
|
+
def order_params_for(attr, key: resource_name)
|
|
27
|
+
{ key => order.order_params_for(attr) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def order
|
|
33
|
+
options[:order] || Order.new
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Page
|
|
5
|
+
class Form < Page::Base
|
|
6
|
+
def initialize(dashboard, resource)
|
|
7
|
+
super(dashboard)
|
|
8
|
+
@resource = resource
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :resource
|
|
12
|
+
|
|
13
|
+
def attributes
|
|
14
|
+
dashboard.form_attributes.map do |attribute|
|
|
15
|
+
attribute_field(dashboard, resource, attribute, :form)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def page_title
|
|
20
|
+
dashboard.display_resource(resource)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
|
|
25
|
+
attr_reader :dashboard
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Administrate
|
|
4
|
+
module Page
|
|
5
|
+
class Show < Page::Base
|
|
6
|
+
def initialize(dashboard, resource)
|
|
7
|
+
super(dashboard)
|
|
8
|
+
@resource = resource
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :resource
|
|
12
|
+
|
|
13
|
+
def page_title
|
|
14
|
+
dashboard.display_resource(resource)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def attributes
|
|
18
|
+
dashboard.show_page_attributes.map do |attr_name|
|
|
19
|
+
attribute_field(dashboard, resource, attr_name, :show)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Administrate
|
|
2
|
+
class ResourceResolver
|
|
3
|
+
def initialize(controller_path)
|
|
4
|
+
@controller_path = controller_path
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def dashboard_class
|
|
8
|
+
ActiveSupport::Inflector.constantize("#{resource_class_name}Dashboard")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def namespace
|
|
12
|
+
controller_path.split("/").first
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def resource_class
|
|
16
|
+
ActiveSupport::Inflector.constantize(resource_class_name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def resource_name
|
|
20
|
+
model_path_parts.map(&:underscore).join("__").to_sym
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def resource_title
|
|
24
|
+
model_path_parts.join(" ")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def resource_class_name
|
|
30
|
+
model_path_parts.join("::")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def model_path_parts
|
|
34
|
+
controller_path_parts.map(&:camelize)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def controller_path_parts
|
|
38
|
+
controller_path.split("/")[1..-1].map(&:singularize)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
attr_reader :controller_path
|
|
42
|
+
end
|
|
43
|
+
end
|