tiny_admin 0.3.0 → 0.5.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 +157 -71
- data/lib/tiny_admin/actions/basic_action.rb +15 -6
- data/lib/tiny_admin/actions/index.rb +21 -10
- data/lib/tiny_admin/actions/show.rb +10 -7
- data/lib/tiny_admin/context.rb +10 -1
- data/lib/tiny_admin/field.rb +11 -4
- data/lib/tiny_admin/plugins/active_record_repository.rb +17 -29
- data/lib/tiny_admin/plugins/base_repository.rb +14 -0
- data/lib/tiny_admin/router.rb +26 -19
- data/lib/tiny_admin/settings.rb +88 -42
- data/lib/tiny_admin/support.rb +35 -0
- data/lib/tiny_admin/utils.rb +13 -5
- data/lib/tiny_admin/version.rb +1 -1
- data/lib/tiny_admin/views/actions/index.rb +45 -21
- data/lib/tiny_admin/views/actions/show.rb +24 -22
- data/lib/tiny_admin/views/components/basic_component.rb +15 -0
- data/lib/tiny_admin/views/components/filters_form.rb +2 -7
- data/lib/tiny_admin/views/components/flash.rb +7 -10
- data/lib/tiny_admin/views/components/head.rb +2 -8
- data/lib/tiny_admin/views/components/navbar.rb +15 -14
- data/lib/tiny_admin/views/components/pagination.rb +2 -8
- data/lib/tiny_admin/views/default_layout.rb +3 -2
- data/lib/tiny_admin.rb +1 -1
- metadata +4 -2
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.pages.each do |slug, data|
|
31
33
|
setup_page_route(r, slug, data)
|
32
34
|
end
|
33
35
|
|
34
|
-
|
36
|
+
context.resources.each do |slug, options|
|
35
37
|
setup_resource_routes(r, slug, options: options || {})
|
36
38
|
end
|
37
39
|
|
@@ -74,29 +76,30 @@ 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
|
|
88
90
|
# Index
|
89
|
-
|
90
|
-
if !actions || actions.include?(:index) || actions.include?('index')
|
91
|
+
if options[:only].include?(:index) || options[:only].include?('index')
|
91
92
|
router.is do
|
92
|
-
|
93
|
-
|
93
|
+
context.actions = custom_actions
|
94
|
+
context.request = request
|
95
|
+
index_action = TinyAdmin::Actions::Index.new
|
96
|
+
render_page index_action.call(app: self, context: context, options: action_options)
|
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,32 +109,36 @@ 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
|
|
113
116
|
# Show
|
114
|
-
|
115
|
-
if !actions || actions.include?(:show) || actions.include?('show')
|
117
|
+
if options[:only].include?(:show) || options[:only].include?('show')
|
116
118
|
router.is do
|
117
|
-
|
118
|
-
|
119
|
+
context.actions = custom_actions
|
120
|
+
context.request = request
|
121
|
+
show_action = TinyAdmin::Actions::Show.new
|
122
|
+
render_page show_action.call(app: self, context: context, options: action_options)
|
119
123
|
end
|
120
124
|
end
|
121
125
|
end
|
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.actions = {}
|
136
|
+
context.request = request
|
137
|
+
custom_action = action_class.new
|
131
138
|
render_page custom_action.call(app: self, context: context, options: options)
|
132
139
|
end
|
133
140
|
|
134
|
-
action_slug.to_s
|
141
|
+
result[action_slug.to_s] = action_class
|
135
142
|
end
|
136
143
|
end
|
137
144
|
end
|
data/lib/tiny_admin/settings.rb
CHANGED
@@ -5,10 +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,
|
11
|
-
:
|
27
|
+
:helper_class,
|
12
28
|
:page_not_found,
|
13
29
|
:record_not_found,
|
14
30
|
:repository,
|
@@ -18,66 +34,96 @@ module TinyAdmin
|
|
18
34
|
:scripts,
|
19
35
|
:style_links
|
20
36
|
|
21
|
-
|
37
|
+
def [](key)
|
38
|
+
send(key)
|
39
|
+
end
|
40
|
+
|
41
|
+
def []=(key, value)
|
42
|
+
send("#{key}=", value)
|
43
|
+
convert_value(key, value)
|
44
|
+
end
|
22
45
|
|
23
46
|
def load_settings
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@pages ||= {}
|
35
|
-
@repository ||= Plugins::ActiveRecordRepository
|
36
|
-
@resources ||= {}
|
37
|
-
@root_path ||= '/admin'
|
38
|
-
@root_path = '/' if @root_path == ''
|
39
|
-
@sections ||= []
|
47
|
+
# default values
|
48
|
+
DEFAULTS.each do |(option, param), default|
|
49
|
+
if param
|
50
|
+
self[option] ||= {}
|
51
|
+
self[option][param] ||= default
|
52
|
+
else
|
53
|
+
self[option] ||= default
|
54
|
+
end
|
55
|
+
end
|
40
56
|
|
41
|
-
|
42
|
-
|
43
|
-
@
|
57
|
+
context.pages ||= {}
|
58
|
+
context.resources ||= {}
|
59
|
+
@sections ||= []
|
60
|
+
@root_path = '/' if @root_path == ''
|
44
61
|
|
45
|
-
if @authentication[:plugin]
|
46
|
-
@authentication[:logout] ||=
|
62
|
+
if @authentication[:plugin] <= Plugins::SimpleAuth
|
63
|
+
@authentication[:logout] ||= { name: 'logout', path: "#{root_path}/auth/logout" }
|
47
64
|
end
|
65
|
+
context.navbar = prepare_navbar(sections, logout: authentication[:logout])
|
66
|
+
end
|
48
67
|
|
49
|
-
|
50
|
-
@components[:flash] ||= Views::Components::Flash
|
51
|
-
@components[:head] ||= Views::Components::Head
|
52
|
-
@components[:navbar] ||= Views::Components::Navbar
|
53
|
-
@components[:pagination] ||= Views::Components::Pagination
|
68
|
+
private
|
54
69
|
|
55
|
-
|
70
|
+
def convert_value(key, value)
|
71
|
+
if value.is_a?(Hash)
|
72
|
+
value.each_key do |key2|
|
73
|
+
path = [key, key2]
|
74
|
+
if DEFAULTS[path].is_a?(Class) || DEFAULTS[path].is_a?(Module)
|
75
|
+
self[key][key2] = Object.const_get(self[key][key2])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
elsif value.is_a?(String) && (DEFAULTS[[key]].is_a?(Class) || DEFAULTS[[key]].is_a?(Module))
|
79
|
+
self[key] = Object.const_get(self[key])
|
80
|
+
end
|
56
81
|
end
|
57
82
|
|
58
83
|
def prepare_navbar(sections, logout:)
|
59
84
|
items = sections.each_with_object({}) do |section, list|
|
60
|
-
|
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
|
61
93
|
case section[:type]&.to_sym
|
62
94
|
when :url
|
63
|
-
list[slug] =
|
95
|
+
list[slug] = add_url_section(slug, section)
|
64
96
|
when :page
|
65
|
-
|
66
|
-
pages[slug] = page.is_a?(String) ? Object.const_get(page) : page
|
67
|
-
list[slug] = [section[:name], route_for(slug)]
|
97
|
+
list[slug] = add_page_section(slug, section)
|
68
98
|
when :resource
|
69
|
-
|
70
|
-
resources[slug] = {
|
71
|
-
model: section[:model].is_a?(String) ? Object.const_get(section[:model]) : section[:model],
|
72
|
-
repository: repository.is_a?(String) ? Object.const_get(repository) : repository
|
73
|
-
}
|
74
|
-
resources[slug].merge! section.slice(:resource, :only, :index, :show, :collection_actions, :member_actions)
|
75
|
-
hidden = section[:options] && (section[:options].include?(:hidden) || section[:options].include?('hidden'))
|
76
|
-
list[slug] = [section[:name], route_for(slug)] unless hidden
|
99
|
+
list[slug] = add_resource_section(slug, section)
|
77
100
|
end
|
78
101
|
end
|
79
102
|
items['auth/logout'] = logout if logout
|
80
103
|
items
|
81
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
|
82
128
|
end
|
83
129
|
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
|
+
options.inject(value) { |result, message| result&.send(message) } if value && options&.any?
|
8
|
+
end
|
9
|
+
|
10
|
+
def downcase(value, options: [])
|
11
|
+
value&.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def format(value, options: [])
|
15
|
+
Kernel.format(options.first, value) if value && options&.any?
|
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&.strftime(options&.first || '%Y-%m-%d %H:%M')
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_date(value, options: [])
|
27
|
+
value.to_date.to_s if 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
@@ -5,7 +5,8 @@ module TinyAdmin
|
|
5
5
|
def params_to_s(params)
|
6
6
|
list = params.each_with_object([]) do |(param, value), result|
|
7
7
|
if value.is_a?(Hash)
|
8
|
-
|
8
|
+
values = value.map { |key, val| "#{param}[#{key}]=#{val}" }
|
9
|
+
result.concat(values)
|
9
10
|
else
|
10
11
|
result.push(["#{param}=#{value}"])
|
11
12
|
end
|
@@ -18,23 +19,30 @@ module TinyAdmin
|
|
18
19
|
page.options = options
|
19
20
|
page.head_component = settings.components[:head]&.new
|
20
21
|
page.flash_component = settings.components[:flash]&.new
|
21
|
-
page.navbar_component = settings.components[:navbar]&.new
|
22
|
+
page.navbar_component = settings.components[:navbar]&.new
|
23
|
+
page.navbar_component&.update_attributes(
|
22
24
|
current_slug: context&.slug,
|
23
25
|
root_path: settings.root_path,
|
24
26
|
root_title: settings.root[:title],
|
25
|
-
items: options&.include?(:no_menu) ? [] :
|
27
|
+
items: options&.include?(:no_menu) ? [] : context&.navbar
|
26
28
|
)
|
27
|
-
|
28
29
|
yield(page) if block_given?
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
|
-
def route_for(section, reference: nil, action: nil)
|
33
|
+
def route_for(section, reference: nil, action: nil, query: nil)
|
33
34
|
root_path = settings.root_path == '/' ? nil : settings.root_path
|
34
35
|
route = [root_path, section, reference, action].compact.join("/")
|
36
|
+
route << "?#{query}" if query
|
35
37
|
route[0] == '/' ? route : route.prepend('/')
|
36
38
|
end
|
37
39
|
|
40
|
+
def to_label(string)
|
41
|
+
return '' unless string
|
42
|
+
|
43
|
+
string.respond_to?(:humanize) ? string.humanize : string.tr('_', ' ').capitalize
|
44
|
+
end
|
45
|
+
|
38
46
|
def context
|
39
47
|
TinyAdmin::Context.instance
|
40
48
|
end
|
data/lib/tiny_admin/version.rb
CHANGED
@@ -4,12 +4,9 @@ module TinyAdmin
|
|
4
4
|
module Views
|
5
5
|
module Actions
|
6
6
|
class Index < DefaultLayout
|
7
|
-
attr_accessor :actions, :fields, :filters, :pagination_component, :prepare_record, :records
|
7
|
+
attr_accessor :actions, :fields, :filters, :links, :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,10 +28,11 @@ module TinyAdmin
|
|
38
28
|
}
|
39
29
|
}
|
40
30
|
|
41
|
-
if filters
|
31
|
+
if filters&.any?
|
42
32
|
div(class: 'col-3') {
|
43
|
-
|
44
|
-
|
33
|
+
filters_form = TinyAdmin::Views::Components::FiltersForm.new
|
34
|
+
filters_form.update_attributes(section_path: route_for(context.slug), filters: filters)
|
35
|
+
render filters_form
|
45
36
|
}
|
46
37
|
end
|
47
38
|
}
|
@@ -57,7 +48,9 @@ module TinyAdmin
|
|
57
48
|
thead {
|
58
49
|
tr {
|
59
50
|
fields.each_value do |field|
|
60
|
-
td(class: "field-header-#{field.name} field-header-type-#{field.type}") {
|
51
|
+
td(class: "field-header-#{field.name} field-header-type-#{field.type}") {
|
52
|
+
field.options[:header] || field.title
|
53
|
+
}
|
61
54
|
end
|
62
55
|
td { whitespace }
|
63
56
|
}
|
@@ -73,15 +66,46 @@ module TinyAdmin
|
|
73
66
|
field = fields[key]
|
74
67
|
td(class: "field-value-#{field.name} field-value-type-#{field.type}") {
|
75
68
|
if field.options && field.options[:link_to]
|
76
|
-
|
77
|
-
|
69
|
+
a(href: route_for(field.options[:link_to], reference: value)) {
|
70
|
+
field.apply_call_option(record) || value
|
71
|
+
}
|
78
72
|
else
|
79
73
|
value
|
80
74
|
end
|
81
75
|
}
|
82
76
|
end
|
83
|
-
|
84
|
-
|
77
|
+
|
78
|
+
td(class: 'actions p-1') {
|
79
|
+
div(class: 'btn-group btn-group-sm') {
|
80
|
+
link_class = 'btn btn-outline-secondary'
|
81
|
+
if links
|
82
|
+
links.each do |link|
|
83
|
+
whitespace
|
84
|
+
if link == 'show'
|
85
|
+
a(href: route_for(context.slug, reference: record.id), class: link_class) { 'show' }
|
86
|
+
else
|
87
|
+
a(href: route_for(context.slug, reference: record.id, action: link), class: link_class) {
|
88
|
+
to_label(link)
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
else
|
93
|
+
a(href: route_for(context.slug, reference: record.id), class: link_class) { 'show' }
|
94
|
+
end
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
end
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
def actions_buttons
|
103
|
+
ul(class: 'nav justify-content-end') {
|
104
|
+
(actions || {}).each do |action, action_class|
|
105
|
+
li(class: 'nav-item mx-1') {
|
106
|
+
href = route_for(context.slug, action: action)
|
107
|
+
a(href: href, class: 'nav-link btn btn-outline-secondary') {
|
108
|
+
action_class.respond_to?(:title) ? action_class.title : action
|
85
109
|
}
|
86
110
|
}
|
87
111
|
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
|
-
if field.options
|
43
|
-
|
44
|
-
|
28
|
+
if field.options[:link_to]
|
29
|
+
a(href: route_for(field.options[:link_to], reference: value)) {
|
30
|
+
field.apply_call_option(record) || value
|
31
|
+
}
|
45
32
|
else
|
46
33
|
value
|
47
34
|
end
|
@@ -51,6 +38,21 @@ 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
|
+
a(href: href, class: 'nav-link btn btn-outline-secondary') {
|
50
|
+
action_class.respond_to?(:title) ? action_class.title : action
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
}
|
55
|
+
end
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TinyAdmin
|
4
|
+
module Views
|
5
|
+
module Components
|
6
|
+
class BasicComponent < Phlex::HTML
|
7
|
+
def update_attributes(attributes)
|
8
|
+
attributes.each do |key, value|
|
9
|
+
send("#{key}=", value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -3,13 +3,8 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
module Views
|
5
5
|
module Components
|
6
|
-
class FiltersForm <
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(section_path:, filters:)
|
10
|
-
@section_path = section_path
|
11
|
-
@filters = filters
|
12
|
-
end
|
6
|
+
class FiltersForm < BasicComponent
|
7
|
+
attr_accessor :filters, :section_path
|
13
8
|
|
14
9
|
def template
|
15
10
|
form(class: 'form_filters', method: 'get') {
|
@@ -3,24 +3,21 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
module Views
|
5
5
|
module Components
|
6
|
-
class Flash <
|
7
|
-
|
6
|
+
class Flash < BasicComponent
|
7
|
+
attr_accessor :messages
|
8
8
|
|
9
9
|
def template
|
10
|
+
@messages ||= {}
|
11
|
+
notices = messages[:notices]
|
12
|
+
warnings = messages[:warnings]
|
13
|
+
errors = messages[:errors]
|
14
|
+
|
10
15
|
div(class: 'flash') {
|
11
16
|
div(class: 'notices alert alert-success', role: 'alert') { notices.join(', ') } if notices&.any?
|
12
17
|
div(class: 'notices alert alert-warning', role: 'alert') { warnings.join(', ') } if warnings&.any?
|
13
18
|
div(class: 'notices alert alert-danger', role: 'alert') { errors.join(', ') } if errors&.any?
|
14
19
|
}
|
15
20
|
end
|
16
|
-
|
17
|
-
def update(messages:)
|
18
|
-
return unless messages
|
19
|
-
|
20
|
-
@notices = messages[:notices]
|
21
|
-
@warnings = messages[:warnings]
|
22
|
-
@errors = messages[:errors]
|
23
|
-
end
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module TinyAdmin
|
4
4
|
module Views
|
5
5
|
module Components
|
6
|
-
class Head <
|
7
|
-
|
6
|
+
class Head < BasicComponent
|
7
|
+
attr_accessor :extra_styles, :page_title, :style_links
|
8
8
|
|
9
9
|
def template
|
10
10
|
head {
|
@@ -19,12 +19,6 @@ module TinyAdmin
|
|
19
19
|
style { extra_styles } if extra_styles
|
20
20
|
}
|
21
21
|
end
|
22
|
-
|
23
|
-
def update(page_title, style_links: [], extra_styles: nil)
|
24
|
-
@page_title = page_title
|
25
|
-
@style_links = style_links
|
26
|
-
@extra_styles = extra_styles
|
27
|
-
end
|
28
22
|
end
|
29
23
|
end
|
30
24
|
end
|