tiny_admin 0.10.0 → 0.11.0
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/tiny_admin/actions/index.rb +4 -4
- data/lib/tiny_admin/authentication.rb +8 -8
- data/lib/tiny_admin/basic_app.rb +5 -3
- data/lib/tiny_admin/field.rb +5 -4
- data/lib/tiny_admin/plugins/active_record_repository.rb +1 -1
- data/lib/tiny_admin/plugins/base_repository.rb +2 -1
- data/lib/tiny_admin/plugins/no_auth.rb +2 -2
- data/lib/tiny_admin/plugins/simple_auth.rb +10 -10
- data/lib/tiny_admin/raw_html.rb +11 -0
- data/lib/tiny_admin/router.rb +36 -29
- data/lib/tiny_admin/settings.rb +22 -8
- data/lib/tiny_admin/store.rb +9 -12
- data/lib/tiny_admin/support.rb +14 -2
- data/lib/tiny_admin/utils.rb +7 -5
- data/lib/tiny_admin/version.rb +1 -1
- data/lib/tiny_admin/views/actions/index.rb +23 -27
- data/lib/tiny_admin/views/actions/show.rb +15 -21
- data/lib/tiny_admin/views/attributes.rb +18 -0
- data/lib/tiny_admin/views/basic_layout.rb +1 -6
- data/lib/tiny_admin/views/components/actions_buttons.rb +24 -0
- data/lib/tiny_admin/views/components/basic_component.rb +1 -5
- data/lib/tiny_admin/views/components/field_value.rb +15 -4
- data/lib/tiny_admin/views/components/filters_form.rb +21 -21
- data/lib/tiny_admin/views/components/flash.rb +5 -5
- data/lib/tiny_admin/views/components/head.rb +4 -4
- data/lib/tiny_admin/views/components/navbar.rb +17 -17
- data/lib/tiny_admin/views/components/pagination.rb +15 -15
- data/lib/tiny_admin/views/components/widgets.rb +23 -8
- data/lib/tiny_admin/views/default_layout.rb +8 -8
- data/lib/tiny_admin/views/pages/content.rb +4 -4
- data/lib/tiny_admin/views/pages/error_page.rb +26 -0
- data/lib/tiny_admin/views/pages/page_not_allowed.rb +2 -10
- data/lib/tiny_admin/views/pages/page_not_found.rb +2 -10
- data/lib/tiny_admin/views/pages/record_not_found.rb +2 -10
- data/lib/tiny_admin/views/pages/root.rb +3 -3
- data/lib/tiny_admin/views/pages/simple_auth_login.rb +12 -12
- data/lib/tiny_admin.rb +8 -8
- metadata +13 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b1b97d53e29a9534e5bad33db4ab61e52de4325cd68d6556da668bf940815b5
|
|
4
|
+
data.tar.gz: 2d94e52253fdf7fe44edf2ef731c166ade81c5972b84fac80d3adc99d7e347d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b681c29bc30097703aa541af928a9f0d73e698cb0a7bf1e95264f92be92c6b420f556f1eda1fe9dd3c6a12efcefa3c975c84ab52664607cf2a9eab15e88e3192
|
|
7
|
+
data.tar.gz: dd1ae44d4d8eb14d212c980487ba3f57a37d0cf460f7a6cfa05eced7436ec2b6bd5015fb822f565f7923c8110e81c5c7a6072f688cb7b637a5b33479e16db668
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/rb/tiny_admin)
|
|
4
4
|
[](https://rubygems.org/gems/tiny_admin)
|
|
5
5
|
[](https://github.com/blocknotes/tiny_admin/actions/workflows/linters.yml)
|
|
6
|
-
[](https://github.com/blocknotes/tiny_admin/actions/workflows/tests.yml)
|
|
7
7
|
|
|
8
8
|
A compact and composable dashboard component for Ruby.
|
|
9
9
|
|
|
@@ -45,14 +45,14 @@ module TinyAdmin
|
|
|
45
45
|
@params = context.request.params
|
|
46
46
|
@repository = context.repository
|
|
47
47
|
@pagination = options[:pagination] || 10
|
|
48
|
-
@current_page = (params[
|
|
49
|
-
@query_string = params_to_s(params.except(
|
|
48
|
+
@current_page = (params["p"] || 1).to_i
|
|
49
|
+
@query_string = params_to_s(params.except("p"))
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def prepare_filters(fields)
|
|
53
53
|
filters = (options[:filters] || []).map { _1.is_a?(Hash) ? _1 : { field: _1 } }
|
|
54
|
-
filters = filters.
|
|
55
|
-
values =
|
|
54
|
+
filters = filters.to_h { |filter| [filter[:field], filter] }
|
|
55
|
+
values = params["q"] || {}
|
|
56
56
|
fields.each_with_object({}) do |(name, field), result|
|
|
57
57
|
result[field] = { value: values[name], filter: filters[name] } if filters.key?(name)
|
|
58
58
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module TinyAdmin
|
|
4
4
|
class Authentication < BasicApp
|
|
5
5
|
route do |r|
|
|
6
|
-
r.get
|
|
6
|
+
r.get "unauthenticated" do
|
|
7
7
|
if current_user
|
|
8
8
|
r.redirect TinyAdmin.settings.root_path
|
|
9
9
|
else
|
|
@@ -11,15 +11,15 @@ module TinyAdmin
|
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
r.post
|
|
14
|
+
r.post "unauthenticated" do
|
|
15
15
|
warning = TinyAdmin.settings.helper_class.label_for(
|
|
16
|
-
|
|
17
|
-
options: [
|
|
16
|
+
"Failed to authenticate",
|
|
17
|
+
options: ["authentication.unauthenticated"]
|
|
18
18
|
)
|
|
19
19
|
render_login(warnings: [warning])
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
r.get
|
|
22
|
+
r.get "logout" do
|
|
23
23
|
logout_user
|
|
24
24
|
r.redirect TinyAdmin.settings.root_path
|
|
25
25
|
end
|
|
@@ -33,9 +33,9 @@ module TinyAdmin
|
|
|
33
33
|
|
|
34
34
|
page = prepare_page(login, options: %i[no_menu compact_layout])
|
|
35
35
|
page.messages = {
|
|
36
|
-
notices: notices || flash[
|
|
37
|
-
warnings: warnings || flash[
|
|
38
|
-
errors: errors || flash[
|
|
36
|
+
notices: notices || flash["notices"],
|
|
37
|
+
warnings: warnings || flash["warnings"],
|
|
38
|
+
errors: errors || flash["errors"]
|
|
39
39
|
}
|
|
40
40
|
render(inline: page.call)
|
|
41
41
|
end
|
data/lib/tiny_admin/basic_app.rb
CHANGED
|
@@ -5,17 +5,19 @@ module TinyAdmin
|
|
|
5
5
|
include Utils
|
|
6
6
|
|
|
7
7
|
class << self
|
|
8
|
+
include Utils
|
|
9
|
+
|
|
8
10
|
def authentication_plugin
|
|
9
11
|
plugin = TinyAdmin.settings.authentication&.dig(:plugin)
|
|
10
|
-
plugin_class =
|
|
12
|
+
plugin_class = to_class(plugin) if plugin
|
|
11
13
|
plugin_class || TinyAdmin::Plugins::NoAuth
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
plugin :flash
|
|
16
18
|
plugin :not_found
|
|
17
|
-
plugin :render, engine:
|
|
18
|
-
plugin :sessions, secret: SecureRandom.hex(64)
|
|
19
|
+
plugin :render, engine: "html"
|
|
20
|
+
plugin :sessions, secret: ENV.fetch("TINY_ADMIN_SECRET") { SecureRandom.hex(64) }
|
|
19
21
|
|
|
20
22
|
plugin authentication_plugin, TinyAdmin.settings.authentication
|
|
21
23
|
|
data/lib/tiny_admin/field.rb
CHANGED
|
@@ -12,13 +12,13 @@ module TinyAdmin
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def apply_call_option(target)
|
|
15
|
-
messages = (options[:call] ||
|
|
15
|
+
messages = (options[:call] || "").split(",").map(&:strip)
|
|
16
16
|
messages.inject(target) { |result, msg| result&.send(msg) } if messages.any?
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def translate_value(value)
|
|
20
20
|
if options && options[:method]
|
|
21
|
-
method, *args = options[:method].split(
|
|
21
|
+
method, *args = options[:method].split(",").map(&:strip)
|
|
22
22
|
if options[:converter]
|
|
23
23
|
Object.const_get(options[:converter]).send(method, value, options: args || [])
|
|
24
24
|
else
|
|
@@ -30,10 +30,11 @@ module TinyAdmin
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
class << self
|
|
33
|
+
include Utils
|
|
34
|
+
|
|
33
35
|
def create_field(name:, title: nil, type: nil, options: {})
|
|
34
36
|
field_name = name.to_s
|
|
35
|
-
|
|
36
|
-
new(name: field_name, title: title || field_title, type: type || :string, options: options || {})
|
|
37
|
+
new(name: field_name, title: title || humanize(field_name), type: type || :string, options: options || {})
|
|
37
38
|
end
|
|
38
39
|
end
|
|
39
40
|
end
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "digest"
|
|
4
4
|
|
|
5
5
|
module TinyAdmin
|
|
6
6
|
module Plugins
|
|
7
7
|
module SimpleAuth
|
|
8
8
|
class << self
|
|
9
9
|
def configure(app, opts = {})
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
opts ||= {}
|
|
11
|
+
password_hash = opts[:password] || ENV.fetch("ADMIN_PASSWORD_HASH", nil)
|
|
12
12
|
|
|
13
13
|
Warden::Strategies.add(:secret) do
|
|
14
|
-
|
|
15
|
-
secret = params[
|
|
16
|
-
return fail(:invalid_credentials) if Digest::SHA512.hexdigest(secret) !=
|
|
14
|
+
define_method(:authenticate!) do
|
|
15
|
+
secret = params["secret"] || ""
|
|
16
|
+
return fail(:invalid_credentials) if Digest::SHA512.hexdigest(secret) != password_hash
|
|
17
17
|
|
|
18
|
-
success!(app:
|
|
18
|
+
success!(app: "TinyAdmin")
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -29,15 +29,15 @@ module TinyAdmin
|
|
|
29
29
|
|
|
30
30
|
module InstanceMethods
|
|
31
31
|
def authenticate_user!
|
|
32
|
-
env[
|
|
32
|
+
env["warden"].authenticate!
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def current_user
|
|
36
|
-
env[
|
|
36
|
+
env["warden"].user
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def logout_user
|
|
40
|
-
env[
|
|
40
|
+
env["warden"].logout
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
data/lib/tiny_admin/router.rb
CHANGED
|
@@ -9,7 +9,7 @@ module TinyAdmin
|
|
|
9
9
|
route do |r|
|
|
10
10
|
TinyAdmin.settings.load_settings
|
|
11
11
|
|
|
12
|
-
r.on
|
|
12
|
+
r.on "auth" do
|
|
13
13
|
r.run Authentication
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -25,7 +25,7 @@ module TinyAdmin
|
|
|
25
25
|
# :nocov:
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
r.post
|
|
28
|
+
r.post "" do
|
|
29
29
|
r.redirect TinyAdmin.settings.root_path
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -48,13 +48,13 @@ module TinyAdmin
|
|
|
48
48
|
|
|
49
49
|
def render_page(page)
|
|
50
50
|
if page.respond_to?(:messages=)
|
|
51
|
-
page.messages = { notices: flash[
|
|
51
|
+
page.messages = { notices: flash["notices"], warnings: flash["warnings"], errors: flash["errors"] }
|
|
52
52
|
end
|
|
53
53
|
render(inline: page.call)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def root_route(req)
|
|
57
|
-
|
|
57
|
+
authorize!(:root) do
|
|
58
58
|
if TinyAdmin.settings.root[:redirect]
|
|
59
59
|
req.redirect route_for(TinyAdmin.settings.root[:redirect])
|
|
60
60
|
else
|
|
@@ -62,31 +62,27 @@ module TinyAdmin
|
|
|
62
62
|
attributes = TinyAdmin.settings.root.slice(:content, :title, :widgets)
|
|
63
63
|
render_page prepare_page(page_class, attributes: attributes, params: request.params)
|
|
64
64
|
end
|
|
65
|
-
else
|
|
66
|
-
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
|
67
65
|
end
|
|
68
66
|
end
|
|
69
67
|
|
|
70
68
|
def setup_page_route(req, slug, page_data)
|
|
71
69
|
req.get slug do
|
|
72
|
-
|
|
70
|
+
authorize!(:page, slug) do
|
|
73
71
|
attributes = page_data.slice(:content, :title, :widgets)
|
|
74
72
|
render_page prepare_page(page_data[:class], slug: slug, attributes: attributes, params: request.params)
|
|
75
|
-
else
|
|
76
|
-
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
|
77
73
|
end
|
|
78
74
|
end
|
|
79
75
|
end
|
|
80
76
|
|
|
81
77
|
def setup_resource_routes(req, slug, options:)
|
|
82
78
|
req.on slug do
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
repository = options[:repository].new(options[:model])
|
|
80
|
+
setup_collection_routes(req, slug, options: options, repository: repository)
|
|
81
|
+
setup_member_routes(req, slug, options: options, repository: repository)
|
|
85
82
|
end
|
|
86
83
|
end
|
|
87
84
|
|
|
88
|
-
def setup_collection_routes(req, slug, options:)
|
|
89
|
-
repository = options[:repository].new(options[:model])
|
|
85
|
+
def setup_collection_routes(req, slug, options:, repository:)
|
|
90
86
|
action_options = options[:index] || {}
|
|
91
87
|
|
|
92
88
|
# Custom actions
|
|
@@ -99,9 +95,9 @@ module TinyAdmin
|
|
|
99
95
|
)
|
|
100
96
|
|
|
101
97
|
# Index
|
|
102
|
-
if options[:only].include?(:index) || options[:only].include?(
|
|
98
|
+
if options[:only].include?(:index) || options[:only].include?("index")
|
|
103
99
|
req.is do
|
|
104
|
-
|
|
100
|
+
authorize!(:resource_index, slug) do
|
|
105
101
|
context = Context.new(
|
|
106
102
|
actions: custom_actions,
|
|
107
103
|
repository: repository,
|
|
@@ -111,15 +107,12 @@ module TinyAdmin
|
|
|
111
107
|
)
|
|
112
108
|
index_action = TinyAdmin::Actions::Index.new
|
|
113
109
|
render_page index_action.call(app: self, context: context, options: action_options)
|
|
114
|
-
else
|
|
115
|
-
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
|
116
110
|
end
|
|
117
111
|
end
|
|
118
112
|
end
|
|
119
113
|
end
|
|
120
114
|
|
|
121
|
-
def setup_member_routes(req, slug, options:)
|
|
122
|
-
repository = options[:repository].new(options[:model])
|
|
115
|
+
def setup_member_routes(req, slug, options:, repository:)
|
|
123
116
|
action_options = (options[:show] || {}).merge(record_not_found_page: TinyAdmin.settings.record_not_found)
|
|
124
117
|
|
|
125
118
|
req.on String do |reference|
|
|
@@ -134,9 +127,9 @@ module TinyAdmin
|
|
|
134
127
|
)
|
|
135
128
|
|
|
136
129
|
# Show
|
|
137
|
-
if options[:only].include?(:show) || options[:only].include?(
|
|
130
|
+
if options[:only].include?(:show) || options[:only].include?("show")
|
|
138
131
|
req.is do
|
|
139
|
-
|
|
132
|
+
authorize!(:resource_show, slug) do
|
|
140
133
|
context = Context.new(
|
|
141
134
|
actions: custom_actions,
|
|
142
135
|
reference: reference,
|
|
@@ -147,8 +140,6 @@ module TinyAdmin
|
|
|
147
140
|
)
|
|
148
141
|
show_action = TinyAdmin::Actions::Show.new
|
|
149
142
|
render_page show_action.call(app: self, context: context, options: action_options)
|
|
150
|
-
else
|
|
151
|
-
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
|
152
143
|
end
|
|
153
144
|
end
|
|
154
145
|
end
|
|
@@ -157,11 +148,11 @@ module TinyAdmin
|
|
|
157
148
|
|
|
158
149
|
def setup_custom_actions(req, custom_actions = nil, options:, repository:, slug:, reference: nil)
|
|
159
150
|
(custom_actions || []).each_with_object({}) do |custom_action, result|
|
|
160
|
-
action_slug,
|
|
161
|
-
action_class =
|
|
151
|
+
action_slug, action_config = custom_action.first
|
|
152
|
+
action_class, http_method = parse_action_config(action_config)
|
|
162
153
|
|
|
163
|
-
req.
|
|
164
|
-
|
|
154
|
+
req.public_send(http_method, action_slug.to_s) do
|
|
155
|
+
authorize!(:custom_action, action_slug.to_s) do
|
|
165
156
|
context = Context.new(
|
|
166
157
|
actions: {},
|
|
167
158
|
reference: reference,
|
|
@@ -172,8 +163,6 @@ module TinyAdmin
|
|
|
172
163
|
)
|
|
173
164
|
custom_action = action_class.new
|
|
174
165
|
render_page custom_action.call(app: self, context: context, options: options)
|
|
175
|
-
else
|
|
176
|
-
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
|
177
166
|
end
|
|
178
167
|
end
|
|
179
168
|
|
|
@@ -181,8 +170,26 @@ module TinyAdmin
|
|
|
181
170
|
end
|
|
182
171
|
end
|
|
183
172
|
|
|
173
|
+
def parse_action_config(config)
|
|
174
|
+
if config.is_a?(Hash)
|
|
175
|
+
action_class = to_class(config[:action] || config["action"])
|
|
176
|
+
http_method = (config[:method] || config["method"] || "get").to_sym
|
|
177
|
+
[action_class, http_method]
|
|
178
|
+
else
|
|
179
|
+
[to_class(config), :get]
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
184
183
|
def authorization
|
|
185
184
|
TinyAdmin.settings.authorization_class
|
|
186
185
|
end
|
|
186
|
+
|
|
187
|
+
def authorize!(action, param = nil)
|
|
188
|
+
if authorization.allowed?(current_user, action, param)
|
|
189
|
+
yield
|
|
190
|
+
else
|
|
191
|
+
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
187
194
|
end
|
|
188
195
|
end
|
data/lib/tiny_admin/settings.rb
CHANGED
|
@@ -19,9 +19,9 @@ module TinyAdmin
|
|
|
19
19
|
%i[page_not_found] => Views::Pages::PageNotFound,
|
|
20
20
|
%i[record_not_found] => Views::Pages::RecordNotFound,
|
|
21
21
|
%i[repository] => Plugins::ActiveRecordRepository,
|
|
22
|
-
%i[root_path] =>
|
|
22
|
+
%i[root_path] => "/admin",
|
|
23
23
|
%i[root page] => Views::Pages::Root,
|
|
24
|
-
%i[root title] =>
|
|
24
|
+
%i[root title] => "TinyAdmin",
|
|
25
25
|
%i[sections] => []
|
|
26
26
|
}.freeze
|
|
27
27
|
|
|
@@ -67,6 +67,8 @@ module TinyAdmin
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
def load_settings
|
|
70
|
+
return if @loaded
|
|
71
|
+
|
|
70
72
|
# default values
|
|
71
73
|
DEFAULTS.each do |(option, param), default|
|
|
72
74
|
if param
|
|
@@ -78,17 +80,23 @@ module TinyAdmin
|
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
@store ||= TinyAdmin::Store.new(self)
|
|
81
|
-
self.root_path =
|
|
83
|
+
self.root_path = "/" if root_path == ""
|
|
82
84
|
|
|
83
|
-
if authentication[:plugin] <= Plugins::SimpleAuth
|
|
85
|
+
if authentication[:plugin].is_a?(Module) && authentication[:plugin] <= Plugins::SimpleAuth
|
|
84
86
|
logout_path = "#{root_path}/auth/logout"
|
|
85
|
-
authentication[:logout] ||= TinyAdmin::Section.new(name:
|
|
87
|
+
authentication[:logout] ||= TinyAdmin::Section.new(name: "logout", slug: "logout", path: logout_path)
|
|
86
88
|
end
|
|
87
89
|
store.prepare_sections(sections, logout: authentication[:logout])
|
|
90
|
+
@loaded = true
|
|
88
91
|
end
|
|
89
92
|
|
|
90
93
|
def reset!
|
|
91
|
-
@options = {
|
|
94
|
+
@options = {
|
|
95
|
+
components: {},
|
|
96
|
+
sections: []
|
|
97
|
+
}
|
|
98
|
+
@store = nil
|
|
99
|
+
@loaded = false
|
|
92
100
|
end
|
|
93
101
|
|
|
94
102
|
private
|
|
@@ -104,12 +112,18 @@ module TinyAdmin
|
|
|
104
112
|
value.each_key do |key2|
|
|
105
113
|
path = [key, key2]
|
|
106
114
|
if (DEFAULTS[path].is_a?(Class) || DEFAULTS[path].is_a?(Module)) && self[key][key2].is_a?(String)
|
|
107
|
-
self[key][key2] =
|
|
115
|
+
self[key][key2] = resolve_class(self[key][key2], setting: "#{key}.#{key2}")
|
|
108
116
|
end
|
|
109
117
|
end
|
|
110
118
|
elsif value.is_a?(String) && (DEFAULTS[[key]].is_a?(Class) || DEFAULTS[[key]].is_a?(Module))
|
|
111
|
-
self[key] =
|
|
119
|
+
self[key] = resolve_class(self[key], setting: key.to_s)
|
|
112
120
|
end
|
|
113
121
|
end
|
|
122
|
+
|
|
123
|
+
def resolve_class(class_name, setting:)
|
|
124
|
+
Object.const_get(class_name)
|
|
125
|
+
rescue NameError => e
|
|
126
|
+
raise NameError, "TinyAdmin: invalid class '#{class_name}' for setting '#{setting}' - #{e.message}"
|
|
127
|
+
end
|
|
114
128
|
end
|
|
115
129
|
end
|
data/lib/tiny_admin/store.rb
CHANGED
|
@@ -22,18 +22,15 @@ module TinyAdmin
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
slug = section[:slug].to_s
|
|
25
|
-
case section[:type]&.to_sym
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
when :url
|
|
33
|
-
list << add_url_section(slug, section)
|
|
34
|
-
end
|
|
25
|
+
item = case section[:type]&.to_sym
|
|
26
|
+
when :content then add_content_section(slug, section)
|
|
27
|
+
when :page then add_page_section(slug, section)
|
|
28
|
+
when :resource then add_resource_section(slug, section)
|
|
29
|
+
when :url then add_url_section(slug, section)
|
|
30
|
+
end
|
|
31
|
+
list << item if item
|
|
35
32
|
end
|
|
36
|
-
navbar << logout if logout
|
|
33
|
+
@navbar << logout if logout
|
|
37
34
|
end
|
|
38
35
|
|
|
39
36
|
private
|
|
@@ -56,7 +53,7 @@ module TinyAdmin
|
|
|
56
53
|
repository: to_class(section[:repository] || settings.repository)
|
|
57
54
|
)
|
|
58
55
|
|
|
59
|
-
hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?(
|
|
56
|
+
hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?("hidden"))
|
|
60
57
|
TinyAdmin::Section.new(name: section[:name], slug: slug) unless hidden
|
|
61
58
|
end
|
|
62
59
|
|
data/lib/tiny_admin/support.rb
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module TinyAdmin
|
|
4
4
|
class Support
|
|
5
5
|
class << self
|
|
6
|
+
def raw_html(value)
|
|
7
|
+
TinyAdmin::RawHtml.new(value)
|
|
8
|
+
end
|
|
9
|
+
|
|
6
10
|
def call(value, options: [])
|
|
7
11
|
options.inject(value) { |result, message| result&.send(message) } if value && options&.any?
|
|
8
12
|
end
|
|
@@ -24,11 +28,19 @@ module TinyAdmin
|
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def strftime(value, options: [])
|
|
27
|
-
value&.strftime(options&.first ||
|
|
31
|
+
value&.strftime(options&.first || "%Y-%m-%d %H:%M")
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def to_date(value, options: [])
|
|
31
|
-
value
|
|
35
|
+
value&.to_date&.to_s
|
|
36
|
+
rescue NoMethodError, ArgumentError
|
|
37
|
+
value&.to_s
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def multiline(array, options: [])
|
|
41
|
+
return unless array.is_a?(Array)
|
|
42
|
+
|
|
43
|
+
raw_html(array.join("<br/>"))
|
|
32
44
|
end
|
|
33
45
|
|
|
34
46
|
def upcase(value, options: [])
|
data/lib/tiny_admin/utils.rb
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "cgi"
|
|
4
|
+
|
|
3
5
|
module TinyAdmin
|
|
4
6
|
module Utils
|
|
5
7
|
def params_to_s(params)
|
|
6
8
|
list = params.each_with_object([]) do |(param, value), result|
|
|
7
9
|
if value.is_a?(Hash)
|
|
8
|
-
values = value.map { |key, val| "#{param}[#{key}]=#{val}" }
|
|
10
|
+
values = value.map { |key, val| "#{CGI.escape(param.to_s)}[#{CGI.escape(key.to_s)}]=#{CGI.escape(val.to_s)}" }
|
|
9
11
|
result.concat(values)
|
|
10
12
|
else
|
|
11
|
-
result.push(
|
|
13
|
+
result.push("#{CGI.escape(param.to_s)}=#{CGI.escape(value.to_s)}")
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
|
-
list.join(
|
|
16
|
+
list.join("&")
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def prepare_page(page_class, slug: nil, attributes: nil, options: nil, params: nil)
|
|
@@ -40,9 +42,9 @@ module TinyAdmin
|
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
def humanize(string)
|
|
43
|
-
return
|
|
45
|
+
return "" unless string
|
|
44
46
|
|
|
45
|
-
string.respond_to?(:humanize) ? string.humanize : string.tr(
|
|
47
|
+
string.respond_to?(:humanize) ? string.humanize : string.tr("_", " ").capitalize
|
|
46
48
|
end
|
|
47
49
|
end
|
|
48
50
|
end
|
data/lib/tiny_admin/version.rb
CHANGED