trestle 0.8.5 → 0.8.6

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/trestle/admin.js +11 -10
  3. data/app/assets/javascripts/trestle/{_confirmation.js → components/_confirmation.js} +1 -1
  4. data/app/assets/javascripts/trestle/{_datepicker.js → components/_datepicker.js} +4 -4
  5. data/app/assets/javascripts/trestle/components/_dialog.js +107 -0
  6. data/app/assets/javascripts/trestle/{_errors.js → components/_errors.js} +2 -2
  7. data/app/assets/javascripts/trestle/components/_form.js +48 -0
  8. data/app/assets/javascripts/trestle/{_gallery.js → components/_gallery.js} +3 -3
  9. data/app/assets/javascripts/trestle/{_select.js → components/_select.js} +2 -2
  10. data/app/assets/javascripts/trestle/{_sidebar.js → components/_sidebar.js} +3 -1
  11. data/app/assets/javascripts/trestle/{_table.js → components/_table.js} +1 -1
  12. data/app/assets/javascripts/trestle/components/_tabs.js +24 -0
  13. data/app/assets/javascripts/trestle/components/_tooltips.js +3 -0
  14. data/app/assets/javascripts/trestle/core/_contexts.js +13 -0
  15. data/app/assets/javascripts/trestle/{_cookies.js → core/_cookies.js} +2 -1
  16. data/app/assets/javascripts/trestle/core/_events.js +39 -0
  17. data/app/assets/javascripts/trestle/core/_visit.js +10 -0
  18. data/app/assets/stylesheets/trestle/components/_buttons.scss +9 -0
  19. data/app/assets/stylesheets/trestle/components/_modal.scss +92 -0
  20. data/app/assets/stylesheets/trestle/components/_navigation.scss +47 -12
  21. data/app/assets/stylesheets/trestle/components/_sidebar.scss +1 -0
  22. data/app/assets/stylesheets/trestle/core/_defaults.scss +5 -1
  23. data/app/controllers/trestle/application_controller.rb +5 -1
  24. data/app/helpers/trestle/dialog_helper.rb +7 -0
  25. data/app/helpers/trestle/form_helper.rb +7 -0
  26. data/app/helpers/trestle/url_helper.rb +34 -6
  27. data/app/views/layouts/trestle/admin.html.erb +1 -1
  28. data/app/views/trestle/application/_dialog.html.erb +36 -0
  29. data/app/views/trestle/application/_tabs.html.erb +7 -1
  30. data/app/views/trestle/resource/edit.html.erb +5 -5
  31. data/app/views/trestle/resource/index.html.erb +2 -2
  32. data/app/views/trestle/resource/new.html.erb +2 -2
  33. data/app/views/trestle/resource/show.html.erb +5 -5
  34. data/bower.json +1 -1
  35. data/config/locales/en.yml +25 -21
  36. data/config/locales/fr.rb +18 -0
  37. data/config/locales/fr.yml +69 -0
  38. data/config/locales/nl.yml +14 -14
  39. data/config/locales/pl.rb +18 -0
  40. data/config/locales/pl.yml +70 -0
  41. data/config/locales/pt-BR.yml +22 -22
  42. data/lib/generators/trestle/resource/templates/admin.rb.erb +1 -1
  43. data/lib/trestle/admin.rb +14 -1
  44. data/lib/trestle/admin/builder.rb +10 -2
  45. data/lib/trestle/breadcrumb.rb +13 -0
  46. data/lib/trestle/configuration.rb +6 -1
  47. data/lib/trestle/form.rb +7 -3
  48. data/lib/trestle/form/automatic.rb +1 -1
  49. data/lib/trestle/reloader.rb +1 -1
  50. data/lib/trestle/resource.rb +20 -5
  51. data/lib/trestle/resource/builder.rb +15 -0
  52. data/lib/trestle/resource/controller.rb +19 -6
  53. data/lib/trestle/table.rb +4 -0
  54. data/lib/trestle/table/actions_column.rb +9 -7
  55. data/lib/trestle/table/column.rb +3 -2
  56. data/lib/trestle/table/row.rb +7 -1
  57. data/lib/trestle/version.rb +1 -1
  58. data/trestle.gemspec +3 -3
  59. data/vendor/assets/bower_components/trestle/select2/dist/js/select2.full.js +90 -69
  60. metadata +30 -19
  61. data/app/assets/javascripts/trestle/_form.js +0 -6
  62. data/app/assets/javascripts/trestle/_tabs.js +0 -13
  63. data/app/assets/javascripts/trestle/_tooltips.js +0 -3
