tiny_admin 0.8.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -1
- data/lib/tiny_admin/actions/index.rb +5 -4
- data/lib/tiny_admin/plugins/authorization.rb +13 -0
- data/lib/tiny_admin/router.rb +76 -51
- data/lib/tiny_admin/settings.rb +4 -0
- data/lib/tiny_admin/utils.rb +3 -1
- data/lib/tiny_admin/version.rb +1 -1
- data/lib/tiny_admin/views/actions/index.rb +10 -3
- data/lib/tiny_admin/views/actions/show.rb +6 -1
- data/lib/tiny_admin/views/basic_layout.rb +1 -1
- data/lib/tiny_admin/views/components/pagination.rb +22 -14
- data/lib/tiny_admin/views/pages/page_not_allowed.rb +21 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 748ac60bbfef74485795f95728033866510e728572d391b2a3f381fde88434f6
|
4
|
+
data.tar.gz: 59c0a78183a960e28cb1670d4484be18e368ec48cf622bd8034087192385b7dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ba6531f80fbaab695c59a309e7249f071a1f4491fd7800edb2562571beb352d3f4faff625876cf6dc87e9cdcbf8d12d002f343076446c8ad82653c8d488ce78
|
7
|
+
data.tar.gz: 162637202396ce2106c9ad9c2117a22becc3ad99c3a4e0f72f850624089cb110e2eda4ae39aa66e6c4897bb6c5ad0789003d10711c94ba74f28616afa3e5e82a
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ Please ⭐ if you like it.
|
|
19
19
|
|
20
20
|
## Install
|
21
21
|
|
22
|
-
- Add to your Gemfile: `gem 'tiny_admin', '~> 0.
|
22
|
+
- Add to your Gemfile: `gem 'tiny_admin', '~> 0.10'`
|
23
23
|
- Mount the app in a route (check some examples with: Hanami, Rails, Roda and standalone in [extra](extra))
|
24
24
|
+ in Rails, update _config/routes.rb_: `mount TinyAdmin::Router => '/admin'`
|
25
25
|
- Configure the dashboard using `TinyAdmin.configure` and/or `TinyAdmin.configure_from_file` with a YAML config file (see [configuration](#configuration) below):
|
@@ -43,6 +43,12 @@ Plugins available:
|
|
43
43
|
|
44
44
|
- **NoAuth**: no authentication.
|
45
45
|
|
46
|
+
### Authorization
|
47
|
+
|
48
|
+
Plugins available:
|
49
|
+
|
50
|
+
- **Authorization**: base class to provide an authorization per action, the host application should inherit from it and override the class method `allowed?`.
|
51
|
+
|
46
52
|
### Repository
|
47
53
|
|
48
54
|
Plugin available:
|
@@ -134,6 +140,10 @@ authentication:
|
|
134
140
|
password: 'f1891cea80fc05e433c943254c6bdabc159577a02a7395dfebbfbc4f7661d4af56f2d372131a45936de40160007368a56ef216a30cb202c66d3145fd24380906'
|
135
141
|
```
|
136
142
|
|
143
|
+
`authorization_class` (String): a plugin class to use;
|
144
|
+
|
145
|
+
> 📚 [Wiki Authentication page](https://github.com/blocknotes/tiny_admin/wiki/Authorization) available
|
146
|
+
|
137
147
|
`sections` (Array of hashes): define the admin sections, properties:
|
138
148
|
|
139
149
|
- `slug` (String): section reference identifier;
|
@@ -218,6 +228,8 @@ model: Post
|
|
218
228
|
|
219
229
|
#### Resource index options
|
220
230
|
|
231
|
+
> 📚 [Wiki Resource index page](https://github.com/blocknotes/tiny_admin/wiki/Resource-index) available
|
232
|
+
|
221
233
|
The Index hash supports the following options:
|
222
234
|
|
223
235
|
- `attributes` (Array): fields to expose in the resource list page;
|
@@ -257,6 +269,8 @@ Example:
|
|
257
269
|
|
258
270
|
#### Resource show options
|
259
271
|
|
272
|
+
> 📚 [Wiki Resource show page](https://github.com/blocknotes/tiny_admin/wiki/Resource-show) available
|
273
|
+
|
260
274
|
The Show hash supports the following options:
|
261
275
|
|
262
276
|
- `attributes` (Array): fields to expose in the resource details page.
|
@@ -58,12 +58,13 @@ module TinyAdmin
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def setup_pagination(page,
|
61
|
+
def setup_pagination(page, pagination_component, total_count:)
|
62
62
|
@pages = (total_count / pagination.to_f).ceil
|
63
|
-
return if pages <= 1 || !
|
63
|
+
return if pages <= 1 || !pagination_component
|
64
64
|
|
65
|
-
|
66
|
-
page.pagination_component
|
65
|
+
attributes = { current: current_page, pages: pages, query_string: query_string, total_count: total_count }
|
66
|
+
page.pagination_component = pagination_component.new
|
67
|
+
page.pagination_component.update_attributes(attributes)
|
67
68
|
end
|
68
69
|
end
|
69
70
|
end
|
data/lib/tiny_admin/router.rb
CHANGED
@@ -53,36 +53,45 @@ module TinyAdmin
|
|
53
53
|
render(inline: page.call)
|
54
54
|
end
|
55
55
|
|
56
|
-
def root_route(
|
57
|
-
if
|
58
|
-
|
56
|
+
def root_route(req)
|
57
|
+
if authorization.allowed?(current_user, :root)
|
58
|
+
if TinyAdmin.settings.root[:redirect]
|
59
|
+
req.redirect route_for(TinyAdmin.settings.root[:redirect])
|
60
|
+
else
|
61
|
+
page_class = to_class(TinyAdmin.settings.root[:page])
|
62
|
+
attributes = TinyAdmin.settings.root.slice(:content, :title, :widgets)
|
63
|
+
render_page prepare_page(page_class, attributes: attributes, params: request.params)
|
64
|
+
end
|
59
65
|
else
|
60
|
-
|
61
|
-
render_page prepare_page(page_class, attributes: TinyAdmin.settings.root.slice(:content, :title, :widgets))
|
66
|
+
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
62
67
|
end
|
63
68
|
end
|
64
69
|
|
65
|
-
def setup_page_route(
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
def setup_page_route(req, slug, page_data)
|
71
|
+
req.get slug do
|
72
|
+
if authorization.allowed?(current_user, :page, slug)
|
73
|
+
attributes = page_data.slice(:content, :title, :widgets)
|
74
|
+
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
|
+
end
|
69
78
|
end
|
70
79
|
end
|
71
80
|
|
72
|
-
def setup_resource_routes(
|
73
|
-
|
74
|
-
setup_collection_routes(
|
75
|
-
setup_member_routes(
|
81
|
+
def setup_resource_routes(req, slug, options:)
|
82
|
+
req.on slug do
|
83
|
+
setup_collection_routes(req, slug, options: options)
|
84
|
+
setup_member_routes(req, slug, options: options)
|
76
85
|
end
|
77
86
|
end
|
78
87
|
|
79
|
-
def setup_collection_routes(
|
88
|
+
def setup_collection_routes(req, slug, options:)
|
80
89
|
repository = options[:repository].new(options[:model])
|
81
90
|
action_options = options[:index] || {}
|
82
91
|
|
83
92
|
# Custom actions
|
84
93
|
custom_actions = setup_custom_actions(
|
85
|
-
|
94
|
+
req,
|
86
95
|
options[:collection_actions],
|
87
96
|
options: action_options,
|
88
97
|
repository: repository,
|
@@ -91,28 +100,32 @@ module TinyAdmin
|
|
91
100
|
|
92
101
|
# Index
|
93
102
|
if options[:only].include?(:index) || options[:only].include?('index')
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
103
|
+
req.is do
|
104
|
+
if authorization.allowed?(current_user, :resource_index, slug)
|
105
|
+
context = Context.new(
|
106
|
+
actions: custom_actions,
|
107
|
+
repository: repository,
|
108
|
+
request: request,
|
109
|
+
router: req,
|
110
|
+
slug: slug
|
111
|
+
)
|
112
|
+
index_action = TinyAdmin::Actions::Index.new
|
113
|
+
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
|
+
end
|
104
117
|
end
|
105
118
|
end
|
106
119
|
end
|
107
120
|
|
108
|
-
def setup_member_routes(
|
121
|
+
def setup_member_routes(req, slug, options:)
|
109
122
|
repository = options[:repository].new(options[:model])
|
110
123
|
action_options = (options[:show] || {}).merge(record_not_found_page: TinyAdmin.settings.record_not_found)
|
111
124
|
|
112
|
-
|
125
|
+
req.on String do |reference|
|
113
126
|
# Custom actions
|
114
127
|
custom_actions = setup_custom_actions(
|
115
|
-
|
128
|
+
req,
|
116
129
|
options[:member_actions],
|
117
130
|
options: action_options,
|
118
131
|
repository: repository,
|
@@ -122,42 +135,54 @@ module TinyAdmin
|
|
122
135
|
|
123
136
|
# Show
|
124
137
|
if options[:only].include?(:show) || options[:only].include?('show')
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
138
|
+
req.is do
|
139
|
+
if authorization.allowed?(current_user, :resource_show, slug)
|
140
|
+
context = Context.new(
|
141
|
+
actions: custom_actions,
|
142
|
+
reference: reference,
|
143
|
+
repository: repository,
|
144
|
+
request: request,
|
145
|
+
router: req,
|
146
|
+
slug: slug
|
147
|
+
)
|
148
|
+
show_action = TinyAdmin::Actions::Show.new
|
149
|
+
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
|
+
end
|
136
153
|
end
|
137
154
|
end
|
138
155
|
end
|
139
156
|
end
|
140
157
|
|
141
|
-
def setup_custom_actions(
|
158
|
+
def setup_custom_actions(req, custom_actions = nil, options:, repository:, slug:, reference: nil)
|
142
159
|
(custom_actions || []).each_with_object({}) do |custom_action, result|
|
143
160
|
action_slug, action = custom_action.first
|
144
161
|
action_class = to_class(action)
|
145
162
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
163
|
+
req.get action_slug.to_s do
|
164
|
+
if authorization.allowed?(current_user, :custom_action, action_slug.to_s)
|
165
|
+
context = Context.new(
|
166
|
+
actions: {},
|
167
|
+
reference: reference,
|
168
|
+
repository: repository,
|
169
|
+
request: request,
|
170
|
+
router: req,
|
171
|
+
slug: slug
|
172
|
+
)
|
173
|
+
custom_action = action_class.new
|
174
|
+
render_page custom_action.call(app: self, context: context, options: options)
|
175
|
+
else
|
176
|
+
render_page prepare_page(TinyAdmin.settings.page_not_allowed)
|
177
|
+
end
|
157
178
|
end
|
158
179
|
|
159
180
|
result[action_slug.to_s] = action_class
|
160
181
|
end
|
161
182
|
end
|
183
|
+
|
184
|
+
def authorization
|
185
|
+
TinyAdmin.settings.authorization_class
|
186
|
+
end
|
162
187
|
end
|
163
188
|
end
|
data/lib/tiny_admin/settings.rb
CHANGED
@@ -7,6 +7,7 @@ module TinyAdmin
|
|
7
7
|
DEFAULTS = {
|
8
8
|
%i[authentication plugin] => Plugins::NoAuth,
|
9
9
|
%i[authentication login] => Views::Pages::SimpleAuthLogin,
|
10
|
+
%i[authorization_class] => Plugins::Authorization,
|
10
11
|
%i[components field_value] => Views::Components::FieldValue,
|
11
12
|
%i[components flash] => Views::Components::Flash,
|
12
13
|
%i[components head] => Views::Components::Head,
|
@@ -14,6 +15,7 @@ module TinyAdmin
|
|
14
15
|
%i[components pagination] => Views::Components::Pagination,
|
15
16
|
%i[content_page] => Views::Pages::Content,
|
16
17
|
%i[helper_class] => Support,
|
18
|
+
%i[page_not_allowed] => Views::Pages::PageNotAllowed,
|
17
19
|
%i[page_not_found] => Views::Pages::PageNotFound,
|
18
20
|
%i[record_not_found] => Views::Pages::RecordNotFound,
|
19
21
|
%i[repository] => Plugins::ActiveRecordRepository,
|
@@ -25,10 +27,12 @@ module TinyAdmin
|
|
25
27
|
|
26
28
|
OPTIONS = %i[
|
27
29
|
authentication
|
30
|
+
authorization_class
|
28
31
|
components
|
29
32
|
content_page
|
30
33
|
extra_styles
|
31
34
|
helper_class
|
35
|
+
page_not_allowed
|
32
36
|
page_not_found
|
33
37
|
record_not_found
|
34
38
|
repository
|
data/lib/tiny_admin/utils.rb
CHANGED
@@ -14,7 +14,7 @@ module TinyAdmin
|
|
14
14
|
list.join('&')
|
15
15
|
end
|
16
16
|
|
17
|
-
def prepare_page(page_class, slug: nil, attributes: nil, options: nil)
|
17
|
+
def prepare_page(page_class, slug: nil, attributes: nil, options: nil, params: nil)
|
18
18
|
page_class.new.tap do |page|
|
19
19
|
page.options = options
|
20
20
|
page.head_component = TinyAdmin.settings.components[:head]&.new
|
@@ -27,9 +27,11 @@ module TinyAdmin
|
|
27
27
|
items: options&.include?(:no_menu) ? [] : TinyAdmin.settings.store&.navbar
|
28
28
|
)
|
29
29
|
attrs = attributes || {}
|
30
|
+
attrs[:params] = params if params
|
30
31
|
attrs[:widgets] = attrs[:widgets].map { to_class(_1) } if attrs[:widgets]
|
31
32
|
page.update_attributes(attrs) unless attrs.empty?
|
32
33
|
yield(page) if block_given?
|
34
|
+
page.setup if page.respond_to?(:setup)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
data/lib/tiny_admin/version.rb
CHANGED
@@ -4,7 +4,14 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Actions
|
6
6
|
class Index < DefaultLayout
|
7
|
-
attr_accessor :actions,
|
7
|
+
attr_accessor :actions,
|
8
|
+
:fields,
|
9
|
+
:filters,
|
10
|
+
:links,
|
11
|
+
:pagination_component,
|
12
|
+
:prepare_record,
|
13
|
+
:records,
|
14
|
+
:slug
|
8
15
|
|
9
16
|
def template
|
10
17
|
super do
|
@@ -28,6 +35,8 @@ module TinyAdmin
|
|
28
35
|
|
29
36
|
table_body
|
30
37
|
}
|
38
|
+
|
39
|
+
render pagination_component if pagination_component
|
31
40
|
}
|
32
41
|
|
33
42
|
if filters&.any?
|
@@ -39,8 +48,6 @@ module TinyAdmin
|
|
39
48
|
end
|
40
49
|
}
|
41
50
|
|
42
|
-
render pagination_component if pagination_component
|
43
|
-
|
44
51
|
render TinyAdmin::Views::Components::Widgets.new(widgets)
|
45
52
|
}
|
46
53
|
end
|
@@ -4,7 +4,12 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Actions
|
6
6
|
class Show < DefaultLayout
|
7
|
-
attr_accessor :actions,
|
7
|
+
attr_accessor :actions,
|
8
|
+
:fields,
|
9
|
+
:prepare_record,
|
10
|
+
:record,
|
11
|
+
:reference,
|
12
|
+
:slug
|
8
13
|
|
9
14
|
def template
|
10
15
|
super do
|
@@ -4,23 +4,31 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Components
|
6
6
|
class Pagination < BasicComponent
|
7
|
-
attr_accessor :current, :pages, :query_string
|
7
|
+
attr_accessor :current, :pages, :query_string, :total_count
|
8
8
|
|
9
9
|
def template
|
10
|
-
div(class: '
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
pages_range(1..pages)
|
15
|
-
elsif current <= 4 || current >= pages - 3
|
16
|
-
pages_range(1..(current <= 4 ? current + 2 : 4), with_dots: true)
|
17
|
-
pages_range((current > pages - 4 ? current - 2 : pages - 2)..pages)
|
18
|
-
else
|
19
|
-
pages_range(1..1, with_dots: true)
|
20
|
-
pages_range(current - 2..current + 2, with_dots: true)
|
21
|
-
pages_range(pages..pages)
|
22
|
-
end
|
10
|
+
div(class: 'container') {
|
11
|
+
div(class: 'row') {
|
12
|
+
div(class: 'col total-count') {
|
13
|
+
"#{total_count} items"
|
23
14
|
}
|
15
|
+
div(class: 'col col-6 text-center pagination-div') {
|
16
|
+
nav(class: 'd-inline-block', 'aria-label': 'Pagination') {
|
17
|
+
ul(class: 'pagination') {
|
18
|
+
if pages <= 10
|
19
|
+
pages_range(1..pages)
|
20
|
+
elsif current <= 4 || current >= pages - 3
|
21
|
+
pages_range(1..(current <= 4 ? current + 2 : 4), with_dots: true)
|
22
|
+
pages_range((current > pages - 4 ? current - 2 : pages - 2)..pages)
|
23
|
+
else
|
24
|
+
pages_range(1..1, with_dots: true)
|
25
|
+
pages_range(current - 2..current + 2, with_dots: true)
|
26
|
+
pages_range(pages..pages)
|
27
|
+
end
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
div(class: 'col')
|
24
32
|
}
|
25
33
|
}
|
26
34
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
module Views
|
5
|
+
module Pages
|
6
|
+
class PageNotAllowed < DefaultLayout
|
7
|
+
def template
|
8
|
+
super do
|
9
|
+
div(class: 'page_not_allowed') {
|
10
|
+
h1(class: 'title') { title }
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
'Page not allowed'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tiny_admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Roccoberton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- lib/tiny_admin/context.rb
|
84
84
|
- lib/tiny_admin/field.rb
|
85
85
|
- lib/tiny_admin/plugins/active_record_repository.rb
|
86
|
+
- lib/tiny_admin/plugins/authorization.rb
|
86
87
|
- lib/tiny_admin/plugins/base_repository.rb
|
87
88
|
- lib/tiny_admin/plugins/no_auth.rb
|
88
89
|
- lib/tiny_admin/plugins/simple_auth.rb
|
@@ -107,6 +108,7 @@ files:
|
|
107
108
|
- lib/tiny_admin/views/components/widgets.rb
|
108
109
|
- lib/tiny_admin/views/default_layout.rb
|
109
110
|
- lib/tiny_admin/views/pages/content.rb
|
111
|
+
- lib/tiny_admin/views/pages/page_not_allowed.rb
|
110
112
|
- lib/tiny_admin/views/pages/page_not_found.rb
|
111
113
|
- lib/tiny_admin/views/pages/record_not_found.rb
|
112
114
|
- lib/tiny_admin/views/pages/root.rb
|
@@ -134,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
136
|
- !ruby/object:Gem::Version
|
135
137
|
version: '0'
|
136
138
|
requirements: []
|
137
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.4.10
|
138
140
|
signing_key:
|
139
141
|
specification_version: 4
|
140
142
|
summary: Tiny Admin
|