trestle 0.8.4 → 0.8.5

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.travis.yml +10 -1
  4. data/Gemfile +4 -0
  5. data/README.md +1 -0
  6. data/app/assets/javascripts/trestle/_cookies.js +23 -0
  7. data/app/assets/javascripts/trestle/_sidebar.js +24 -3
  8. data/app/assets/stylesheets/trestle/components/_alerts.scss +28 -0
  9. data/app/assets/stylesheets/trestle/components/_navigation.scss +41 -6
  10. data/app/helpers/trestle/hook_helper.rb +8 -3
  11. data/app/views/trestle/application/_alert.html.erb +2 -0
  12. data/app/views/trestle/application/_flash.html.erb +18 -4
  13. data/app/views/trestle/resource/edit.html.erb +1 -1
  14. data/app/views/trestle/resource/index.html.erb +5 -2
  15. data/app/views/trestle/resource/new.html.erb +1 -1
  16. data/app/views/trestle/resource/show.html.erb +1 -1
  17. data/app/views/trestle/shared/_sidebar.html.erb +3 -2
  18. data/config/locales/en.yml +6 -4
  19. data/config/locales/nl.rb +18 -0
  20. data/config/locales/nl.yml +67 -0
  21. data/config/locales/pt-BR.rb +18 -0
  22. data/config/locales/pt-BR.yml +69 -0
  23. data/gemfiles/rails-4.2.gemfile +14 -0
  24. data/gemfiles/rails-5.0.gemfile +14 -0
  25. data/gemfiles/rails-5.1.gemfile +14 -0
  26. data/gemfiles/rails-edge.gemfile +15 -0
  27. data/lib/generators/trestle/install/templates/trestle.rb.erb +6 -0
  28. data/lib/trestle.rb +1 -0
  29. data/lib/trestle/configuration.rb +7 -1
  30. data/lib/trestle/display.rb +1 -1
  31. data/lib/trestle/model_name.rb +64 -0
  32. data/lib/trestle/navigation/group.rb +8 -0
  33. data/lib/trestle/navigation/item.rb +1 -1
  34. data/lib/trestle/options.rb +7 -5
  35. data/lib/trestle/resource.rb +2 -11
  36. data/lib/trestle/resource/controller.rb +12 -7
  37. data/lib/trestle/table.rb +3 -1
  38. data/lib/trestle/table/actions_column.rb +17 -14
  39. data/lib/trestle/table/automatic.rb +1 -2
  40. data/lib/trestle/table/builder.rb +2 -2
  41. data/lib/trestle/table/column.rb +3 -3
  42. data/lib/trestle/table/row.rb +2 -2
  43. data/lib/trestle/version.rb +1 -1
  44. data/trestle.gemspec +1 -0
  45. metadata +27 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f4f02402474a2f77fc6f4af6582e9b68f59274d0
4
- data.tar.gz: bb9815ae6b48b970443740c5b111aefef96dcea3
3
+ metadata.gz: f43ff0c051a7e29be0e0a815f1500753456f8aef
4
+ data.tar.gz: 75bc749e3cd64de9c5339e98dda6c921985d5c61
5
5
  SHA512:
6
- metadata.gz: c1593ee4dafcde35f20c312441df49e1b0861b82d87e387b4ed407e60a29758fb24e9efe4274339a1e04c78aac60cb0e85b9c76a425863fc3176d6a1f3afb70a
7
- data.tar.gz: 04e575f53c928a249a74aa4cc8ad3477c7cd16fad6ef26874e0d9adf9397bbfe070fd059f74b4c85c25cba599887d84dbf3f5da1fd0cd91d26704c85ef976a1b
6
+ metadata.gz: 86dbf71a36e6cfb0499e7ec5d6852103f9148acead9755775883fbb7011b019e435ccb7331866f19a6555c5d7fb9de049aed2139874a70bbe3417c88e79a806e
7
+ data.tar.gz: 10e8387dbb008465043180543be49f16a659372ce62f8d908b86595c91ebdb6b1b2950c7391c9ec7eb1041feb325f19c817e7c7f5c3e3fb5a078651d1518a0d2
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
3
  /Gemfile.lock
