trestle 0.8.6 → 0.8.7
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 +5 -5
- data/README.md +10 -9
- data/app/assets/javascripts/trestle/components/_dialog.js +29 -8
- data/app/assets/javascripts/trestle/components/_form.js +28 -7
- data/app/assets/javascripts/trestle/components/_sidebar.js +10 -8
- data/app/assets/javascripts/trestle/components/_tabs.js +2 -1
- data/app/assets/javascripts/trestle/components/_tooltips.js +16 -0
- data/app/assets/stylesheets/trestle/components/_modal.scss +4 -0
- data/app/assets/stylesheets/trestle/components/_navigation.scss +31 -11
- data/app/assets/stylesheets/trestle/components/_sidebar.scss +2 -2
- data/app/assets/stylesheets/trestle/components/_tags.scss +9 -0
- data/app/assets/stylesheets/trestle/components/_wells.scss +9 -1
- data/app/assets/stylesheets/trestle/core/_defaults.scss +4 -4
- data/app/assets/stylesheets/trestle/core/_layout.scss +8 -0
- data/app/assets/stylesheets/trestle/core/_typography.scss +39 -0
- data/app/controllers/concerns/trestle/controller/breadcrumbs.rb +21 -0
- data/app/controllers/concerns/trestle/controller/callbacks.rb +21 -0
- data/app/controllers/concerns/trestle/controller/dialog.rb +16 -0
- data/app/controllers/concerns/trestle/controller/helpers.rb +18 -0
- data/app/controllers/concerns/trestle/controller/layout.rb +16 -0
- data/app/controllers/concerns/trestle/controller/location.rb +15 -0
- data/app/controllers/trestle/application_controller.rb +6 -34
- data/app/helpers/trestle/debug_helper.rb +11 -0
- data/app/helpers/trestle/format_helper.rb +7 -3
- data/app/helpers/trestle/headings_helper.rb +27 -0
- data/app/helpers/trestle/panel_helper.rb +24 -0
- data/app/helpers/trestle/table_helper.rb +41 -2
- data/app/helpers/trestle/url_helper.rb +3 -1
- data/app/views/layouts/trestle/admin.html.erb +1 -1
- data/app/views/trestle/application/_flash.html.erb +1 -1
- data/app/views/trestle/shared/_sidebar.html.erb +2 -2
- data/app/views/trestle/table/_table.html.erb +2 -6
- data/lib/generators/trestle/resource/templates/admin.rb.erb +2 -2
- data/lib/trestle.rb +6 -4
- data/lib/trestle/adapters/active_record_adapter.rb +0 -4
- data/lib/trestle/adapters/adapter.rb +15 -10
- data/lib/trestle/adapters/sequel_adapter.rb +0 -4
- data/lib/trestle/admin.rb +18 -1
- data/lib/trestle/admin/builder.rb +22 -10
- data/lib/trestle/form/automatic.rb +5 -2
- data/lib/trestle/form/builder.rb +5 -1
- data/lib/trestle/form/field.rb +1 -1
- data/lib/trestle/form/fields/form_group.rb +3 -1
- data/lib/trestle/form/fields/select.rb +5 -1
- data/lib/trestle/form/fields/tag_select.rb +1 -1
- data/lib/trestle/form/renderer.rb +1 -1
- data/lib/trestle/navigation.rb +11 -5
- data/lib/trestle/navigation/item.rb +10 -0
- data/lib/trestle/resource.rb +27 -61
- data/lib/trestle/resource/builder.rb +15 -14
- data/lib/trestle/resource/collection.rb +48 -0
- data/lib/trestle/resource/controller.rb +36 -23
- data/lib/trestle/scope.rb +13 -3
- data/lib/trestle/table.rb +10 -4
- data/lib/trestle/table/column.rb +13 -2
- data/lib/trestle/table/row.rb +10 -0
- data/lib/trestle/version.rb +1 -1
- data/trestle.gemspec +1 -0
- data/vendor/assets/stylesheets/trestle/magnific-popup.scss +13 -1
- metadata +27 -4
- data/app/helpers/trestle/dialog_helper.rb +0 -7
data/lib/trestle/admin.rb
CHANGED
@@ -8,7 +8,6 @@ module Trestle
|
|
8
8
|
class << self
|
9
9
|
attr_accessor :menu
|
10
10
|
|
11
|
-
attr_accessor :table
|
12
11
|
attr_accessor :form
|
13
12
|
|
14
13
|
attr_accessor :additional_routes
|
@@ -20,6 +19,20 @@ module Trestle
|
|
20
19
|
@options ||= {}
|
21
20
|
end
|
22
21
|
|
22
|
+
def tables
|
23
|
+
@tables ||= {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# Deprecated: Use `tables[:index]` instead
|
27
|
+
def table
|
28
|
+
tables[:index]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Deprecated: Use `tables[:index]=` instead
|
32
|
+
def table=(table)
|
33
|
+
tables[:index] = table
|
34
|
+
end
|
35
|
+
|
23
36
|
def breadcrumbs
|
24
37
|
Breadcrumb::Trail.new(Array(Trestle.config.root_breadcrumbs) + [breadcrumb])
|
25
38
|
end
|
@@ -75,6 +88,10 @@ module Trestle
|
|
75
88
|
def railtie_routes_url_helpers(include_path_helpers=true)
|
76
89
|
Trestle.railtie_routes_url_helpers(include_path_helpers)
|
77
90
|
end
|
91
|
+
|
92
|
+
def build(&block)
|
93
|
+
Admin::Builder.build(self, &block)
|
94
|
+
end
|
78
95
|
end
|
79
96
|
end
|
80
97
|
end
|
@@ -11,23 +11,29 @@ module Trestle
|
|
11
11
|
|
12
12
|
delegate :helper, :before_action, :after_action, :around_action, to: :@controller
|
13
13
|
|
14
|
-
def initialize(
|
14
|
+
def initialize(admin)
|
15
|
+
@admin, @controller = admin, admin.const_get(:AdminController)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create(name, options={}, &block)
|
15
19
|
# Create admin subclass
|
16
|
-
|
17
|
-
|
20
|
+
admin = Class.new(admin_class)
|
21
|
+
admin.options = options
|
18
22
|
|
19
23
|
# Define a constant based on the admin name
|
20
24
|
scope = options[:scope] || Object
|
21
|
-
scope.const_set("#{name.to_s.camelize}Admin",
|
25
|
+
scope.const_set("#{name.to_s.camelize}Admin", admin)
|
22
26
|
|
23
27
|
# Define admin controller class
|
24
28
|
# This is done using class_eval rather than Class.new so that the full
|
25
29
|
# class name and parent chain is set when Rails' inherited hooks are called.
|
26
|
-
|
30
|
+
admin.class_eval("class AdminController < #{controller.name}; end")
|
27
31
|
|
28
32
|
# Set a reference on the controller class to the admin class
|
29
|
-
|
30
|
-
|
33
|
+
controller = admin.const_get(:AdminController)
|
34
|
+
controller.instance_variable_set("@admin", admin)
|
35
|
+
|
36
|
+
admin.build(&block)
|
31
37
|
end
|
32
38
|
|
33
39
|
def menu(*args, &block)
|
@@ -38,8 +44,14 @@ module Trestle
|
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
41
|
-
def table(options={}, &block)
|
42
|
-
|
47
|
+
def table(name_or_options={}, options={}, &block)
|
48
|
+
if name_or_options.is_a?(Hash)
|
49
|
+
name, options = :index, name_or_options.reverse_merge(admin: admin, sortable: true)
|
50
|
+
else
|
51
|
+
name = name_or_options
|
52
|
+
end
|
53
|
+
|
54
|
+
admin.tables[name] = Table::Builder.build(options, &block)
|
43
55
|
end
|
44
56
|
|
45
57
|
def form(options={}, &block)
|
@@ -47,7 +59,7 @@ module Trestle
|
|
47
59
|
end
|
48
60
|
|
49
61
|
def admin(&block)
|
50
|
-
@admin.
|
62
|
+
@admin.instance_eval(&block) if block_given?
|
51
63
|
@admin
|
52
64
|
end
|
53
65
|
|
@@ -13,8 +13,11 @@ module Trestle
|
|
13
13
|
when :association
|
14
14
|
if attribute.polymorphic?
|
15
15
|
static_field attribute.name do
|
16
|
-
associated_instance = instance.public_send(attribute.association_name)
|
17
|
-
|
16
|
+
if associated_instance = instance.public_send(attribute.association_name)
|
17
|
+
admin_link_to format_value(associated_instance), associated_instance
|
18
|
+
else
|
19
|
+
content_tag(:span, I18n.t("admin.format.blank"), class: "blank")
|
20
|
+
end
|
18
21
|
end
|
19
22
|
else
|
20
23
|
prompt = I18n.t("admin.form.select.prompt", default: "- Select %{attribute_name} -", attribute_name: admin.human_attribute_name(attribute.association_name))
|
data/lib/trestle/form/builder.rb
CHANGED
data/lib/trestle/form/field.rb
CHANGED
@@ -39,7 +39,7 @@ module Trestle
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def extract_options!
|
42
|
-
@wrapper = extract_wrapper_options(
|
42
|
+
@wrapper = extract_wrapper_options(*Fields::FormGroup::WRAPPER_OPTIONS).merge(options.delete(:wrapper))
|
43
43
|
end
|
44
44
|
|
45
45
|
private
|
@@ -2,10 +2,12 @@ module Trestle
|
|
2
2
|
class Form
|
3
3
|
module Fields
|
4
4
|
class FormGroup < Field
|
5
|
+
WRAPPER_OPTIONS = [:help, :label, :hide_label]
|
6
|
+
|
5
7
|
def render
|
6
8
|
options[:class] << 'has-error' if errors.any?
|
7
9
|
|
8
|
-
content_tag(:div, options) do
|
10
|
+
content_tag(:div, options.except(*WRAPPER_OPTIONS)) do
|
9
11
|
concat label unless options[:label] == false
|
10
12
|
concat block.call if block
|
11
13
|
concat help_message if options[:help]
|
@@ -7,7 +7,7 @@ module Trestle
|
|
7
7
|
def initialize(builder, template, name, choices=nil, options={}, html_options={}, &block)
|
8
8
|
super(builder, template, name, options, &block)
|
9
9
|
|
10
|
-
@choices = Choices.new(choices ||
|
10
|
+
@choices = Choices.new(choices || default_choices)
|
11
11
|
@html_options = default_html_options.merge(html_options)
|
12
12
|
end
|
13
13
|
|
@@ -19,6 +19,10 @@ module Trestle
|
|
19
19
|
Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
|
20
20
|
end
|
21
21
|
|
22
|
+
def default_choices
|
23
|
+
builder.object.send(name) if builder.object
|
24
|
+
end
|
25
|
+
|
22
26
|
# Allows an array of model instances (or a scope) to be
|
23
27
|
# passed to the select field as the list of choices.
|
24
28
|
class Choices
|
@@ -5,7 +5,7 @@ module Trestle
|
|
5
5
|
include ::ActionView::Helpers::CaptureHelper
|
6
6
|
|
7
7
|
# Whitelisted helpers will concatenate their result to the output buffer when called.
|
8
|
-
WHITELISTED_HELPERS = [:row, :col, :render, :tab, :toolbar, :table, :divider]
|
8
|
+
WHITELISTED_HELPERS = [:row, :col, :render, :tab, :toolbar, :table, :divider, :h1, :h2, :h3, :h4, :h5, :h6, :panel, :well]
|
9
9
|
|
10
10
|
# Raw block helpers will pass their block argument directly to the method
|
11
11
|
# without wrapping it in a new output buffer.
|
data/lib/trestle/navigation.rb
CHANGED
@@ -7,12 +7,10 @@ module Trestle
|
|
7
7
|
autoload :Group
|
8
8
|
autoload :NullGroup, "trestle/navigation/group"
|
9
9
|
|
10
|
-
|
11
|
-
@blocks = blocks
|
12
|
-
end
|
10
|
+
attr_reader :items
|
13
11
|
|
14
|
-
def items
|
15
|
-
@
|
12
|
+
def initialize(items)
|
13
|
+
@items = items
|
16
14
|
end
|
17
15
|
|
18
16
|
def by_group
|
@@ -28,6 +26,14 @@ module Trestle
|
|
28
26
|
sorted.first.first if sorted.any?
|
29
27
|
end
|
30
28
|
|
29
|
+
def visible(context)
|
30
|
+
self.class.new(items.select { |item| item.visible?(context) })
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.build(blocks)
|
34
|
+
new(blocks.map(&:items).flatten)
|
35
|
+
end
|
36
|
+
|
31
37
|
private
|
32
38
|
def stable_sort(items)
|
33
39
|
items.sort_by.with_index { |item, i| [item, i] }
|
@@ -55,6 +55,16 @@ module Trestle
|
|
55
55
|
Badge.new(options[:badge]) if badge?
|
56
56
|
end
|
57
57
|
|
58
|
+
def visible?(context)
|
59
|
+
if options[:if]
|
60
|
+
context.instance_exec(&options[:if])
|
61
|
+
elsif options[:unless]
|
62
|
+
!context.instance_exec(&options[:unless])
|
63
|
+
else
|
64
|
+
true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
58
68
|
class Badge
|
59
69
|
attr_reader :text
|
60
70
|
|
data/lib/trestle/resource.rb
CHANGED
@@ -3,11 +3,17 @@ module Trestle
|
|
3
3
|
extend ActiveSupport::Autoload
|
4
4
|
|
5
5
|
autoload :Builder
|
6
|
+
autoload :Collection
|
6
7
|
autoload :Controller
|
7
8
|
|
8
9
|
RESOURCE_ACTIONS = [:index, :show, :new, :create, :edit, :update, :destroy]
|
9
10
|
READONLY_ACTIONS = [:index, :show]
|
10
11
|
|
12
|
+
class_attribute :decorator
|
13
|
+
|
14
|
+
class_attribute :pagination_options
|
15
|
+
self.pagination_options = {}
|
16
|
+
|
11
17
|
class << self
|
12
18
|
def adapter
|
13
19
|
@adapter ||= Trestle.config.default_adapter.new(self)
|
@@ -20,10 +26,11 @@ module Trestle
|
|
20
26
|
# Defines a method that can be overridden with a custom block,
|
21
27
|
# but is otherwise delegated to the adapter instance.
|
22
28
|
def self.adapter_method(name)
|
23
|
-
|
29
|
+
block_method = :"#{name}_block"
|
30
|
+
attr_accessor block_method
|
24
31
|
|
25
32
|
define_method(name) do |*args|
|
26
|
-
if override =
|
33
|
+
if override = public_send(block_method)
|
27
34
|
instance_exec(*args, &override)
|
28
35
|
else
|
29
36
|
adapter.public_send(name, *args)
|
@@ -31,33 +38,33 @@ module Trestle
|
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
41
|
+
# Collection-focused adapter methods
|
34
42
|
adapter_method :collection
|
43
|
+
adapter_method :merge_scopes
|
44
|
+
adapter_method :sort
|
45
|
+
adapter_method :paginate
|
46
|
+
adapter_method :finalize_collection
|
47
|
+
adapter_method :decorate_collection
|
48
|
+
adapter_method :count
|
49
|
+
|
50
|
+
# Instance-focused adapter methods
|
35
51
|
adapter_method :find_instance
|
36
52
|
adapter_method :build_instance
|
37
53
|
adapter_method :update_instance
|
38
54
|
adapter_method :save_instance
|
39
55
|
adapter_method :delete_instance
|
40
|
-
adapter_method :to_param
|
41
56
|
adapter_method :permitted_params
|
42
|
-
|
43
|
-
|
44
|
-
adapter_method :
|
45
|
-
adapter_method :count
|
46
|
-
adapter_method :sort
|
47
|
-
adapter_method :paginate
|
57
|
+
|
58
|
+
# Common adapter methods
|
59
|
+
adapter_method :to_param
|
48
60
|
adapter_method :human_attribute_name
|
61
|
+
|
62
|
+
# Automatic tables and forms adapter methods
|
49
63
|
adapter_method :default_table_attributes
|
50
64
|
adapter_method :default_form_attributes
|
51
65
|
|
52
|
-
attr_accessor :decorator
|
53
|
-
|
54
66
|
def prepare_collection(params)
|
55
|
-
|
56
|
-
collection = apply_scopes(collection, params)
|
57
|
-
collection = apply_sorting(collection, params)
|
58
|
-
collection = paginate(collection, params)
|
59
|
-
collection = decorate_collection(collection)
|
60
|
-
collection
|
67
|
+
Collection.new(self).prepare(params)
|
61
68
|
end
|
62
69
|
|
63
70
|
def initialize_collection(params)
|
@@ -68,47 +75,10 @@ module Trestle
|
|
68
75
|
@scopes ||= {}
|
69
76
|
end
|
70
77
|
|
71
|
-
def apply_scopes(collection, params)
|
72
|
-
unscoped = unscope(collection)
|
73
|
-
|
74
|
-
scopes_for(params).each do |scope|
|
75
|
-
collection = merge_scopes(collection, scope.apply(unscoped))
|
76
|
-
end
|
77
|
-
|
78
|
-
collection
|
79
|
-
end
|
80
|
-
|
81
|
-
def scopes_for(params)
|
82
|
-
result = []
|
83
|
-
|
84
|
-
if params[:scope] && scopes.has_key?(params[:scope].to_sym)
|
85
|
-
result << scopes[params[:scope].to_sym]
|
86
|
-
end
|
87
|
-
|
88
|
-
if result.empty? && default_scope = scopes.values.find(&:default?)
|
89
|
-
result << default_scope
|
90
|
-
end
|
91
|
-
|
92
|
-
result
|
93
|
-
end
|
94
|
-
|
95
78
|
def column_sorts
|
96
79
|
@column_sorts ||= {}
|
97
80
|
end
|
98
81
|
|
99
|
-
def apply_sorting(collection, params)
|
100
|
-
return collection unless params[:sort]
|
101
|
-
|
102
|
-
field = params[:sort].to_sym
|
103
|
-
order = params[:order].to_s.downcase == "desc" ? :desc : :asc
|
104
|
-
|
105
|
-
if column_sorts.has_key?(field)
|
106
|
-
instance_exec(collection, order, &column_sorts[field])
|
107
|
-
else
|
108
|
-
sort(collection, field, order)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
82
|
def table
|
113
83
|
super || Table::Automatic.new(self)
|
114
84
|
end
|
@@ -148,15 +118,11 @@ module Trestle
|
|
148
118
|
end
|
149
119
|
|
150
120
|
def return_locations
|
151
|
-
@return_locations ||= {
|
152
|
-
create: Proc.new { |instance| path(:show, id: to_param(instance)) },
|
153
|
-
update: Proc.new { |instance| path(:show, id: to_param(instance)) },
|
154
|
-
destroy: Proc.new { path(:index) }
|
155
|
-
}
|
121
|
+
@return_locations ||= {}
|
156
122
|
end
|
157
123
|
|
158
|
-
def
|
159
|
-
|
124
|
+
def build(&block)
|
125
|
+
Resource::Builder.build(self, &block)
|
160
126
|
end
|
161
127
|
|
162
128
|
private
|
@@ -22,36 +22,36 @@ module Trestle
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def collection(&block)
|
25
|
-
admin.
|
25
|
+
admin.collection_block = block
|
26
26
|
end
|
27
27
|
|
28
28
|
def find_instance(&block)
|
29
|
-
admin.
|
29
|
+
admin.find_instance_block = block
|
30
30
|
end
|
31
31
|
alias instance find_instance
|
32
32
|
|
33
33
|
def build_instance(&block)
|
34
|
-
admin.
|
34
|
+
admin.build_instance_block = block
|
35
35
|
end
|
36
36
|
|
37
37
|
def update_instance(&block)
|
38
|
-
admin.
|
38
|
+
admin.update_instance_block = block
|
39
39
|
end
|
40
40
|
|
41
41
|
def save_instance(&block)
|
42
|
-
admin.
|
42
|
+
admin.save_instance_block = block
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete_instance(&block)
|
46
|
-
admin.
|
46
|
+
admin.delete_instance_block = block
|
47
47
|
end
|
48
48
|
|
49
49
|
def to_param(&block)
|
50
|
-
admin.
|
50
|
+
admin.to_param_block = block
|
51
51
|
end
|
52
52
|
|
53
53
|
def params(&block)
|
54
|
-
admin.
|
54
|
+
admin.permitted_params_block = block
|
55
55
|
end
|
56
56
|
|
57
57
|
def decorator(decorator)
|
@@ -59,27 +59,28 @@ module Trestle
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def decorate_collection(&block)
|
62
|
-
admin.
|
62
|
+
admin.decorate_collection_block = block
|
63
63
|
end
|
64
64
|
|
65
65
|
def merge_scopes(&block)
|
66
|
-
admin.
|
66
|
+
admin.merge_scopes_block = block
|
67
67
|
end
|
68
68
|
|
69
69
|
def sort(&block)
|
70
|
-
admin.
|
70
|
+
admin.sort_block = block
|
71
71
|
end
|
72
72
|
|
73
73
|
def sort_column(column, &block)
|
74
74
|
admin.column_sorts[column.to_sym] = block
|
75
75
|
end
|
76
76
|
|
77
|
-
def paginate(&block)
|
78
|
-
admin.
|
77
|
+
def paginate(options={}, &block)
|
78
|
+
admin.pagination_options = admin.pagination_options.merge(options)
|
79
|
+
admin.paginate_block = block
|
79
80
|
end
|
80
81
|
|
81
82
|
def count(&block)
|
82
|
-
admin.
|
83
|
+
admin.count_block = block
|
83
84
|
end
|
84
85
|
|
85
86
|
def scope(name, scope=nil, options={}, &block)
|