tiny_admin 0.3.0 → 0.4.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 +35 -29
- data/lib/tiny_admin/actions/basic_action.rb +15 -6
- data/lib/tiny_admin/actions/index.rb +14 -6
- data/lib/tiny_admin/actions/show.rb +11 -7
- data/lib/tiny_admin/context.rb +1 -1
- data/lib/tiny_admin/field.rb +9 -3
- data/lib/tiny_admin/plugins/active_record_repository.rb +16 -28
- data/lib/tiny_admin/plugins/base_repository.rb +14 -0
- data/lib/tiny_admin/router.rb +19 -13
- data/lib/tiny_admin/settings.rb +51 -24
- data/lib/tiny_admin/support.rb +35 -0
- data/lib/tiny_admin/utils.rb +2 -1
- data/lib/tiny_admin/version.rb +1 -1
- data/lib/tiny_admin/views/actions/index.rb +21 -16
- data/lib/tiny_admin/views/actions/show.rb +22 -21
- data/lib/tiny_admin.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6eb4a218cc1a4ff6acc940c402d74202582d2092b39f920e6551e5b395da752e
|
4
|
+
data.tar.gz: fb137625f9f5faa5b33dd5c7633a68eec7a4a2d2bb31db6f70758d6ed9ec3750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd7800ab65bd0e92ce5646210f08823d031fdd217f5230bc99207a0e00375b068ad2337805ddce196ca317fe6f0df60ad3e209fc885e31c765c68c125f83d900
|
7
|
+
data.tar.gz: f1df2bd938781a04c4af36c9653a7efffcc075cf72accd8f9fbaedbcc74286d860a1953bab159ec833c6a2cf5851a00633f555966b915fedec625af9ef2f85fa
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Please ⭐ if you like it.
|
|
16
16
|
|
17
17
|
## Install
|
18
18
|
|
19
|
-
- Add to your Gemfile: `gem 'tiny_admin', '~> 0.
|
19
|
+
- Add to your Gemfile: `gem 'tiny_admin', '~> 0.4'`
|
20
20
|
- Mount the app in a route (check some examples with: Hanami, Rails, Roda and standalone in [extra](extra))
|
21
21
|
+ in Rails, update _config/routes.rb_: `mount TinyAdmin::Router => '/admin'`
|
22
22
|
- Configure the dashboard using `TinyAdmin.configure` and/or `TinyAdmin.configure_from_file` (see [configuration](#configuration) below):
|
@@ -82,6 +82,12 @@ root:
|
|
82
82
|
redirect: posts
|
83
83
|
```
|
84
84
|
|
85
|
+
`helper_class` (String): class or module with helper methods, used for attributes' formatters.
|
86
|
+
|
87
|
+
`page_not_found` (String): a view object to render when a missing page is requested.
|
88
|
+
|
89
|
+
`record_not_found` (String): a view object to render when a missing record is requested.
|
90
|
+
|
85
91
|
`authentication` (Hash): define the authentication method, properties:
|
86
92
|
- `plugin` (String): a plugin class to use (ex. `TinyAdmin::Plugins::SimpleAuth`);
|
87
93
|
- `password` (String): a password hash used by _SimpleAuth_ plugin (generated with `Digest::SHA512.hexdigest("some password")`).
|
@@ -175,65 +181,64 @@ end
|
|
175
181
|
---
|
176
182
|
authentication:
|
177
183
|
plugin: TinyAdmin::Plugins::SimpleAuth
|
178
|
-
# password: '
|
179
|
-
page_not_found: Admin::PageNotFound
|
180
|
-
record_not_found: Admin::RecordNotFound
|
184
|
+
# password: 'f1891cea80fc05e433c943254c6bdabc159577a02a7395dfebbfbc4f7661d4af56f2d372131a45936de40160007368a56ef216a30cb202c66d3145fd24380906'
|
181
185
|
root:
|
182
|
-
title:
|
183
|
-
page:
|
184
|
-
|
186
|
+
title: Test Admin
|
187
|
+
# page: RootPage
|
188
|
+
helper_class: AdminHelper
|
189
|
+
page_not_found: PageNotFound
|
190
|
+
record_not_found: RecordNotFound
|
185
191
|
sections:
|
186
192
|
- slug: google
|
187
193
|
name: Google.it
|
188
194
|
type: url
|
189
195
|
url: https://www.google.it
|
190
196
|
options:
|
191
|
-
target:
|
192
|
-
- slug:
|
193
|
-
name:
|
197
|
+
target: _blank
|
198
|
+
- slug: sample
|
199
|
+
name: Sample page
|
194
200
|
type: page
|
195
|
-
page:
|
201
|
+
page: SamplePage
|
196
202
|
- slug: authors
|
197
203
|
name: Authors
|
198
204
|
type: resource
|
199
205
|
model: Author
|
200
|
-
repository: Admin::AuthorsRepo
|
201
206
|
collection_actions:
|
202
|
-
-
|
207
|
+
- sample_col: SampleCollectionAction
|
203
208
|
member_actions:
|
204
|
-
-
|
205
|
-
# only:
|
206
|
-
# - index
|
207
|
-
# options:
|
208
|
-
# - hidden
|
209
|
+
- sample_mem: SampleMemberAction
|
209
210
|
- slug: posts
|
210
211
|
name: Posts
|
211
212
|
type: resource
|
212
213
|
model: Post
|
213
214
|
index:
|
214
|
-
|
215
|
-
- author_id DESC
|
216
|
-
pagination: 15
|
215
|
+
pagination: 5
|
217
216
|
attributes:
|
218
217
|
- id
|
219
218
|
- title
|
220
219
|
- field: author_id
|
221
220
|
link_to: authors
|
222
|
-
-
|
221
|
+
- category: upcase
|
222
|
+
- state: downcase
|
223
223
|
- published
|
224
|
-
-
|
224
|
+
- position: round, 1
|
225
|
+
- dt: to_date
|
225
226
|
- field: created_at
|
226
|
-
converter:
|
227
|
+
converter: AdminUtils
|
227
228
|
method: datetime_formatter
|
229
|
+
- updated_at: strftime, %Y%m%d %H:%M
|
228
230
|
filters:
|
229
231
|
- title
|
230
|
-
-
|
232
|
+
- author_id
|
233
|
+
- field: category
|
231
234
|
type: select
|
232
235
|
values:
|
233
|
-
-
|
234
|
-
-
|
235
|
-
-
|
236
|
+
- news
|
237
|
+
- sport
|
238
|
+
- tech
|
236
239
|
- published
|
240
|
+
- dt
|
241
|
+
- created_at
|
237
242
|
show:
|
238
243
|
attributes:
|
239
244
|
- id
|
@@ -243,7 +248,8 @@ sections:
|
|
243
248
|
link_to: authors
|
244
249
|
- category
|
245
250
|
- published
|
246
|
-
-
|
251
|
+
- position: format, %f
|
252
|
+
- dt
|
247
253
|
- created_at
|
248
254
|
style_links:
|
249
255
|
- href: /bootstrap.min.css
|
@@ -5,12 +5,21 @@ module TinyAdmin
|
|
5
5
|
class BasicAction
|
6
6
|
include Utils
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
def attribute_options(options)
|
9
|
+
options&.each_with_object({}) do |field, result|
|
10
|
+
field_data =
|
11
|
+
if field.is_a?(Hash)
|
12
|
+
if field.one?
|
13
|
+
field, method = field.first
|
14
|
+
{ field.to_s => { field: field.to_s, method: method } }
|
15
|
+
else
|
16
|
+
{ field[:field] => field }
|
17
|
+
end
|
18
|
+
else
|
19
|
+
{ field => { field: field } }
|
20
|
+
end
|
21
|
+
result.merge!(field_data)
|
22
|
+
end
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|
@@ -3,7 +3,15 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
module Actions
|
5
5
|
class Index < BasicAction
|
6
|
-
attr_reader :current_page,
|
6
|
+
attr_reader :current_page,
|
7
|
+
:fields_options,
|
8
|
+
:filters_list,
|
9
|
+
:pagination,
|
10
|
+
:pages,
|
11
|
+
:params,
|
12
|
+
:query_string,
|
13
|
+
:repository,
|
14
|
+
:sort
|
7
15
|
|
8
16
|
def call(app:, context:, options:, actions:)
|
9
17
|
evaluate_options(options)
|
@@ -27,9 +35,9 @@ module TinyAdmin
|
|
27
35
|
private
|
28
36
|
|
29
37
|
def evaluate_options(options)
|
30
|
-
@fields_options = options[:attributes]
|
31
|
-
|
32
|
-
|
38
|
+
@fields_options = attribute_options(options[:attributes])
|
39
|
+
@params = context.request.params
|
40
|
+
@repository = context.repository
|
33
41
|
@filters_list = options[:filters]
|
34
42
|
@pagination = options[:pagination] || 10
|
35
43
|
@sort = options[:sort] || ['id']
|
@@ -42,8 +50,8 @@ module TinyAdmin
|
|
42
50
|
filters = (filters_list || []).map { _1.is_a?(Hash) ? _1 : { field: _1 } }
|
43
51
|
filters = filters.each_with_object({}) { |filter, result| result[filter[:field]] = filter }
|
44
52
|
values = (params['q'] || {})
|
45
|
-
fields.each_with_object({}) do |field, result|
|
46
|
-
result[field] = { value: values[
|
53
|
+
fields.each_with_object({}) do |(name, field), result|
|
54
|
+
result[field] = { value: values[name], filter: filters[name] } if filters.key?(name)
|
47
55
|
end
|
48
56
|
end
|
49
57
|
|
@@ -3,17 +3,21 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
module Actions
|
5
5
|
class Show < BasicAction
|
6
|
+
attr_reader :repository
|
7
|
+
|
6
8
|
def call(app:, context:, options:, actions:)
|
7
|
-
|
8
|
-
|
9
|
-
end
|
9
|
+
@repository = context.repository
|
10
|
+
fields_options = attribute_options(options[:attributes])
|
10
11
|
record = repository.find(context.reference)
|
11
|
-
prepare_record = ->(record_data) { repository.show_record_attrs(record_data, fields: fields_options) }
|
12
|
-
fields = repository.fields(options: fields_options)
|
13
12
|
|
14
13
|
prepare_page(Views::Actions::Show) do |page|
|
15
|
-
page.
|
16
|
-
|
14
|
+
page.update_attributes(
|
15
|
+
actions: actions,
|
16
|
+
fields: repository.fields(options: fields_options),
|
17
|
+
prepare_record: ->(record_data) { repository.show_record_attrs(record_data, fields: fields_options) },
|
18
|
+
record: record,
|
19
|
+
title: repository.show_title(record)
|
20
|
+
)
|
17
21
|
end
|
18
22
|
rescue Plugins::BaseRepository::RecordNotFound => _e
|
19
23
|
prepare_page(options[:record_not_found_page] || Views::Pages::RecordNotFound)
|
data/lib/tiny_admin/context.rb
CHANGED
data/lib/tiny_admin/field.rb
CHANGED
@@ -4,7 +4,7 @@ module TinyAdmin
|
|
4
4
|
class Field
|
5
5
|
attr_reader :name, :options, :title, :type
|
6
6
|
|
7
|
-
def initialize(
|
7
|
+
def initialize(name:, title:, type:, options: {})
|
8
8
|
@type = type
|
9
9
|
@name = name
|
10
10
|
@title = title || name
|
@@ -12,8 +12,14 @@ module TinyAdmin
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class << self
|
15
|
-
def create_field(name:, title
|
16
|
-
|
15
|
+
def create_field(name:, title: nil, type: nil, options: {})
|
16
|
+
field_name = name.to_s
|
17
|
+
new(
|
18
|
+
name: field_name,
|
19
|
+
title: title || field_name.respond_to?(:humanize) ? field_name.humanize : field_name.tr('_', ' ').capitalize,
|
20
|
+
type: type || :string,
|
21
|
+
options: options
|
22
|
+
)
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -4,17 +4,11 @@ module TinyAdmin
|
|
4
4
|
module Plugins
|
5
5
|
class ActiveRecordRepository < BaseRepository
|
6
6
|
def index_record_attrs(record, fields: nil)
|
7
|
-
return record.attributes.transform_values(&:to_s)
|
7
|
+
return record.attributes.transform_values(&:to_s) unless fields
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
if field_data[:converter] && field_data[:method]
|
13
|
-
converter = Object.const_get(field_data[:converter])
|
14
|
-
converter.send(field_data[:method], value)
|
15
|
-
else
|
16
|
-
value&.to_s
|
17
|
-
end
|
9
|
+
fields.to_h do |name, field|
|
10
|
+
value = record.send(name)
|
11
|
+
[name, translate_value(value, field)]
|
18
12
|
end
|
19
13
|
end
|
20
14
|
|
@@ -24,25 +18,19 @@ module TinyAdmin
|
|
24
18
|
end
|
25
19
|
|
26
20
|
def fields(options: nil)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
name = column.name
|
37
|
-
type = opts.dig(column.name, :type) || column.type
|
38
|
-
TinyAdmin::Field.create_field(name: name, title: name.humanize, type: type, options: opts[name])
|
21
|
+
if options
|
22
|
+
types = model.columns.to_h { [_1.name, _1.type] }
|
23
|
+
options.each_with_object({}) do |(name, field_options), result|
|
24
|
+
result[name] = TinyAdmin::Field.create_field(name: name, type: types[name], options: field_options)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
model.columns.each_with_object({}) do |column, result|
|
28
|
+
result[column.name] = TinyAdmin::Field.create_field(name: column.name, type: column.type)
|
29
|
+
end
|
39
30
|
end
|
40
31
|
end
|
41
32
|
|
42
|
-
|
43
|
-
attrs = !fields || fields.empty? ? record.attributes : record.attributes.slice(*fields.keys)
|
44
|
-
attrs.transform_values(&:to_s)
|
45
|
-
end
|
33
|
+
alias show_record_attrs index_record_attrs
|
46
34
|
|
47
35
|
def show_title(record)
|
48
36
|
"#{model} ##{record.id}"
|
@@ -54,10 +42,10 @@ module TinyAdmin
|
|
54
42
|
raise BaseRepository::RecordNotFound, e.message
|
55
43
|
end
|
56
44
|
|
57
|
-
def list(page: 1, limit: 10,
|
58
|
-
page_offset = page.positive? ? (page - 1) * limit : 0
|
45
|
+
def list(page: 1, limit: 10, sort: ['id'], filters: nil)
|
59
46
|
query = model.all.order(sort)
|
60
47
|
query = apply_filters(query, filters) if filters
|
48
|
+
page_offset = page.positive? ? (page - 1) * limit : 0
|
61
49
|
records = query.offset(page_offset).limit(limit).to_a
|
62
50
|
[records, query.count]
|
63
51
|
end
|
@@ -10,6 +10,20 @@ module TinyAdmin
|
|
10
10
|
def initialize(model)
|
11
11
|
@model = model
|
12
12
|
end
|
13
|
+
|
14
|
+
def translate_value(value, field)
|
15
|
+
if field[:method]
|
16
|
+
method, *options = field[:method].split(',').map(&:strip)
|
17
|
+
if field[:converter]
|
18
|
+
converter = Object.const_get(field[:converter])
|
19
|
+
converter.send(method, value, options: options || [])
|
20
|
+
else
|
21
|
+
Settings.instance.helper_class.send(method, value, options: options || [])
|
22
|
+
end
|
23
|
+
else
|
24
|
+
value&.to_s
|
25
|
+
end
|
26
|
+
end
|
13
27
|
end
|
14
28
|
end
|
15
29
|
end
|
data/lib/tiny_admin/router.rb
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
module TinyAdmin
|
4
4
|
class Router < BasicApp
|
5
|
-
TinyAdmin::Settings.instance.load_settings
|
6
|
-
|
7
5
|
route do |r|
|
6
|
+
context.settings = TinyAdmin::Settings.instance
|
7
|
+
context.settings.load_settings
|
8
|
+
context.router = r
|
9
|
+
|
8
10
|
r.on 'auth' do
|
9
11
|
context.slug = nil
|
10
12
|
r.run Authentication
|
@@ -27,11 +29,11 @@ module TinyAdmin
|
|
27
29
|
r.redirect settings.root_path
|
28
30
|
end
|
29
31
|
|
30
|
-
|
32
|
+
context.settings.pages.each do |slug, data|
|
31
33
|
setup_page_route(r, slug, data)
|
32
34
|
end
|
33
35
|
|
34
|
-
|
36
|
+
context.settings.resources.each do |slug, options|
|
35
37
|
setup_resource_routes(r, slug, options: options || {})
|
36
38
|
end
|
37
39
|
|
@@ -74,14 +76,14 @@ module TinyAdmin
|
|
74
76
|
end
|
75
77
|
|
76
78
|
def setup_collection_routes(router, options:)
|
77
|
-
repository = options[:repository].new(options[:model])
|
79
|
+
context.repository = options[:repository].new(options[:model])
|
78
80
|
action_options = options[:index] || {}
|
79
81
|
|
80
82
|
# Custom actions
|
81
83
|
custom_actions = setup_custom_actions(
|
82
84
|
router,
|
83
85
|
options[:collection_actions],
|
84
|
-
repository: repository,
|
86
|
+
repository: context.repository,
|
85
87
|
options: action_options
|
86
88
|
)
|
87
89
|
|
@@ -89,14 +91,15 @@ module TinyAdmin
|
|
89
91
|
actions = options[:only]
|
90
92
|
if !actions || actions.include?(:index) || actions.include?('index')
|
91
93
|
router.is do
|
92
|
-
|
94
|
+
context.request = request
|
95
|
+
index_action = TinyAdmin::Actions::Index.new
|
93
96
|
render_page index_action.call(app: self, context: context, options: action_options, actions: custom_actions)
|
94
97
|
end
|
95
98
|
end
|
96
99
|
end
|
97
100
|
|
98
101
|
def setup_member_routes(router, options:)
|
99
|
-
repository = options[:repository].new(options[:model])
|
102
|
+
context.repository = options[:repository].new(options[:model])
|
100
103
|
action_options = (options[:show] || {}).merge(record_not_found_page: settings.record_not_found)
|
101
104
|
|
102
105
|
router.on String do |reference|
|
@@ -106,7 +109,7 @@ module TinyAdmin
|
|
106
109
|
custom_actions = setup_custom_actions(
|
107
110
|
router,
|
108
111
|
options[:member_actions],
|
109
|
-
repository: repository,
|
112
|
+
repository: context.repository,
|
110
113
|
options: action_options
|
111
114
|
)
|
112
115
|
|
@@ -114,7 +117,8 @@ module TinyAdmin
|
|
114
117
|
actions = options[:only]
|
115
118
|
if !actions || actions.include?(:show) || actions.include?('show')
|
116
119
|
router.is do
|
117
|
-
|
120
|
+
context.request = request
|
121
|
+
show_action = TinyAdmin::Actions::Show.new
|
118
122
|
render_page show_action.call(app: self, context: context, options: action_options, actions: custom_actions)
|
119
123
|
end
|
120
124
|
end
|
@@ -122,16 +126,18 @@ module TinyAdmin
|
|
122
126
|
end
|
123
127
|
|
124
128
|
def setup_custom_actions(router, custom_actions, repository:, options:)
|
125
|
-
|
129
|
+
context.repository = repository
|
130
|
+
(custom_actions || []).each_with_object({}) do |custom_action, result|
|
126
131
|
action_slug, action = custom_action.first
|
127
132
|
action_class = action.is_a?(String) ? Object.const_get(action) : action
|
128
133
|
|
129
134
|
router.get action_slug.to_s do
|
130
|
-
|
135
|
+
context.request = request
|
136
|
+
custom_action = action_class.new
|
131
137
|
render_page custom_action.call(app: self, context: context, options: options)
|
132
138
|
end
|
133
139
|
|
134
|
-
action_slug.to_s
|
140
|
+
result[action_slug.to_s] = action_class
|
135
141
|
end
|
136
142
|
end
|
137
143
|
end
|
data/lib/tiny_admin/settings.rb
CHANGED
@@ -5,9 +5,26 @@ module TinyAdmin
|
|
5
5
|
include Singleton
|
6
6
|
include Utils
|
7
7
|
|
8
|
+
DEFAULTS = {
|
9
|
+
%i[authentication plugin] => Plugins::NoAuth,
|
10
|
+
%i[authentication login] => Views::Pages::SimpleAuthLogin,
|
11
|
+
%i[components flash] => Views::Components::Flash,
|
12
|
+
%i[components head] => Views::Components::Head,
|
13
|
+
%i[components navbar] => Views::Components::Navbar,
|
14
|
+
%i[components pagination] => Views::Components::Pagination,
|
15
|
+
%i[helper_class] => Support,
|
16
|
+
%i[page_not_found] => Views::Pages::PageNotFound,
|
17
|
+
%i[record_not_found] => Views::Pages::RecordNotFound,
|
18
|
+
%i[repository] => Plugins::ActiveRecordRepository,
|
19
|
+
%i[root_path] => '/admin',
|
20
|
+
%i[root page] => Views::Pages::Root,
|
21
|
+
%i[root title] => 'TinyAdmin'
|
22
|
+
}.freeze
|
23
|
+
|
8
24
|
attr_accessor :authentication,
|
9
25
|
:components,
|
10
26
|
:extra_styles,
|
27
|
+
:helper_class,
|
11
28
|
:navbar,
|
12
29
|
:page_not_found,
|
13
30
|
:record_not_found,
|
@@ -20,38 +37,33 @@ module TinyAdmin
|
|
20
37
|
|
21
38
|
attr_reader :pages, :resources
|
22
39
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
40
|
+
def [](key)
|
41
|
+
send(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def []=(key, value)
|
45
|
+
send("#{key}=", value)
|
46
|
+
convert_value(key, value)
|
47
|
+
end
|
28
48
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
49
|
+
def load_settings
|
50
|
+
# default values
|
51
|
+
DEFAULTS.each do |(option, param), default|
|
52
|
+
if param
|
53
|
+
self[option] ||= {}
|
54
|
+
self[option][param] ||= default
|
55
|
+
else
|
56
|
+
self[option] ||= default
|
57
|
+
end
|
58
|
+
end
|
33
59
|
|
34
60
|
@pages ||= {}
|
35
|
-
@repository ||= Plugins::ActiveRecordRepository
|
36
61
|
@resources ||= {}
|
37
|
-
@root_path ||= '/admin'
|
38
|
-
@root_path = '/' if @root_path == ''
|
39
62
|
@sections ||= []
|
40
|
-
|
41
|
-
@root ||= {}
|
42
|
-
@root[:title] ||= 'TinyAdmin'
|
43
|
-
@root[:page] ||= Views::Pages::Root
|
44
|
-
|
63
|
+
@root_path = '/' if @root_path == ''
|
45
64
|
if @authentication[:plugin] == Plugins::SimpleAuth
|
46
65
|
@authentication[:logout] ||= ['logout', "#{root_path}/auth/logout"]
|
47
66
|
end
|
48
|
-
|
49
|
-
@components ||= {}
|
50
|
-
@components[:flash] ||= Views::Components::Flash
|
51
|
-
@components[:head] ||= Views::Components::Head
|
52
|
-
@components[:navbar] ||= Views::Components::Navbar
|
53
|
-
@components[:pagination] ||= Views::Components::Pagination
|
54
|
-
|
55
67
|
@navbar = prepare_navbar(sections, logout: authentication[:logout])
|
56
68
|
end
|
57
69
|
|
@@ -79,5 +91,20 @@ module TinyAdmin
|
|
79
91
|
items['auth/logout'] = logout if logout
|
80
92
|
items
|
81
93
|
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def convert_value(key, value)
|
98
|
+
if value.is_a?(Hash)
|
99
|
+
value.each_key do |key2|
|
100
|
+
path = [key, key2]
|
101
|
+
if DEFAULTS[path].is_a?(Class) || DEFAULTS[path].is_a?(Module)
|
102
|
+
self[key][key2] = Object.const_get(self[key][key2])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
elsif value.is_a?(String) && (DEFAULTS[[key]].is_a?(Class) || DEFAULTS[[key]].is_a?(Module))
|
106
|
+
self[key] = Object.const_get(self[key])
|
107
|
+
end
|
108
|
+
end
|
82
109
|
end
|
83
110
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
class Support
|
5
|
+
class << self
|
6
|
+
def call(value, options: [])
|
7
|
+
value && options&.any? ? options.inject(value) { |result, message| result&.send(message) } : value
|
8
|
+
end
|
9
|
+
|
10
|
+
def downcase(value, options: [])
|
11
|
+
value&.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def format(value, options: [])
|
15
|
+
value && options&.any? ? Kernel.format(options.first, value) : value
|
16
|
+
end
|
17
|
+
|
18
|
+
def round(value, options: [])
|
19
|
+
value&.round(options&.first&.to_i || 2)
|
20
|
+
end
|
21
|
+
|
22
|
+
def strftime(value, options: [])
|
23
|
+
value ? value.strftime(options&.first || '%Y-%m-%d %H:%M') : ''
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_date(value, options: [])
|
27
|
+
value ? value.to_date.to_s : value
|
28
|
+
end
|
29
|
+
|
30
|
+
def upcase(value, options: [])
|
31
|
+
value&.upcase
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/tiny_admin/utils.rb
CHANGED
@@ -29,9 +29,10 @@ module TinyAdmin
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def route_for(section, reference: nil, action: nil)
|
32
|
+
def route_for(section, reference: nil, action: nil, query: nil)
|
33
33
|
root_path = settings.root_path == '/' ? nil : settings.root_path
|
34
34
|
route = [root_path, section, reference, action].compact.join("/")
|
35
|
+
route << "?#{query}" if query
|
35
36
|
route[0] == '/' ? route : route.prepend('/')
|
36
37
|
end
|
37
38
|
|
data/lib/tiny_admin/version.rb
CHANGED
@@ -7,9 +7,6 @@ module TinyAdmin
|
|
7
7
|
attr_accessor :actions, :fields, :filters, :pagination_component, :prepare_record, :records
|
8
8
|
|
9
9
|
def template
|
10
|
-
@fields = fields.each_with_object({}) { |field, result| result[field.name] = field }
|
11
|
-
@filters ||= {}
|
12
|
-
|
13
10
|
super do
|
14
11
|
div(class: 'index') {
|
15
12
|
div(class: 'row') {
|
@@ -17,19 +14,12 @@ module TinyAdmin
|
|
17
14
|
h1(class: 'title') { title }
|
18
15
|
}
|
19
16
|
div(class: 'col-8') {
|
20
|
-
|
21
|
-
(actions || []).each do |action|
|
22
|
-
li(class: 'nav-item') {
|
23
|
-
href = route_for(context.slug, action: action)
|
24
|
-
a(href: href, class: 'nav-link btn btn-outline-secondary') { action }
|
25
|
-
}
|
26
|
-
end
|
27
|
-
}
|
17
|
+
actions_buttons
|
28
18
|
}
|
29
19
|
}
|
30
20
|
|
31
21
|
div(class: 'row') {
|
32
|
-
div_class = filters
|
22
|
+
div_class = filters&.any? ? 'col-9' : 'col-12'
|
33
23
|
div(class: div_class) {
|
34
24
|
table(class: 'table') {
|
35
25
|
table_header if fields.any?
|
@@ -38,7 +28,7 @@ module TinyAdmin
|
|
38
28
|
}
|
39
29
|
}
|
40
30
|
|
41
|
-
if filters
|
31
|
+
if filters&.any?
|
42
32
|
div(class: 'col-3') {
|
43
33
|
filters_form_attrs = { section_path: route_for(context.slug), filters: filters }
|
44
34
|
render TinyAdmin::Views::Components::FiltersForm.new(**filters_form_attrs)
|
@@ -57,7 +47,9 @@ module TinyAdmin
|
|
57
47
|
thead {
|
58
48
|
tr {
|
59
49
|
fields.each_value do |field|
|
60
|
-
td(class: "field-header-#{field.name} field-header-type-#{field.type}") {
|
50
|
+
td(class: "field-header-#{field.name} field-header-type-#{field.type}") {
|
51
|
+
field.options[:header] || field.title
|
52
|
+
}
|
61
53
|
end
|
62
54
|
td { whitespace }
|
63
55
|
}
|
@@ -73,8 +65,9 @@ module TinyAdmin
|
|
73
65
|
field = fields[key]
|
74
66
|
td(class: "field-value-#{field.name} field-value-type-#{field.type}") {
|
75
67
|
if field.options && field.options[:link_to]
|
76
|
-
|
77
|
-
|
68
|
+
messages = (field.options[:call] || '').split(',').map(&:strip)
|
69
|
+
label = messages.any? ? messages.inject(record) { |result, msg| result&.send(msg) } : value
|
70
|
+
a(href: route_for(field.options[:link_to], reference: value)) { label }
|
78
71
|
else
|
79
72
|
value
|
80
73
|
end
|
@@ -87,6 +80,18 @@ module TinyAdmin
|
|
87
80
|
end
|
88
81
|
}
|
89
82
|
end
|
83
|
+
|
84
|
+
def actions_buttons
|
85
|
+
ul(class: 'nav justify-content-end') {
|
86
|
+
(actions || {}).each do |action, action_class|
|
87
|
+
li(class: 'nav-item mx-1') {
|
88
|
+
href = route_for(context.slug, action: action)
|
89
|
+
title = action_class.respond_to?(:title) ? action_class.title : action
|
90
|
+
a(href: href, class: 'nav-link btn btn-outline-secondary') { title }
|
91
|
+
}
|
92
|
+
end
|
93
|
+
}
|
94
|
+
end
|
90
95
|
end
|
91
96
|
end
|
92
97
|
end
|
@@ -4,14 +4,7 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Actions
|
6
6
|
class Show < DefaultLayout
|
7
|
-
|
8
|
-
attr_accessor :actions
|
9
|
-
|
10
|
-
def setup_record(record:, fields:, prepare_record:)
|
11
|
-
@record = record
|
12
|
-
@fields = fields
|
13
|
-
@prepare_record = prepare_record
|
14
|
-
end
|
7
|
+
attr_accessor :actions, :fields, :prepare_record, :record
|
15
8
|
|
16
9
|
def template
|
17
10
|
super do
|
@@ -21,27 +14,21 @@ module TinyAdmin
|
|
21
14
|
h1(class: 'title') { title }
|
22
15
|
}
|
23
16
|
div(class: 'col-8') {
|
24
|
-
|
25
|
-
(actions || []).each do |action|
|
26
|
-
li(class: 'nav-item') {
|
27
|
-
href = route_for(context.slug, reference: context.reference, action: action)
|
28
|
-
a(href: href, class: 'nav-link btn btn-outline-secondary') { action }
|
29
|
-
}
|
30
|
-
end
|
31
|
-
}
|
17
|
+
actions_buttons
|
32
18
|
}
|
33
19
|
}
|
34
20
|
|
35
|
-
prepare_record.call(record).
|
36
|
-
field = fields[
|
21
|
+
prepare_record.call(record).each do |key, value|
|
22
|
+
field = fields[key]
|
37
23
|
div(class: "field-#{field.name} row lh-lg") {
|
38
24
|
if field
|
39
|
-
div(class: 'field-header col-2') { field.title }
|
25
|
+
div(class: 'field-header col-2') { field.options[:header] || field.title }
|
40
26
|
end
|
41
27
|
div(class: 'field-value col-10') {
|
42
28
|
if field.options && field.options[:link_to]
|
43
|
-
|
44
|
-
|
29
|
+
messages = (field.options[:call] || '').split(',').map(&:strip)
|
30
|
+
label = messages.any? ? messages.inject(record) { |result, msg| result&.send(msg) } : value
|
31
|
+
a(href: route_for(field.options[:link_to], reference: value)) { label }
|
45
32
|
else
|
46
33
|
value
|
47
34
|
end
|
@@ -51,6 +38,20 @@ module TinyAdmin
|
|
51
38
|
}
|
52
39
|
end
|
53
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def actions_buttons
|
45
|
+
ul(class: 'nav justify-content-end') {
|
46
|
+
(actions || {}).each do |action, action_class|
|
47
|
+
li(class: 'nav-item mx-1') {
|
48
|
+
href = route_for(context.slug, reference: context.reference, action: action)
|
49
|
+
title = action_class.respond_to?(:title) ? action_class.title : action
|
50
|
+
a(href: href, class: 'nav-link btn btn-outline-secondary') { title }
|
51
|
+
}
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
54
55
|
end
|
55
56
|
end
|
56
57
|
end
|
data/lib/tiny_admin.rb
CHANGED
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.4.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-04-
|
11
|
+
date: 2023-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- lib/tiny_admin/plugins/simple_auth.rb
|
89
89
|
- lib/tiny_admin/router.rb
|
90
90
|
- lib/tiny_admin/settings.rb
|
91
|
+
- lib/tiny_admin/support.rb
|
91
92
|
- lib/tiny_admin/utils.rb
|
92
93
|
- lib/tiny_admin/version.rb
|
93
94
|
- lib/tiny_admin/views/actions/index.rb
|