4
+ /gemfiles/*.lock
4
5
  /_yardoc/
5
6
  /coverage/
6
7
  /doc/
@@ -11,4 +12,7 @@
11
12
  /sandbox/*.sqlite3-journal
12
13
  /sandbox/log/*.log
13
14
  /sandbox/tmp/
15
+ /spec/dummy/db/*.sqlite3
16
+ /spec/dummy/*.sqlite3-journal
14
17
  /spec/dummy/log/*.log
18
+ /spec/dummy/tmp/*
@@ -1,4 +1,13 @@
1
1
  language: ruby
2
+
3
+ before_install:
4
+ - gem install bundler
5
+
2
6
  rvm:
3
7
  - 2.4.1
4
- before_install: gem install bundler
8
+
9
+ gemfile:
10
+ - gemfiles/rails-4.2.gemfile
11
+ - gemfiles/rails-5.0.gemfile
12
+ - gemfiles/rails-5.1.gemfile
13
+ - gemfiles/rails-edge.gemfile
data/Gemfile CHANGED
@@ -6,6 +6,10 @@ gemspec
6
6
  group :test do
7
7
  gem 'coveralls', require: false
8
8
  gem 'simplecov', require: false
9
+
10
+ gem 'capybara'
11
+ gem 'capybara-selenium'
12
+ gem 'selenium-webdriver'
9
13
  end
10
14
 
11
15
  gem 'haml'
data/README.md CHANGED
@@ -92,6 +92,7 @@ The following plugins are currently available:
92
92
  | *trestle-auth* | User authentication plugin | https://github.com/TrestleAdmin/trestle-auth |
93
93
  | *trestle-search* | Search plugin | https://github.com/TrestleAdmin/trestle-search |
94
94
  | *trestle-tinymce* | TinyMCE (WYSIWYG editor) integration | https://github.com/TrestleAdmin/trestle-tinymce |
95
+ | *trestle-simplemde* | SimpleMDE (Markdown editor) integration | https://github.com/TrestleAdmin/trestle-simplemde |
95
96
 
96
97
 
97
98
  ## License
@@ -0,0 +1,23 @@
1
+ Trestle.cookie = {
2
+ get: function(name) {
3
+ name += '=';
4
+
5
+ var cookies = document.cookie.split(/;\s*/)
6
+
7
+ for (i = cookies.length - 1; i >= 0; i--) {
8
+ if (!cookies[i].indexOf(name)) {
9
+ return cookies[i].replace(name, '');
10
+ }
11
+ }
12
+
13
+ return "";
14
+ },
15
+
16
+ set: function(name, value) {
17
+ document.cookie = name + "=" + encodeURIComponent(value) + "; path=/";
18
+ },
19
+
20
+ delete: function(name) {
21
+ document.cookie = name + "=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
22
+ }
23
+ };
@@ -40,13 +40,34 @@ Trestle.ready(function() {
40
40
 
41
41
  if (sidebar.hasClass('expanded') || sidebar.hasClass('collapsed')) {
42
42
  sidebar.removeClass('expanded').removeClass('collapsed');
43
- document.cookie = "trestle:sidebar=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
43
+ Trestle.cookie.delete("trestle:sidebar");
44
44
  } else if ($(document).width() >= 1200) {
45
45
  sidebar.addClass('collapsed');
46
- document.cookie = "trestle:sidebar=collapsed; path=/";
46
+ Trestle.cookie.set("trestle:sidebar", "collapsed");
47
47
  } else if ($(document).width() >= 768) {
48
48
  sidebar.addClass('expanded');
49
- document.cookie = "trestle:sidebar=expanded; path=/";
49
+ Trestle.cookie.set("trestle:sidebar", "expanded");
50
50
  }
51
51
  });
52
+
53
+
54
+ // Toggle navigation groups
55
+
56
+ sidebar.find('.nav-header a').on('click', function(e) {
57
+ e.preventDefault();
58
+
59
+ $(this).closest('ul').toggleClass('collapsed');
60
+
61
+ var collapsed = sidebar.find('.collapsed .nav-header a').map(function() {
62
+ return $(this).attr('href').replace(/^#/, '');
63
+ }).toArray();
64
+
65
+ Trestle.cookie.set("trestle:navigation:collapsed", collapsed.join(","))
66
+ });
67
+
68
+
69
+ // Scroll sidebar to active item
70
+
71
+ var active = sidebar.find('.active');
72
+ sidebar.find('.app-sidebar-inner').scrollTop(active.offset().top - 100);
52
73
  });
@@ -22,6 +22,10 @@
22
22
  margin-bottom: 0;
23
23
  }
24
24
 
25
+ a {
26
+ color: white;
27
+ }
28
+
25
29
  @include mobile {
26
30
  padding: 5px 10px;
27
31
 
@@ -57,3 +61,27 @@
57
61
  }
58
62
  }
59
63
  }
64
+
65
+ .toggle-debug-errors {
66
+ &:hover, &:focus {
67
+ text-decoration: none;
68
+ }
69
+
70
+ &:after {
71
+ @extend .ion;
72
+ content: $ionicon-var-chevron-down;
73
+ font-size: 10px;
74
+ margin-left: 5px;
75
+ }
76
+ }
77
+
78
+ .debug-errors {
79
+ overflow: hidden;
80
+
81
+ ul {
82
+ list-style: none;
83
+ margin: 5px 0 0 0;
84
+ padding: 0 0 0 5px;
85
+ border-left: 4px solid rgba(white, 0.25);
86
+ }
87
+ }
@@ -38,7 +38,8 @@
38
38
  vertical-align: 0;
39
39
  }
40
40
 
41
- .nav-header {
41
+ .nav-header a {
42
+ position: relative;
42
43
  color: rgba(white, 0.25);
43
44
 
44
45
  text-transform: uppercase;
@@ -46,6 +47,24 @@
46
47
  font-size: 11px;
47
48
 
48
49
  padding: 5px 20px;
50
+
51
+ &:after {
52
+ @extend .ion;
53
+ content: $ionicon-var-arrow-down-b;
54
+
55
+ float: right;
56
+ margin-top: 2px;
57
+
58
+ opacity: 0.75;
59
+ }
60
+
61
+ &:hover, &:focus {
62
+ background: none;
63
+
64
+ &:after {
65
+ opacity: 1.0;
66
+ }
67
+ }
49
68
  }
50
69
 
51
70
  .active a {
@@ -62,14 +81,30 @@
62
81
  position: relative;
63
82
  top: 1px;
64
83
  }
84
+
85
+ .collapsed {
86
+ li {
87
+ display: none;
88
+
89
+ &.nav-header {
90
+ display: block;
91
+ }
92
+ }
93
+ }
65
94
  }
