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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 499a6802f0891311253e5a4999b494715ccdfa8d070bae35827268044fc5a7f8
4
- data.tar.gz: 5ac6a1b33a8b33ae636a7c948adc42d73212f6fba90b7ea71953a69b961f4723
3
+ metadata.gz: c1640cda170a3f473968769e1c0380de2689ac11ecdd88c0b19bf93796701680
4
+ data.tar.gz: c3c78457d933155de6eba4bac6500a906e4fb78dce4232a68040ddeb2dfd919e
5
5
  SHA512:
6
- metadata.gz: aef9565030e42e5fe42dd0a0773c65b1eb35a41c743678a1799ae57df99e438f7d61c3cb74b905171ff844134176f9a1c95a21ff917e6e25e072b494d1d776bb
7
- data.tar.gz: 4971e16e2e693081c8ed4d20a53bf4ce980261e66c0370c208356eadd41877f411290a8c81f5e0e5a796e5cfa70ff17a2cb5ab7b5b74848e658806d99cb89646
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 :posts, icon: "fa fa-file-text-o", group: :blog_management
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.getElement();
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 id="dialog" class="modal fade" tabindex="-1">' +
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.getElement = function() {
19
- var el = $('#dialog');
18
+ Trestle.Dialog.createElement = function() {
19
+ var el = $(Trestle.Dialog.TEMPLATE).appendTo('body');
20
20
 
21
- if (el.length == 0) {
22
- el = $(Trestle.Dialog.TEMPLATE).appendTo('body');
21
+ el.modal({ show: false });
23
22
 
24
- el.modal({ show: false });
23
+ // Remove dialog elements once hidden
24
+ el.on('hidden.bs.modal', function() {
25
+ el.remove();
26
+ });
25
27
 
26
- // Remove dialog elements once hidden
27
- el.on('hidden.bs.modal', function() {
28
- el.remove();
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
- // Set X-Trestle-Dialog header on AJAX requests initiated from the dialog
32
- el.on('ajax:beforeSend', '[data-remote]', function(e, xhr, options) {
33
- xhr.setRequestHeader("X-Trestle-Dialog", true);
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.
@@ -1,3 +1,12 @@
1
+ .modal {
2
+ &.background {
3
+ .modal-dialog {
4
+ transform: scale(0.9);
5
+ opacity: 0.75;
6
+ }
7
+ }
8
+ }
9
+
1
10
  .modal-content {
2
11
  border: none;
3
12
  border-radius: 0;
@@ -1,4 +1,5 @@
1
1
  .pagination-container {
2
+ margin-left: auto;
2
3
  text-align: right;
3
4
 
4
5
  p {
@@ -24,6 +25,8 @@
24
25
 
25
26
  @include mobile {
26
27
  .pagination-container {
28
+ margin-right: auto;
29
+
27
30
  text-align: center;
28
31
 
29
32
  display: flex;
@@ -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.initialize_collection(params))) %>)
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
 
@@ -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
@@ -12,7 +12,9 @@ module Trestle
12
12
  end
13
13
  end
14
14
 
15
- delegate :admin, to: :class
15
+ def admin
16
+ @_admin ||= self.class.admin.new(self)
17
+ end
16
18
  helper_method :admin
17
19
 
18
20
  protected
@@ -16,7 +16,16 @@ module Trestle
16
16
  end
17
17
 
18
18
  def help_message
19
- content_tag(:p, options[:help], class: "help-block")
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
@@ -14,7 +14,10 @@ module Trestle
14
14
  end
15
15
 
16
16
  def by_group
17
- Hash[stable_sort(items.group_by(&:group)).map { |group, items| [group, stable_sort(items)] }]
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
@@ -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
- class << self
18
- def adapter
19
- @adapter ||= Trestle.config.default_adapter.new(self)
20
- end
21
-
22
- def adapter=(klass)
23
- @adapter = klass.new(self)
24
- end
25
-
26
- # Defines a method that can be overridden with a custom block,
27
- # but is otherwise delegated to the adapter instance.
28
- def self.adapter_method(name)
29
- block_method = :"#{name}_block"
30
- attr_accessor block_method
31
-
32
- define_method(name) do |*args|
33
- if override = public_send(block_method)
34
- instance_exec(*args, &override)
35
- else
36
- adapter.public_send(name, *args)
37
- end
38
- end
39
- end
40
-
41
- # Collection-focused adapter methods
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
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
- def initialize_collection(params)
71
- collection(params)
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? && find_instance_block.nil?
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.adapter
9
- klass.instance_eval(&block) if block_given?
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.adapter = adapter
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.collection_block = block
25
+ admin.define_adapter_method(:collection, &block)
26
26
  end
27
27
 
28
28
  def find_instance(&block)
29
- admin.find_instance_block = block
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.build_instance_block = block
34
+ admin.define_adapter_method(:build_instance, &block)
35
35
  end
36
36
 
37
37
  def update_instance(&block)
38
- admin.update_instance_block = block
38
+ admin.define_adapter_method(:update_instance, &block)
39
39
  end
40
40
 
41
41
  def save_instance(&block)
42
- admin.save_instance_block = block
42
+ admin.define_adapter_method(:save_instance, &block)
43
43
  end
44
44
 
45
45
  def delete_instance(&block)
46
- admin.delete_instance_block = block
46
+ admin.define_adapter_method(:delete_instance, &block)
47
47
  end
48
48
 
49
49
  def to_param(&block)
50
- admin.to_param_block = block
50
+ admin.define_adapter_method(:to_param, &block)
51
51
  end
52
52
 
53
53
  def params(&block)
54
- admin.permitted_params_block = block
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.decorate_collection_block = block
62
+ admin.define_adapter_method(:decorate_collection, &block)
63
63
  end
64
64
 
65
65
  def merge_scopes(&block)
66
- admin.merge_scopes_block = block
66
+ admin.define_adapter_method(:merge_scopes, &block)
67
67
  end
68
68
 
69
69
  def sort(&block)
70
- admin.sort_block = block
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.paginate_block = block
79
+ admin.define_adapter_method(:paginate, &block)
80
80
  end
81
81
 
82
82
  def count(&block)
83
- admin.count_block = block
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 :initialize_collection, :paginate, :finalize_collection, :decorate_collection,
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 = initialize_collection(params)
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 = initialize_collection(params)
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])
@@ -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
@@ -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
 
@@ -20,7 +20,7 @@ module Trestle
20
20
  end
21
21
 
22
22
  def columns
23
- table.columns.map { |column| column.renderer(@template) }
23
+ table.columns.map { |column| column.renderer(@template) }.select(&:render?)
24
24
  end
25
25
 
26
26
  def render(instance)
@@ -1,3 +1,3 @@
1
1
  module Trestle
2
- VERSION = "0.8.10"
2
+ VERSION = "0.8.11"
3
3
  end
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.10
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-08-23 00:00:00.000000000 Z
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