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.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +10 -9
  3. data/app/assets/javascripts/trestle/components/_dialog.js +29 -8
  4. data/app/assets/javascripts/trestle/components/_form.js +28 -7
  5. data/app/assets/javascripts/trestle/components/_sidebar.js +10 -8
  6. data/app/assets/javascripts/trestle/components/_tabs.js +2 -1
  7. data/app/assets/javascripts/trestle/components/_tooltips.js +16 -0
  8. data/app/assets/stylesheets/trestle/components/_modal.scss +4 -0
  9. data/app/assets/stylesheets/trestle/components/_navigation.scss +31 -11
  10. data/app/assets/stylesheets/trestle/components/_sidebar.scss +2 -2
  11. data/app/assets/stylesheets/trestle/components/_tags.scss +9 -0
  12. data/app/assets/stylesheets/trestle/components/_wells.scss +9 -1
  13. data/app/assets/stylesheets/trestle/core/_defaults.scss +4 -4
  14. data/app/assets/stylesheets/trestle/core/_layout.scss +8 -0
  15. data/app/assets/stylesheets/trestle/core/_typography.scss +39 -0
  16. data/app/controllers/concerns/trestle/controller/breadcrumbs.rb +21 -0
  17. data/app/controllers/concerns/trestle/controller/callbacks.rb +21 -0
  18. data/app/controllers/concerns/trestle/controller/dialog.rb +16 -0
  19. data/app/controllers/concerns/trestle/controller/helpers.rb +18 -0
  20. data/app/controllers/concerns/trestle/controller/layout.rb +16 -0
  21. data/app/controllers/concerns/trestle/controller/location.rb +15 -0
  22. data/app/controllers/trestle/application_controller.rb +6 -34
  23. data/app/helpers/trestle/debug_helper.rb +11 -0
  24. data/app/helpers/trestle/format_helper.rb +7 -3
  25. data/app/helpers/trestle/headings_helper.rb +27 -0
  26. data/app/helpers/trestle/panel_helper.rb +24 -0
  27. data/app/helpers/trestle/table_helper.rb +41 -2
  28. data/app/helpers/trestle/url_helper.rb +3 -1
  29. data/app/views/layouts/trestle/admin.html.erb +1 -1
  30. data/app/views/trestle/application/_flash.html.erb +1 -1
  31. data/app/views/trestle/shared/_sidebar.html.erb +2 -2
  32. data/app/views/trestle/table/_table.html.erb +2 -6
  33. data/lib/generators/trestle/resource/templates/admin.rb.erb +2 -2
  34. data/lib/trestle.rb +6 -4
  35. data/lib/trestle/adapters/active_record_adapter.rb +0 -4
  36. data/lib/trestle/adapters/adapter.rb +15 -10
  37. data/lib/trestle/adapters/sequel_adapter.rb +0 -4
  38. data/lib/trestle/admin.rb +18 -1
  39. data/lib/trestle/admin/builder.rb +22 -10
  40. data/lib/trestle/form/automatic.rb +5 -2
  41. data/lib/trestle/form/builder.rb +5 -1
  42. data/lib/trestle/form/field.rb +1 -1
  43. data/lib/trestle/form/fields/form_group.rb +3 -1
  44. data/lib/trestle/form/fields/select.rb +5 -1
  45. data/lib/trestle/form/fields/tag_select.rb +1 -1
  46. data/lib/trestle/form/renderer.rb +1 -1
  47. data/lib/trestle/navigation.rb +11 -5
  48. data/lib/trestle/navigation/item.rb +10 -0
  49. data/lib/trestle/resource.rb +27 -61
  50. data/lib/trestle/resource/builder.rb +15 -14
  51. data/lib/trestle/resource/collection.rb +48 -0
  52. data/lib/trestle/resource/controller.rb +36 -23
  53. data/lib/trestle/scope.rb +13 -3
  54. data/lib/trestle/table.rb +10 -4
  55. data/lib/trestle/table/column.rb +13 -2
  56. data/lib/trestle/table/row.rb +10 -0
  57. data/lib/trestle/version.rb +1 -1
  58. data/trestle.gemspec +1 -0
  59. data/vendor/assets/stylesheets/trestle/magnific-popup.scss +13 -1
  60. metadata +27 -4
  61. data/app/helpers/trestle/dialog_helper.rb +0 -7
