trestle 0.8.6 → 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +10 -9
- data/app/assets/javascripts/trestle/components/_dialog.js +29 -8
- data/app/assets/javascripts/trestle/components/_form.js +28 -7
- data/app/assets/javascripts/trestle/components/_sidebar.js +10 -8
- data/app/assets/javascripts/trestle/components/_tabs.js +2 -1
- data/app/assets/javascripts/trestle/components/_tooltips.js +16 -0
- data/app/assets/stylesheets/trestle/components/_modal.scss +4 -0
- data/app/assets/stylesheets/trestle/components/_navigation.scss +31 -11
- data/app/assets/stylesheets/trestle/components/_sidebar.scss +2 -2
- data/app/assets/stylesheets/trestle/components/_tags.scss +9 -0
- data/app/assets/stylesheets/trestle/components/_wells.scss +9 -1
- data/app/assets/stylesheets/trestle/core/_defaults.scss +4 -4
- data/app/assets/stylesheets/trestle/core/_layout.scss +8 -0
- data/app/assets/stylesheets/trestle/core/_typography.scss +39 -0
- data/app/controllers/concerns/trestle/controller/breadcrumbs.rb +21 -0
- data/app/controllers/concerns/trestle/controller/callbacks.rb +21 -0
- data/app/controllers/concerns/trestle/controller/dialog.rb +16 -0
- data/app/controllers/concerns/trestle/controller/helpers.rb +18 -0
- data/app/controllers/concerns/trestle/controller/layout.rb +16 -0
- data/app/controllers/concerns/trestle/controller/location.rb +15 -0
- data/app/controllers/trestle/application_controller.rb +6 -34
- data/app/helpers/trestle/debug_helper.rb +11 -0
- data/app/helpers/trestle/format_helper.rb +7 -3
- data/app/helpers/trestle/headings_helper.rb +27 -0
- data/app/helpers/trestle/panel_helper.rb +24 -0
- data/app/helpers/trestle/table_helper.rb +41 -2
- data/app/helpers/trestle/url_helper.rb +3 -1
- data/app/views/layouts/trestle/admin.html.erb +1 -1
- data/app/views/trestle/application/_flash.html.erb +1 -1
- data/app/views/trestle/shared/_sidebar.html.erb +2 -2
- data/app/views/trestle/table/_table.html.erb +2 -6
- data/lib/generators/trestle/resource/templates/admin.rb.erb +2 -2
- data/lib/trestle.rb +6 -4
- data/lib/trestle/adapters/active_record_adapter.rb +0 -4
- data/lib/trestle/adapters/adapter.rb +15 -10
- data/lib/trestle/adapters/sequel_adapter.rb +0 -4
- data/lib/trestle/admin.rb +18 -1
- data/lib/trestle/admin/builder.rb +22 -10
- data/lib/trestle/form/automatic.rb +5 -2
- data/lib/trestle/form/builder.rb +5 -1
- data/lib/trestle/form/field.rb +1 -1
- data/lib/trestle/form/fields/form_group.rb +3 -1
- data/lib/trestle/form/fields/select.rb +5 -1
- data/lib/trestle/form/fields/tag_select.rb +1 -1
- data/lib/trestle/form/renderer.rb +1 -1
- data/lib/trestle/navigation.rb +11 -5
- data/lib/trestle/navigation/item.rb +10 -0
- data/lib/trestle/resource.rb +27 -61
- data/lib/trestle/resource/builder.rb +15 -14
- data/lib/trestle/resource/collection.rb +48 -0
- data/lib/trestle/resource/controller.rb +36 -23
- data/lib/trestle/scope.rb +13 -3
- data/lib/trestle/table.rb +10 -4
- data/lib/trestle/table/column.rb +13 -2
- data/lib/trestle/table/row.rb +10 -0
- data/lib/trestle/version.rb +1 -1
- data/trestle.gemspec +1 -0
- data/vendor/assets/stylesheets/trestle/magnific-popup.scss +13 -1
- metadata +27 -4
- data/app/helpers/trestle/dialog_helper.rb +0 -7
@@ -0,0 +1,21 @@
|
|
1
|
+
module Trestle
|
2
|
+
module Controller
|
3
|
+
module Breadcrumbs
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
helper_method :breadcrumbs
|
8
|
+
helper_method :breadcrumb
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
def breadcrumbs
|
13
|
+
@breadcrumbs ||= Trestle::Breadcrumb::Trail.new(Trestle.config.root_breadcrumbs)
|
14
|
+
end
|
15
|
+
|
16
|
+
def breadcrumb(label, path=nil)
|
17
|
+
breadcrumbs.append(label, path)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Trestle
|
2
|
+
module Controller
|
3
|
+
module Callbacks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
Trestle.config.before_actions.each do |action|
|
8
|
+
before_action(action.options, &action.block)
|
9
|
+
end
|
10
|
+
|
11
|
+
Trestle.config.after_actions.each do |action|
|
12
|
+
after_action(action.options, &action.block)
|
13
|
+
end
|
14
|
+
|
15
|
+
Trestle.config.around_actions.each do |action|
|
16
|
+
around_action(action.options, &action.block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Trestle
|
2
|
+
module Controller
|
3
|
+
module Helpers
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
# Allow inclusion of helpers from Rails application
|
8
|
+
self.helpers_path += Rails.application.helpers_paths
|
9
|
+
|
10
|
+
# Add helpers declared from configuration as blocks
|
11
|
+
helper Trestle.config.helper_module
|
12
|
+
|
13
|
+
# Add helpers declared from configuration as module references
|
14
|
+
helper *Trestle.config.helpers
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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,38 +1,10 @@
|
|
1
1
|
class Trestle::ApplicationController < ActionController::Base
|
2
2
|
protect_from_forgery
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# Global callbacks
|
12
|
-
Trestle.config.before_actions.each do |action|
|
13
|
-
before_action(action.options, &action.block)
|
14
|
-
end
|
15
|
-
|
16
|
-
Trestle.config.after_actions.each do |action|
|
17
|
-
after_action(action.options, &action.block)
|
18
|
-
end
|
19
|
-
|
20
|
-
Trestle.config.around_actions.each do |action|
|
21
|
-
around_action(action.options, &action.block)
|
22
|
-
end
|
23
|
-
|
24
|
-
protected
|
25
|
-
def breadcrumbs
|
26
|
-
@breadcrumbs ||= Trestle::Breadcrumb::Trail.new(Trestle.config.root_breadcrumbs)
|
27
|
-
end
|
28
|
-
helper_method :breadcrumbs
|
29
|
-
|
30
|
-
def breadcrumb(label, path=nil)
|
31
|
-
breadcrumbs.append(label, path)
|
32
|
-
end
|
33
|
-
helper_method :breadcrumb
|
34
|
-
|
35
|
-
def choose_layout
|
36
|
-
request.xhr? ? false : "trestle/admin"
|
37
|
-
end
|
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
|
38
10
|
end
|
@@ -13,7 +13,7 @@ module Trestle
|
|
13
13
|
when :currency
|
14
14
|
number_to_currency(value)
|
15
15
|
when :tags
|
16
|
-
safe_join(value.map { |tag| content_tag(:span, tag, class: "tag") })
|
16
|
+
safe_join(Array(value).map { |tag| content_tag(:span, tag, class: "tag") })
|
17
17
|
else
|
18
18
|
value
|
19
19
|
end
|
@@ -30,8 +30,12 @@ module Trestle
|
|
30
30
|
when TrueClass, FalseClass
|
31
31
|
status_tag(icon("fa fa-check"), :success) if value
|
32
32
|
when NilClass
|
33
|
-
|
34
|
-
|
33
|
+
blank = options.key?(:blank) ? options[:blank] : I18n.t("admin.format.blank")
|
34
|
+
if blank.respond_to?(:call)
|
35
|
+
instance_exec(&blank)
|
36
|
+
else
|
37
|
+
content_tag(:span, blank, class: "blank")
|
38
|
+
end
|
35
39
|
when String
|
36
40
|
if value.html_safe? || options[:truncate] == false
|
37
41
|
value
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Trestle
|
2
|
+
module HeadingsHelper
|
3
|
+
def h1(text, options={})
|
4
|
+
content_tag(:h1, text, options)
|
5
|
+
end
|
6
|
+
|
7
|
+
def h2(text, options={})
|
8
|
+
content_tag(:h2, text, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def h3(text, options={})
|
12
|
+
content_tag(:h3, text, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def h4(text, options={})
|
16
|
+
content_tag(:h4, text, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def h5(text, options={})
|
20
|
+
content_tag(:h5, text, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def h6(text, options={})
|
24
|
+
content_tag(:h6, text, options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Trestle
|
2
|
+
module PanelHelper
|
3
|
+
def panel(options={}, &block)
|
4
|
+
html_class = options.fetch(:class) { "panel-default" }
|
5
|
+
|
6
|
+
content_tag(:div, class: ["panel", html_class]) do
|
7
|
+
if options[:title]
|
8
|
+
concat content_tag(:div, options[:title], class: "panel-heading")
|
9
|
+
end
|
10
|
+
|
11
|
+
concat content_tag(:div, class: "panel-body", &block)
|
12
|
+
|
13
|
+
if options[:footer]
|
14
|
+
concat content_tag(:div, options[:footer], class: "panel-footer")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def well(options={}, &block)
|
20
|
+
html_class = ["well", options[:class]].compact
|
21
|
+
content_tag(:div, options.merge(class: html_class), &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,7 +1,46 @@
|
|
1
1
|
module Trestle
|
2
2
|
module TableHelper
|
3
|
-
|
4
|
-
|
3
|
+
# Renders an existing named table or builds and renders a custom table if a block is provided.
|
4
|
+
#
|
5
|
+
# name - The (optional) name of the table to render (as a Symbol), or the actual Trestle::Table instance itself.
|
6
|
+
# options - Hash of options that will be passed to the table builder (default: {}):
|
7
|
+
# :collection - The collection that should be rendered within the table. It should be an
|
8
|
+
# Array-like object, but will most likely be an ActiveRecord scope. It can
|
9
|
+
# also be a callable object (i.e. a Proc) in which case the result of calling
|
10
|
+
# the block will be used as the collection.
|
11
|
+
# See Trestle::Table::Builder for additional options.
|
12
|
+
# block - An optional block that is passed to Trestle::Table::Builder to define a custom table.
|
13
|
+
# One of either the name or block must be provided, but not both.
|
14
|
+
#
|
15
|
+
# Examples
|
16
|
+
#
|
17
|
+
# <%= table collection: -> { Account.all }, admin: :accounts do %>
|
18
|
+
# <% column(:name) %>
|
19
|
+
# <% column(:balance) { |account| account.balance.format } %>
|
20
|
+
# <% column(:created_at, align: :center)
|
21
|
+
# <% end %>
|
22
|
+
#
|
23
|
+
# <%= table :accounts %>
|
24
|
+
#
|
25
|
+
# Returns the HTML representation of the table as a HTML-safe String.
|
26
|
+
def table(name=nil, options={}, &block)
|
27
|
+
if block_given?
|
28
|
+
if name.is_a?(Hash)
|
29
|
+
options = name
|
30
|
+
else
|
31
|
+
collection = name
|
32
|
+
end
|
33
|
+
|
34
|
+
table = Table::Builder.build(options, &block)
|
35
|
+
elsif name.is_a?(Trestle::Table)
|
36
|
+
table = name
|
37
|
+
else
|
38
|
+
table = admin.tables.fetch(name) { raise ArgumentError, "Unable to find table named #{name.inspect}" }
|
39
|
+
end
|
40
|
+
|
41
|
+
collection ||= options[:collection] || table.options[:collection]
|
42
|
+
collection = collection.call if collection.respond_to?(:call)
|
43
|
+
|
5
44
|
render "trestle/table/table", table: table, collection: collection
|
6
45
|
end
|
7
46
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Trestle
|
2
2
|
module UrlHelper
|
3
|
+
DIALOG_ACTIONS = [:new, :show, :edit]
|
4
|
+
|
3
5
|
def admin_link_to(content, instance_or_url=nil, options={}, &block)
|
4
6
|
if block_given?
|
5
7
|
instance_or_url, options = content, instance_or_url || {}
|
@@ -27,7 +29,7 @@ module Trestle
|
|
27
29
|
params = options.delete(:params) || {}
|
28
30
|
params[:id] ||= admin.to_param(instance_or_url) if instance_or_url
|
29
31
|
|
30
|
-
if
|
32
|
+
if DIALOG_ACTIONS.include?(action) && admin.form.dialog?
|
31
33
|
options[:data] ||= {}
|
32
34
|
options[:data][:behavior] ||= "dialog"
|
33
35
|
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
title: t("trestle.flash.failure.title", default: "Warning!"),
|
12
12
|
message: flash[:error]
|
13
13
|
} do %>
|
14
|
-
<%- if
|
14
|
+
<%- if debug_form_errors? -%>
|
15
15
|
<%= link_to "Debug errors", "#debug-errors", class: "toggle-debug-errors small", data: { toggle: "collapse" } %>
|
16
16
|
<div id="debug-errors" class="debug-errors collapse">
|
17
17
|
<ul>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<aside class="app-sidebar
|
1
|
+
<aside class="app-sidebar">
|
2
2
|
<header class="app-sidebar-header">
|
3
3
|
<button class="navbar-toggle">
|
4
4
|
<span class="sr-only"><%= t("admin.ui.toggle_navigation", default: "Toggle navigation") %></span>
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<div class="app-sidebar-inner">
|
14
14
|
<nav class="app-nav">
|
15
15
|
<% collapsed = cookies["trestle:navigation:collapsed"].try(:split, ",") || [] %>
|
16
|
-
<% Trestle.navigation.each do |group, items| %>
|
16
|
+
<% Trestle.navigation.visible(self).each do |group, items| %>
|
17
17
|
<ul<% if group.present? && collapsed.include?(group.id) %> class="collapsed"<% end %>>
|
18
18
|
<% if group.present? %>
|
19
19
|
<li class="nav-header"><%= link_to group.label, "##{group.id}" %></li>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% table = table.renderer(self) %>
|
2
2
|
|
3
3
|
<div class="table-container">
|
4
|
-
<%= content_tag(:table, class: table.classes, data: table.data) do %>
|
4
|
+
<%= content_tag(:table, id: table.id, class: table.classes, data: table.data) do %>
|
5
5
|
<thead>
|
6
6
|
<tr>
|
7
7
|
<% table.columns.each do |column| %>
|
@@ -12,11 +12,7 @@
|
|
12
12
|
|
13
13
|
<tbody>
|
14
14
|
<% collection.each do |instance| %>
|
15
|
-
<%=
|
16
|
-
<% table.columns.each do |column| %>
|
17
|
-
<%= content_tag(:td, column.content(instance), class: column.classes, data: column.data) %>
|
18
|
-
<% end %>
|
19
|
-
<% end %>
|
15
|
+
<%= table.row.render(instance) %>
|
20
16
|
<% end %>
|
21
17
|
</tbody>
|
22
18
|
<% end %>
|
@@ -13,7 +13,7 @@ Trestle.resource(:<%= plural_name %><% if module? %>, scope: <%= module_name %><
|
|
13
13
|
|
14
14
|
# Customize the form fields shown on the new/edit views.
|
15
15
|
#
|
16
|
-
# form do |<%=
|
16
|
+
# form do |<%= singular_table_name %>|
|
17
17
|
# text_field :name
|
18
18
|
#
|
19
19
|
# row do
|
@@ -30,6 +30,6 @@ Trestle.resource(:<%= plural_name %><% if module? %>, scope: <%= module_name %><
|
|
30
30
|
# http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters
|
31
31
|
#
|
32
32
|
# params do |params|
|
33
|
-
# params.require(:<%=
|
33
|
+
# params.require(:<%= singular_table_name %>).permit(:name, ...)
|
34
34
|
# end
|
35
35
|
end
|
data/lib/trestle.rb
CHANGED
@@ -31,12 +31,14 @@ module Trestle
|
|
31
31
|
self.admins = {}
|
32
32
|
|
33
33
|
def self.admin(name, options={}, &block)
|
34
|
-
|
35
|
-
self.admins[admin.admin_name] = admin
|
34
|
+
register(Admin::Builder.create(name, options, &block))
|
36
35
|
end
|
37
36
|
|
38
37
|
def self.resource(name, options={}, &block)
|
39
|
-
|
38
|
+
register(Resource::Builder.create(name, options, &block))
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.register(admin)
|
40
42
|
self.admins[admin.admin_name] = admin
|
41
43
|
end
|
42
44
|
|
@@ -54,7 +56,7 @@ module Trestle
|
|
54
56
|
end
|
55
57
|
|
56
58
|
def self.navigation
|
57
|
-
Navigation.
|
59
|
+
Navigation.build(config.menus + admins.values.map(&:menu).compact)
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
@@ -61,6 +61,18 @@ module Trestle
|
|
61
61
|
raise NotImplementedError
|
62
62
|
end
|
63
63
|
|
64
|
+
# Finalizes a collection so that it can be rendered within the index view.
|
65
|
+
#
|
66
|
+
# In most cases (e.g. ActiveRecord), no finalization is required. However if you are using a search library then
|
67
|
+
# you may need to explicitly execute the search, or access the models via a #records or #objects method.
|
68
|
+
#
|
69
|
+
# collection - The collection to finalize
|
70
|
+
#
|
71
|
+
# Returns an enumerable collection of instances.
|
72
|
+
def finalize_collection(collection)
|
73
|
+
collection
|
74
|
+
end
|
75
|
+
|
64
76
|
# Decorates a collection for rendering by the index view.
|
65
77
|
# Decorating is the final step in preparing the collection for the view.
|
66
78
|
#
|
@@ -82,15 +94,6 @@ module Trestle
|
|
82
94
|
instance.id
|
83
95
|
end
|
84
96
|
|
85
|
-
# Unscopes a collection so that it can be merged with other scopes without duplication or interference.
|
86
|
-
#
|
87
|
-
# scope - The scope to unscope
|
88
|
-
#
|
89
|
-
# Returns a scope object.
|
90
|
-
def unscope(scope)
|
91
|
-
scope
|
92
|
-
end
|
93
|
-
|
94
97
|
# Merges scopes together for Trestle scope application and counting.
|
95
98
|
#
|
96
99
|
# scope - The first scope
|
@@ -131,7 +134,9 @@ module Trestle
|
|
131
134
|
# Returns a Kaminari-compatible scope corresponding to a single page.
|
132
135
|
def paginate(collection, params)
|
133
136
|
collection = Kaminari.paginate_array(collection.to_a) unless collection.respond_to?(:page)
|
134
|
-
|
137
|
+
per_page = admin.pagination_options[:per]
|
138
|
+
|
139
|
+
collection.page(params[:page]).per(per_page)
|
135
140
|
end
|
136
141
|
|
137
142
|
# Filters the submitted form parameters and returns a whitelisted attributes 'hash'
|