tiny_admin 0.5.0 → 0.7.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 +37 -3
- data/lib/tiny_admin/actions/index.rb +23 -23
- data/lib/tiny_admin/actions/show.rb +11 -9
- data/lib/tiny_admin/authentication.rb +6 -3
- data/lib/tiny_admin/basic_app.rb +3 -3
- data/lib/tiny_admin/context.rb +9 -14
- data/lib/tiny_admin/plugins/active_record_repository.rb +9 -5
- data/lib/tiny_admin/plugins/base_repository.rb +1 -1
- data/lib/tiny_admin/router.rb +59 -41
- data/lib/tiny_admin/section.rb +14 -0
- data/lib/tiny_admin/settings.rb +53 -72
- data/lib/tiny_admin/store.rb +67 -0
- data/lib/tiny_admin/utils.rb +13 -21
- data/lib/tiny_admin/version.rb +1 -1
- data/lib/tiny_admin/views/actions/index.rb +12 -8
- data/lib/tiny_admin/views/actions/show.rb +5 -3
- data/lib/tiny_admin/views/basic_layout.rb +2 -0
- data/lib/tiny_admin/views/basic_widget.rb +8 -0
- data/lib/tiny_admin/views/components/navbar.rb +5 -5
- data/lib/tiny_admin/views/components/widgets.rb +35 -0
- data/lib/tiny_admin/views/default_layout.rb +3 -3
- data/lib/tiny_admin/views/pages/content.rb +21 -0
- data/lib/tiny_admin/views/pages/root.rb +1 -1
- data/lib/tiny_admin.rb +16 -3
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8059ea24a18bfb14f8e868a70203db8045099e20196f5098f1c63b121421e49
|
4
|
+
data.tar.gz: d0da80d718362c58a50e963b2e79dff550e77a763d7872a0ba96efea43f408b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3067f890f10f10f5dc7379c7b147f01f5cb62b8d59f06ad7b4387c685cd2e32cdeb1f87fbfe36b0e2c388c854ce461f1a18b2659ee479e401ba74ed3c5559a3a
|
7
|
+
data.tar.gz: 0a4b4129b33e0dbf2ab2d01df14ead0ec3971a098dbed39a5b50c287e2a00c5c8448011de81a233c7bb1dda58bb42b648d44069684a65cdb4e42e3faf2a453bb
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Tiny Admin
|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/tiny_admin)
|
3
|
+
[](https://badge.fury.io/rb/tiny_admin)
|
4
|
+
[](https://rubygems.org/gems/tiny_admin)
|
5
|
+
[](https://github.com/blocknotes/tiny_admin/actions/workflows/linters.yml)
|
6
|
+
[](https://github.com/blocknotes/tiny_admin/actions/workflows/specs.yml)
|
4
7
|
|
5
8
|
A compact and composable dashboard component for Ruby.
|
6
9
|
|
@@ -16,7 +19,7 @@ Please ⭐ if you like it.
|
|
16
19
|
|
17
20
|
## Install
|
18
21
|
|
19
|
-
- Add to your Gemfile: `gem 'tiny_admin', '~> 0.
|
22
|
+
- Add to your Gemfile: `gem 'tiny_admin', '~> 0.7'`
|
20
23
|
- Mount the app in a route (check some examples with: Hanami, Rails, Roda and standalone in [extra](extra))
|
21
24
|
+ in Rails, update _config/routes.rb_: `mount TinyAdmin::Router => '/admin'`
|
22
25
|
- Configure the dashboard using `TinyAdmin.configure` and/or `TinyAdmin.configure_from_file` with a YAML config file (see [configuration](#configuration) below):
|
@@ -51,6 +54,7 @@ Plugin available:
|
|
51
54
|
Pages available:
|
52
55
|
|
53
56
|
- **Root**: define how to present the content in the main page of the interface;
|
57
|
+
- **Content**: define how to present page with inline content;
|
54
58
|
- **PageNotFound**: define how to present pages not found;
|
55
59
|
- **RecordNotFound**: define how to present record not found page;
|
56
60
|
- **SimpleAuthLogin**: define how to present the login form for SimpleAuth plugin;
|
@@ -79,6 +83,7 @@ The following options are supported:
|
|
79
83
|
- `title` (String): root section's title;
|
80
84
|
- `page` (String): a view object to render;
|
81
85
|
- `redirect` (String): alternative to _page_ option - redirects to a specific slug;
|
86
|
+
- `widgets` (Array): list of widgets (as View components) to present.
|
82
87
|
|
83
88
|
Example:
|
84
89
|
|
@@ -86,6 +91,9 @@ Example:
|
|
86
91
|
root:
|
87
92
|
title: MyAdmin
|
88
93
|
redirect: posts
|
94
|
+
widgets:
|
95
|
+
- LatestAuthorsWidget
|
96
|
+
- LatestPostsWidget
|
89
97
|
```
|
90
98
|
|
91
99
|
`helper_class` (String): class or module with helper methods, used for attributes' formatters.
|
@@ -122,9 +130,28 @@ authentication:
|
|
122
130
|
|
123
131
|
- `slug` (String): section reference identifier;
|
124
132
|
- `name` (String): section's title;
|
125
|
-
- `type` (String): the type of section: `
|
133
|
+
- `type` (String): the type of section: `content`, `page`, `resource` or `url`;
|
134
|
+
- `widgets` (Array): list of widgets (as View components) to present;
|
126
135
|
- other properties depends on the section's type.
|
127
136
|
|
137
|
+
For _content_ sections:
|
138
|
+
|
139
|
+
- `content` (String): the HTML content to present.
|
140
|
+
|
141
|
+
Example:
|
142
|
+
|
143
|
+
```yml
|
144
|
+
slug: test-content
|
145
|
+
name: Test content
|
146
|
+
type: content
|
147
|
+
content: >
|
148
|
+
<h1>Test content!</h1>
|
149
|
+
<p>Some test content</p>
|
150
|
+
widgets:
|
151
|
+
- LatestAuthorsWidget
|
152
|
+
- LatestPostsWidget
|
153
|
+
```
|
154
|
+
|
128
155
|
For _url_ sections:
|
129
156
|
|
130
157
|
- `url` (String): the URL to load when clicking on the section's menu item;
|
@@ -163,6 +190,7 @@ For _resource_ sections:
|
|
163
190
|
- `show` (Hash): detail's action options (see below);
|
164
191
|
- `collection_actions` (Array of hashes): custom collection's actions;
|
165
192
|
- `member_actions` (Array of hashes): custom details's actions;
|
193
|
+
- `widgets` (Array): list of widgets (as View components) to present;
|
166
194
|
- `only` (Array of strings): list of supported actions (ex. `index`);
|
167
195
|
- `options` (Array of strings): resource options (ex. `hidden`).
|
168
196
|
|
@@ -240,6 +268,9 @@ Example:
|
|
240
268
|
header: The author
|
241
269
|
link_to: authors
|
242
270
|
call: author, name
|
271
|
+
widgets:
|
272
|
+
- LatestAuthorsWidget
|
273
|
+
- LatestPostsWidget
|
243
274
|
```
|
244
275
|
|
245
276
|
### Sample
|
@@ -264,6 +295,9 @@ authentication:
|
|
264
295
|
# password: 'f1891cea80fc05e433c943254c6bdabc159577a02a7395dfebbfbc4f7661d4af56f2d372131a45936de40160007368a56ef216a30cb202c66d3145fd24380906'
|
265
296
|
root:
|
266
297
|
title: Test Admin
|
298
|
+
widgets:
|
299
|
+
- LatestAuthorsWidget
|
300
|
+
- LatestPostsWidget
|
267
301
|
# page: RootPage
|
268
302
|
helper_class: AdminHelper
|
269
303
|
page_not_found: PageNotFound
|
@@ -3,34 +3,38 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
module Actions
|
5
5
|
class Index < BasicAction
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :context,
|
7
|
+
:current_page,
|
7
8
|
:fields_options,
|
8
|
-
:filters_list,
|
9
9
|
:links,
|
10
|
+
:options,
|
10
11
|
:pagination,
|
11
12
|
:pages,
|
12
13
|
:params,
|
13
14
|
:query_string,
|
14
|
-
:repository
|
15
|
-
:sort
|
15
|
+
:repository
|
16
16
|
|
17
17
|
def call(app:, context:, options:)
|
18
|
+
@context = context
|
19
|
+
@options = options || {}
|
18
20
|
evaluate_options(options)
|
19
21
|
fields = repository.fields(options: fields_options)
|
20
|
-
filters = prepare_filters(fields
|
21
|
-
records,
|
22
|
+
filters = prepare_filters(fields)
|
23
|
+
records, count = repository.list(page: current_page, limit: pagination, filters: filters, sort: options[:sort])
|
24
|
+
attributes = {
|
25
|
+
actions: context.actions,
|
26
|
+
fields: fields,
|
27
|
+
filters: filters,
|
28
|
+
links: options[:links],
|
29
|
+
prepare_record: ->(record) { repository.index_record_attrs(record, fields: fields_options) },
|
30
|
+
records: records,
|
31
|
+
slug: context.slug,
|
32
|
+
title: repository.index_title,
|
33
|
+
widgets: options[:widgets]
|
34
|
+
}
|
22
35
|
|
23
|
-
prepare_page(Views::Actions::Index) do |page|
|
24
|
-
setup_pagination(page, settings.components[:pagination], total_count:
|
25
|
-
page.update_attributes(
|
26
|
-
actions: context.actions,
|
27
|
-
fields: fields,
|
28
|
-
filters: filters,
|
29
|
-
links: links,
|
30
|
-
prepare_record: ->(record) { repository.index_record_attrs(record, fields: fields_options) },
|
31
|
-
records: records,
|
32
|
-
title: repository.index_title
|
33
|
-
)
|
36
|
+
prepare_page(Views::Actions::Index, slug: context.slug, attributes: attributes) do |page|
|
37
|
+
setup_pagination(page, TinyAdmin.settings.components[:pagination], total_count: count)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
@@ -40,17 +44,13 @@ module TinyAdmin
|
|
40
44
|
@fields_options = attribute_options(options[:attributes])
|
41
45
|
@params = context.request.params
|
42
46
|
@repository = context.repository
|
43
|
-
@filters_list = options[:filters]
|
44
47
|
@pagination = options[:pagination] || 10
|
45
|
-
@sort = options[:sort]
|
46
|
-
@links = options[:links]
|
47
|
-
|
48
48
|
@current_page = (params['p'] || 1).to_i
|
49
49
|
@query_string = params_to_s(params.except('p'))
|
50
50
|
end
|
51
51
|
|
52
|
-
def prepare_filters(fields
|
53
|
-
filters = (
|
52
|
+
def prepare_filters(fields)
|
53
|
+
filters = (options[:filters] || []).map { _1.is_a?(Hash) ? _1 : { field: _1 } }
|
54
54
|
filters = filters.each_with_object({}) { |filter, result| result[filter[:field]] = filter }
|
55
55
|
values = (params['q'] || {})
|
56
56
|
fields.each_with_object({}) do |(name, field), result|
|
@@ -8,16 +8,18 @@ module TinyAdmin
|
|
8
8
|
repository = context.repository
|
9
9
|
record = repository.find(context.reference)
|
10
10
|
prepare_record = ->(record_data) { repository.show_record_attrs(record_data, fields: fields_options) }
|
11
|
+
attributes = {
|
12
|
+
actions: context.actions,
|
13
|
+
fields: repository.fields(options: fields_options),
|
14
|
+
prepare_record: prepare_record,
|
15
|
+
record: record,
|
16
|
+
reference: context.reference,
|
17
|
+
slug: context.slug,
|
18
|
+
title: repository.show_title(record),
|
19
|
+
widgets: options[:widgets]
|
20
|
+
}
|
11
21
|
|
12
|
-
prepare_page(Views::Actions::Show
|
13
|
-
page.update_attributes(
|
14
|
-
actions: context.actions,
|
15
|
-
fields: repository.fields(options: fields_options),
|
16
|
-
prepare_record: prepare_record,
|
17
|
-
record: record,
|
18
|
-
title: repository.show_title(record)
|
19
|
-
)
|
20
|
-
end
|
22
|
+
prepare_page(Views::Actions::Show, slug: context.slug, attributes: attributes)
|
21
23
|
rescue Plugins::BaseRepository::RecordNotFound => _e
|
22
24
|
prepare_page(options[:record_not_found_page] || Views::Pages::RecordNotFound)
|
23
25
|
end
|
@@ -5,7 +5,7 @@ module TinyAdmin
|
|
5
5
|
route do |r|
|
6
6
|
r.get 'unauthenticated' do
|
7
7
|
if current_user
|
8
|
-
r.redirect settings.root_path
|
8
|
+
r.redirect TinyAdmin.settings.root_path
|
9
9
|
else
|
10
10
|
render_login
|
11
11
|
end
|
@@ -17,14 +17,17 @@ module TinyAdmin
|
|
17
17
|
|
18
18
|
r.get 'logout' do
|
19
19
|
logout_user
|
20
|
-
r.redirect settings.root_path
|
20
|
+
r.redirect TinyAdmin.settings.root_path
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def render_login(notices: nil, warnings: nil, errors: nil)
|
27
|
-
|
27
|
+
login = TinyAdmin.settings.authentication[:login]
|
28
|
+
return unless login
|
29
|
+
|
30
|
+
page = prepare_page(login, options: %i[no_menu compact_layout])
|
28
31
|
page.messages = {
|
29
32
|
notices: notices || flash['notices'],
|
30
33
|
warnings: warnings || flash['warnings'],
|
data/lib/tiny_admin/basic_app.rb
CHANGED
@@ -6,7 +6,7 @@ module TinyAdmin
|
|
6
6
|
|
7
7
|
class << self
|
8
8
|
def authentication_plugin
|
9
|
-
plugin = TinyAdmin
|
9
|
+
plugin = TinyAdmin.settings.authentication&.dig(:plugin)
|
10
10
|
plugin_class = plugin.is_a?(String) ? Object.const_get(plugin) : plugin
|
11
11
|
plugin_class || TinyAdmin::Plugins::NoAuth
|
12
12
|
end
|
@@ -17,8 +17,8 @@ module TinyAdmin
|
|
17
17
|
plugin :render, engine: 'html'
|
18
18
|
plugin :sessions, secret: SecureRandom.hex(64)
|
19
19
|
|
20
|
-
plugin authentication_plugin, TinyAdmin
|
20
|
+
plugin authentication_plugin, TinyAdmin.settings.authentication
|
21
21
|
|
22
|
-
not_found { prepare_page(settings.page_not_found).call }
|
22
|
+
not_found { prepare_page(TinyAdmin.settings.page_not_found).call }
|
23
23
|
end
|
24
24
|
end
|
data/lib/tiny_admin/context.rb
CHANGED
@@ -1,18 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module TinyAdmin
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:resources,
|
14
|
-
:router,
|
15
|
-
:settings,
|
16
|
-
:slug
|
17
|
-
end
|
4
|
+
Context = Struct.new(
|
5
|
+
:actions,
|
6
|
+
:reference,
|
7
|
+
:repository,
|
8
|
+
:request,
|
9
|
+
:router,
|
10
|
+
:slug,
|
11
|
+
keyword_init: true
|
12
|
+
)
|
18
13
|
end
|
@@ -20,12 +20,12 @@ module TinyAdmin
|
|
20
20
|
def fields(options: nil)
|
21
21
|
if options
|
22
22
|
types = model.columns.to_h { [_1.name, _1.type] }
|
23
|
-
options.
|
24
|
-
|
23
|
+
options.to_h do |name, field_options|
|
24
|
+
[name, TinyAdmin::Field.create_field(name: name, type: types[name], options: field_options)]
|
25
25
|
end
|
26
26
|
else
|
27
|
-
model.columns.
|
28
|
-
|
27
|
+
model.columns.to_h do |column|
|
28
|
+
[column.name, TinyAdmin::Field.create_field(name: column.name, type: column.type)]
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -42,8 +42,12 @@ module TinyAdmin
|
|
42
42
|
raise BaseRepository::RecordNotFound, e.message
|
43
43
|
end
|
44
44
|
|
45
|
+
def collection
|
46
|
+
model.all
|
47
|
+
end
|
48
|
+
|
45
49
|
def list(page: 1, limit: 10, sort: nil, filters: nil)
|
46
|
-
query = sort ?
|
50
|
+
query = sort ? collection.order(sort) : collection
|
47
51
|
query = apply_filters(query, filters) if filters
|
48
52
|
page_offset = page.positive? ? (page - 1) * limit : 0
|
49
53
|
records = query.offset(page_offset).limit(limit).to_a
|
@@ -18,7 +18,7 @@ module TinyAdmin
|
|
18
18
|
converter = Object.const_get(field[:converter])
|
19
19
|
converter.send(method, value, options: options || [])
|
20
20
|
else
|
21
|
-
|
21
|
+
TinyAdmin.settings.helper_class.send(method, value, options: options || [])
|
22
22
|
end
|
23
23
|
else
|
24
24
|
value&.to_s
|
data/lib/tiny_admin/router.rb
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
module TinyAdmin
|
4
4
|
class Router < BasicApp
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegator TinyAdmin, :route_for
|
8
|
+
|
5
9
|
route do |r|
|
6
|
-
|
7
|
-
context.settings.load_settings
|
8
|
-
context.router = r
|
10
|
+
TinyAdmin.settings.load_settings
|
9
11
|
|
10
12
|
r.on 'auth' do
|
11
|
-
context.slug = nil
|
12
13
|
r.run Authentication
|
13
14
|
end
|
14
15
|
|
@@ -25,15 +26,14 @@ module TinyAdmin
|
|
25
26
|
end
|
26
27
|
|
27
28
|
r.post '' do
|
28
|
-
|
29
|
-
r.redirect settings.root_path
|
29
|
+
r.redirect TinyAdmin.settings.root_path
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
setup_page_route(r, slug,
|
32
|
+
store.pages.each do |slug, page_data|
|
33
|
+
setup_page_route(r, slug, page_data)
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
store.resources.each do |slug, options|
|
37
37
|
setup_resource_routes(r, slug, options: options || {})
|
38
38
|
end
|
39
39
|
|
@@ -42,6 +42,10 @@ module TinyAdmin
|
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
|
+
def store
|
46
|
+
@store ||= TinyAdmin.settings.store
|
47
|
+
end
|
48
|
+
|
45
49
|
def render_page(page)
|
46
50
|
if page.respond_to?(:messages=)
|
47
51
|
page.messages = { notices: flash['notices'], warnings: flash['warnings'], errors: flash['errors'] }
|
@@ -50,74 +54,83 @@ module TinyAdmin
|
|
50
54
|
end
|
51
55
|
|
52
56
|
def root_route(router)
|
53
|
-
|
54
|
-
|
55
|
-
router.redirect route_for(settings.root[:redirect])
|
57
|
+
if TinyAdmin.settings.root[:redirect]
|
58
|
+
router.redirect route_for(TinyAdmin.settings.root[:redirect])
|
56
59
|
else
|
57
|
-
|
58
|
-
|
59
|
-
render_page prepare_page(page_class)
|
60
|
+
page_class = to_class(TinyAdmin.settings.root[:page])
|
61
|
+
render_page prepare_page(page_class, attributes: TinyAdmin.settings.root.slice(:content, :title, :widgets))
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
def setup_page_route(router, slug,
|
65
|
+
def setup_page_route(router, slug, page_data)
|
64
66
|
router.get slug do
|
65
|
-
|
66
|
-
render_page prepare_page(
|
67
|
+
attributes = page_data.slice(:content, :title, :widgets)
|
68
|
+
render_page prepare_page(page_data[:class], slug: slug, attributes: attributes)
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
70
72
|
def setup_resource_routes(router, slug, options:)
|
71
73
|
router.on slug do
|
72
|
-
|
73
|
-
|
74
|
-
setup_member_routes(router, options: options)
|
74
|
+
setup_collection_routes(router, slug, options: options)
|
75
|
+
setup_member_routes(router, slug, options: options)
|
75
76
|
end
|
76
77
|
end
|
77
78
|
|
78
|
-
def setup_collection_routes(router, options:)
|
79
|
-
|
79
|
+
def setup_collection_routes(router, slug, options:)
|
80
|
+
repository = options[:repository].new(options[:model])
|
80
81
|
action_options = options[:index] || {}
|
81
82
|
|
82
83
|
# Custom actions
|
83
84
|
custom_actions = setup_custom_actions(
|
84
85
|
router,
|
85
86
|
options[:collection_actions],
|
86
|
-
|
87
|
-
|
87
|
+
options: action_options,
|
88
|
+
repository: repository,
|
89
|
+
slug: slug
|
88
90
|
)
|
89
91
|
|
90
92
|
# Index
|
91
93
|
if options[:only].include?(:index) || options[:only].include?('index')
|
92
94
|
router.is do
|
93
|
-
context
|
94
|
-
|
95
|
+
context = Context.new(
|
96
|
+
actions: custom_actions,
|
97
|
+
repository: repository,
|
98
|
+
request: request,
|
99
|
+
router: router,
|
100
|
+
slug: slug
|
101
|
+
)
|
95
102
|
index_action = TinyAdmin::Actions::Index.new
|
96
103
|
render_page index_action.call(app: self, context: context, options: action_options)
|
97
104
|
end
|
98
105
|
end
|
99
106
|
end
|
100
107
|
|
101
|
-
def setup_member_routes(router, options:)
|
102
|
-
|
103
|
-
action_options = (options[:show] || {}).merge(record_not_found_page: settings.record_not_found)
|
108
|
+
def setup_member_routes(router, slug, options:)
|
109
|
+
repository = options[:repository].new(options[:model])
|
110
|
+
action_options = (options[:show] || {}).merge(record_not_found_page: TinyAdmin.settings.record_not_found)
|
104
111
|
|
105
112
|
router.on String do |reference|
|
106
|
-
context.reference = reference
|
107
|
-
|
108
113
|
# Custom actions
|
109
114
|
custom_actions = setup_custom_actions(
|
110
115
|
router,
|
111
116
|
options[:member_actions],
|
112
|
-
|
113
|
-
|
117
|
+
options: action_options,
|
118
|
+
repository: repository,
|
119
|
+
slug: slug,
|
120
|
+
reference: reference
|
114
121
|
)
|
115
122
|
|
116
123
|
# Show
|
117
124
|
if options[:only].include?(:show) || options[:only].include?('show')
|
118
125
|
router.is do
|
119
|
-
context
|
120
|
-
|
126
|
+
context = Context.new(
|
127
|
+
actions: custom_actions,
|
128
|
+
reference: reference,
|
129
|
+
repository: repository,
|
130
|
+
request: request,
|
131
|
+
router: router,
|
132
|
+
slug: slug
|
133
|
+
)
|
121
134
|
show_action = TinyAdmin::Actions::Show.new
|
122
135
|
render_page show_action.call(app: self, context: context, options: action_options)
|
123
136
|
end
|
@@ -125,15 +138,20 @@ module TinyAdmin
|
|
125
138
|
end
|
126
139
|
end
|
127
140
|
|
128
|
-
def setup_custom_actions(router, custom_actions, repository:,
|
129
|
-
context.repository = repository
|
141
|
+
def setup_custom_actions(router, custom_actions, options:, repository:, slug:, reference: nil)
|
130
142
|
(custom_actions || []).each_with_object({}) do |custom_action, result|
|
131
143
|
action_slug, action = custom_action.first
|
132
|
-
action_class =
|
144
|
+
action_class = to_class(action)
|
133
145
|
|
134
146
|
router.get action_slug.to_s do
|
135
|
-
context
|
136
|
-
|
147
|
+
context = Context.new(
|
148
|
+
actions: {},
|
149
|
+
reference: reference,
|
150
|
+
repository: repository,
|
151
|
+
request: request,
|
152
|
+
router: router,
|
153
|
+
slug: slug
|
154
|
+
)
|
137
155
|
custom_action = action_class.new
|
138
156
|
render_page custom_action.call(app: self, context: context, options: options)
|
139
157
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
class Section
|
5
|
+
attr_reader :name, :options, :path, :slug
|
6
|
+
|
7
|
+
def initialize(name:, slug: nil, path: nil, options: {})
|
8
|
+
@name = name
|
9
|
+
@options = options
|
10
|
+
@path = path || TinyAdmin.route_for(slug)
|
11
|
+
@slug = slug
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/tiny_admin/settings.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
class Settings
|
5
5
|
include Singleton
|
6
|
-
include Utils
|
7
6
|
|
8
7
|
DEFAULTS = {
|
9
8
|
%i[authentication plugin] => Plugins::NoAuth,
|
@@ -12,34 +11,53 @@ module TinyAdmin
|
|
12
11
|
%i[components head] => Views::Components::Head,
|
13
12
|
%i[components navbar] => Views::Components::Navbar,
|
14
13
|
%i[components pagination] => Views::Components::Pagination,
|
14
|
+
%i[content_page] => Views::Pages::Content,
|
15
15
|
%i[helper_class] => Support,
|
16
16
|
%i[page_not_found] => Views::Pages::PageNotFound,
|
17
17
|
%i[record_not_found] => Views::Pages::RecordNotFound,
|
18
18
|
%i[repository] => Plugins::ActiveRecordRepository,
|
19
19
|
%i[root_path] => '/admin',
|
20
20
|
%i[root page] => Views::Pages::Root,
|
21
|
-
%i[root title] => 'TinyAdmin'
|
21
|
+
%i[root title] => 'TinyAdmin',
|
22
|
+
%i[sections] => []
|
22
23
|
}.freeze
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
OPTIONS = %i[
|
26
|
+
authentication
|
27
|
+
components
|
28
|
+
content_page
|
29
|
+
extra_styles
|
30
|
+
helper_class
|
31
|
+
page_not_found
|
32
|
+
record_not_found
|
33
|
+
repository
|
34
|
+
root
|
35
|
+
root_path
|
36
|
+
sections
|
37
|
+
scripts
|
38
|
+
style_links
|
39
|
+
].freeze
|
40
|
+
|
41
|
+
attr_reader :store
|
42
|
+
|
43
|
+
OPTIONS.each do |option|
|
44
|
+
define_method(option) do
|
45
|
+
self[option]
|
46
|
+
end
|
47
|
+
|
48
|
+
define_method("#{option}=") do |value|
|
49
|
+
self[option] = value
|
50
|
+
end
|
51
|
+
end
|
36
52
|
|
37
|
-
def [](
|
38
|
-
|
53
|
+
def [](*path)
|
54
|
+
key, option = fetch_setting(path)
|
55
|
+
option[key]
|
39
56
|
end
|
40
57
|
|
41
|
-
def []=(
|
42
|
-
|
58
|
+
def []=(*path, value)
|
59
|
+
key, option = fetch_setting(path)
|
60
|
+
option[key] = value
|
43
61
|
convert_value(key, value)
|
44
62
|
end
|
45
63
|
|
@@ -54,24 +72,33 @@ module TinyAdmin
|
|
54
72
|
end
|
55
73
|
end
|
56
74
|
|
57
|
-
|
58
|
-
|
59
|
-
@sections ||= []
|
60
|
-
@root_path = '/' if @root_path == ''
|
75
|
+
@store ||= TinyAdmin::Store.new(self)
|
76
|
+
self.root_path = '/' if root_path == ''
|
61
77
|
|
62
|
-
if
|
63
|
-
|
78
|
+
if authentication[:plugin] <= Plugins::SimpleAuth
|
79
|
+
logout_path = "#{root_path}/auth/logout"
|
80
|
+
authentication[:logout] ||= TinyAdmin::Section.new(name: 'logout', slug: 'logout', path: logout_path)
|
64
81
|
end
|
65
|
-
|
82
|
+
store.prepare_sections(sections, logout: authentication[:logout])
|
83
|
+
end
|
84
|
+
|
85
|
+
def reset!
|
86
|
+
@options = {}
|
66
87
|
end
|
67
88
|
|
68
89
|
private
|
69
90
|
|
91
|
+
def fetch_setting(path)
|
92
|
+
@options ||= {}
|
93
|
+
*parts, last = path.map(&:to_sym)
|
94
|
+
[last, parts.inject(@options) { |result, part| result[part] ||= {} }]
|
95
|
+
end
|
96
|
+
|
70
97
|
def convert_value(key, value)
|
71
98
|
if value.is_a?(Hash)
|
72
99
|
value.each_key do |key2|
|
73
100
|
path = [key, key2]
|
74
|
-
if DEFAULTS[path].is_a?(Class) || DEFAULTS[path].is_a?(Module)
|
101
|
+
if (DEFAULTS[path].is_a?(Class) || DEFAULTS[path].is_a?(Module)) && self[key][key2].is_a?(String)
|
75
102
|
self[key][key2] = Object.const_get(self[key][key2])
|
76
103
|
end
|
77
104
|
end
|
@@ -79,51 +106,5 @@ module TinyAdmin
|
|
79
106
|
self[key] = Object.const_get(self[key])
|
80
107
|
end
|
81
108
|
end
|
82
|
-
|
83
|
-
def prepare_navbar(sections, logout:)
|
84
|
-
items = sections.each_with_object({}) do |section, list|
|
85
|
-
unless section.is_a?(Hash)
|
86
|
-
section_class = Object.const_get(section)
|
87
|
-
next unless section_class.respond_to?(:to_h)
|
88
|
-
|
89
|
-
section = section_class.to_h
|
90
|
-
end
|
91
|
-
|
92
|
-
slug = section[:slug].to_s
|
93
|
-
case section[:type]&.to_sym
|
94
|
-
when :url
|
95
|
-
list[slug] = add_url_section(slug, section)
|
96
|
-
when :page
|
97
|
-
list[slug] = add_page_section(slug, section)
|
98
|
-
when :resource
|
99
|
-
list[slug] = add_resource_section(slug, section)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
items['auth/logout'] = logout if logout
|
103
|
-
items
|
104
|
-
end
|
105
|
-
|
106
|
-
def add_url_section(_slug, section)
|
107
|
-
section.slice(:name, :options).tap { _1[:path] = section[:url] }
|
108
|
-
end
|
109
|
-
|
110
|
-
def add_page_section(slug, section)
|
111
|
-
page = section[:page]
|
112
|
-
context.pages[slug] = page.is_a?(String) ? Object.const_get(page) : page
|
113
|
-
{ name: section[:name], path: route_for(slug), class: context.pages[slug] }
|
114
|
-
end
|
115
|
-
|
116
|
-
def add_resource_section(slug, section)
|
117
|
-
repository = section[:repository] || settings.repository
|
118
|
-
context.resources[slug] = {
|
119
|
-
model: section[:model].is_a?(String) ? Object.const_get(section[:model]) : section[:model],
|
120
|
-
repository: repository.is_a?(String) ? Object.const_get(repository) : repository
|
121
|
-
}
|
122
|
-
resource_options = section.slice(:resource, :only, :index, :show, :collection_actions, :member_actions)
|
123
|
-
resource_options[:only] ||= %i[index show]
|
124
|
-
context.resources[slug].merge!(resource_options)
|
125
|
-
hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?('hidden'))
|
126
|
-
{ name: section[:name], path: route_for(slug) } unless hidden
|
127
|
-
end
|
128
109
|
end
|
129
110
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
class Store
|
5
|
+
include Utils
|
6
|
+
|
7
|
+
attr_reader :navbar, :pages, :resources, :settings
|
8
|
+
|
9
|
+
def initialize(settings)
|
10
|
+
@pages = {}
|
11
|
+
@resources = {}
|
12
|
+
@settings = settings
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare_sections(sections, logout:)
|
16
|
+
@navbar = sections.each_with_object([]) do |section, list|
|
17
|
+
unless section.is_a?(Hash)
|
18
|
+
section_class = to_class(section)
|
19
|
+
next unless section_class.respond_to?(:to_h)
|
20
|
+
|
21
|
+
section = section_class.to_h
|
22
|
+
end
|
23
|
+
|
24
|
+
slug = section[:slug].to_s
|
25
|
+
case section[:type]&.to_sym
|
26
|
+
when :content
|
27
|
+
list << add_content_section(slug, section)
|
28
|
+
when :page
|
29
|
+
list << add_page_section(slug, section)
|
30
|
+
when :resource
|
31
|
+
list << add_resource_section(slug, section)
|
32
|
+
when :url
|
33
|
+
list << add_url_section(slug, section)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
navbar << logout if logout
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def add_content_section(slug, section)
|
42
|
+
pages[slug] = { class: settings.content_page, content: section[:content], widgets: section[:widgets] }
|
43
|
+
TinyAdmin::Section.new(name: section[:name], slug: slug)
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_page_section(slug, section)
|
47
|
+
pages[slug] = { class: to_class(section[:page]) }
|
48
|
+
TinyAdmin::Section.new(name: section[:name], slug: slug)
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_resource_section(slug, section)
|
52
|
+
resource = section.slice(:resource, :only, :index, :show, :collection_actions, :member_actions)
|
53
|
+
resource[:only] ||= %i[index show]
|
54
|
+
resources[slug] = resource.merge(
|
55
|
+
model: to_class(section[:model]),
|
56
|
+
repository: to_class(section[:repository] || settings.repository)
|
57
|
+
)
|
58
|
+
|
59
|
+
hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?('hidden'))
|
60
|
+
TinyAdmin::Section.new(name: section[:name], slug: slug) unless hidden
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_url_section(slug, section)
|
64
|
+
TinyAdmin::Section.new(name: section[:name], options: section[:options], path: section[:url], slug: slug)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/tiny_admin/utils.rb
CHANGED
@@ -14,27 +14,27 @@ module TinyAdmin
|
|
14
14
|
list.join('&')
|
15
15
|
end
|
16
16
|
|
17
|
-
def prepare_page(page_class, options: nil)
|
17
|
+
def prepare_page(page_class, slug: nil, attributes: nil, options: nil)
|
18
18
|
page_class.new.tap do |page|
|
19
19
|
page.options = options
|
20
|
-
page.head_component = settings.components[:head]&.new
|
21
|
-
page.flash_component = settings.components[:flash]&.new
|
22
|
-
page.navbar_component = settings.components[:navbar]&.new
|
20
|
+
page.head_component = TinyAdmin.settings.components[:head]&.new
|
21
|
+
page.flash_component = TinyAdmin.settings.components[:flash]&.new
|
22
|
+
page.navbar_component = TinyAdmin.settings.components[:navbar]&.new
|
23
23
|
page.navbar_component&.update_attributes(
|
24
|
-
current_slug:
|
25
|
-
root_path: settings.root_path,
|
26
|
-
root_title: settings.root[:title],
|
27
|
-
items: options&.include?(:no_menu) ? [] :
|
24
|
+
current_slug: slug,
|
25
|
+
root_path: TinyAdmin.settings.root_path,
|
26
|
+
root_title: TinyAdmin.settings.root[:title],
|
27
|
+
items: options&.include?(:no_menu) ? [] : TinyAdmin.settings.store&.navbar
|
28
28
|
)
|
29
|
+
attrs = attributes || {}
|
30
|
+
attrs[:widgets] = attrs[:widgets].map { to_class(_1) } if attrs[:widgets]
|
31
|
+
page.update_attributes(attrs) unless attrs.empty?
|
29
32
|
yield(page) if block_given?
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
33
|
-
def
|
34
|
-
|
35
|
-
route = [root_path, section, reference, action].compact.join("/")
|
36
|
-
route << "?#{query}" if query
|
37
|
-
route[0] == '/' ? route : route.prepend('/')
|
36
|
+
def to_class(klass)
|
37
|
+
klass.is_a?(String) ? Object.const_get(klass) : klass
|
38
38
|
end
|
39
39
|
|
40
40
|
def to_label(string)
|
@@ -42,13 +42,5 @@ module TinyAdmin
|
|
42
42
|
|
43
43
|
string.respond_to?(:humanize) ? string.humanize : string.tr('_', ' ').capitalize
|
44
44
|
end
|
45
|
-
|
46
|
-
def context
|
47
|
-
TinyAdmin::Context.instance
|
48
|
-
end
|
49
|
-
|
50
|
-
def settings
|
51
|
-
TinyAdmin::Settings.instance
|
52
|
-
end
|
53
45
|
end
|
54
46
|
end
|
data/lib/tiny_admin/version.rb
CHANGED
@@ -4,14 +4,16 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Actions
|
6
6
|
class Index < DefaultLayout
|
7
|
-
attr_accessor :actions, :fields, :filters, :links, :pagination_component, :prepare_record, :records
|
7
|
+
attr_accessor :actions, :fields, :filters, :links, :pagination_component, :prepare_record, :records, :slug
|
8
8
|
|
9
9
|
def template
|
10
10
|
super do
|
11
11
|
div(class: 'index') {
|
12
12
|
div(class: 'row') {
|
13
13
|
div(class: 'col-4') {
|
14
|
-
h1(class: 'title') {
|
14
|
+
h1(class: 'title') {
|
15
|
+
title
|
16
|
+
}
|
15
17
|
}
|
16
18
|
div(class: 'col-8') {
|
17
19
|
actions_buttons
|
@@ -31,13 +33,15 @@ module TinyAdmin
|
|
31
33
|
if filters&.any?
|
32
34
|
div(class: 'col-3') {
|
33
35
|
filters_form = TinyAdmin::Views::Components::FiltersForm.new
|
34
|
-
filters_form.update_attributes(section_path: route_for(
|
36
|
+
filters_form.update_attributes(section_path: TinyAdmin.route_for(slug), filters: filters)
|
35
37
|
render filters_form
|
36
38
|
}
|
37
39
|
end
|
38
40
|
}
|
39
41
|
|
40
42
|
render pagination_component if pagination_component
|
43
|
+
|
44
|
+
render TinyAdmin::Views::Components::Widgets.new(widgets)
|
41
45
|
}
|
42
46
|
end
|
43
47
|
end
|
@@ -66,7 +70,7 @@ module TinyAdmin
|
|
66
70
|
field = fields[key]
|
67
71
|
td(class: "field-value-#{field.name} field-value-type-#{field.type}") {
|
68
72
|
if field.options && field.options[:link_to]
|
69
|
-
a(href: route_for(field.options[:link_to], reference: value)) {
|
73
|
+
a(href: TinyAdmin.route_for(field.options[:link_to], reference: value)) {
|
70
74
|
field.apply_call_option(record) || value
|
71
75
|
}
|
72
76
|
else
|
@@ -82,15 +86,15 @@ module TinyAdmin
|
|
82
86
|
links.each do |link|
|
83
87
|
whitespace
|
84
88
|
if link == 'show'
|
85
|
-
a(href: route_for(
|
89
|
+
a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) { 'show' }
|
86
90
|
else
|
87
|
-
a(href: route_for(
|
91
|
+
a(href: TinyAdmin.route_for(slug, reference: record.id, action: link), class: link_class) {
|
88
92
|
to_label(link)
|
89
93
|
}
|
90
94
|
end
|
91
95
|
end
|
92
96
|
else
|
93
|
-
a(href: route_for(
|
97
|
+
a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) { 'show' }
|
94
98
|
end
|
95
99
|
}
|
96
100
|
}
|
@@ -103,7 +107,7 @@ module TinyAdmin
|
|
103
107
|
ul(class: 'nav justify-content-end') {
|
104
108
|
(actions || {}).each do |action, action_class|
|
105
109
|
li(class: 'nav-item mx-1') {
|
106
|
-
href = route_for(
|
110
|
+
href = TinyAdmin.route_for(slug, action: action)
|
107
111
|
a(href: href, class: 'nav-link btn btn-outline-secondary') {
|
108
112
|
action_class.respond_to?(:title) ? action_class.title : action
|
109
113
|
}
|
@@ -4,7 +4,7 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Actions
|
6
6
|
class Show < DefaultLayout
|
7
|
-
attr_accessor :actions, :fields, :prepare_record, :record
|
7
|
+
attr_accessor :actions, :fields, :prepare_record, :record, :reference, :slug
|
8
8
|
|
9
9
|
def template
|
10
10
|
super do
|
@@ -26,7 +26,7 @@ module TinyAdmin
|
|
26
26
|
end
|
27
27
|
div(class: 'field-value col-10') {
|
28
28
|
if field.options[:link_to]
|
29
|
-
a(href: route_for(field.options[:link_to], reference: value)) {
|
29
|
+
a(href: TinyAdmin.route_for(field.options[:link_to], reference: value)) {
|
30
30
|
field.apply_call_option(record) || value
|
31
31
|
}
|
32
32
|
else
|
@@ -35,6 +35,8 @@ module TinyAdmin
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
end
|
38
|
+
|
39
|
+
render TinyAdmin::Views::Components::Widgets.new(widgets)
|
38
40
|
}
|
39
41
|
end
|
40
42
|
end
|
@@ -45,7 +47,7 @@ module TinyAdmin
|
|
45
47
|
ul(class: 'nav justify-content-end') {
|
46
48
|
(actions || {}).each do |action, action_class|
|
47
49
|
li(class: 'nav-item mx-1') {
|
48
|
-
href = route_for(
|
50
|
+
href = TinyAdmin.route_for(slug, reference: reference, action: action)
|
49
51
|
a(href: href, class: 'nav-link btn btn-outline-secondary') {
|
50
52
|
action_class.respond_to?(:title) ? action_class.title : action
|
51
53
|
}
|
@@ -23,14 +23,14 @@ module TinyAdmin
|
|
23
23
|
}
|
24
24
|
div(class: 'collapse navbar-collapse', id: 'navbarNav') {
|
25
25
|
ul(class: 'navbar-nav') {
|
26
|
-
items.each do |
|
26
|
+
items.each do |item|
|
27
27
|
classes = %w[nav-link]
|
28
|
-
classes << 'active' if slug == current_slug
|
29
|
-
link_attributes = { class: classes.join(' '), href: item
|
30
|
-
link_attributes.merge!(item
|
28
|
+
classes << 'active' if item.slug == current_slug
|
29
|
+
link_attributes = { class: classes.join(' '), href: item.path, 'aria-current' => 'page' }
|
30
|
+
link_attributes.merge!(item.options) if item.options
|
31
31
|
|
32
32
|
li(class: 'nav-item') {
|
33
|
-
a(**link_attributes) { item
|
33
|
+
a(**link_attributes) { item.name }
|
34
34
|
}
|
35
35
|
end
|
36
36
|
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
module Views
|
5
|
+
module Components
|
6
|
+
class Widgets < BasicComponent
|
7
|
+
def initialize(widgets)
|
8
|
+
@widgets = widgets
|
9
|
+
end
|
10
|
+
|
11
|
+
def template
|
12
|
+
return if @widgets.nil? || @widgets.empty?
|
13
|
+
|
14
|
+
div(class: 'container widgets') {
|
15
|
+
@widgets.each_slice(2).each do |row|
|
16
|
+
div(class: 'row') {
|
17
|
+
row.each do |widget|
|
18
|
+
next unless widget < Phlex::HTML
|
19
|
+
|
20
|
+
div(class: 'col') {
|
21
|
+
div(class: 'card') {
|
22
|
+
div(class: 'card-body') {
|
23
|
+
render widget.new
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -6,7 +6,7 @@ module TinyAdmin
|
|
6
6
|
attr_accessor :flash_component, :head_component, :messages, :navbar_component, :options, :title
|
7
7
|
|
8
8
|
def template(&block)
|
9
|
-
extra_styles = settings.extra_styles
|
9
|
+
extra_styles = TinyAdmin.settings.extra_styles
|
10
10
|
flash_component&.messages = messages
|
11
11
|
head_component&.update_attributes(page_title: title, style_links: style_links, extra_styles: extra_styles)
|
12
12
|
|
@@ -49,7 +49,7 @@ module TinyAdmin
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def style_links
|
52
|
-
settings.style_links || [
|
52
|
+
TinyAdmin.settings.style_links || [
|
53
53
|
# Bootstrap CDN
|
54
54
|
{
|
55
55
|
href: 'https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css',
|
@@ -61,7 +61,7 @@ module TinyAdmin
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def render_scripts
|
64
|
-
(settings.scripts || []).each do |script_attrs|
|
64
|
+
(TinyAdmin.settings.scripts || []).each do |script_attrs|
|
65
65
|
script(**script_attrs)
|
66
66
|
end
|
67
67
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
module Views
|
5
|
+
module Pages
|
6
|
+
class Content < DefaultLayout
|
7
|
+
def template
|
8
|
+
super do
|
9
|
+
div(class: 'content') {
|
10
|
+
div(class: 'content-data') {
|
11
|
+
unsafe_raw(content)
|
12
|
+
}
|
13
|
+
|
14
|
+
render TinyAdmin::Views::Components::Widgets.new(widgets)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/tiny_admin.rb
CHANGED
@@ -4,6 +4,7 @@ require 'phlex'
|
|
4
4
|
require 'roda'
|
5
5
|
require 'zeitwerk'
|
6
6
|
|
7
|
+
require 'forwardable'
|
7
8
|
require 'singleton'
|
8
9
|
require 'yaml'
|
9
10
|
|
@@ -12,15 +13,27 @@ loader.setup
|
|
12
13
|
|
13
14
|
module TinyAdmin
|
14
15
|
def configure(&block)
|
15
|
-
block&.call(
|
16
|
+
block&.call(settings) || settings
|
16
17
|
end
|
17
18
|
|
18
19
|
def configure_from_file(file)
|
20
|
+
settings.reset!
|
19
21
|
config = YAML.load_file(file, symbolize_names: true)
|
20
22
|
config.each do |key, value|
|
21
|
-
|
23
|
+
settings[key] = value
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
|
27
|
+
def route_for(section, reference: nil, action: nil, query: nil)
|
28
|
+
root_path = settings.root_path == '/' ? nil : settings.root_path
|
29
|
+
route = [root_path, section, reference, action].compact.join("/")
|
30
|
+
route << "?#{query}" if query
|
31
|
+
route[0] == '/' ? route : route.prepend('/')
|
32
|
+
end
|
33
|
+
|
34
|
+
def settings
|
35
|
+
TinyAdmin::Settings.instance
|
36
|
+
end
|
37
|
+
|
38
|
+
module_function :configure, :configure_from_file, :route_for, :settings
|
26
39
|
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.7.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-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex
|
@@ -87,20 +87,25 @@ files:
|
|
87
87
|
- lib/tiny_admin/plugins/no_auth.rb
|
88
88
|
- lib/tiny_admin/plugins/simple_auth.rb
|
89
89
|
- lib/tiny_admin/router.rb
|
90
|
+
- lib/tiny_admin/section.rb
|
90
91
|
- lib/tiny_admin/settings.rb
|
92
|
+
- lib/tiny_admin/store.rb
|
91
93
|
- lib/tiny_admin/support.rb
|
92
94
|
- lib/tiny_admin/utils.rb
|
93
95
|
- lib/tiny_admin/version.rb
|
94
96
|
- lib/tiny_admin/views/actions/index.rb
|
95
97
|
- lib/tiny_admin/views/actions/show.rb
|
96
98
|
- lib/tiny_admin/views/basic_layout.rb
|
99
|
+
- lib/tiny_admin/views/basic_widget.rb
|
97
100
|
- lib/tiny_admin/views/components/basic_component.rb
|
98
101
|
- lib/tiny_admin/views/components/filters_form.rb
|
99
102
|
- lib/tiny_admin/views/components/flash.rb
|
100
103
|
- lib/tiny_admin/views/components/head.rb
|
101
104
|
- lib/tiny_admin/views/components/navbar.rb
|
102
105
|
- lib/tiny_admin/views/components/pagination.rb
|
106
|
+
- lib/tiny_admin/views/components/widgets.rb
|
103
107
|
- lib/tiny_admin/views/default_layout.rb
|
108
|
+
- lib/tiny_admin/views/pages/content.rb
|
104
109
|
- lib/tiny_admin/views/pages/page_not_found.rb
|
105
110
|
- lib/tiny_admin/views/pages/record_not_found.rb
|
106
111
|
- lib/tiny_admin/views/pages/root.rb
|