trestle 0.8.12 → 0.8.13

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