@@ -0,0 +1,48 @@
1
+ module Trestle
2
+ class Resource
3
+ class Collection
4
+ delegate :initialize_collection, :paginate, :finalize_collection, :decorate_collection,
5
+ :scopes, :merge_scopes, :column_sorts, :sort, to: :@admin
6
+
7
+ def initialize(admin)
8
+ @admin = admin
9
+ end
10
+
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)
18
+ collection
19
+ end
20
+
21
+ private
22
+ def apply_scopes(collection, params)
23
+ unscoped = initialize_collection(params)
24
+
25
+ active_scopes(params).reduce(collection) do |collection, scope|
26
+ merge_scopes(collection, scope.apply(unscoped))
27
+ end
28
+ end
29
+
30
+ def active_scopes(params)
31
+ scopes.values.select { |s| s.active?(params) }
32
+ end
33
+
34
+ def apply_sorting(collection, params)
35
+ return collection unless params[:sort]
36
+
37
+ field = params[:sort].to_sym
38
+ order = params[:order].to_s.downcase == "desc" ? :desc : :asc
39
+
40
+ if column_sorts.has_key?(field)
41
+ @admin.instance_exec(collection, order, &column_sorts[field])
42
+ else
43
+ sort(collection, field, order)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,11 +1,7 @@
1
1
  module Trestle
2
2
  class Resource
3
3
  class Controller < Admin::Controller
4
- after_action :set_trestle_location_header
5
-
6
4
  def index
7
- self.collection = admin.prepare_collection(params)
8
-
9
5
  respond_to do |format|
10
6
  format.html
11
7
  format.json { render json: collection }
@@ -24,13 +20,13 @@ module Trestle
24
20
  end
25
21
 
26
22
  def create
27
- self.instance = admin.build_instance(admin.permitted_params(params), params)
23
+ self.instance = admin.build_instance(permitted_params, params)
28
24
 
29
25
  if admin.save_instance(instance)
30
26
  respond_to do |format|
31
27
  format.html do
32
28
  flash[:message] = flash_message("success.create", default: "The %{lowercase_model_name} was successfully created.")
33
- redirect_to(admin.return_location(:create, instance), turbolinks: false)
29
+ redirect_to_return_location(:create, instance, default: admin.path(:show, id: admin.to_param(instance)))
34
30
  end
35
31
  format.json { render json: instance, status: :created, location: { action: :show, id: admin.to_param(instance) } }
36
32
  format.js
@@ -48,8 +44,6 @@ module Trestle
48
44
  end
49
45
 
50
46
  def show
51
- self.instance = admin.find_instance(params)
52
-
53
47
  respond_to do |format|
54
48
  format.html
55
49
  format.json { render json: instance }
@@ -58,18 +52,16 @@ module Trestle
58
52
  end
59
53
 
60
54
  def edit
61
- self.instance = admin.find_instance(params)
62
55
  end
63
56
 
64
57
  def update
65
- self.instance = admin.find_instance(params)
66
- admin.update_instance(instance, admin.permitted_params(params), params)
58
+ admin.update_instance(instance, permitted_params, params)
67
59
 
68
60
  if admin.save_instance(instance)
69
61
  respond_to do |format|
70
62
  format.html do
71
63
  flash[:message] = flash_message("success.update", default: "The %{lowercase_model_name} was successfully updated.")
72
- redirect_to(admin.return_location(:update, instance), turbolinks: false)
64
+ redirect_to_return_location(:update, instance, default: admin.path(:show, id: admin.to_param(instance)))
73
65
  end
74
66
  format.json { render json: instance, status: :ok }
75
67
  format.js
@@ -87,21 +79,20 @@ module Trestle
87
79
  end
88
80
 
89
81
  def destroy
90
- self.instance = admin.find_instance(params)
91
82
  success = admin.delete_instance(instance)
92
83
 
93
84
  respond_to do |format|
94
85
  format.html do
95
86
  if success
96
87
  flash[:message] = flash_message("success.destroy", default: "The %{lowercase_model_name} was successfully deleted.")
97
- redirect_to admin.return_location(:destroy)
88
+ redirect_to_return_location(:destroy, instance, default: admin.path(:index))
98
89
  else
99
90
  flash[:error] = flash_message("failure.destroy", default: "Could not delete %{lowercase_model_name}.")
100
91
 
101
92
  if self.instance = admin.find_instance(params)
102
- redirect_to action: :show, id: admin.to_param(instance)
93
+ redirect_to_return_location(:update, instance, default: admin.path(:show, id: admin.to_param(instance)))
103
94
  else
104
- redirect_to admin.return_location(:destroy)
95
+ redirect_to_return_location(:destroy, instance, default: admin.path(:index))
105
96
  end
106
97
  end
107
98
  end
@@ -111,19 +102,41 @@ module Trestle
111
102
  end
112
103
 
113
104
  protected
114
- attr_accessor :collection
115
- helper_method :collection
105
+ def instance
106
+ @instance ||= admin.find_instance(params)
107
+ end
116
108
 
117
- attr_accessor :instance
118
- helper_method :instance
109
+ def collection
110
+ @collection ||= admin.prepare_collection(params)
111
+ end
112
+
113
+ attr_writer :instance, :collection
114
+ helper_method :instance, :collection
119
115
 
120
116
  def flash_message(type, options={})
