trestle 0.8.9 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/trestle/components/_confirmation.js +31 -14
  3. data/app/assets/javascripts/trestle/components/_form.js +19 -15
  4. data/app/assets/javascripts/trestle/components/_tabs.js +1 -1
  5. data/app/assets/stylesheets/trestle/components/_breadcrumbs.scss +12 -0
  6. data/app/assets/stylesheets/trestle/components/_buttons.scss +102 -1
  7. data/app/assets/stylesheets/trestle/components/_content.scss +41 -21
  8. data/app/assets/stylesheets/trestle/components/_input-group.scss +8 -1
  9. data/app/assets/stylesheets/trestle/components/_modal.scss +3 -0
  10. data/app/assets/stylesheets/trestle/components/_pagination.scss +0 -3
  11. data/app/assets/stylesheets/trestle/components/_scopes.scss +11 -2
  12. data/app/assets/stylesheets/trestle/components/_table.scss +34 -10
  13. data/app/assets/stylesheets/trestle/components/_timestamp.scss +4 -1
  14. data/app/assets/stylesheets/trestle/components/_toolbars.scss +55 -0
  15. data/app/assets/stylesheets/trestle/core/_defaults.scss +13 -2
  16. data/app/assets/stylesheets/trestle/core/_mixins.scss +11 -0
  17. data/app/helpers/trestle/form_helper.rb +1 -5
  18. data/app/helpers/trestle/hook_helper.rb +10 -6
  19. data/app/helpers/trestle/timestamp_helper.rb +49 -7
  20. data/app/helpers/trestle/toolbars_helper.rb +34 -0
  21. data/app/views/layouts/trestle/admin.html.erb +2 -2
  22. data/app/views/trestle/application/_dialog.html.erb +8 -10
  23. data/app/views/trestle/application/_header.html.erb +22 -20
  24. data/app/views/trestle/resource/edit.html.erb +4 -6
  25. data/app/views/trestle/resource/index.html.erb +15 -6
  26. data/app/views/trestle/resource/new.html.erb +2 -2
  27. data/app/views/trestle/resource/show.html.erb +4 -6
  28. data/app/views/trestle/shared/_sidebar.html.erb +3 -1
  29. data/app/views/trestle/shared/_title.html.erb +14 -0
  30. data/config/locales/en.yml +2 -0
  31. data/config/locales/es-MX.yml +94 -0
  32. data/config/locales/es.yml +94 -0
  33. data/config/locales/lv.rb +18 -0
  34. data/config/locales/lv.yml +94 -0
  35. data/lib/generators/trestle/install/templates/trestle.rb.erb +12 -2
  36. data/lib/trestle.rb +2 -0
  37. data/lib/trestle/configuration.rb +9 -3
  38. data/lib/trestle/engine.rb +5 -3
  39. data/lib/trestle/form/fields/form_control.rb +14 -4
  40. data/lib/trestle/form/renderer.rb +2 -2
  41. data/lib/trestle/hook.rb +27 -0
  42. data/lib/trestle/table/actions_column.rb +31 -26
  43. data/lib/trestle/table/column.rb +1 -0
  44. data/lib/trestle/toolbar.rb +43 -0
  45. data/lib/trestle/toolbar/builder.rb +52 -0
  46. data/lib/trestle/toolbar/context.rb +39 -0
  47. data/lib/trestle/version.rb +1 -1
  48. metadata +13 -3
  49. data/app/helpers/trestle/title_helper.rb +0 -26
