trestle 0.8.6 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
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