66
95
 
67
96
  @mixin collapsed-nav-header {
68
- border-bottom: 1px solid rgba(white, 0.1);
69
97
  height: 0;
70
- margin: 0 15px 14px;
71
- padding: 5px 0;
98
+ padding: 10px 15px 15px;
72
99
  text-indent: -99999px;
100
+
101
+ &:after {
102
+ display: block;
103
+ float: none;
104
+ margin-top: -12px;
105
+ content: '';
106
+ border-bottom: 1px solid rgba(white, 0.1);
107
+ }
73
108
  }
74
109
 
75
110
  @include tablet {
@@ -78,7 +113,7 @@
78
113
  display: none;
79
114
  }
80
115
 
81
- .nav-header {
116
+ .nav-header a {
82
117
  @include collapsed-nav-header;
83
118
  }
84
119
 
@@ -104,7 +139,7 @@
104
139
  display: none;
105
140
  }
106
141
 
107
- .nav-header {
142
+ .nav-header a {
108
143
  @include collapsed-nav-header;
109
144
  }
110
145
  }
@@ -1,13 +1,18 @@
1
1
  module Trestle
2
2
  module HookHelper
3
3
  def hook(name)
4
- safe_join(Trestle.config.hooks[name.to_s].map { |hook|
4
+ safe_join(hooks[name.to_s].map { |hook|
5
5
  instance_exec(&hook)
6
- }, "\n")
6
+ }, "\n") if hook?(name)
7
7
  end
8
8
 
9
9
  def hook?(name)
10
- Trestle.config.hooks[name.to_s].any?
10
+ hooks.key?(name.to_s) && hooks[name.to_s].any?
11
+ end
12
+
13
+ protected
14
+ def hooks
15
+ Trestle.config.hooks
11
16
  end
12
17
  end
13
18
  end
@@ -6,5 +6,7 @@
6
6
  <div class="alert-content">
7
7
  <h3><%= title %></h3>
8
8
  <p><%= message %></p>
9
+
10
+ <%= yield if block_given? %>
9
11
  </div>
10
12
  </div>
@@ -4,8 +4,22 @@
4
4
  title: t("trestle.flash.success.title", default: "Success!"),
5
5
  message: flash[:message] %>
6
6
  <% elsif flash[:error] -%>
7
- <%= render "alert", html_class: "alert-danger",
8
- icon: icon("alert-icon ion-ios-close-outline"),
9
- title: t("trestle.flash.failure.title", default: "Warning!"),
10
- message: flash[:error] %>
7
+ <%= render layout: "alert",
8
+ locals: {
9
+ html_class: "alert-danger",
10
+ icon: icon("alert-icon ion-ios-close-outline"),
11
+ title: t("trestle.flash.failure.title", default: "Warning!"),
12
+ message: flash[:error]
13
+ } do %>
14
+ <%- if Trestle.config.debug_form_errors && instance && instance.errors.any? -%>
15
+ <%= link_to "Debug errors", "#debug-errors", class: "toggle-debug-errors small", data: { toggle: "collapse" } %>
16
+ <div id="debug-errors" class="debug-errors collapse">
17
+ <ul>
18
+ <% instance.errors.each do |key, message| %>
19
+ <li class="small"><tt><%= key %>:</tt> <%= message %></li>
20
+ <% end %>
21
+ </ul>
22
+ </div>
23
+ <%- end -%>
24
+ <% end %>
11
25
  <% end -%>
@@ -1,4 +1,4 @@
1
- <% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize) %>
1
+ <% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize) %>
2
2
 
3
3
  <% content_for(:title, title) %>
4
4
  <% breadcrumb title %>