@@ -1,3 +1,17 @@
1
+ @mixin table-container-background($background) {
2
+ background-image: linear-gradient(to right, $background 30%, rgba($background, 0)),
3
+ linear-gradient(to left, $background 30%, rgba($background, 0)),
4
+ radial-gradient(at 0 50%, rgba(black, 0.2), rgba(black, 0) 70%),
5
+ radial-gradient(at 100% 50%, rgba(black, 0.2), rgba(black, 0) 70%);
6
+
7
+ background-color: $background;
8
+
9
+ background-position: 0 0, 100% 0, 0 0, 100% 0;
10
+ background-repeat: no-repeat;
11
+ background-size: 50px 100%, 50px 100%, 15px 100%, 15px 100%;
12
+ background-attachment: local, local, scroll, scroll;
13
+ }
14
+
1
15
  .table-container {
2
16
  overflow-x: auto;
3
17
 
@@ -5,15 +19,11 @@
5
19
  // scrolling background hints. Must be disabled explicitly.
6
20
  -webkit-overflow-scrolling: auto;
7
21
 
8
- background-image: linear-gradient(to right, white 30%, rgba(white, 0)),
9
- linear-gradient(to left, white 30%, rgba(white, 0)),
10
- radial-gradient(at 0 50%, rgba(black, 0.2), rgba(black, 0) 70%),
11
- radial-gradient(at 100% 50%, rgba(black, 0.2), rgba(black, 0) 70%);
12
- background-position: 0 0, 100% 0, 0 0, 100% 0;
13
- background-repeat: no-repeat;
14
- background-color: white;
15
- background-size: 50px 100%, 50px 100%, 15px 100%, 15px 100%;
16
- background-attachment: local, local, scroll, scroll;
22
+ @include table-container-background(white);
23
+
24
+ .main-content-sidebar & {
25
+ @include table-container-background($content-sidebar-background);
26
+ }
17
27
  }
18
28
 
19
29
  .trestle-table {
@@ -66,10 +76,24 @@
66
76
  text-align: center;
67
77
  }
68
78
 
69
- & + .btn {
79
+ &.has-icon .btn-label {
80
+ @include sr-only;
81
+ }
82
+ }
83
+
84
+ .btn,
85
+ .btn-group {
86
+ + .btn,
87
+ + .btn-group {
70
88
  margin-left: 4px;
71
89
  }
72
90
  }
91
+
92
+ .btn-group {
93
+ .btn + .btn {
94
+ margin-left: -1px;
95
+ }
96
+ }
73
97
  }
74
98
 
