tiny_admin 0.3.0 → 0.5.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 +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
|