trestle 0.8.10 → 0.8.11
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 +4 -4
- data/README.md +5 -1
- data/app/assets/javascripts/trestle/components/_dialog.js +20 -16
- data/app/assets/stylesheets/trestle/components/_content.scss +12 -0
- data/app/assets/stylesheets/trestle/components/_fields.scss +17 -0
- data/app/assets/stylesheets/trestle/components/_modal.scss +9 -0
- data/app/assets/stylesheets/trestle/components/_pagination.scss +3 -0
- data/app/helpers/trestle/url_helper.rb +6 -0
- data/app/views/trestle/resource/_scopes.html.erb +1 -1
- data/app/views/trestle/table/_table.html.erb +2 -0
- data/lib/trestle/adapters/active_record_adapter.rb +2 -2
- data/lib/trestle/adapters/adapter.rb +23 -3
- data/lib/trestle/adapters/sequel_adapter.rb +2 -2
- data/lib/trestle/admin.rb +23 -0
- data/lib/trestle/admin/controller.rb +3 -1
- data/lib/trestle/form/fields/form_group.rb +10 -1
- data/lib/trestle/navigation.rb +13 -1
- data/lib/trestle/navigation/group.rb +8 -0
- data/lib/trestle/resource.rb +40 -55
- data/lib/trestle/resource/adapter_methods.rb +62 -0
- data/lib/trestle/resource/builder.rb +16 -16
- data/lib/trestle/resource/collection.rb +30 -10
- data/lib/trestle/resource/controller.rb +6 -14
- data/lib/trestle/table.rb +5 -1
- data/lib/trestle/table/column.rb +18 -0
- data/lib/trestle/table/row.rb +1 -1
- data/lib/trestle/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1640cda170a3f473968769e1c0380de2689ac11ecdd88c0b19bf93796701680
|
4
|
+
data.tar.gz: c3c78457d933155de6eba4bac6500a906e4fb78dce4232a68040ddeb2dfd919e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d597693a4f29721adb0a3b8e0b6d15679bef552b6d050b390940fcf53a28922f99cca9c993d1f9458d284786f5f4e29fbce2bef6bcc7891be639b53e7502ea83
|
7
|
+
data.tar.gz: ba5bd00f7a509ea1a349e57d52dd46e15f86c78d95fd0cabc755a82c5079155fcc9db8b405523378977119f274d171ff9e3ca0d5c128631a39f6a2fb72577afa
|
data/README.md
CHANGED
@@ -38,7 +38,11 @@ After restarting your Rails server, visit http://localhost:3000/admin to view yo
|
|
38
38
|
```ruby
|
39
39
|
Trestle.resource(:posts) do
|
40
40
|
# Add a link to this admin in the main navigation
|
41
|
-
menu
|
41
|
+
menu do
|
42
|
+
group :blog_management, priority: :first do
|
43
|
+
item :posts, icon: "fa fa-file-text-o"
|
44
|
+
end
|
45
|
+
end
|
42
46
|
|
43
47
|
# Define custom scopes for the index view
|
44
48
|
scope :all, default: true
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Trestle.Dialog = function(options) {
|
2
2
|
options = options || {};
|
3
3
|
|
4
|
-
this.el = Trestle.Dialog.
|
4
|
+
this.el = Trestle.Dialog.createElement();
|
5
5
|
|
6
6
|
if (options.modalClass) {
|
7
7
|
this.el.find('.modal-dialog').addClass(options.modalClass);
|
@@ -9,30 +9,31 @@ Trestle.Dialog = function(options) {
|
|
9
9
|
};
|
10
10
|
|
11
11
|
Trestle.Dialog.TEMPLATE =
|
12
|
-
'<div
|
12
|
+
'<div class="modal fade" tabindex="-1">' +
|
13
13
|
'<div class="modal-dialog">' +
|
14
14
|
'<div class="modal-content" data-context></div>' +
|
15
15
|
'</div>' +
|
16
16
|
'</div>';
|
17
17
|
|
18
|
-
Trestle.Dialog.
|
19
|
-
var el = $('
|
18
|
+
Trestle.Dialog.createElement = function() {
|
19
|
+
var el = $(Trestle.Dialog.TEMPLATE).appendTo('body');
|
20
20
|
|
21
|
-
|
22
|
-
el = $(Trestle.Dialog.TEMPLATE).appendTo('body');
|
21
|
+
el.modal({ show: false });
|
23
22
|
|
24
|
-
|
23
|
+
// Remove dialog elements once hidden
|
24
|
+
el.on('hidden.bs.modal', function() {
|
25
|
+
el.remove();
|
26
|
+
});
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
// Restore the next visible modal to the foreground
|
29
|
+
el.on('hide.bs.modal', function() {
|
30
|
+
el.prevAll('.modal.in').last().removeClass('background');
|
31
|
+
});
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
33
|
+
// Set X-Trestle-Dialog header on AJAX requests initiated from the dialog
|
34
|
+
el.on('ajax:beforeSend', '[data-remote]', function(e, xhr, options) {
|
35
|
+
xhr.setRequestHeader("X-Trestle-Dialog", true);
|
36
|
+
});
|
36
37
|
|
37
38
|
return el;
|
38
39
|
};
|
@@ -113,6 +114,9 @@ Trestle.Dialog.prototype.showError = function(title, content) {
|
|
113
114
|
|
114
115
|
Trestle.Dialog.prototype.show = function() {
|
115
116
|
this.el.modal('show');
|
117
|
+
|
118
|
+
// Background any existing visible modals
|
119
|
+
this.el.prevAll('.modal.in').addClass('background');
|
116
120
|
};
|
117
121
|
|
118
122
|
Trestle.Dialog.prototype.hide = function() {
|
@@ -53,6 +53,12 @@
|
|
53
53
|
min-width: 0;
|
54
54
|
}
|
55
55
|
|
56
|
+
.main-content-header,
|
57
|
+
.main-content-footer {
|
58
|
+
display: flex;
|
59
|
+
justify-content: space-between;
|
60
|
+
}
|
61
|
+
|
56
62
|
.main-content-header {
|
57
63
|
margin: -20px -20px 20px !important;
|
58
64
|
padding: $main-content-header-padding;
|
@@ -114,6 +120,12 @@
|
|
114
120
|
padding: 15px;
|
115
121
|
}
|
116
122
|
|
123
|
+
.main-content-header,
|
124
|
+
.main-content-footer {
|
125
|
+
flex-direction: column;
|
126
|
+
align-items: center;
|
127
|
+
}
|
128
|
+
|
117
129
|
.main-content-header {
|
118
130
|
margin: -15px -15px 15px !important;
|
119
131
|
padding-left: 15px;
|
@@ -1,3 +1,20 @@
|
|
1
|
+
.form-group {
|
2
|
+
position: relative;
|
3
|
+
}
|
4
|
+
|
5
|
+
.help-block {
|
6
|
+
font-size: 13px;
|
7
|
+
|
8
|
+
@media (min-width: $screen-sm-min) {
|
9
|
+
&.floating {
|
10
|
+
position: absolute;
|
11
|
+
top: 0;
|
12
|
+
right: 0;
|
13
|
+
margin: 2px 0;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
1
18
|
.select2-container--bootstrap {
|
2
19
|
// This is required to ensure the select field is rendered at full width
|
3
20
|
// within Bootstrap tabs that are hidden when the page is first loaded.
|
@@ -30,6 +30,9 @@ module Trestle
|
|
30
30
|
admin ||= self.admin if respond_to?(:admin)
|
31
31
|
|
32
32
|
if admin
|
33
|
+
# Ensure admin has controller context
|
34
|
+
admin = admin.new(self) if admin.is_a?(Class)
|
35
|
+
|
33
36
|
# Generate path
|
34
37
|
action = options.delete(:action) || :show
|
35
38
|
params = options.delete(:params) || {}
|
@@ -59,6 +62,9 @@ module Trestle
|
|
59
62
|
admin ||= admin_for(instance)
|
60
63
|
return unless admin
|
61
64
|
|
65
|
+
# Ensure admin has controller context
|
66
|
+
admin = admin.new(self) if admin.is_a?(Class)
|
67
|
+
|
62
68
|
if admin.respond_to?(:instance_path)
|
63
69
|
admin.instance_path(instance, options)
|
64
70
|
else
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<% admin.scopes.each do |name, scope| %>
|
3
3
|
<%= content_tag(:li, class: ("active" if scope.active?(params))) do %>
|
4
4
|
<%= link_to persistent_params.merge(scope: (name unless scope.active?(params))) do %>
|
5
|
-
<strong><%= scope.label %></strong> (<%= number_with_delimiter(scope.count(admin.
|
5
|
+
<strong><%= scope.label %></strong> (<%= number_with_delimiter(scope.count(admin.collection(params))) %>)
|
6
6
|
<% end %>
|
7
7
|
<% end %>
|
8
8
|
<% end %>
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
<div class="table-container">
|
4
4
|
<%= content_tag(:table, id: table.id, class: table.classes, data: table.data) do %>
|
5
|
+
<% if table.header? %>
|
5
6
|
<thead>
|
6
7
|
<tr>
|
7
8
|
<% table.columns.each do |column| %>
|
@@ -9,6 +10,7 @@
|
|
9
10
|
<% end %>
|
10
11
|
</tr>
|
11
12
|
</thead>
|
13
|
+
<% end %>
|
12
14
|
|
13
15
|
<tbody>
|
14
16
|
<% collection.each do |instance| %>
|
@@ -17,11 +17,11 @@ module Trestle
|
|
17
17
|
instance.assign_attributes(attrs)
|
18
18
|
end
|
19
19
|
|
20
|
-
def save_instance(instance)
|
20
|
+
def save_instance(instance, params={})
|
21
21
|
instance.save
|
22
22
|
end
|
23
23
|
|
24
|
-
def delete_instance(instance)
|
24
|
+
def delete_instance(instance, params={})
|
25
25
|
instance.destroy
|
26
26
|
end
|
27
27
|
|
@@ -4,8 +4,9 @@ module Trestle
|
|
4
4
|
attr_reader :admin
|
5
5
|
delegate :model, to: :admin
|
6
6
|
|
7
|
-
def initialize(admin)
|
7
|
+
def initialize(admin, context=nil)
|
8
8
|
@admin = admin
|
9
|
+
@context = context
|
9
10
|
end
|
10
11
|
|
11
12
|
# Loads the initial collection for use by the index action.
|
@@ -46,18 +47,20 @@ module Trestle
|
|
46
47
|
# Saves an instance (used by the create and update actions).
|
47
48
|
#
|
48
49
|
# instance - The instance to save
|
50
|
+
# params - Unfiltered params hash from the controller
|
49
51
|
#
|
50
52
|
# Returns a boolean indicating the success/fail status of the save.
|
51
|
-
def save_instance(instance)
|
53
|
+
def save_instance(instance, params={})
|
52
54
|
raise NotImplementedError
|
53
55
|
end
|
54
56
|
|
55
57
|
# Deletes an instance (used by the destroy action).
|
56
58
|
#
|
57
59
|
# instance - The instance to delete
|
60
|
+
# params - Unfiltered params hash from the controller
|
58
61
|
#
|
59
62
|
# Returns a boolean indicating the success/fail status of the deletion.
|
60
|
-
def delete_instance(instance)
|
63
|
+
def delete_instance(instance, params={})
|
61
64
|
raise NotImplementedError
|
62
65
|
end
|
63
66
|
|
@@ -176,6 +179,23 @@ module Trestle
|
|
176
179
|
def default_form_attributes
|
177
180
|
raise NotImplementedError
|
178
181
|
end
|
182
|
+
|
183
|
+
protected
|
184
|
+
# Missing methods are called on the given context if available.
|
185
|
+
#
|
186
|
+
# We include private methods as methods such as current_user
|
187
|
+
# are usually declared as private or protected.
|
188
|
+
def method_missing(name, *args, &block)
|
189
|
+
if @context && @context.respond_to?(name, true)
|
190
|
+
@context.send(name, *args, &block)
|
191
|
+
else
|
192
|
+
super
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def respond_to_missing?(name, include_private=false)
|
197
|
+
(@context && @context.respond_to?(name, true)) || super
|
198
|
+
end
|
179
199
|
end
|
180
200
|
end
|
181
201
|
end
|
@@ -26,11 +26,11 @@ module Trestle
|
|
26
26
|
instance.set(attrs)
|
27
27
|
end
|
28
28
|
|
29
|
-
def save_instance(instance)
|
29
|
+
def save_instance(instance, params={})
|
30
30
|
instance.save
|
31
31
|
end
|
32
32
|
|
33
|
-
def delete_instance(instance)
|
33
|
+
def delete_instance(instance, params={})
|
34
34
|
instance.destroy
|
35
35
|
end
|
36
36
|
|
data/lib/trestle/admin.rb
CHANGED
@@ -5,6 +5,25 @@ module Trestle
|
|
5
5
|
autoload :Builder
|
6
6
|
autoload :Controller
|
7
7
|
|
8
|
+
delegate :to_param, to: :class
|
9
|
+
|
10
|
+
def initialize(context=nil)
|
11
|
+
@context = context
|
12
|
+
end
|
13
|
+
|
14
|
+
# Delegate all missing methods to corresponding class method if available
|
15
|
+
def method_missing(name, *args, &block)
|
16
|
+
if self.class.respond_to?(name)
|
17
|
+
self.class.send(name, *args, &block)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(name, include_private=false)
|
24
|
+
self.class.respond_to?(name, include_private) || super
|
25
|
+
end
|
26
|
+
|
8
27
|
class << self
|
9
28
|
attr_accessor :menu
|
10
29
|
|
@@ -89,6 +108,10 @@ module Trestle
|
|
89
108
|
Engine.routes.url_for(options.merge(controller: controller_namespace, action: action, only_path: true))
|
90
109
|
end
|
91
110
|
|
111
|
+
def to_param(*)
|
112
|
+
raise NoMethodError, "#to_param called on non-resourceful admin. You may need to explicitly specify the admin."
|
113
|
+
end
|
114
|
+
|
92
115
|
def actions
|
93
116
|
[:index]
|
94
117
|
end
|
@@ -16,7 +16,16 @@ module Trestle
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def help_message
|
19
|
-
|
19
|
+
classes = ["help-block"]
|
20
|
+
|
21
|
+
if options[:help].is_a?(Hash)
|
22
|
+
message = options[:help][:text]
|
23
|
+
classes << "floating" if options[:help][:float]
|
24
|
+
else
|
25
|
+
message = options[:help]
|
26
|
+
end
|
27
|
+
|
28
|
+
content_tag(:p, message, class: classes)
|
20
29
|
end
|
21
30
|
|
22
31
|
def error_message
|
data/lib/trestle/navigation.rb
CHANGED
@@ -14,7 +14,10 @@ module Trestle
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def by_group
|
17
|
-
|
17
|
+
sorted_groups = stable_sort(items.group_by { |item| groups[item.group.id] })
|
18
|
+
sorted_items = sorted_groups.map { |group, items| [group, stable_sort(items)] }
|
19
|
+
|
20
|
+
Hash[sorted_items]
|
18
21
|
end
|
19
22
|
|
20
23
|
def each(&block)
|
@@ -38,5 +41,14 @@ module Trestle
|
|
38
41
|
def stable_sort(items)
|
39
42
|
items.sort_by.with_index { |item, i| [item, i] }
|
40
43
|
end
|
44
|
+
|
45
|
+
def groups
|
46
|
+
@groups ||= items.inject({}) { |groups, item|
|
47
|
+
group = groups[item.group.id]
|
48
|
+
|
49
|
+
groups[item.group.id] = group ? group.merge(item.group) : item.group
|
50
|
+
groups
|
51
|
+
}
|
52
|
+
end
|
41
53
|
end
|
42
54
|
end
|
@@ -26,6 +26,10 @@ module Trestle
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
def merge(other)
|
30
|
+
self.class.new(name, options.merge(other.options))
|
31
|
+
end
|
32
|
+
|
29
33
|
def priority
|
30
34
|
case options[:priority]
|
31
35
|
when :first
|
@@ -70,6 +74,10 @@ module Trestle
|
|
70
74
|
def <=>(other)
|
71
75
|
-1
|
72
76
|
end
|
77
|
+
|
78
|
+
def merge(other)
|
79
|
+
self
|
80
|
+
end
|
73
81
|
end
|
74
82
|
end
|
75
83
|
end
|
data/lib/trestle/resource.rb
CHANGED
@@ -2,10 +2,13 @@ module Trestle
|
|
2
2
|
class Resource < Admin
|
3
3
|
extend ActiveSupport::Autoload
|
4
4
|
|
5
|
+
autoload :AdapterMethods
|
5
6
|
autoload :Builder
|
6
7
|
autoload :Collection
|
7
8
|
autoload :Controller
|
8
9
|
|
10
|
+
include AdapterMethods
|
11
|
+
|
9
12
|
RESOURCE_ACTIONS = [:index, :show, :new, :create, :edit, :update, :destroy]
|
10
13
|
READONLY_ACTIONS = [:index, :show]
|
11
14
|
|
@@ -14,61 +17,43 @@ module Trestle
|
|
14
17
|
class_attribute :pagination_options
|
15
18
|
self.pagination_options = {}
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# Instance-focused adapter methods
|
51
|
-
adapter_method :find_instance
|
52
|
-
adapter_method :build_instance
|
53
|
-
adapter_method :update_instance
|
54
|
-
adapter_method :save_instance
|
55
|
-
adapter_method :delete_instance
|
56
|
-
adapter_method :permitted_params
|
57
|
-
|
58
|
-
# Common adapter methods
|
59
|
-
adapter_method :to_param
|
60
|
-
adapter_method :human_attribute_name
|
61
|
-
|
62
|
-
# Automatic tables and forms adapter methods
|
63
|
-
adapter_method :default_table_attributes
|
64
|
-
adapter_method :default_form_attributes
|
65
|
-
|
66
|
-
def prepare_collection(params)
|
67
|
-
Collection.new(self).prepare(params)
|
68
|
-
end
|
20
|
+
# Collection-focused adapter methods
|
21
|
+
adapter_method :collection
|
22
|
+
adapter_method :merge_scopes
|
23
|
+
adapter_method :sort
|
24
|
+
adapter_method :paginate
|
25
|
+
adapter_method :finalize_collection
|
26
|
+
adapter_method :decorate_collection
|
27
|
+
adapter_method :count
|
28
|
+
|
29
|
+
# Instance-focused adapter methods
|
30
|
+
adapter_method :find_instance
|
31
|
+
adapter_method :build_instance
|
32
|
+
adapter_method :update_instance
|
33
|
+
adapter_method :save_instance
|
34
|
+
adapter_method :delete_instance
|
35
|
+
adapter_method :permitted_params
|
36
|
+
|
37
|
+
# Common adapter methods
|
38
|
+
adapter_method :to_param
|
39
|
+
adapter_method :human_attribute_name
|
40
|
+
|
41
|
+
# Automatic tables and forms adapter methods
|
42
|
+
adapter_method :default_table_attributes
|
43
|
+
adapter_method :default_form_attributes
|
44
|
+
|
45
|
+
# Prepares a collection for use in the resource controller's index action.
|
46
|
+
#
|
47
|
+
# Applies scopes, sorts, pagination, finalization and decorators according
|
48
|
+
# to the admin's adapter and any admin-specific adapter methods.
|
49
|
+
def prepare_collection(params, options={})
|
50
|
+
Collection.new(self, options).prepare(params)
|
51
|
+
end
|
69
52
|
|
70
|
-
|
71
|
-
|
53
|
+
class << self
|
54
|
+
# Deprecated: use instance method instead
|
55
|
+
def prepare_collection(params, options={})
|
56
|
+
Collection.new(self, options).prepare(params)
|
72
57
|
end
|
73
58
|
|
74
59
|
def scopes
|
@@ -155,7 +140,7 @@ module Trestle
|
|
155
140
|
end
|
156
141
|
|
157
142
|
def validate!
|
158
|
-
if singular? &&
|
143
|
+
if singular? && !adapter_methods.method_defined?(:find_instance)
|
159
144
|
raise NotImplementedError, "Singular resources must define an instance block."
|
160
145
|
end
|
161
146
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Trestle
|
2
|
+
class Resource
|
3
|
+
module AdapterMethods
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Adapter instance bound to the current resource's context.
|
7
|
+
def adapter
|
8
|
+
@adapter ||= adapter_class.new(self, @context)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
# Declares a method that is handled by the admin's adapter class.
|
13
|
+
def adapter_method(name)
|
14
|
+
delegate name, to: :adapter
|
15
|
+
|
16
|
+
singleton_class.class_eval do
|
17
|
+
delegate name, to: :adapter
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Defines an admin-specific adapter method.
|
22
|
+
#
|
23
|
+
# The given block is wrapped rather than passed to #define_method directly, so that
|
24
|
+
# adapter methods can be defined with incomplete block parameters. Unfortunately
|
25
|
+
# this means we lose the ability to call super from within a custom adapter method.
|
26
|
+
def define_adapter_method(name, &block)
|
27
|
+
return unless block_given?
|
28
|
+
|
29
|
+
adapter_methods.module_eval do
|
30
|
+
define_method(name) do |*args|
|
31
|
+
instance_exec(*args, &block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the adapter class for this admin.
|
37
|
+
#
|
38
|
+
# Defaults to a subclass of `Trestle.config.default_adapter` with
|
39
|
+
# the admin-specific adapter methods module included.
|
40
|
+
def adapter_class
|
41
|
+
@adapter_class ||= Class.new(Trestle.config.default_adapter).include(adapter_methods)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets an explicit adapter class for this admin.
|
45
|
+
# A subclass is created with the admin-specific adapter methods module included.
|
46
|
+
def adapter_class=(klass)
|
47
|
+
@adapter_class = Class.new(klass).include(adapter_methods)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Module container for admin-specific adapter methods.
|
51
|
+
def adapter_methods
|
52
|
+
@adapter_methods ||= Module.new
|
53
|
+
end
|
54
|
+
|
55
|
+
# Unbound instance of adapter.
|
56
|
+
def adapter
|
57
|
+
@adapter ||= adapter_class.new(self)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -5,13 +5,13 @@ module Trestle
|
|
5
5
|
self.controller = Controller
|
6
6
|
|
7
7
|
def adapter(&block)
|
8
|
-
klass = admin.
|
9
|
-
klass.
|
8
|
+
klass = admin.adapter_class
|
9
|
+
klass.class_eval(&block) if block_given?
|
10
10
|
klass
|
11
11
|
end
|
12
12
|
|
13
13
|
def adapter=(adapter)
|
14
|
-
admin.
|
14
|
+
admin.adapter_class = adapter
|
15
15
|
end
|
16
16
|
|
17
17
|
def remove_action(*actions)
|
@@ -22,36 +22,36 @@ module Trestle
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def collection(&block)
|
25
|
-
admin.
|
25
|
+
admin.define_adapter_method(:collection, &block)
|
26
26
|
end
|
27
27
|
|
28
28
|
def find_instance(&block)
|
29
|
-
admin.
|
29
|
+
admin.define_adapter_method(:find_instance, &block)
|
30
30
|
end
|
31
31
|
alias instance find_instance
|
32
32
|
|
33
33
|
def build_instance(&block)
|
34
|
-
admin.
|
34
|
+
admin.define_adapter_method(:build_instance, &block)
|
35
35
|
end
|
36
36
|
|
37
37
|
def update_instance(&block)
|
38
|
-
admin.
|
38
|
+
admin.define_adapter_method(:update_instance, &block)
|
39
39
|
end
|
40
40
|
|
41
41
|
def save_instance(&block)
|
42
|
-
admin.
|
42
|
+
admin.define_adapter_method(:save_instance, &block)
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete_instance(&block)
|
46
|
-
admin.
|
46
|
+
admin.define_adapter_method(:delete_instance, &block)
|
47
47
|
end
|
48
48
|
|
49
49
|
def to_param(&block)
|
50
|
-
admin.
|
50
|
+
admin.define_adapter_method(:to_param, &block)
|
51
51
|
end
|
52
52
|
|
53
53
|
def params(&block)
|
54
|
-
admin.
|
54
|
+
admin.define_adapter_method(:permitted_params, &block)
|
55
55
|
end
|
56
56
|
|
57
57
|
def decorator(decorator)
|
@@ -59,15 +59,15 @@ module Trestle
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def decorate_collection(&block)
|
62
|
-
admin.
|
62
|
+
admin.define_adapter_method(:decorate_collection, &block)
|
63
63
|
end
|
64
64
|
|
65
65
|
def merge_scopes(&block)
|
66
|
-
admin.
|
66
|
+
admin.define_adapter_method(:merge_scopes, &block)
|
67
67
|
end
|
68
68
|
|
69
69
|
def sort(&block)
|
70
|
-
admin.
|
70
|
+
admin.define_adapter_method(:sort, &block)
|
71
71
|
end
|
72
72
|
|
73
73
|
def sort_column(column, &block)
|
@@ -76,11 +76,11 @@ module Trestle
|
|
76
76
|
|
77
77
|
def paginate(options={}, &block)
|
78
78
|
admin.pagination_options = admin.pagination_options.merge(options)
|
79
|
-
admin.
|
79
|
+
admin.define_adapter_method(:paginate, &block)
|
80
80
|
end
|
81
81
|
|
82
82
|
def count(&block)
|
83
|
-
admin.
|
83
|
+
admin.define_adapter_method(:count, &block)
|
84
84
|
end
|
85
85
|
|
86
86
|
def scope(name, scope=nil, options={}, &block)
|
@@ -1,26 +1,46 @@
|
|
1
1
|
module Trestle
|
2
2
|
class Resource
|
3
3
|
class Collection
|
4
|
-
delegate :
|
4
|
+
delegate :collection, :paginate, :finalize_collection, :decorate_collection,
|
5
5
|
:scopes, :merge_scopes, :column_sorts, :sort, to: :@admin
|
6
6
|
|
7
|
-
def initialize(admin)
|
8
|
-
@admin = admin
|
7
|
+
def initialize(admin, options={})
|
8
|
+
@admin, @options = admin, options
|
9
9
|
end
|
10
10
|
|
11
11
|
def prepare(params)
|
12
|
-
collection =
|
13
|
-
collection = apply_scopes(collection, params)
|
14
|
-
collection = apply_sorting(collection, params)
|
15
|
-
collection = paginate(collection, params)
|
16
|
-
collection = finalize_collection(collection)
|
17
|
-
collection = decorate_collection(collection)
|
12
|
+
collection = collection(params)
|
13
|
+
collection = apply_scopes(collection, params) if scope?
|
14
|
+
collection = apply_sorting(collection, params) if sort?
|
15
|
+
collection = paginate(collection, params) if paginate?
|
16
|
+
collection = finalize_collection(collection) if finalize?
|
17
|
+
collection = decorate_collection(collection) if decorate?
|
18
18
|
collection
|
19
19
|
end
|
20
20
|
|
21
|
+
def scope?
|
22
|
+
@options[:scope] != false
|
23
|
+
end
|
24
|
+
|
25
|
+
def sort?
|
26
|
+
@options[:sort] != false
|
27
|
+
end
|
28
|
+
|
29
|
+
def paginate?
|
30
|
+
@options[:paginate] != false
|
31
|
+
end
|
32
|
+
|
33
|
+
def finalize?
|
34
|
+
@options[:finalize] != false
|
35
|
+
end
|
36
|
+
|
37
|
+
def decorate?
|
38
|
+
@options[:decorate] != false
|
39
|
+
end
|
40
|
+
|
21
41
|
private
|
22
42
|
def apply_scopes(collection, params)
|
23
|
-
unscoped =
|
43
|
+
unscoped = collection(params)
|
24
44
|
|
25
45
|
active_scopes(params).reduce(collection) do |collection, scope|
|
26
46
|
merge_scopes(collection, scope.apply(unscoped))
|
@@ -13,7 +13,7 @@ module Trestle
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def new
|
16
|
-
self.instance = admin.build_instance(params.key?(admin.parameter_name) ? permitted_params : {}, params)
|
16
|
+
self.instance = admin.build_instance(params.key?(admin.parameter_name) ? admin.permitted_params(params) : {}, params)
|
17
17
|
|
18
18
|
respond_to do |format|
|
19
19
|
format.html
|
@@ -23,9 +23,9 @@ module Trestle
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def create
|
26
|
-
self.instance = admin.build_instance(permitted_params, params)
|
26
|
+
self.instance = admin.build_instance(admin.permitted_params(params), params)
|
27
27
|
|
28
|
-
if admin.save_instance(instance)
|
28
|
+
if admin.save_instance(instance, params)
|
29
29
|
respond_to do |format|
|
30
30
|
format.html do
|
31
31
|
flash[:message] = flash_message("create.success", title: "Success!", message: "The %{lowercase_model_name} was successfully created.")
|
@@ -66,9 +66,9 @@ module Trestle
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def update
|
69
|
-
admin.update_instance(instance, permitted_params, params)
|
69
|
+
admin.update_instance(instance, admin.permitted_params(params), params)
|
70
70
|
|
71
|
-
if admin.save_instance(instance)
|
71
|
+
if admin.save_instance(instance, params)
|
72
72
|
respond_to do |format|
|
73
73
|
format.html do
|
74
74
|
flash[:message] = flash_message("update.success", title: "Success!", message: "The %{lowercase_model_name} was successfully updated.")
|
@@ -90,7 +90,7 @@ module Trestle
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def destroy
|
93
|
-
success = admin.delete_instance(instance)
|
93
|
+
success = admin.delete_instance(instance, params)
|
94
94
|
|
95
95
|
respond_to do |format|
|
96
96
|
format.html do
|
@@ -131,14 +131,6 @@ module Trestle
|
|
131
131
|
}
|
132
132
|
end
|
133
133
|
|
134
|
-
def permitted_params
|
135
|
-
if admin.permitted_params_block
|
136
|
-
instance_exec(params, &admin.permitted_params_block)
|
137
|
-
else
|
138
|
-
admin.permitted_params(params)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
134
|
def redirect_to_return_location(action, instance, default:)
|
143
135
|
if admin.return_locations[action] && !dialog_request?
|
144
136
|
location = instance_exec(instance, &admin.return_locations[action])
|
data/lib/trestle/table.rb
CHANGED
@@ -29,6 +29,10 @@ module Trestle
|
|
29
29
|
options[:autolink] != false
|
30
30
|
end
|
31
31
|
|
32
|
+
def header?
|
33
|
+
options[:header] != false
|
34
|
+
end
|
35
|
+
|
32
36
|
def renderer(template)
|
33
37
|
Renderer.new(self, template)
|
34
38
|
end
|
@@ -38,7 +42,7 @@ module Trestle
|
|
38
42
|
end
|
39
43
|
|
40
44
|
class Renderer
|
41
|
-
delegate :options, to: :@table
|
45
|
+
delegate :options, :header?, to: :@table
|
42
46
|
|
43
47
|
def initialize(table, template)
|
44
48
|
@table, @template = table, template
|
data/lib/trestle/table/column.rb
CHANGED
@@ -49,6 +49,24 @@ module Trestle
|
|
49
49
|
@template.content_tag(:td, content(instance), class: classes, data: data)
|
50
50
|
end
|
51
51
|
|
52
|
+
def render?
|
53
|
+
if options.key?(:if)
|
54
|
+
if options[:if].respond_to?(:call)
|
55
|
+
@template.instance_exec(&options[:if])
|
56
|
+
else
|
57
|
+
options[:if]
|
58
|
+
end
|
59
|
+
elsif options.key?(:unless)
|
60
|
+
if options[:unless].respond_to?(:call)
|
61
|
+
!@template.instance_exec(&options[:unless])
|
62
|
+
else
|
63
|
+
!options[:unless]
|
64
|
+
end
|
65
|
+
else
|
66
|
+
true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
52
70
|
def header
|
53
71
|
return if options.key?(:header) && options[:header].in?([nil, false])
|
54
72
|
|
data/lib/trestle/table/row.rb
CHANGED
data/lib/trestle/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trestle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Pohlenz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -408,6 +408,7 @@ files:
|
|
408
408
|
- lib/trestle/options.rb
|
409
409
|
- lib/trestle/reloader.rb
|
410
410
|
- lib/trestle/resource.rb
|
411
|
+
- lib/trestle/resource/adapter_methods.rb
|
411
412
|
- lib/trestle/resource/builder.rb
|
412
413
|
- lib/trestle/resource/collection.rb
|
413
414
|
- lib/trestle/resource/controller.rb
|