75
99
  .avatar {
@@ -5,8 +5,11 @@
5
5
  small {
6
6
  display: block;
7
7
  color: #666;
8
+ }
8
9
 
9
- .inline & {
10
+ &.timestamp-inline,
11
+ &.inline, {
12
+ small {
10
13
  display: inline;
11
14
  }
12
15
  }
@@ -0,0 +1,55 @@
1
+ .btn-toolbar {
2
+ .btn,
3
+ .btn-group,
4
+ .input-group {
5
+ float: none;
6
+ }
7
+
8
+ > .btn,
9
+ > .btn-group,
10
+ > .input-group {
11
+ margin-left: 1px;
12
+ }
13
+
14
+ .btn-group {
15
+ .btn + .btn,
16
+ .btn + .btn-group,
17
+ .btn-group + .btn,
18
+ .btn-group + .btn-group {
19
+ margin-left: -4px;
20
+ }
21
+ }
22
+ }
23
+
24
+ .primary-toolbar {
25
+ .btn {
26
+ @extend .btn-lg;
27
+ font-size: 20px;
28
+ padding: 8px 16px;
29
+ border-radius: $border-radius-base;
30
+
31
+ @include mobile {
32
+ font-size: 18px;
33
+ padding: 7px 12px;
34
+ }
35
+ }
36
+ }
37
+
38
+ .secondary-toolbar {
39
+ .btn {
40
+ font-size: 12px;
41
+ padding: 4px 10px;
42
+
43
+ i {
44
+ font-size: 11px;
45
+ }
46
+
47
+ @include mobile {
48
+ font-size: 11px;
49
+
50
+ i {
51
+ font-size: 10px;
52
+ }
53
+ }
54
+ }
55
+ }
@@ -32,7 +32,15 @@ $sidebar-toggle-color: rgba(white, 0.5) !default;
32
32
  $content-header-background: rgba(white, 0.6) !default;
33
33
 
34
34
  $content-sidebar-width: 285px !default;
35
- $content-sidebar-background: rgba(black, 0.025) !default;
35
+ $content-sidebar-background: #f9f9f9 !default;
36
+
37
+ $main-content-header-background: $content-sidebar-background !default;
38
+ $main-content-header-padding: 12px 20px !default;
39
+ $main-content-header-border: 1px solid rgba(black, 0.1) !default;
40
+
41
+ $main-content-footer-background: $content-sidebar-background !default;
42
+ $main-content-footer-padding: 12px 20px !default;
43
+ $main-content-footer-border: 1px solid rgba(black, 0.1) !default;
36
44
 
37
45
  $sidebar-transition-duration: 250ms !default;
38
46
 
@@ -41,7 +49,7 @@ $footer-text: #888 !default;
41
49
 
42
50
  $headings-font-weight: 400 !default;
43
51
 
44
- $btn-default-bg: #dbdbdb !default;
52
+ $btn-default-bg: #bbb !default;
45
53
  $btn-default-color: white !default;
46
54
 
47
55
  $state-success-bg: lighten(#dff0d8, 5%) !default;
@@ -83,4 +91,7 @@ $input-bg-disabled: #fafafa !default;
83
91
  $modal-inner-padding: 20px !default;
84
92
  $modal-title-padding: 15px 20px !default;
85
93
 
94
+ $modal-footer-background: $content-sidebar-background !default;
95
+ $modal-footer-border-color: rgba(black, 0.1) !default;
96
+
86
97
  $s2bs-btn-default-bg: #eee !default;
@@ -24,6 +24,17 @@
24
24
  right: 0;
25
25
  }
26
26
 
27
+ @mixin sr-only {
28
+ position: absolute;
29
+ width: 1px;
30
+ height: 1px;
31
+ margin: -1px;
32
+ padding: 0;
33
+ overflow: hidden;
34
+ clip: rect(0, 0, 0, 0);
35
+ border: 0;
36
+ }
37
+
27
38
  @mixin mobile {
28
39
  @media (max-width: $screen-xs-max) {
29
40
  @content;
@@ -5,7 +5,7 @@ module Trestle
5
5
  options[:as] ||= admin.parameter_name
6
6
 
7
7
  options[:data] ||= {}
8
- options[:data].merge!(remote: true, type: :html, behavior: "trestle-form", turbolinks: false)
8
+ options[:data].reverse_merge!(remote: true, type: :html, behavior: "trestle-form", turbolinks: false)
9
9
 
10
10
  form_for(instance, options) do |f|
11
11
  with_form(f) { yield f }
@@ -23,10 +23,6 @@ module Trestle
23
23
  @_trestle_form
24
24
  end
25
25
 
26
- def toolbar(name, &block)
27
- content_for(:"#{name}_toolbar", &block)
28
- end
29
-
30
26
  def sidebar(&block)
31
27
  content_for(:sidebar, &block)
32
28
  end
@@ -1,18 +1,22 @@
1
1
  module Trestle
2
2
  module HookHelper
3
3
  def hook(name)
4
- safe_join(hooks[name.to_s].map { |hook|
5
- instance_exec(&hook)
6
- }, "\n") if hook?(name)
4
+ if hook?(name)
5
+ safe_join(hooks(name).map { |hook|
6
+ hook.evaluate(self)
7
+ }, "\n")
8
+ elsif block_given?
9
+ yield
10
+ end
7
11
  end
8
12
 
9
13
  def hook?(name)
10
- hooks.key?(name.to_s) && hooks[name.to_s].any?
14
+ Trestle.config.hooks.key?(name.to_s) && hooks(name).any?
11
15
  end
12
16
 
13
17
  protected
14
- def hooks
15
- Trestle.config.hooks
18
+ def hooks(name)
19
+ Trestle.config.hooks[name.to_s].select { |h| h.visible?(self) }
16
20
  end
17
21
  end
18
22
  end
@@ -1,17 +1,59 @@
1
1
  module Trestle
2
2
  module TimestampHelper
3
- def timestamp(time)
4
- time_tag(time, class: "timestamp") do
3
+ # Renders a Time object as a formatted timestamp (using a <time> tag)
4
+ #
5
+ # time - The Time object to format.
6
+ # options - Hash of options (default: {}):
7
+ # :class - Additional HTML classes to add to the <time> tag.
8
+ # :precision - Time precision, either :minutes or :seconds (default: :minutes).
9
+ # :date_format - I18n date format to use for the date (default: :trestle_date).
10
+ # :time_format - I18n time format to use for the time (default: :trestle_time).
11
+ #
12
+ # Examples
13
+ #
14
+ # <%= timestamp(article.created_at) %>
15
+ #
16
+ # <%= timestamp(Time.current, class: "timestamp-inline", precision: :seconds) %>
17
+ #
18
+ # Returns the HTML representation of the given Time.
19
+ def timestamp(time, options={})
20
+ return unless time
21
+
22
+ classes = ["timestamp", options[:class]].compact
23
+ precision = options.fetch(:precision) { Trestle.config.timestamp_precision }
24
+ date_format = options.fetch(:date_format) { :trestle_date }
25
+ time_format = options.fetch(:time_format) { precision == :seconds ? :trestle_time_with_seconds : :trestle_time }
26
+
27
+ time_tag(time, class: classes) do
5
28
  safe_join([
6
- l(time, format: :trestle_date, default: proc { |date| "#{date.day.ordinalize} %b %Y" }),
7
- content_tag(:small, l(time, format: :trestle_time_with_seconds, default: "%l:%M:%S %p"))
29
+ l(time, format: date_format, default: proc { |date| "#{date.day.ordinalize} %b %Y" }),
30
+ content_tag(:small, l(time, format: time_format, default: "%l:%M:%S %p"))
8
31
  ], "\n")
9
32
  end
10
33
  end
11
34
 
12
- def datestamp(date)
13
- time_tag(date, class: "datestamp") do
14
- l(date, format: :trestle_calendar, default: "%-m/%-d/%Y")
35
+ # Renders a Date object as formatted datestamp (using a <time> tag)
36
+ #
37
+ # date - The Date object to format.
38
+ # options - Hash of options (default: {}):
39
+ # :class - Additional HTML classes to add to the <time> tag.
40
+ # :format - I18n date format to use (default: :trestle_calendar).
41
+ #
42
+ # Examples
43
+ #
44
+ # <%= datestamp(Date.current) %>
45
+ #
46
+ # <%= datestamp(article.created_at, format: :trestle_date, class: "custom-datestamp") %>
47
+ #
48
+ # Returns the HTML representation of the given Date.
49
+ def datestamp(date, options={})
50
+ return unless date
51
+
52
+ classes = ["datestamp", options[:class]].compact
53
+ format = options.fetch(:format) { :trestle_calendar}
54
+
55
+ time_tag(date, class: classes) do
56
+ l(date, format: format, default: "%-m/%-d/%Y")
15
57
  end
16
58
  end
17
59
  end
@@ -0,0 +1,34 @@
1
+ module Trestle
2
+ module ToolbarsHelper
3
+ def toolbar(name, &block)
4
+ toolbar = (toolbars[name.to_s] ||= Toolbar.new)
5
+ toolbar.prepend(&block) if block_given?
6
+ toolbar
7
+ end
8
+
9
+ def toolbars
10
+ @_toolbars ||= {}
11
+ end
12
+
13
+ def render_toolbar(toolbar, *args)
14
+ result = toolbar.groups(self, *args).map do |items|
15
+ if items.many?
16
+ content_tag(:div, class: "btn-group", role: "group") do
17
+ safe_join(items, "\n")
18
+ end
19
+ else
20
+ items.first
21
+ end
22
+ end
23
+
24
+ safe_join(result, "\n")
25
+ end
26
+
27
+ def deprecated_toolbar(name)
28
+ if content_for?(:"#{name}_toolbar")
29
+ ActiveSupport::Deprecation.warn("Using content_for(:#{name}_toolbar) is deprecated. Please use toolbar(:#{name}) instead.")
30
+ content_for(:"#{name}_toolbar")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -36,14 +36,14 @@
36
36
  <%= hook :head %>
37
37
  </head>
38
38
 
39
- <body<%= " class=\"sidebar-#{cookies["trestle:sidebar"]}\"" if cookies["trestle:sidebar"] %>>
39
+ <body<%=raw " class=\"sidebar-#{cookies["trestle:sidebar"]}\"" if cookies["trestle:sidebar"] %>>
40
40
  <div class="app-wrapper">
41
41
  <%= render "trestle/shared/sidebar" %>
42
42
 
43
43
  <div class="app-container">
44
44
  <%= render "trestle/shared/header" %>
45
45
 
46
- <main class="app-main" data-context="<%= request.path %>">
46
+ <main class="app-main" data-context="<%= request.fullpath %>">
47
47
  <%= yield %>
48
48
  </main>
49
49
 
@@ -22,15 +22,13 @@
22
22
  </div>
23
23
 
24
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 %>
25
+ <div class="btn-toolbar secondary-toolbar">
26
+ <%= render_toolbar(toolbar(:secondary)) %>
27
+ <%= deprecated_toolbar(:secondary) %>
28
+ </div>
30
29
 
31
- <% if content_for?(:primary_toolbar) %>
32
- <div class="btn-toolbar primary-toolbar">
33
- <%= content_for(:primary_toolbar) %>
34
- </div>
35
- <% end %>
30
+ <div class="btn-toolbar primary-toolbar">
31
+ <%= render_toolbar(toolbar(:primary)) %>
32
+ <%= deprecated_toolbar(:primary) %>
33
+ </div>
36
34
  </div>
@@ -1,27 +1,29 @@
1
1
  <header class="content-header">
2
- <% if content_for?(:primary_toolbar) %>
2
+ <div class="content-header-title">
3
+ <h1>
4
+ <%= content_for(:title) %>
5
+ </h1>
6
+
7
+ <% unless local_assigns.fetch(:hide_breadcrumbs, false) %>
8
+ <ol class="breadcrumb">
9
+ <% breadcrumbs.each do |breadcrumb| %>
10
+ <li class="breadcrumb-item<% if breadcrumb == breadcrumbs.last %> active<% end %>">
11
+ <%= link_to breadcrumb.label, breadcrumb.path %>
12
+ </li>
13
+ <% end %>
14
+ </ol>
15
+ <% end %>
16
+ </div>
17
+
18
+ <div class="content-header-toolbars">
3
19
  <div class="btn-toolbar primary-toolbar">
4
- <%= content_for(:primary_toolbar) %>
20
+ <%= render_toolbar(toolbar(:primary)) %>
21
+ <%= deprecated_toolbar(:primary) %>
5
22
  </div>
6
- <% end %>
7
23
 
8
- <% if content_for?(:secondary_toolbar) %>
9
24
  <div class="btn-toolbar secondary-toolbar">
10
- <%= content_for(:secondary_toolbar) %>
25
+ <%= render_toolbar(toolbar(:secondary)) %>
26
+ <%= deprecated_toolbar(:secondary) %>
11
27
  </div>
12
- <% end %>
13
-
14
- <h1>
15
- <%= content_for(:title) %>
16
- </h1>
17
-
18
- <% unless local_assigns.fetch(:hide_breadcrumbs, false) %>
19
- <ol class="breadcrumb">
20
- <% breadcrumbs.each do |breadcrumb| %>
21
- <li class="breadcrumb-item<% if breadcrumb == breadcrumbs.last %> active<% end %>">
22
- <%= link_to breadcrumb.label, breadcrumb.path %>
23
- </li>
24
- <% end %>
25
- </ol>
26
- <% end %>
28
+ </div>
27
29
  </header>
@@ -3,14 +3,12 @@
3
3
  <% content_for(:title, title) %>
4
4
  <% breadcrumb(title) %>
5
5
 
6
- <% content_for(:primary_toolbar) do %>
7
- <%= button_tag admin.t("buttons.save", default: "Save %{model_name}"), class: "btn btn-success btn-lg" if admin.actions.include?(:update) %>
6
+ <% toolbar(:primary) do |t| %>
7
+ <%= t.button admin.t("buttons.save", default: "Save %{model_name}"), style: :success if admin.actions.include?(:update) %>
8
8
  <% end %>
9
9
 
10
- <% content_for(:secondary_toolbar) do %>
11
- <%= admin_link_to instance, action: :destroy, method: :delete, class: "btn btn-danger", data: { toggle: "confirm-delete", placement: "bottom" } do %>
12
- <%= icon("fa fa-trash") %> <%= admin.t("buttons.delete", default: "Delete %{model_name}") %>
13
- <% end if admin.actions.include?(:destroy) %>
10
+ <% toolbar(:secondary) do |t| %>
11
+ <%= t.link admin.t("buttons.delete", default: "Delete %{model_name}"), instance, action: :destroy, method: :delete, style: :danger, icon: "fa fa-trash", data: { toggle: "confirm-delete", placement: "bottom" } if admin.actions.include?(:destroy) %>
14
12
  <% end %>
15
13
 
16
14
  <%= trestle_form_for instance, url: admin.actions.include?(:update) ? admin.instance_path(instance, action: :update) : "#", method: :patch do |f| %>