@@ -1,7 +1,10 @@
1
- <% content_for(:title, t("admin.titles.index", default: "Listing %{pluralized_model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize)) %>
1
+ <% content_for(:title, t("admin.titles.index", default: "Listing %{pluralized_model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize)) %>
2
2
 
3
3
  <% content_for(:primary_toolbar) do %>
4
- <%= link_to icon("fa fa-plus"), admin.path(:new), class: "btn btn-default btn-lg" unless admin.readonly? %>
4
+ <%= link_to admin.path(:new), class: "btn btn-default btn-lg" do %>
5
+ <%= icon("fa fa-plus") %>
6
+ <span class="sr-only"><%= t("admin.buttons.new", default: "New %{model_name}", model_name: admin.model_name) %></span>
7
+ <% end unless admin.readonly? %>
5
8
  <% end %>
6
9
 
7
10
  <% content_for(:utilities) do %>
@@ -1,4 +1,4 @@
1
- <% title = t("admin.titles.new", default: "New %{model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize) %>
1
+ <% title = t("admin.titles.new", default: "New %{model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize) %>
2
2
 
3
3
  <% content_for(:title, title) %>
4
4
  <% breadcrumb title %>
@@ -1,4 +1,4 @@
1
- <% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name, pluralized_model_name: admin.model_name.pluralize) %>
1
+ <% title = t("admin.titles.edit", default: "Editing %{model_name}", model_name: admin.model_name.titleize, pluralized_model_name: admin.model_name.plural.titleize) %>
2
2
 
3
3
  <% content_for(:title, title) %>
4
4
  <% breadcrumb title %>
@@ -12,10 +12,11 @@
12
12
 
13
13
  <div class="app-sidebar-inner">
14
14
  <nav class="app-nav">
15
+ <% collapsed = cookies["trestle:navigation:collapsed"].try(:split, ",") || [] %>
15
16
  <% Trestle.navigation.each do |group, items| %>
16
- <ul>
17
+ <ul<% if group.present? && collapsed.include?(group.id) %> class="collapsed"<% end %>>
17
18
  <% if group.present? %>
18
- <li class="nav-header"><%= group.label %></li>
19
+ <li class="nav-header"><%= link_to group.label, "##{group.id}" %></li>
19
20
  <% end %>
20
21
 
21
22
  <% items.each do |item| %>
@@ -7,15 +7,15 @@ en:
7
7
  flash:
8
8
  success:
9
9
  title: "Success!"
10
- create: "The %{model_name} was successfully created."
11
- update: "The %{model_name} was successfully updated."
12
- destroy: "The %{model_name} was successfully deleted."
10
+ create: "The %{lowercase_model_name} was successfully created."
11
+ update: "The %{lowercase_model_name} was successfully updated."
12
+ destroy: "The %{lowercase_model_name} was successfully deleted."
13
13
 
14
14
  failure:
15
15
  title: "Warning!"
16
16
  create: "Please correct the errors below."
17
17
  update: "Please correct the errors below."
18
- destroy: "Could not delete %{model_name}."
18
+ destroy: "Could not delete %{lowercase_model_name}."
19
19
 
20
20
  helpers:
21
21
  page_entries_info:
@@ -37,9 +37,11 @@ en:
37
37
  admin:
38
38
  titles:
39
39
  index: Listing %{pluralized_model_name}
40
+ new: New %{model_name}
40
41
  edit: Editing %{model_name}
41
42
 
42
43
  buttons:
44
+ new: New %{model_name}
43
45
  save: Save %{model_name}
44
46
  delete: Delete %{model_name}
45
47
 
@@ -0,0 +1,18 @@
1
+ {
2
+ nl: {
3
+ date: {
4
+ formats: {
5
+ trestle_date: proc { |date| "#{date.day} %b %Y" },
6
+ trestle_calendar: "%-d-%-m-%Y"
7
+ }
8
+ },
9
+
10
+ time: {
11
+ formats: {
12
+ trestle_date: proc { |time| "#{time.day} %b %Y" },
13
+ trestle_time: "%R %p",
14
+ trestle_time_with_seconds: "%T %p"
15
+ }
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,67 @@
1
+ nl:
2
+ trestle:
3
+ title: Trestle Admin
4
+ footer: Powered by Trestle
5
+ version: Versie
6
+
7
+ flash:
8
+ success:
9
+ title: "Gelukt!"
10
+ create: "De %{model_name} succesvol toegevoegd."
11
+ update: "De %{model_name} is succesvol gewijzigd."
12
+ destroy: "De %{model_name} is succesvol verwijderd."
13
+
14
+ failure:
15
+ title: "Waarschuwing!"
16
+ create: "Kon niet toevoegen om de volgende redenen."
17
+ update: "Kon niet aanpassen om de volgende redenen."
18
+ destroy: "Kon %{model_name} niet verwijderen."
19
+
20
+ helpers:
21
+ page_entries_info:
22
+ one_page:
23
+ display_entries:
24
+ zero: "Geen %{entry_name} gevonden"
25
+ one: "<strong>1</strong> %{entry_name} wordt weergeven"
26
+ other: "<strong>Alle %{count}</strong> %{entry_name} worden weergeven"
27
+
28
+ more_pages:
29
+ display_entries: "%{entry_name} <strong>%{first}&nbsp;-&nbsp;%{last}</strong> van de <b>%{total}</b> worden weergeven"
30
+
31
+ onboarding:
32
+ welcome: Welkom bij Trestle
33
+ no_admins: Voeg een admin toe in <code>app/admin</code> om te beginnen.
34
+ no_template: Maak <code>%{path}</code> aan om dit template aan te passen.
35
+ no_form: Definieer een form block of maak een <code>_form.html</code> partial.
36
+
37
+ admin:
38
+ titles:
39
+ index: Lijst van %{pluralized_model_name}
40
+ edit: "%{model_name} aanpassen"
41
+
42
+ buttons:
43
+ save: "%{model_name} opslaan"
44
+ delete: "%{model_name} verwijderen"
45
+
46
+ breadcrumbs:
47
+ home: Home
48
+
49
+ table:
50
+ headers:
51
+ id: ID
52
+
53
+ form:
54
+ select:
55
+ prompt: "- Selecteer %{attribute_name} -"
56
+
57
+ confirmation:
58
+ title: Weer je het zeker?
59
+ delete: Verwijderen
60
+ cancel: Annuleren
61
+
62
+ ui:
63
+ toggle_navigation: "Navigation tonen/verbergen"
64
+ toggle_sidebar: "Sidebar tonen/verbergen"
65
+
66
+ format:
67
+ blank: Geen
@@ -0,0 +1,18 @@
1
+ {
2
+ 'pt-BR': {
3
+ date: {
4
+ formats: {
5
+ trestle_date: proc { |date| "#{date.day}º %b %Y" },
6
+ trestle_calendar: "%-m/%-d/%Y"
7
+ }
8
+ },
9
+
10
+ time: {
11
+ formats: {
12
+ trestle_date: proc { |time| "#{time.day}º %b %Y" },
13
+ trestle_time: "%-l:%M %p",
14
+ trestle_time_with_seconds: "%l:%M:%S %p"
15
+ }
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,69 @@
1
+ pt-BR:
2
+ trestle:
3
+ title: Trestle Admin
4
+ footer: Powered by Trestle
5
+ version: Versão
6
+
7
+ flash:
8
+ success:
9
+ title: "Sucesso!"
10
+ create: "O %{model_name} foi criado com sucesso."
11
+ update: "O %{model_name} foi atualizado com sucesso."
12
+ destroy: "O %{model_name} foi deletado com sucesso."
13
+
14
+ failure:
15
+ title: "Atenção!"
16
+ create: "Por favor corrija os erros abaixo."
17
+ update: "Por favor corrija os erros abaixo."
18
+ destroy: "Falha ao excluir %{model_name}."
19
+
20
+ helpers:
21
+ page_entries_info:
22
+ one_page:
23
+ display_entries:
24
+ zero: "Nenhum %{entry_name} encontrado"
25
+ one: "Mostrando <strong>1</strong> %{entry_name}"
26
+ other: "Mostrando <strong>all %{count}</strong> %{entry_name}"
27
+
28
+ more_pages:
29
+ display_entries: "Mostrando %{entry_name} <strong>%{first}&nbsp;-&nbsp;%{last}</strong> de <b>%{total}</b>"
30
+
31
+ onboarding:
32
+ welcome: Bem-vindo ao Trestle
33
+ no_admins: Para começar, crie um admin dentro de <code>app/admin</code>.
34
+ no_template: Para personalizar este template, crie <code>%{path}</code>.
35
+ no_form: Defina um bloco de formulário ou crie um <code>_form.html</code> parcial.
36
+
37
+ admin:
38
+ titles:
39
+ index: Listando %{pluralized_model_name}
40
+ new: Novo %{model_name}
41
+ edit: Editando %{model_name}
42
+
43
+ buttons:
44
+ new: Novo %{model_name}
45
+ save: Salvar %{model_name}
46
+ delete: Excluir %{model_name}
47
+
48
+ breadcrumbs:
49
+ home: Home
50
+
51
+ table:
52
+ headers:
53
+ id: ID
54
+
55
+ form:
56
+ select:
57
+ prompt: "- Selecione %{attribute_name} -"
58
+
59
+ confirmation:
60
+ title: Você tem certeza?
61
+ delete: Excluir
62
+ cancel: Cancelar
63
+
64
+ ui:
65
+ toggle_navigation: Alternar naveção
66
+ toggle_sidebar: Alternar barra lateral
67
+
68
+ format:
69
+ blank: Nenhum
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'coveralls', require: false
5
+ gem 'simplecov', require: false
6
+
7
+ gem 'capybara'
8
+ gem 'capybara-selenium'
9
+ gem 'selenium-webdriver'
10
+ end
11
+
12
+ gem 'rails', '~> 4.2.0'
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'coveralls', require: false
5
+ gem 'simplecov', require: false
6
+
7
+ gem 'capybara'
8
+ gem 'capybara-selenium'
9
+ gem 'selenium-webdriver'
10
+ end
11
+
12
+ gem 'rails', '~> 5.0.0'
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'coveralls', require: false
5
+ gem 'simplecov', require: false
6
+
7
+ gem 'capybara'
8
+ gem 'capybara-selenium'
9
+ gem 'selenium-webdriver'
10
+ end
11
+
12
+ gem 'rails', '~> 5.1.0'
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'coveralls', require: false
5
+ gem 'simplecov', require: false
6
+
7
+ gem 'capybara'
8
+ gem 'capybara-selenium'
9
+ gem 'selenium-webdriver'
10
+ end
11
+
12
+ gem 'rails', github: 'rails/rails'
13
+ gem 'arel', github: 'rails/arel'
14
+
15
+ gemspec :path => "../"
@@ -105,4 +105,10 @@ Trestle.configure do |config|
105
105
  # end
106
106
  #
107
107
  # config.form_field :custom, CustomFormField
108
+
109
+ # == Debugging Options
110
+ #
111
+ # Enable debugging of form errors. Defaults to true in development mode.
112
+ #
113
+ # config.debug_form_errors = true
108
114
  end
@@ -18,6 +18,7 @@ module Trestle
18
18
  autoload :Configuration
19
19
  autoload :Display
20
20
  autoload :Form
21
+ autoload :ModelName
21
22
  autoload :Navigation
22
23
  autoload :Options
23
24
  autoload :Reloader
@@ -64,7 +64,7 @@ module Trestle
64
64
  option :persistent_params, [:sort, :order, :scope]
65
65
 
66
66
  # List of methods to try calling on an instance when displayed by the `display` helper
67
- option :display_methods, [:display_name, :full_name, :name, :title, :username, :login, :email, :to_s]
67
+ option :display_methods, [:display_name, :full_name, :name, :title, :username, :login, :email]
68
68
 
69
69
  # Default adapter class used by all admin resources
70
70
  option :default_adapter, Adapters.compose(Adapters::ActiveRecordAdapter, Adapters::DraperAdapter)
@@ -86,6 +86,12 @@ module Trestle
86
86
  option :javascript_i18n_keys, ["admin.confirmation.title", "admin.confirmation.delete", "admin.confirmation.cancel"]
87
87
 
88
88
 
89
+ ## Debugging
90
+
91
+ # Enable debugging of form errors
92
+ option :debug_form_errors, Rails.env.development?
93
+
94
+
89
95
  ## Callbacks
90
96
 
91
97
  Action = Struct.new(:options, :block)
@@ -14,7 +14,7 @@ module Trestle
14
14
 
15
15
  private
16
16
  def display_method
17
- @display_method ||= Trestle.config.display_methods.find { |m| @instance.respond_to?(m) }
17
+ @display_method ||= Trestle.config.display_methods.find { |m| @instance.respond_to?(m) } || :to_s
18
18
  end
19
19
  end
20
20
  end
@@ -0,0 +1,64 @@
1
+ require "active_model/naming"
2
+
3
+ module Trestle
4
+ class ModelName
5
+ attr_reader :klass
6
+
7
+ delegate :downcase, :upcase, :titleize, :titlecase, to: :to_s
8
+
9
+ def initialize(klass)
10
+ @klass = klass
11
+ @name = klass.respond_to?(:model_name) ? klass.model_name : ActiveModel::Name.new(klass)
12
+ end
13
+
14
+ def ==(other)
15
+ other.is_a?(self.class) && klass == other.klass
16
+ end
17
+
18
+ def to_s
19
+ singular
20
+ end
21
+
22
+ def singular(options={})
23
+ human(default_singular, options)
24
+ end
25
+ alias_method :singularize, :singular
26
+
27
+ def plural(options={})
28
+ if i18n_supported? && i18n_pluralizations_available?
29
+ human(default_plural, { count: :many }.merge(options))
30
+ else
31
+ default_plural
32
+ end
33
+ end
34
+ alias_method :pluralize, :plural
35
+
36
+ protected
37
+ # Default singular version if it cannot be determined from i18n
38
+ def default_singular
39
+ @name.name.demodulize.titleize
40
+ end
41
+
42
+ # Default plural version if it cannot be determined from i18n
43
+ def default_plural
44
+ singular.pluralize(I18n.locale)
45
+ end
46
+
47
+ # Safely delegates to ActiveModel::Name#human, catching exceptions caused by missing pluralizations
48
+ def human(default, options={})
49
+ @name.human(options.merge(default: default))
50
+ rescue I18n::InvalidPluralizationData
51
+ default
52
+ end
53
+
54
+ # Checks if the model can be translated by ActiveModel
55
+ def i18n_supported?
56
+ klass.respond_to?(:lookup_ancestors) && klass.respond_to?(:i18n_scope)
57
+ end
58
+
59
+ # Checks if multiple pluralization forms (e.g. zero/one/few/many/other) are available from i18n
60
+ def i18n_pluralizations_available?
61
+ @name.human(count: nil).is_a?(Hash)
62
+ end
63
+ end
64
+ end
@@ -40,6 +40,10 @@ module Trestle
40
40
  def label
41
41
  I18n.t("admin.navigation.groups.#{name}", default: name.to_s.titlecase)
42
42
  end
43
+
44
+ def id
45
+ name.to_s.parameterize
46
+ end
43
47
  end
44
48
 
45
49
  class NullGroup
@@ -59,6 +63,10 @@ module Trestle
59
63
  NullGroup.hash
60
64
  end
61
65
 
66
+ def id
67
+ nil
68
+ end
69
+
62
70
  def <=>(other)
63
71
  -1
64
72
  end
@@ -40,7 +40,7 @@ module Trestle
40
40
  end
41
41
 
42
42
  def label
43
- I18n.t("admin.navigation.items.#{name}", default: name.to_s.titlecase)
43
+ options[:label] || I18n.t("admin.navigation.items.#{name}", default: name.to_s.titlecase)
44
44
  end
45
45
 
46
46
  def icon
@@ -4,13 +4,15 @@ module Trestle
4
4
  self[hash]
5
5
  end
6
6
 
7
- def merge(other)
8
- dup.merge!(other)
7
+ def merge(other, &block)
8
+ dup.merge!(other, &block)
9
9
  end
10
10
 
11
- def merge!(other)
12
- deep_merge!(other || {}) do |key, v1, v2|
13
- if v1.is_a?(Array)
11
+ def merge!(other, &block)
12
+ super(other || {}) do |key, v1, v2|
13
+ if v1.is_a?(Hash) && v2.is_a?(Hash)
14
+ v1.merge(v2, &block)
15
+ elsif v1.is_a?(Array)
14
16
  v1 + Array(v2)
15
17
  else
16
18
  v2
@@ -119,7 +119,7 @@ module Trestle
119
119
  end
120
120
 
121
121
  def model_name
122
- options[:as] || default_model_name
122
+ @model_name ||= Trestle::ModelName.new(model)
123
123
  end
124
124
 
125
125
  def readonly?
@@ -127,7 +127,7 @@ module Trestle
127
127
  end
128
128
 
129
129
  def breadcrumb
130
- Breadcrumb.new(model_name.pluralize, path)
130
+ Breadcrumb.new(model_name.plural.titleize, path)
131
131
  end
132
132
 
133
133
  def routes
@@ -150,15 +150,6 @@ module Trestle
150
150
  rescue NameError
151
151
  raise NameError, "Unable to find model #{admin_name.classify}. Specify a different model using Trestle.resource(:#{admin_name}, model: MyModel)"
152
152
  end
153
-
154
- def default_model_name
155
- if model.respond_to?(:model_name)
156
- model_name = model.model_name
157
- model_name.respond_to?(:human) ? model_name.human : model_name.to_s.titleize
158
- else
159
- model.name.titleize
160
- end
161
- end
162
153
  end
163
154
  end
164
155
  end
@@ -25,7 +25,7 @@ module Trestle
25
25
  if admin.save_instance(instance)
26
26
  respond_to do |format|
27
27
  format.html do
28
- flash[:message] = flash_message("success.create", default: "The %{model_name} was successfully created.")
28
+ flash[:message] = flash_message("success.create", default: "The %{lowercase_model_name} was successfully created.")
29
29
  redirect_to action: :show, id: admin.to_param(instance)
30
30
  end
31
31
  format.json { render json: instance, status: :created, location: { action: :show, id: admin.to_param(instance) } }
@@ -62,7 +62,7 @@ module Trestle
62
62
  if admin.save_instance(instance)
63
63
  respond_to do |format|
64
64
  format.html do
65
- flash[:message] = flash_message("success.update", default: "The %{model_name} was successfully updated.")
65
+ flash[:message] = flash_message("success.update", default: "The %{lowercase_model_name} was successfully updated.")
66
66
  redirect_to action: :show, id: admin.to_param(instance)
67
67
  end
68
68
  format.json { render json: instance, status: :ok }
@@ -86,12 +86,17 @@ module Trestle
86
86
  respond_to do |format|
87
87
  format.html do
88
88
  if success
89
- flash[:message] = flash_message("success.destroy", default: "The %{model_name} was successfully deleted.")
89
+ flash[:message] = flash_message("success.destroy", default: "The %{lowercase_model_name} was successfully deleted.")
90
+ redirect_to action: :index
90
91
  else
91
- flash[:message] = flash_message("failure.destroy", default: "Could not delete %{model_name}.")
92
- end
92
+ flash[:error] = flash_message("failure.destroy", default: "Could not delete %{lowercase_model_name}.")
93
93
 
94
- redirect_to action: :index
94
+ if self.instance = admin.find_instance(params)
95
+ redirect_to action: :show, id: admin.to_param(instance)
96
+ else
97
+ redirect_to action: :index
98
+ end
99
+ end
95
100
  end
96
101
  format.json { head :no_content }
97
102
  format.js
@@ -106,7 +111,7 @@ module Trestle
106
111
  helper_method :instance
107
112
 
108
113
  def flash_message(type, options={})
109
- t("trestle.flash.#{type}", options.merge(model_name: admin.model_name.underscore.humanize(capitalize: false)))
114
+ t("trestle.flash.#{type}", options.merge(model_name: admin.model_name, lowercase_model_name: admin.model_name.downcase))
110
115
  end
111
116
  end
112
117
  end
@@ -9,11 +9,13 @@ module Trestle
9
9
  autoload :SelectColumn
10
10
  autoload :Row
11
11
 
12
- attr_reader :columns, :options
12
+ attr_reader :columns, :options, :admin
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
+
17
19
  @columns = []
18
20
  end
19
21
 
@@ -1,10 +1,10 @@
1
1
  module Trestle
2
2
  class Table
3
3
  class ActionsColumn
4
- attr_reader :table, :block
4
+ attr_reader :table, :options, :block
5
5
 
6
- def initialize(table, &block)
7
- @table = table
6
+ def initialize(table, options={}, &block)
7
+ @table, @options = table, options
8
8
  @block = block_given? ? block : default_actions
9
9
  end
10
10
 
@@ -23,37 +23,40 @@ module Trestle
23
23
 
24
24
  delegate :table, to: :@column
25
25
 
26
+ delegate :icon, :admin_url_for, :concat, :link_to, to: :@template
27
+
26
28
  def initialize(column, template, instance)
27
29
  @column, @template, @instance = column, template, instance
28
30
  end
29
31
 
32
+ def show
33
+ button(icon("fa fa-info"), admin_url_for(instance, admin: table.admin, action: :show), class: "btn-info")
34
+ end
35
+
36
+ def edit
37
+ button(icon("fa fa-pencil"), admin_url_for(instance, admin: table.admin, action: :edit), class: "btn-warning")
38
+ end
39
+
30
40
  def delete
31
- button(@template.icon("fa fa-trash"), @template.admin_url_for(instance, admin: table.options[:admin], action: :destroy), method: :delete, class: "btn-danger", data: { toggle: "confirm-delete", placement: "left" })
41
+ button(icon("fa fa-trash"), admin_url_for(instance, admin: table.admin, action: :destroy), method: :delete, class: "btn-danger", data: { toggle: "confirm-delete", placement: "left" })
32
42
  end
33
43
 
34
44
  def button(content, url, options={})
35
45
  options[:class] = Array(options[:class])
36
46
  options[:class] << "btn" unless options[:class].include?("btn")
37
47
 
38
- @template.concat @template.link_to(content, url, options)
48
+ concat link_to(content, url, options)
39
49
  end
40
50
  alias_method :link, :button
41
51
  end
42
52
 
43
53
  class Renderer < Column::Renderer
44
54
  def header
55
+ options[:header]
45
56
  end
46
57
 
47
58
  def classes
48
- "actions"
49
- end
50
-
51
- def options
52
- {}
53
- end
54
-
55
- def data
56
- {}
59
+ super + ["actions"]
57
60
  end
58
61
 
59
62
  def content(instance)
@@ -3,7 +3,6 @@ module Trestle
3
3
  class Automatic < Table
4
4
  def initialize(admin)
5
5
  super(sortable: true, admin: admin)
6
- @admin = admin
7
6
  end
8
7
 
9
8
  def columns
@@ -11,7 +10,7 @@ module Trestle
11
10
  end
12
11
 
13
12
  def content_columns
14
- @admin.default_table_attributes.map.with_index do |attribute, index|
13
+ admin.default_table_attributes.map.with_index do |attribute, index|
15
14
  case attribute.type
16
15
  when :association
17
16
  Column.new(self, attribute.association_name, sort: false)
@@ -25,8 +25,8 @@ module Trestle
25
25
  table.columns << Column.new(table, field, options, &(proc || block))
26
26
  end
27
27
 
28
- def actions(&block)
29
- table.columns << ActionsColumn.new(table, &block)
28
+ def actions(options={}, &block)
29
+ table.columns << ActionsColumn.new(table, options, &block)
30
30
  end
31
31
  end
32
32
  end
@@ -31,8 +31,8 @@ module Trestle
31
31
  def header
32
32
  if options[:header]
33
33
  options[:header]
34
- elsif admin = table.options[:admin]
35
- admin.human_attribute_name(field)
34
+ elsif table.admin
35
+ table.admin.human_attribute_name(field)
36
36
  else
37
37
  field.to_s.humanize.titleize
38
38
  end
@@ -62,7 +62,7 @@ module Trestle
62
62
  content = @template.admin_link_to(content, value)
63
63
  elsif options[:link]
64
64
  # Explicitly link to the specified admin, or the table's admin
65
- content = @template.admin_link_to(content, instance, admin: options[:admin] || @column.table.options[:admin])
65
+ content = @template.admin_link_to(content, instance, admin: options[:admin] || @column.table.admin)
66
66
  end
67
67
 
68
68
  content
@@ -21,7 +21,7 @@ module Trestle
21
21
 
22
22
  def options(instance)
23
23
  options = Trestle::Options.new
24
- options.merge!(data: { url: admin_url_for(instance) }) if table.options[:admin]
24
+ options.merge!(data: { url: admin_url_for(instance) }) if table.admin
25
25
  options.merge!(@row.options)
26
26
  options.merge!(@template.instance_exec(instance, &@row.block)) if @row.block
27
27
  options
@@ -29,7 +29,7 @@ module Trestle
29
29
 
30
30
  protected
31
31
  def admin_url_for(instance)
32
- @template.admin_url_for(instance, admin: table.options[:admin])
32
+ @template.admin_url_for(instance, admin: table.admin)
33
33
  end
34
34
  end
35
35
  end
@@ -1,3 +1,3 @@
1
1
  module Trestle
2
- VERSION = "0.8.4"
2
+ VERSION = "0.8.5"
3
3
  end
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.required_ruby_version = ">= 2.2.2"
35
35
 
36
36
  spec.add_dependency "railties", ">= 4.2.0"
37
+ spec.add_dependency "activemodel", ">= 4.2.0"
37
38
  spec.add_dependency "sass-rails", "~> 5.0.6"
38
39
  spec.add_dependency "autoprefixer-rails", "~> 7.1.2"
39
40
  spec.add_dependency "kaminari", "~> 1.0.1"
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.4
4
+ version: 0.8.5
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-08-24 00:00:00.000000000 Z
11
+ date: 2017-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.2.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: sass-rails
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -168,6 +182,7 @@ files:
168
182
  - app/assets/images/trestle/textures/billie-holiday.png
169
183
  - app/assets/images/trestle/textures/bright-squares.png
170
184
  - app/assets/javascripts/trestle/_confirmation.js
185
+ - app/assets/javascripts/trestle/_cookies.js
171
186
  - app/assets/javascripts/trestle/_datepicker.js
172
187
  - app/assets/javascripts/trestle/_errors.js
173
188
  - app/assets/javascripts/trestle/_form.js
@@ -264,7 +279,15 @@ files:
264
279
  - bower.json
265
280
  - config/locales/en.rb
266
281
  - config/locales/en.yml
282
+ - config/locales/nl.rb
283
+ - config/locales/nl.yml
284
+ - config/locales/pt-BR.rb
285
+ - config/locales/pt-BR.yml
267
286
  - config/routes.rb
287
+ - gemfiles/rails-4.2.gemfile
288
+ - gemfiles/rails-5.0.gemfile
289
+ - gemfiles/rails-5.1.gemfile
290
+ - gemfiles/rails-edge.gemfile
268
291
  - lib/generators/trestle/admin/admin_generator.rb
269
292
  - lib/generators/trestle/admin/templates/admin.rb.erb
270
293
  - lib/generators/trestle/admin/templates/index.html.erb
@@ -329,6 +352,7 @@ files:
329
352
  - lib/trestle/form/fields/url_field.rb
330
353
  - lib/trestle/form/fields/week_field.rb
331
354
  - lib/trestle/form/renderer.rb
355
+ - lib/trestle/model_name.rb
332
356
  - lib/trestle/navigation.rb
333
357
  - lib/trestle/navigation/block.rb
334
358
  - lib/trestle/navigation/group.rb
@@ -560,7 +584,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
560
584
  version: '0'
561
585
  requirements: []
562
586
  rubyforge_project:
563
- rubygems_version: 2.6.12
587
+ rubygems_version: 2.6.13
564
588
  signing_key:
565
589
  specification_version: 4
566
590
  summary: A modern, responsive admin framework for Ruby on Rails