121
117
  t("trestle.flash.#{type}", options.merge(model_name: admin.model_name, lowercase_model_name: admin.model_name.downcase))
122
118
  end
123
119
 
124
- def set_trestle_location_header
125
- unless request.headers["X-Trestle-Dialog"]
126
- headers["X-Trestle-Location"] = request.path
120
+ def permitted_params
121
+ if admin.permitted_params_block
122
+ instance_exec(params, &admin.permitted_params_block)
123
+ else
124
+ admin.permitted_params(params)
125
+ end
126
+ end
127
+
128
+ def redirect_to_return_location(action, instance, default:)
129
+ if admin.return_locations[action] && !dialog_request?
130
+ location = instance_exec(instance, &admin.return_locations[action])
131
+
132
+ case location
133
+ when :back
134
+ redirect_back fallback_location: default, turbolinks: false
135
+ else
136
+ redirect_to location, turbolinks: false
137
+ end
138
+ else
139
+ redirect_to default, turbolinks: false
127
140
  end
128
141
  end
129
142
  end
data/lib/trestle/scope.rb CHANGED
@@ -20,18 +20,28 @@ module Trestle
20
20
 
21
21
  def apply(collection)
22
22
  if @block
23
- @admin.instance_exec(&@block)
23
+ if @block.arity == 1
24
+ @admin.instance_exec(collection, &@block)
25
+ else
26
+ @admin.instance_exec(&@block)
27
+ end
24
28
  else
25
29
  collection.public_send(name)
26
30
  end
27
31
  end
28
32
 
29
33
  def count(collection)
30
- @admin.count(@admin.merge_scopes(collection, apply(@admin.unscope(collection))))
34
+ @admin.count(@admin.merge_scopes(collection, apply(collection)))
31
35
  end
32
36
 
33
37
  def active?(params)
34
- @admin.scopes_for(params).include?(self)
38
+ active_scopes = Array(params[:scope])
39
+
40
+ if active_scopes.any?
41
+ active_scopes.include?(to_param.to_s)
42
+ else
43
+ default?
44
+ end
35
45
  end
36
46
  end
37
47
  end
data/lib/trestle/table.rb CHANGED
@@ -9,16 +9,18 @@ module Trestle
9
9
  autoload :SelectColumn
10
10
  autoload :Row
11
11
 
12
- attr_reader :columns, :options, :admin
12
+ attr_reader :columns, :options
13
13
  attr_writer :row
14
14
 
15
15
  def initialize(options={})
16
16
  @options = options
17
- @admin = Trestle.lookup(options[:admin]) if options.key?(:admin)
18
-
19
17
  @columns = []
20
18
  end
21
19
 
20
+ def admin
21
+ Trestle.lookup(options[:admin]) if options.key?(:admin)
22
+ end
23
+
22
24
  def sortable?
23
25
  options[:sortable] == true
24
26
  end
@@ -47,7 +49,11 @@ module Trestle
47
49
  end
48
50
 
49
51
  def columns
50
- @columns ||= @table.columns.map { |column| column.renderer(@template) }
52
+ @columns ||= row.columns
53
+ end
54
+
55
+ def id
56
+ options[:id]
51
57
  end
52
58
 
53
59
  def classes
@@ -45,6 +45,10 @@ module Trestle
45
45
  @column, @template = column, template
46
46
  end
47
47
 
48
+ def render(instance)
49
+ @template.content_tag(:td, content(instance), class: classes, data: data)
50
+ end
51
+
48
52
  def header
49
53
  return if options.has_key?(:header) && options[:header].in?([nil, false])
50
54
 
@@ -87,10 +91,17 @@ module Trestle
87
91
  # evaluate the block using instance_exec, we need to set this up manually.
88
92
  -> {
89
93
  _hamlout = eval('_hamlout', @column.block.binding)
90
- @template.capture { @template.instance_exec(instance, &@column.block).to_s }
94
+ value = nil
95
+ buffer = @template.capture { value = @template.instance_exec(instance, &@column.block) }
96
+ value.is_a?(String) ? buffer : value
91
97
  }.call
92
98
  else
93
- @template.capture { @template.instance_exec(instance, &@column.block).to_s }
99
+ # Capture both the immediate value and captured output of the block.
100
+ # If the result of the block is a string, then use the contents of the buffer.
101
+ # Otherwise return the result of the block as a raw value (for auto-formatting).
102
+ value = nil
103
+ buffer = @template.capture { value = @template.instance_exec(instance, &@column.block) }
104
+ value.is_a?(String) ? buffer : value
94
105
  end
95
106
  else
96
107
  instance.send(@column.field)
@@ -19,6 +19,16 @@ module Trestle
19
19
  @row, @template = row, template
20
20
  end
21
21
 
