trestle 0.8.12 → 0.8.13

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile +4 -3
  4. data/Guardfile +19 -0
  5. data/README.md +1 -0
  6. data/app/assets/javascripts/trestle/components/_datepicker.js +6 -2
  7. data/app/assets/javascripts/trestle/components/_form.js +3 -3
  8. data/app/assets/javascripts/trestle/components/_table.js +1 -1
  9. data/app/assets/stylesheets/trestle/components/_datepicker.scss +3 -1
  10. data/app/assets/stylesheets/trestle/core/_layout.scss +2 -0
  11. data/app/helpers/trestle/format_helper.rb +3 -1
  12. data/app/helpers/trestle/hook_helper.rb +10 -3
  13. data/app/views/trestle/admin/index.html.erb +1 -1
  14. data/config/locales/fr.yml +14 -2
  15. data/gemfiles/rails-4.2.gemfile +1 -1
  16. data/gemfiles/rails-5.0.gemfile +1 -1
  17. data/gemfiles/rails-5.1.gemfile +1 -1
  18. data/gemfiles/rails-5.2.gemfile +1 -1
  19. data/gemfiles/rails-edge.gemfile +3 -1
  20. data/lib/trestle.rb +12 -0
  21. data/lib/trestle/admin.rb +22 -4
  22. data/lib/trestle/admin/builder.rb +5 -1
  23. data/lib/trestle/admin/controller.rb +4 -2
  24. data/lib/trestle/application_controller.rb +12 -0
  25. data/lib/trestle/configurable.rb +21 -10
  26. data/lib/trestle/configuration.rb +2 -2
  27. data/{app/controllers/concerns → lib}/trestle/controller/breadcrumbs.rb +1 -1
  28. data/{app/controllers/concerns → lib}/trestle/controller/callbacks.rb +0 -0
  29. data/{app/controllers/concerns → lib}/trestle/controller/dialog.rb +0 -0
  30. data/{app/controllers/concerns → lib}/trestle/controller/helpers.rb +0 -0
  31. data/{app/controllers/concerns → lib}/trestle/controller/layout.rb +0 -0
  32. data/lib/trestle/controller/location.rb +24 -0
  33. data/lib/trestle/form/automatic.rb +3 -0
  34. data/lib/trestle/form/fields/collection_select.rb +1 -1
  35. data/lib/trestle/form/fields/date_picker.rb +4 -1
  36. data/lib/trestle/form/fields/date_select.rb +1 -1
  37. data/lib/trestle/form/fields/datetime_select.rb +1 -1
  38. data/lib/trestle/form/fields/select.rb +1 -1
  39. data/lib/trestle/form/fields/tag_select.rb +1 -1
  40. data/lib/trestle/form/fields/time_select.rb +1 -1
  41. data/lib/trestle/form/fields/time_zone_select.rb +1 -1
  42. data/lib/trestle/hook.rb +29 -0
  43. data/lib/trestle/resource.rb +5 -2
  44. data/lib/trestle/resource/controller.rb +33 -9
  45. data/lib/trestle/table/builder.rb +2 -2
  46. data/lib/trestle/table/select_column.rb +3 -3
  47. data/lib/trestle/version.rb +1 -1
  48. metadata +11 -10
  49. data/app/controllers/concerns/trestle/controller/location.rb +0 -15
  50. data/app/controllers/trestle/application_controller.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be67cdeb0e544dff3707615b388ab9380f23cc4f10b8ac026f77681a2b89a58d
4
- data.tar.gz: e560c637fb2418ec119bbdb895dab33fef47af0647f5c479e53ae0bc7ca71307
3
+ metadata.gz: 5bf56a27669452c89b5d5c46780c9b8761108f199a0947c3ab59b769fef98991
4
+ data.tar.gz: a4981f671dd0caced318b2baa9435cba7716a6c1b804649f5b9324ecf1bb0172
5
5
  SHA512:
6
- metadata.gz: ced0081c87529f11111908d9688ccc17c8aa1816d723160980a52892ae1236628c4aa425324f051faa82029add5a042ef211e9a6e9327d3479590e68b0f25dbf
7
- data.tar.gz: 6129c4dd280c17b4b395b58e3221728e8917a50fdecd1960eedc3ae9ccc1a6dadec63976de3780ef8f10e24022a007f9c523778740b985920e4626fc540aa472
6
+ metadata.gz: 1bd4353bb458f9ab766bdd1491675ee9f2ed3449c381441ba4a8954beda81104505d1f3c98b726a229af11b4cfaf422b43583f72f0f1b4e0d0d0f403a400c654
7
+ data.tar.gz: fa626e505ecb79fab31abe00d19ba31c260626773b0098bda9f3af51d366d6753850cc20f918de5ed204770f8711f1493b83a0234d35fa3b8e8a86ad8623212e
@@ -5,7 +5,7 @@ before_install:
5
5
  - gem install bundler