@@ -48,7 +48,7 @@
48
48
 
49
49
  padding: 5px 20px;
50
50
 
51
- &:after {
51
+ &::after {
52
52
  @extend .ion;
53
53
  content: $ionicon-var-arrow-down-b;
54
54
 
@@ -61,8 +61,8 @@
61
61
  &:hover, &:focus {
62
62
  background: none;
63
63
 
64
- &:after {
65
- opacity: 1.0;
64
+ &::before, &::after {
65
+ opacity: 1 !important;
66
66
  }
67
67
  }
68
68
  }
@@ -98,12 +98,28 @@
98
98
  padding: 10px 15px 15px;
99
99
  text-indent: -99999px;
100
100
 
101
- &:after {
102
- display: block;
103
- float: none;
104
- margin-top: -12px;
105
- content: '';
101
+ &::after {
102
+ display: none;
103
+
104
+ position: absolute;
105
+ top: 4px;
106
+ left: 50%;
107
+ margin-left: -3px;
108
+
109
+ text-indent: 0;
110
+ }
111
+
112
+ &::before {
113
+ content: "";
114
+
115
+ position: absolute;
116
+ left: 15px;
117
+ right: 15px;
118
+ top: 50%;
119
+ margin-top: -4px;
120
+
106
121
  border-bottom: 1px solid rgba(white, 0.1);
122
+ opacity: 0.75;
107
123
  }
108
124
  }
109
125
 
@@ -117,14 +133,27 @@
117
133
  @include collapsed-nav-header;
118
134
  }
119
135
 
120
- .expanded & {
121
- .nav-header {
136
+ .collapsed .nav-header a {
137
+ &::after {
122
138
  display: block;
123
- border-bottom: none;
139
+ }
140
+ }
141
+
142
+ .expanded & {
143
+ .nav-header a {
124
144
  height: auto;
125
- margin: 0;
126
145
  padding: 5px 20px;
127
146
  text-indent: 0;
147
+
148
+ &::before {
149
+ display: none;
150
+ }
151
+
152
+ &::after {
153
+ display: block;
154
+ position: static;
155
+ margin-left: 0;
156
+ }
128
157
  }
129
158
 
130
159
  .nav-label { display: inline; }
@@ -142,5 +171,11 @@
142
171
  .nav-header a {
143
172
  @include collapsed-nav-header;
144
173
  }
174
+
175
+ .collapsed .nav-header a {
176
+ &::after {
177
+ display: block;
178
+ }
179
+ }
145
180
  }
146
181
  }
@@ -15,6 +15,7 @@
15
15
  display: flex;
16
16
  flex-direction: column;
17
17
 
18
+ overflow-x: hidden;
18
19
  overflow-y: auto;
19
20
 
20
21
  &::-webkit-scrollbar {
@@ -11,6 +11,7 @@ $theme-bg-gradient: linear-gradient(rgba(white, $theme-bg-gradient-stre
11
11
  $theme-bg-color: darken($brand-primary, 15%) !default;
12
12
 
13
13
  $theme-bg: $theme-bg-texture-url, $theme-bg-gradient, $theme-bg-color !default;
14
+ $error-bg: $theme-bg-texture-url, $theme-bg-gradient, $brand-danger !default;
14
15
 
15
16
  $body-bg: #f3f3f3 !default;
16
17
 
@@ -45,7 +46,7 @@ $btn-default-color: white !default;
45
46
 
46
47
  $state-success-bg: lighten(#dff0d8, 5%) !default;
47
48
  $state-info-bg: lighten(#d9edf7, 5%) !default;
48
- $state-warning-bg: lighten(#fcf8e3, 5%) !default;
49
+ $state-warning-bg: lighten(#fcf8e3, 2.5%) !default;
49
50
  $state-danger-bg: lighten(#f2dede, 5%) !default;
50
51
 
51
52
  $alert-padding: 20px !default;
@@ -79,4 +80,7 @@ $input-border: #ccc !default;
79
80
  $input-border-focus: mix($brand-primary, $input-border) !default;
80
81
  $input-bg-disabled: #fafafa !default;
81
82
 
83
+ $modal-inner-padding: 20px !default;
84
+ $modal-title-padding: 15px 20px !default;
85
+
82
86
  $s2bs-btn-default-bg: #eee !default;
@@ -1,7 +1,7 @@
1
1
  class Trestle::ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
3
 
4
- layout 'trestle/admin'
4
+ layout :choose_layout
5
5
 
6
6
  # Global helpers
7
7
  self.helpers_path += Rails.application.helpers_paths
@@ -31,4 +31,8 @@ protected
31
31
  breadcrumbs.append(label, path)
32
32
  end
33
33
  helper_method :breadcrumb
34
+
35
+ def choose_layout
36
+ request.xhr? ? false : "trestle/admin"
37
+ end
34
38
  end
@@ -0,0 +1,7 @@
1
+ module Trestle
2
+ module DialogHelper
3
+ def dialog_request?
4
+ request.headers["X-Trestle-Dialog"]
5
+ end
6
+ end
7
+ end
@@ -4,6 +4,9 @@ module Trestle
4
4
  options[:builder] ||= Form::Builder
5
5
  options[:as] ||= admin.admin_name.singularize
6
6
 
7
+ options[:data] ||= {}
8
+ options[:data].merge!(remote: true, type: :html, behavior: "trestle-form", turbolinks: false)
9
+
7
10
  form_for(instance, options) do |f|
8
11
  with_form(f) { yield f }
9
12
  end
@@ -27,5 +30,9 @@ module Trestle
27
30
  def sidebar(&block)
28
31
  content_for(:sidebar, &block)
29
32
  end
33
+
34
+ def render_sidebar_as_tab?
35
+ dialog_request? && content_for?(:sidebar)
36
+ end
30
37
  end
31
38
  end
@@ -1,20 +1,48 @@
1
1
  module Trestle
2
2
  module UrlHelper
3
- def admin_link_to(content, instance=nil, options={}, &block)
3
+ def admin_link_to(content, instance_or_url=nil, options={}, &block)
4
4
  if block_given?
5
- instance, options = content, instance || {}
5
+ instance_or_url, options = content, instance_or_url || {}
6
6
  content = capture(&block)
7
7
  end
8
8
 
9
- if admin = (options.key?(:admin) ? Trestle.lookup(options.delete(:admin)) : admin_for(instance))
10
- link_to(content, admin_url_for(instance, admin: admin), options)
9
+ if instance_or_url.is_a?(String)
10
+ link_to(content, instance_or_url, options)
11
11
  else
12
- content
12
+ if instance_or_url.is_a?(Hash)
13
+ instance_or_url, options = nil, instance_or_url
14
+ end
15
+
16
+ if options.key?(:admin)
17
+ admin = Trestle.lookup(options.delete(:admin))
18
+ elsif instance_or_url.respond_to?(:id)
19
+ admin = admin_for(instance_or_url)
20
+ end
21
+
22
+ admin ||= self.admin if respond_to?(:admin)
23
+
24
+ if admin
25
+ action = options.delete(:action) || :show
26
+
27
+ params = options.delete(:params) || {}
28
+ params[:id] ||= admin.to_param(instance_or_url) if instance_or_url
29
+
30
+ if [:show, :edit].include?(action) && admin.form.dialog?
31
+ options[:data] ||= {}
32
+ options[:data][:behavior] ||= "dialog"
33
+ end
34
+
35
+ link_to(content, admin.path(action, params), options)
36
+ else
37
+ raise ActionController::UrlGenerationError, "An admin could not be inferred. Please specify an admin using the :admin option."
38
+ end
13
39
  end
14
40
  end
15
41
 
16
42
  def admin_url_for(instance, options={})
17
- admin = options.key?(:admin) ? Trestle.lookup(options[:admin]) : admin_for(instance)
43
+ admin = Trestle.lookup(options[:admin]) if options.key?(:admin)
44
+ admin ||= admin_for(instance)
45
+
18
46
  admin.path(options[:action] || :show, id: admin.to_param(instance)) if admin
19
47
  end
20
48
 
@@ -45,7 +45,7 @@
45
45
  <div class="app-container">
46
46
  <%= render "trestle/shared/header" %>
47
47
 
48
- <main class="app-main">
48
+ <main class="app-main" data-context="<%= request.path %>">
49
49
  <%= yield %>
50
50
  </main>
51
51
 
@@ -0,0 +1,36 @@
1
+ <div class="modal-header">
2
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
3
+ <h4 class="modal-title"><%= content_for(:title) %></h4>
4
+ </div>
5
+
6
+ <div class="modal-flash">
7
+ <%= render "flash" %>
8
+ </div>
9
+
10
+ <div class="modal-tabs">
11
+ <%= render "tabs" %>
12
+ </div>
13
+
14
+ <div class="modal-body">
15
+ <%= yield %>
16
+
17
+ <% if content_for?(:sidebar) %>
18
+ <div id="tab-sidebar" class="tab-pane" role="tabpanel">
19
+ <%= content_for(:sidebar) %>
20
+ </div>
21
+ <% end %>
22
+ </div>
23
+
24
+ <div class="modal-footer">
25
+ <% if content_for?(:secondary_toolbar) %>
26
+ <div class="btn-toolbar secondary-toolbar">
27
+ <%= content_for(:secondary_toolbar) %>
28
+ </div>
29
+ <% end %>
30
+
31
+ <% if content_for?(:primary_toolbar) %>
32
+ <div class="btn-toolbar primary-toolbar">
33
+ <%= content_for(:primary_toolbar) %>
34
+ </div>
35
+ <% end %>
36
+ </div>
@@ -1,9 +1,15 @@
1
- <% if tabs.size > 1 -%>
1
+ <% if tabs.size > 1 || render_sidebar_as_tab? -%>
2
2
  <ul class="nav nav-tabs">
3
3
  <% tabs.each do |name, tab| %>
4
4
  <li<% if name == tabs.keys.first %> class="active"<% end %>>
5
5
  <%= link_to tab.label, "#tab-#{name}", role: "tab", data: { toggle: "tab" } %>
6
6
  </li>
7
7
  <% end %>
8
+
9
+ <% if render_sidebar_as_tab? %>
10
+ <li class="pull-right">
11
+ <%= link_to icon("fa fa-list-alt"), "#tab-sidebar", role: "tab", data: { toggle: "tab" } %>
12
+ </li>
13
+ <% end %>
8
14
  </ul>
9
15
  <% end %>
@@ -4,15 +4,15 @@
4
4
  <% breadcrumb title %>
5
5
 
6
6
  <% content_for(:primary_toolbar) do %>
7
- <%= button_tag t("admin.buttons.save", default: "Save %{model_name}", model_name: admin.model_name), class: "btn btn-success btn-lg" unless admin.readonly? %>
7
+ <%= button_tag t("admin.buttons.save", default: "Save %{model_name}", model_name: admin.model_name), class: "btn btn-success btn-lg" if admin.actions.include?(:update) %>
8
8
  <% end %>
9
9
 
10
10
  <% content_for(:secondary_toolbar) do %>
11
- <%= link_to admin.path(:destroy, id: admin.to_param(instance)), method: :delete, class: "btn btn-danger", data: { toggle: "confirm-delete", placement: "bottom" } do %>
11
+ <%= admin_link_to instance, action: :destroy, method: :delete, class: "btn btn-danger", data: { toggle: "confirm-delete", placement: "bottom" } do %>
12
12
  <%= icon("fa fa-trash") %> <%= t("admin.buttons.delete", default: "Delete %{model_name}", model_name: admin.model_name) %>
13
- <% end unless admin.readonly? %>
13
+ <% end if admin.actions.include?(:destroy) %>
14
14
  <% end %>
15
15
 
16
- <%= trestle_form_for instance, url: admin.readonly? ? "#" : admin.path(:update, id: admin.to_param(instance)), method: :patch do |f| %>
17
- <%= render partial: "form", layout: "layout" %>
16
+ <%= trestle_form_for instance, url: admin.actions.include?(:update) ? admin.path(:update, id: admin.to_param(instance)) : "#", method: :patch do |f| %>
17
+ <%= render partial: "form", layout: dialog_request? ? "dialog" : "layout" %>
18
18
  <% end %>
@@ -1,10 +1,10 @@
1
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 admin.path(:new), class: "btn btn-default btn-lg" do %>
4
+ <%= admin_link_to action: :new, class: "btn btn-default btn-lg" do %>
5
5
  <%= icon("fa fa-plus") %>
6
6
  <span class="sr-only"><%= t("admin.buttons.new", default: "New %{model_name}", model_name: admin.model_name) %></span>
7
- <% end unless admin.readonly? %>
7
+ <% end if admin.actions.include?(:new) %>
8
8
  <% end %>
9
9
 
10
10
  <% content_for(:utilities) do %>
@@ -4,9 +4,9 @@
4
4
  <% breadcrumb title %>
5
5
 
6
6
  <% content_for(:primary_toolbar) do %>
7
- <%= button_tag t("admin.buttons.save", default: "Save %{model_name}", model_name: admin.model_name), class: "btn btn-success btn-lg" %>
7
+ <%= button_tag t("admin.buttons.save", default: "Save %{model_name}", model_name: admin.model_name), class: "btn btn-success btn-lg" if admin.actions.include?(:create) %>
8
8
  <% end %>
9
9
 
10
10
  <%= trestle_form_for instance, url: admin.path, method: :post do |f| %>
11
- <%= render partial: "form", layout: "layout" %>
11
+ <%= render partial: "form", layout: dialog_request? ? "dialog" : "layout" %>
12
12
  <% end %>
@@ -4,15 +4,15 @@
4
4
  <% breadcrumb title %>
5
5
 
6
6
  <% content_for(:primary_toolbar) do %>
7
- <%= button_tag t("admin.buttons.save", default: "Save %{model_name}", model_name: admin.model_name), class: "btn btn-success btn-lg" unless admin.readonly? %>
7
+ <%= button_tag t("admin.buttons.save", default: "Save %{model_name}", model_name: admin.model_name), class: "btn btn-success btn-lg" if admin.actions.include?(:update) %>
8
8
  <% end %>
9
9
 
10
10
  <% content_for(:secondary_toolbar) do %>
11
- <%= link_to admin.path(:destroy, id: admin.to_param(instance)), method: :delete, class: "btn btn-danger", data: { toggle: "confirm-delete", placement: "bottom" } do %>
11
+ <%= admin_link_to instance, action: :destroy, method: :delete, class: "btn btn-danger", data: { toggle: "confirm-delete", placement: "bottom" } do %>
12
12
  <%= icon("fa fa-trash") %> <%= t("admin.buttons.delete", default: "Delete %{model_name}", model_name: admin.model_name) %>
13
- <% end unless admin.readonly? %>
13
+ <% end if admin.actions.include?(:destroy) %>
14
14
  <% end %>
15
15
 
16
- <%= trestle_form_for instance, url: admin.readonly? ? "#" : admin.path(:update, id: admin.to_param(instance)), method: :patch do |f| %>
17
- <%= render partial: "form", layout: "layout" %>
16
+ <%= trestle_form_for instance, url: admin.actions.include?(:update) ? admin.path(:update, id: admin.to_param(instance)) : "#", method: :patch do |f| %>
17
+ <%= render partial: "form", layout: dialog_request? ? "dialog" : "layout" %>
18
18
  <% end %>
data/bower.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "magnific-popup": "~1.1.0",
10
10
  "bootstrap-confirmation2": "~2.4.0",
11
11
  "flatpickr": "~3.0.7",
12
- "select2": "~4.0.3",
12
+ "select2": "~4.0.5",
13
13
  "select2-bootstrap-theme": "~0.1.0"
14
14
  }
15
15
  }
@@ -1,8 +1,8 @@
1
1
  en:
2
2
  trestle:
3
- title: Trestle Admin
4
- footer: Powered by Trestle
5
- version: Version
3
+ title: "Trestle Admin"
4
+ footer: "Powered by Trestle"
5
+ version: "Version"
6
6
 
7
7
  flash:
8
8
  success:
@@ -29,41 +29,45 @@ en:
29
29
  display_entries: "Displaying %{entry_name} <strong>%{first}&nbsp;-&nbsp;%{last}</strong> of <b>%{total}</b>"
30
30
 
31
31
  onboarding:
32
- welcome: Welcome to Trestle
33
- no_admins: To begin, please create an admin within <code>app/admin</code>.
34
- no_template: To customize this template, please create <code>%{path}</code>.
35
- no_form: Please define a form block or create a <code>_form.html</code> partial.
32
+ welcome: "Welcome to Trestle"
33
+ no_admins: "To begin, please create an admin within <code>app/admin</code>."
34
+ no_template: "To customize this template, please create <code>%{path}</code>."
35
+ no_form: "Please define a form block or create a <code>_form.html</code> partial."
36
+
37
+ dialog:
38
+ error: "The request could not be completed."
36
39
 
37
40
  admin:
38
41
  titles:
39
- index: Listing %{pluralized_model_name}
40
- new: New %{model_name}
41
- edit: Editing %{model_name}
42
+ index: "Listing %{pluralized_model_name}"
43
+ new: "New %{model_name}"
44
+ edit: "Editing %{model_name}"
42
45
 
43
46
  buttons:
44
- new: New %{model_name}
45
- save: Save %{model_name}
46
- delete: Delete %{model_name}
47
+ new: "New %{model_name}"
48
+ save: "Save %{model_name}"
49
+ delete: "Delete %{model_name}"
50
+ ok: "OK"
47
51
 
48
52
  breadcrumbs:
49
- home: Home
53
+ home: "Home"
50
54
 
51
55
  table:
52
56
  headers:
53
- id: ID
57
+ id: "ID"
54
58
 
55
59
  form:
56
60
  select:
57
61
  prompt: "- Select %{attribute_name} -"
58
62
 
59
63
  confirmation:
60
- title: Are you sure?
61
- delete: Delete
62
- cancel: Cancel
64
+ title: "Are you sure?"
65
+ delete: "Delete"
66
+ cancel: "Cancel"
63
67
 
64
68
  ui:
65
- toggle_navigation: Toggle navigation
66
- toggle_sidebar: Toggle sidebar
69
+ toggle_navigation: "Toggle navigation"
70
+ toggle_sidebar: "Toggle sidebar"
67
71
 
68
72
  format:
69
- blank: None
73
+ blank: "None"