22
+ def columns
23
+ table.columns.map { |column| column.renderer(@template) }
24
+ end
25
+
26
+ def render(instance)
27
+ @template.content_tag(:tr, options(instance)) do
28
+ @template.safe_join(columns.map { |column| column.render(instance) }, "\n")
29
+ end
30
+ end
31
+
22
32
  def options(instance)
23
33
  options = Trestle::Options.new
24
34
 
@@ -1,3 +1,3 @@
1
1
  module Trestle
2
- VERSION = "0.8.6"
2
+ VERSION = "0.8.7"
3
3
  end
data/trestle.gemspec CHANGED
@@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
43
43
  spec.add_development_dependency "rake", "~> 10.0"
44
44
  spec.add_development_dependency "rspec-rails", "~> 3.5"
45
45
  spec.add_development_dependency "rspec-html-matchers", "~> 0.7.1"
46
+ spec.add_development_dependency "database_cleaner", "~> 1.6.2"
46
47
 
47
48
  spec.add_development_dependency "sqlite3"
48
49
  spec.add_development_dependency "turbolinks"
@@ -1 +1,13 @@
1
- @import "trestle/magnific-popup/dist/magnific-popup"
1
+ @import "trestle/magnific-popup/dist/magnific-popup";
2
+
3
+ $mfp-z-index-base: 1140;
4
+
5
+ .mfp-bg { z-index: $mfp-z-index-base + 2; }
6
+ .mfp-wrap { z-index: $mfp-z-index-base + 3; }
7
+ .mfp-content { z-index: $mfp-z-index-base + 5; }
8
+ .mfp-preloader { z-index: $mfp-z-index-base + 4; }
9
+
10
+ button.mfp-close,
11
+ button.mfp-arrow {
12
+ z-index: $mfp-z-index-base + 6;
13
+ }
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.6
4
+ version: 0.8.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Pohlenz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-28 00:00:00.000000000 Z
11
+ date: 2018-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.7.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: database_cleaner
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 1.6.2
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 1.6.2
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: sqlite3
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -233,19 +247,27 @@ files:
233
247
  - app/assets/stylesheets/trestle/core/_layout.scss
234
248
  - app/assets/stylesheets/trestle/core/_mixins.scss
235
249
  - app/assets/stylesheets/trestle/core/_typography.scss
250
+ - app/controllers/concerns/trestle/controller/breadcrumbs.rb
251
+ - app/controllers/concerns/trestle/controller/callbacks.rb
252
+ - app/controllers/concerns/trestle/controller/dialog.rb
253
+ - app/controllers/concerns/trestle/controller/helpers.rb
254
+ - app/controllers/concerns/trestle/controller/layout.rb
255
+ - app/controllers/concerns/trestle/controller/location.rb
236
256
  - app/controllers/trestle/application_controller.rb
237
257
  - app/controllers/trestle/dashboard_controller.rb
238
258
  - app/helpers/trestle/avatar_helper.rb
239
259
  - app/helpers/trestle/container_helper.rb
240
- - app/helpers/trestle/dialog_helper.rb
260
+ - app/helpers/trestle/debug_helper.rb
241
261
  - app/helpers/trestle/display_helper.rb
242
262
  - app/helpers/trestle/form_helper.rb
243
263
  - app/helpers/trestle/format_helper.rb
244
264
  - app/helpers/trestle/grid_helper.rb
265
+ - app/helpers/trestle/headings_helper.rb
245
266
  - app/helpers/trestle/hook_helper.rb
246
267
  - app/helpers/trestle/icon_helper.rb
247
268
  - app/helpers/trestle/navigation_helper.rb
248
269
  - app/helpers/trestle/pagination_helper.rb
270
+ - app/helpers/trestle/panel_helper.rb
249
271
  - app/helpers/trestle/params_helper.rb
250
272
  - app/helpers/trestle/sort_helper.rb
251
273
  - app/helpers/trestle/status_helper.rb
@@ -372,6 +394,7 @@ files:
372
394
  - lib/trestle/reloader.rb
373
395
  - lib/trestle/resource.rb
374
396
  - lib/trestle/resource/builder.rb
397
+ - lib/trestle/resource/collection.rb
375
398
  - lib/trestle/resource/controller.rb
376
399
  - lib/trestle/scope.rb
377
400
  - lib/trestle/tab.rb
@@ -595,7 +618,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
595
618
  version: '0'
596
619
  requirements: []
597
620
  rubyforge_project:
598
- rubygems_version: 2.6.13
621
+ rubygems_version: 2.7.3
599
622
  signing_key:
600
623
  specification_version: 4
601
624
  summary: A modern, responsive admin framework for Ruby on Rails
@@ -1,7 +0,0 @@
1
- module Trestle
2
- module DialogHelper
3
- def dialog_request?
4
- request.headers["X-Trestle-Dialog"]
5
- end
6
- end
7
- end