6
6
 
7
7
  rvm:
8
- - 2.6.1
8
+ - 2.6.3
9
9
 
10
10
  gemfile:
11
11
  - gemfiles/rails-4.2.gemfile
data/Gemfile CHANGED
@@ -4,13 +4,14 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- gem 'coveralls', require: false
8
- gem 'simplecov', require: false
7
+ gem 'coveralls', require: false
8
+ gem 'simplecov', require: false
9
+ gem 'guard-rspec', require: false
9
10
 
10
11
  gem 'capybara'
11
12
  gem 'capybara-selenium'
12
13
  gem 'selenium-webdriver'
13
- gem 'chromedriver-helper'
14
+ gem 'webdrivers'
14
15
  gem 'puma'
15
16
  end
16
17
 
@@ -0,0 +1,19 @@
1
+ guard :rspec, cmd: "bundle exec rspec", all_on_start: true, all_after_pass: true do
2
+ require "guard/rspec/dsl"
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # RSpec files
6
+ rspec = dsl.rspec
7
+ watch(rspec.spec_helper) { rspec.spec_dir }
8
+ watch(rspec.spec_support) { rspec.spec_dir }
9
+ watch(rspec.spec_files)
10
+
11
+ # Ruby files
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+
15
+ # Rails files
16
+ rails = dsl.rails(view_extensions: %w(erb))
17
+ dsl.watch_spec_files_for(rails.app_files)
18
+ dsl.watch_spec_files_for(rails.views)
19
+ end
data/README.md CHANGED
@@ -103,6 +103,7 @@ The following plugins are currently available:
103
103
  | *trestle-simplemde* | [SimpleMDE](https://simplemde.com/) (Markdown editor) integration | [GitHub](https://github.com/TrestleAdmin/trestle-simplemde) \| [RubyGems](https://rubygems.org/gems/trestle-simplemde) |
104
104
  | *trestle-sidekiq* | [Sidekiq](http://sidekiq.org/) integration | [GitHub](https://github.com/TrestleAdmin/trestle-sidekiq) \| [RubyGems](https://rubygems.org/gems/trestle-sidekiq) |
105
105
  | *trestle-active_storage* | [Active Storage](https://guides.rubyonrails.org/active_storage_overview.html) integration | [GitHub](https://github.com/richardvenneman/trestle-active_storage) \| [RubyGems](https://rubygems.org/gems/trestle-active_storage) |
106
+ | *trestle-mobility* | [Mobility](https://github.com/shioyama/mobility) integration | [GitHub](https://github.com/richardvenneman/trestle-mobility) \| [RubyGems](https://rubygems.org/gems/trestle-mobility) |
106
107
 
107
108
 
108
109
  ## License
@@ -1,9 +1,13 @@
1
1
  Trestle.setupDatePicker = function(selectedDates, dateStr, instance) {
2
- if ($(instance.input).data('allow-clear')) {
2
+ var input = $(instance.input)
3
+
4
+ if (input.data('allow-clear')) {
3
5
  $('<a href="#">')
4
6
  .on('click', function(e) {
5
7
  e.preventDefault();
6
- instance.clear();
8
+ if (!input.is(':disabled') && !input.hasClass('disabled')) {
9
+ instance.clear();
10
+ }
7
11
  })
8
12
  .addClass('clear-datepicker')
9
13
  .insertBefore(instance.altInput);
@@ -22,9 +22,9 @@ Trestle.init(function(e, root) {
22
22
  $(this).find(':submit').prop('disabled', false).removeClass('loading');
23
23
  $(this).removeData('trestle:submitButton');
24
24
 
25
- var contentType = xhr.getResponseHeader("Content-Type");
25
+ var contentType = (xhr.getResponseHeader('Content-Type') || '').split(';')[0];
26
26
 
27
- if (contentType && contentType.split(";")[0] == "text/html") {
27
+ if (contentType == 'text/html') {
28
28
  if (/<html/i.test(xhr.responseText)) {
29
29
  // Response is a full HTML page, likely an error page. Render within an iframe.
30
30
  var context = $(this).closest('[data-context]');
@@ -43,7 +43,7 @@ Trestle.init(function(e, root) {
43
43
  // Focus the correct tab
44
44
  Trestle.focusActiveTab();
45
45
  }
46
- } else {
46
+ } else if (contentType == 'text/plain') {
47
47
  // Assume an error response
48
48
  var title = xhr.status + " (" + xhr.statusText + ")";
49
49
  Trestle.Dialog.showError(title, xhr.responseText);
@@ -16,6 +16,6 @@ $(document).on('click', 'tr[data-url]:not([data-behavior="dialog"])', function(e
16
16
  }
17
17
  });
18
18
 
19
- $(document).on('click', 'tr[data-url] a', function(e) {
19
+ $(document).on('click', 'tr[data-url] a, tr[data-url] input', function(e) {
20
20
  e.stopPropagation();
21
21
  });
@@ -21,7 +21,9 @@
21
21
  }
22
22
 
23
23
  input[value=""] ~ &,
24
- input:not([value]) ~ & {
24
+ input:not([value]) ~ &,
25
+ input[disabled] ~ &,
26
+ input.disabled ~ & {
25
27
  display: none;
26
28
  }
27
29
  }
@@ -63,6 +63,8 @@ img {
63
63
  .error-iframe {
64
64
  border: 0;
65
65
  flex: 1;
66
+ width: 100%;
67
+ min-height: 400px;
66
68
  }
67
69
 
68
70
  @include mobile {
@@ -22,7 +22,9 @@ module Trestle
22
22
  def autoformat_value(value, options={})
23
23
  case value
24
24
  when Array
25
- content_tag(:ol, safe_join(value.map { |v| content_tag(:li, autoformat_value(v, options)) }, "\n"))
25
+ content_tag(:ol, safe_join(value.map { |v|
26
+ content_tag(:li, v.is_a?(Array) ? v : autoformat_value(v, options)) },
27
+ "\n"))
26
28
  when Time, DateTime
27
29
  timestamp(value)
28
30
  when Date
@@ -6,17 +6,24 @@ module Trestle
6
6
  hook.evaluate(self)
7
7
  }, "\n")
8
8
  elsif block_given?
9
- yield
9
+ capture(&Proc.new)
10
10
  end
11
11
  end
12
12
 
13
13
  def hook?(name)
14
- Trestle.config.hooks.key?(name.to_s) && hooks(name).any?
14
+ hook_sets.any? { |set| set.any?(name) }
15
15
  end
16
16
 
17
17
  protected
18
18
  def hooks(name)
19
- Trestle.config.hooks[name.to_s].select { |h| h.visible?(self) }
19
+ hook_sets.map { |set| set.for(name) }.inject(&:+).select { |h| h.visible?(self) }
20
+ end
21
+
22
+ def hook_sets
23
+ @_hook_sets ||= [
24
+ (admin.hooks if defined?(admin) && admin),
25
+ Trestle.config.hooks
26
+ ].compact
20
27
  end
21
28
  end
22
29
  end
@@ -1,5 +1,5 @@
1
1
  <% content_for(:title, admin.admin_name.titleize) %>
2
2
 
3
3
  <%= render layout: "layout" do %>
4
- <p><%= t("trestle.onboarding.no_template", path: "app/views/#{admin.controller_path}/index.html.erb", default: "To customize this template, please create <code>%{path}</code>.").html_safe %></p>
4
+ <p><%= t("trestle.onboarding.no_template", path: "app/views/#{admin.view_path}/index.html.erb", default: "To customize this template, please create <code>%{path}</code>.").html_safe %></p>
5
5
  <% end %>
@@ -25,8 +25,11 @@ fr:
25
25
  toggle_navigation: "Basculer navigation"
26
26
  toggle_sidebar: "Basculer vue latérale"
27
27
 
28
+ dialog:
29
+ error: "La requête n'a pas pu être traitée."
30
+
28
31
  confirmation:
29
- title: "Voulez-vous supprimer?"
32
+ title: "Voulez-vous supprimer ?"
30
33
  delete: "Oui"
31
34
  cancel: "Non"
32
35
 
@@ -40,9 +43,12 @@ fr:
40
43
  new: "Nouveau"
41
44
  save: "Enregistrer"
42
45
  delete: "Supprimer"
46
+ show: "Voir %{model_name}"
47
+ edit: "Éditer %{model_name}"
48
+ ok: "Valider"
43
49
 
44
50
  breadcrumbs:
45
- home: "Acceuil"
51
+ home: "Accueil"
46
52
 
47
53
  flash:
48
54
  create:
@@ -82,3 +88,9 @@ fr:
82
88
 
83
89
  format:
84
90
  blank: "Aucun"
91
+
92
+ datepicker:
93
+ formats:
94
+ date: "d/m/Y"
95
+ datetime: "d/m/Y H:i"
96
+ time: "H:i"
@@ -7,7 +7,7 @@ group :test do
7
7
  gem 'capybara'
8
8
  gem 'capybara-selenium'
9
9
  gem 'selenium-webdriver'
10
- gem 'chromedriver-helper'
10
+ gem 'webdrivers'
11
11
  gem 'puma'
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ group :test do
7
7
  gem 'capybara'
8
8
  gem 'capybara-selenium'
9
9
  gem 'selenium-webdriver'
10
- gem 'chromedriver-helper'
10
+ gem 'webdrivers'
11
11
  gem 'puma'
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ group :test do
7
7
  gem 'capybara'
8
8
  gem 'capybara-selenium'
9
9
  gem 'selenium-webdriver'
10
- gem 'chromedriver-helper'
10
+ gem 'webdrivers'
11
11
  gem 'puma'
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ group :test do
7
7
  gem 'capybara'
8
8
  gem 'capybara-selenium'
9
9
  gem 'selenium-webdriver'
10
- gem 'chromedriver-helper'
10
+ gem 'webdrivers'
11
11
  gem 'puma'
12
12
  end
13
13
 
@@ -7,11 +7,13 @@ group :test do
7
7
  gem 'capybara'
8
8
  gem 'capybara-selenium'
9
9
  gem 'selenium-webdriver'
10
- gem 'chromedriver-helper'
10
+ gem 'webdrivers'
11
11
  gem 'puma'
12
12
  end
13
13
 
14
14
  gem 'rails', github: 'rails/rails'
15
15
  gem 'arel', github: 'rails/arel'
16
16
 
17
+ gem 'sqlite3', '~> 1.4'
18
+
17
19
  gemspec path: "../"
@@ -11,6 +11,7 @@ module Trestle
11
11
 
12
12
  autoload :Adapters
13
13
  autoload :Admin
14
+ autoload :ApplicationController
14
15
  autoload :Attribute
15
16
  autoload :Breadcrumb
16
17
  autoload :Builder
@@ -30,6 +31,17 @@ module Trestle
30
31
  autoload :Table
31
32
  autoload :Toolbar
32
33
 
34
+ module Controller
35
+ extend ActiveSupport::Autoload
36
+
37
+ autoload :Breadcrumbs
38
+ autoload :Callbacks
39
+ autoload :Dialog
40
+ autoload :Helpers
41
+ autoload :Layout
42
+ autoload :Location
43
+ end
44
+
33
45
  mattr_accessor :admins
34
46
  self.admins = {}
35
47
 
@@ -29,8 +29,6 @@ module Trestle
29
29
 
30
30
  attr_accessor :form
31
31
 
32
- attr_accessor :additional_routes
33
-
34
32
  attr_writer :options
35
33
  attr_writer :breadcrumb
36
34
 
@@ -42,6 +40,10 @@ module Trestle
42
40
  @tables ||= {}
43
41
  end
44
42
 
43
+ def hooks
44
+ @hooks ||= Hook::Set.new
45
+ end
46
+
45
47
  # Deprecated: Use `tables[:index]` instead
46
48
  def table
47
49
  tables[:index]
@@ -96,10 +98,20 @@ module Trestle
96
98
  "#{admin_name.tr('/', '_')}_admin"
97
99
  end
98
100
 
99
- def controller_path
101
+ attr_writer :view_path
102
+
103
+ def view_path
104
+ @view_path || default_view_path
105
+ end
106
+
107
+ def default_view_path
100
108
  "admin/#{name.underscore.sub(/_admin$/, '')}"
101
109
  end
102
110
 
111
+ def view_path_prefixes
112
+ [view_path]
113
+ end
114
+
103
115
  def controller_namespace
104
116
  "#{name.underscore}/admin"
105
117
  end
@@ -120,6 +132,10 @@ module Trestle
120
132
  :index
121
133
  end
122
134
 
135
+ def additional_routes
136
+ @additional_routes ||= []
137
+ end
138
+
123
139
  def routes
124
140
  admin = self
125
141
 
@@ -127,7 +143,9 @@ module Trestle
127
143
  scope controller: admin.controller_namespace, path: admin.options[:path] || admin.admin_name do
128
144
  get "", action: "index", as: admin.route_name
129
145
 
130
- instance_exec(&admin.additional_routes) if admin.additional_routes
146
+ admin.additional_routes.each do |block|
147
+ instance_exec(&block)
148
+ end
131
149
  end
132
150
  end
133
151
  end
@@ -56,6 +56,10 @@ module Trestle
56
56
  admin.form = Form.new(options, &block)
57
57
  end
58
58
 
59
+ def hook(name, options={}, &block)
60
+ admin.hooks.append(name, options, &block)
61
+ end
62
+
59
63
  def admin(&block)
60
64
  @admin.instance_eval(&block) if block_given?
61
65
  @admin
@@ -67,7 +71,7 @@ module Trestle
67
71
  end
68
72
 
69
73
  def routes(&block)
70
- @admin.additional_routes = block
74
+ @admin.additional_routes << block
71
75
  end
72
76
 
73
77
  def breadcrumb(label=nil, path=nil, &block)
@@ -7,8 +7,10 @@ module Trestle
7
7
  class << self
8
8
  attr_reader :admin
9
9
 
10
- def controller_path
11
- admin ? admin.controller_path : super
10
+ private
11
+ def local_prefixes
12
+ return admin.view_path_prefixes if admin
13
+ [controller_path.sub(/\/$/, "")]
12
14
  end
13
15
  end
14
16
 
@@ -0,0 +1,12 @@
1
+ module Trestle
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery
4
+
5
+ include Controller::Breadcrumbs
6
+ include Controller::Callbacks
7
+ include Controller::Dialog
8
+ include Controller::Helpers
9
+ include Controller::Layout
10
+ include Controller::Location
11
+ end
12
+ end
@@ -2,17 +2,28 @@ module Trestle
2
2
  module Configurable
3
3
  extend ActiveSupport::Concern
4
4
 
5
- def initialize
6
- self.class.defaults.each do |name, default|
7
- options[name] = default
8
- end
9
- end
5
+ delegate :defaults, to: :class
10
6
 
11
7
  def configure(&block)
12
8
  yield self if block_given?
13
9
  self
14
10
  end
15
11
 
12
+ def fetch(name)
13
+ name = name.to_sym
14
+
15
+ options.fetch(name) {
16
+ if defaults.key?(name)
17
+ value = defaults[name]
18
+ assign(name, value)
19
+ end
20
+ }
21
+ end
22
+
23
+ def assign(name, value)
24
+ options[name.to_sym] = value
25
+ end
26
+
16
27
  def options
17
28
  @options ||= {}
18
29
  end
@@ -36,17 +47,17 @@ module Trestle
36
47
  name = name.to_sym
37
48
 
38
49
  define_method("#{name}=") do |value|
39
- options[name] = value
50
+ assign(name, value)
40
51
  end
41
52
 
42
53
  define_method(name) do |*args|
43
- value = options[name]
54
+ value = fetch(name)
44
55
 
45
56
  if value.respond_to?(:call) && opts[:evaluate] != false
46
- value.call(*args)
47
- else
48
- value
57
+ value = value.call(*args)
49
58
  end
59
+
60
+ value
50
61
  end
51
62
 
52
63
  defaults[name] = default
@@ -84,11 +84,11 @@ module Trestle
84
84
  end
85
85
 
86
86
  # [Internal] List of registered hooks
87
- option :hooks, Hash.new { |h, k| h[k] = [] }
87
+ option :hooks, Hook::Set.new
88
88
 
89
89
  # Register an extension hook
90
90
  def hook(name, options={}, &block)
91
- hooks[name.to_s] << Hook.new(name.to_s, options, &block)
91
+ hooks.append(name, options, &block)
92
92
  end
93
93
 
94
94
  # List of i18n keys to pass into the Trestle.i18n JavaScript object
@@ -10,7 +10,7 @@ module Trestle
10
10
 
11
11
  protected
12
12
  def breadcrumbs
13
- @breadcrumbs ||= Trestle::Breadcrumb::Trail.new(Trestle.config.root_breadcrumbs)
13
+ @breadcrumbs ||= Breadcrumb::Trail.new(Trestle.config.root_breadcrumbs)
14
14
  end
15
15
 
16
16
  def breadcrumb(label, path=nil)
@@ -0,0 +1,24 @@
1
+ module Trestle
2
+ module Controller
3
+ module Location
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_action :set_trestle_location_header
8
+ end
9
+
10
+ # The X-Trestle-Location header is set to indicate that the remote form has triggered
11
+ # a new page URL (e.g. new -> show) without demanding a full page refresh.
12
+ def set_trestle_location_header
13
+ unless dialog_request? || response.location
14
+ headers["X-Trestle-Location"] = request.path
15
+ end
16
+ end
17
+
18
+ # Do not use Turbolinks for redirects from a dialog request
19
+ def visit_location_with_turbolinks(location, action)
20
+ super unless dialog_request?
21
+ end
22
+ end
23
+ end
24
+ end
@@ -32,6 +32,9 @@ module Trestle
32
32
  datetime_field attribute.name
33
33
  when :boolean
34
34
  check_box attribute.name
35
+ when :json, :jsonb
36
+ value = instance.public_send(attribute.name)
37
+ text_area attribute.name, value: value.try(:to_json)
35
38
  else
36
39
  text_field attribute.name
37
40
  end
@@ -16,7 +16,7 @@ module Trestle
16
16
  end
17
17
 
18
18
  def default_html_options
19
- Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
19
+ Trestle::Options.new(class: ["form-control"], disabled: admin.readonly?, data: { enable_select2: true })
20
20
  end
21
21
  end
22
22
  end
@@ -1,7 +1,10 @@
1
1
  module Trestle::Form::Fields::DatePicker
2
2
  def extract_options!
3
3
  options[:prepend] ||= options.delete(:icon) { default_icon }
4
- options.reverse_merge!(data: { picker: options.delete(:picker) { true }, allow_clear: true })
4
+
5
+ unless options[:disabled] || options[:readonly]
6
+ options.reverse_merge!(data: { picker: options.delete(:picker) { true }, allow_clear: true })
7
+ end
5
8
 
6
9
  super
7
10
  end
@@ -17,7 +17,7 @@ module Trestle
17
17
  end
18
18
 
19
19
  def default_html_options
20
- Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
20
+ Trestle::Options.new(class: ["form-control"], disabled: admin.readonly?, data: { enable_select2: true })
21
21
  end
22
22
  end
23
23
  end
@@ -17,7 +17,7 @@ module Trestle
17
17
  end
18
18
 
19
19
  def default_html_options
20
- Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
20
+ Trestle::Options.new(class: ["form-control"], disabled: admin.readonly?, data: { enable_select2: true })
21
21
  end
22
22
  end
23
23
  end
@@ -18,7 +18,7 @@ module Trestle
18
18
  end
19
19
 
20
20
  def default_html_options
21
- Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
21
+ Trestle::Options.new(class: ["form-control"], disabled: admin.readonly?, data: { enable_select2: true })
22
22
  end
23
23
 
24
24
  def default_choices
@@ -7,7 +7,7 @@ module Trestle
7
7
  end
8
8
 
9
9
  def default_html_options
10
- super.merge(multiple: true, class: "tag-select", data: { tags: true })
10
+ super.merge(multiple: true, class: "tag-select", disabled: admin.readonly?, data: { tags: true })
11
11
  end
12
12
  end
13
13
  end
@@ -17,7 +17,7 @@ module Trestle
17
17
  end
18
18
 
19
19
  def default_html_options
20
- Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
20
+ Trestle::Options.new(class: ["form-control"], disabled: admin.readonly?, data: { enable_select2: true })
21
21
  end
22
22
  end
23
23
  end
@@ -16,7 +16,7 @@ module Trestle
16
16
  end
17
17
 
18
18
  def default_html_options
19
- Trestle::Options.new(class: ["form-control"], data: { enable_select2: true })
19
+ Trestle::Options.new(class: ["form-control"], disabled: admin.readonly?, data: { enable_select2: true })
20
20
  end
21
21
  end
22
22
  end
@@ -23,5 +23,34 @@ module Trestle
23
23
  def evaluate(context)
24
24
  context.instance_exec(&block)
25
25
  end
26
+
27
+ class Set
28
+ attr_reader :hooks
29
+
30
+ def initialize
31
+ @hooks = {}
32
+ end
33
+
34
+ def append(name, options={}, &block)
35
+ hooks[name.to_s] ||= []
36
+ hooks[name.to_s] << Hook.new(name.to_s, options, &block)
37
+ end
38
+
39
+ def any?(name)
40
+ hooks.key?(name.to_s) && hooks[name.to_s].any?
41
+ end
42
+
43
+ def for(name)
44
+ hooks.fetch(name.to_s) { [] }
45
+ end
46
+
47
+ def empty?
48
+ hooks.empty?
49
+ end
50
+
51
+ def ==(other)
52
+ other.is_a?(self.class) && hooks == other.hooks
53
+ end
54
+ end
26
55
  end
27
56
  end
@@ -131,7 +131,9 @@ module Trestle
131
131
 
132
132
  Proc.new do
133
133
  public_send(resource_method, resource_name, resource_options) do
134
- instance_exec(&admin.additional_routes) if admin.additional_routes
134
+ admin.additional_routes.each do |block|
135
+ instance_exec(&block)
136
+ end
135
137
  end
136
138
  end
137
139
  end
@@ -152,7 +154,8 @@ module Trestle
152
154
 
153
155
  private
154
156
  def infer_model_class
155
- parent.const_get(admin_name.classify)
157
+ scope = respond_to?(:module_parent) ? module_parent : parent
158
+ scope.const_get(admin_name.classify)
156
159
  rescue NameError
157
160
  raise NameError, "Unable to find model #{admin_name.classify}. Specify a different model using Trestle.resource(:#{admin_name}, model: MyModel)"
158
161
  end
@@ -8,7 +8,8 @@ module Trestle
8
8
  respond_to do |format|
9
9
  format.html
10
10
  format.json { render json: collection }
11
- format.js
11
+
12
+ yield format if block_given?
12
13
  end
13
14
  end
14
15
 
@@ -18,7 +19,8 @@ module Trestle
18
19
  respond_to do |format|
19
20
  format.html
20
21
  format.json { render json: instance }
21
- format.js
22
+
23
+ yield format if block_given?
22
24
  end
23
25
  end
24
26
 
@@ -32,7 +34,8 @@ module Trestle
32
34
  redirect_to_return_location(:create, instance, default: admin.instance_path(instance))
33
35
  end
34
36
  format.json { render json: instance, status: :created, location: admin.instance_path(instance) }
35
- format.js
37
+
38
+ yield format if block_given?
36
39
  end
37
40
  else
38
41
  respond_to do |format|
@@ -41,7 +44,8 @@ module Trestle
41
44
  render "new", status: :unprocessable_entity
42
45
  end
43
46
  format.json { render json: instance.errors, status: :unprocessable_entity }
44
- format.js
47
+
48
+ yield format if block_given?
45
49
  end
46
50
  end
47
51
  end
@@ -51,18 +55,35 @@ module Trestle
51
55
  respond_to do |format|
52
56
  format.html { redirect_to action: :new }
53
57
  format.json { head :not_found }
54
- format.js
58
+
59
+ yield format if block_given?
55
60
  end
56
61
  else
57
62
  respond_to do |format|
58
63
  format.html
59
64
  format.json { render json: instance }
60
- format.js
65
+
66
+ yield format if block_given?
61
67
  end
62
68
  end
63
69
  end
64
70
 
65
71
  def edit
72
+ if admin.singular? && instance.nil?
73
+ respond_to do |format|
74
+ format.html { redirect_to action: :new }
75
+ format.json { head :not_found }
76
+
77
+ yield format if block_given?
78
+ end
79
+ else
80
+ respond_to do |format|
81
+ format.html
82
+ format.json { render json: instance }
83
+
84
+ yield format if block_given?
85
+ end
86
+ end
66
87
  end
67
88
 
68
89
  def update
@@ -75,7 +96,8 @@ module Trestle
75
96
  redirect_to_return_location(:update, instance, default: admin.instance_path(instance))
76
97
  end
77
98
  format.json { render json: instance, status: :ok }
78
- format.js
99
+
100
+ yield format if block_given?
79
101
  end
80
102
  else
81
103
  respond_to do |format|
@@ -84,7 +106,8 @@ module Trestle
84
106
  render "show", status: :unprocessable_entity
85
107
  end
86
108
  format.json { render json: instance.errors, status: :unprocessable_entity }
87
- format.js
109
+
110
+ yield format if block_given?
88
111
  end
89
112
  end
90
113
  end
@@ -108,7 +131,8 @@ module Trestle
108
131
  end
109
132
  end
110
133
  format.json { head :no_content }
111
- format.js
134
+
135
+ yield format if block_given?
112
136
  end
113
137
  end
114
138
 
@@ -12,8 +12,8 @@ module Trestle
12
12
  table.row = Row.new(table, options, &block)
13
13
  end
14
14
 
15
- def selectable_column
16
- table.columns << SelectColumn.new(table)
15
+ def selectable_column(options={})
16
+ table.columns << SelectColumn.new(table, options)
17
17
  end
18
18
 
19
19
  def column(field, proc=nil, options={}, &block)
@@ -1,10 +1,10 @@
1
1
  module Trestle
2
2
  class Table
3
3
  class SelectColumn
4
- attr_reader :table
4
+ attr_reader :table, :options
5
5
 
6
- def initialize(table)
7
- @table = table
6
+ def initialize(table, options={})
7
+ @table, @options = table, options
8
8
  end
9
9
 
10
10
  def renderer(template)
@@ -1,3 +1,3 @@
1
1
  module Trestle
2
- VERSION = "0.8.12"
2
+ VERSION = "0.8.13"
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.12
4
+ version: 0.8.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Pohlenz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-28 00:00:00.000000000 Z
11
+ date: 2019-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -190,6 +190,7 @@ files:
190
190
  - ".rspec"
191
191
  - ".travis.yml"
192
192
  - Gemfile
193
+ - Guardfile
193
194
  - LICENSE
194
195
  - README.md
195
196
  - Rakefile
@@ -249,13 +250,6 @@ files:
249
250
  - app/assets/stylesheets/trestle/core/_layout.scss
250
251
  - app/assets/stylesheets/trestle/core/_mixins.scss
251
252
  - app/assets/stylesheets/trestle/core/_typography.scss
252
- - app/controllers/concerns/trestle/controller/breadcrumbs.rb
253
- - app/controllers/concerns/trestle/controller/callbacks.rb
254
- - app/controllers/concerns/trestle/controller/dialog.rb
255
- - app/controllers/concerns/trestle/controller/helpers.rb
256
- - app/controllers/concerns/trestle/controller/layout.rb
257
- - app/controllers/concerns/trestle/controller/location.rb
258
- - app/controllers/trestle/application_controller.rb
259
253
  - app/controllers/trestle/dashboard_controller.rb
260
254
  - app/helpers/trestle/avatar_helper.rb
261
255
  - app/helpers/trestle/container_helper.rb
@@ -356,11 +350,18 @@ files:
356
350
  - lib/trestle/admin.rb
357
351
  - lib/trestle/admin/builder.rb
358
352
  - lib/trestle/admin/controller.rb
353
+ - lib/trestle/application_controller.rb
359
354
  - lib/trestle/attribute.rb
360
355
  - lib/trestle/breadcrumb.rb
361
356
  - lib/trestle/builder.rb
362
357
  - lib/trestle/configurable.rb
363
358
  - lib/trestle/configuration.rb
359
+ - lib/trestle/controller/breadcrumbs.rb
360
+ - lib/trestle/controller/callbacks.rb
361
+ - lib/trestle/controller/dialog.rb
362
+ - lib/trestle/controller/helpers.rb
363
+ - lib/trestle/controller/layout.rb
364
+ - lib/trestle/controller/location.rb
364
365
  - lib/trestle/display.rb
365
366
  - lib/trestle/engine.rb
366
367
  - lib/trestle/evaluation_context.rb
@@ -643,7 +644,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
643
644
  - !ruby/object:Gem::Version
644
645
  version: '0'
645
646
  requirements: []
646
- rubygems_version: 3.0.2
647
+ rubygems_version: 3.0.3
647
648
  signing_key:
648
649
  specification_version: 4
649
650
  summary: A modern, responsive admin framework for Ruby on Rails
@@ -1,15 +0,0 @@
1
- module Trestle
2
- module Controller
3
- module Location
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- after_action :set_trestle_location_header, unless: :dialog_request?
8
- end
9
-
10
- def set_trestle_location_header
11
- headers["X-Trestle-Location"] = request.path
12
- end
13
- end
14
- end
15
- end
@@ -1,10 +0,0 @@
1
- class Trestle::ApplicationController < ActionController::Base
2
- protect_from_forgery
3
-
4
- include Trestle::Controller::Breadcrumbs
5
- include Trestle::Controller::Callbacks
6
- include Trestle::Controller::Dialog
7
- include Trestle::Controller::Helpers
8
- include Trestle::Controller::Layout
9
- include Trestle::Controller::Location
10
- end