tiny_admin 0.10.1 → 0.11.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/lib/tiny_admin/actions/index.rb +4 -4
- data/lib/tiny_admin/authentication.rb +8 -8
- data/lib/tiny_admin/basic_app.rb +5 -3
- data/lib/tiny_admin/field.rb +5 -4
- data/lib/tiny_admin/plugins/active_record_repository.rb +1 -1
- data/lib/tiny_admin/plugins/base_repository.rb +2 -1
- data/lib/tiny_admin/plugins/no_auth.rb +2 -2
- data/lib/tiny_admin/plugins/simple_auth.rb +10 -10
- data/lib/tiny_admin/raw_html.rb +11 -0
- data/lib/tiny_admin/router.rb +36 -29
- data/lib/tiny_admin/settings.rb +22 -8
- data/lib/tiny_admin/store.rb +9 -12
- data/lib/tiny_admin/support.rb +14 -2
- data/lib/tiny_admin/utils.rb +7 -5
- data/lib/tiny_admin/version.rb +1 -1
- data/lib/tiny_admin/views/actions/index.rb +22 -26
- data/lib/tiny_admin/views/actions/show.rb +14 -20
- data/lib/tiny_admin/views/attributes.rb +18 -0
- data/lib/tiny_admin/views/basic_layout.rb +1 -6
- data/lib/tiny_admin/views/components/actions_buttons.rb +24 -0
- data/lib/tiny_admin/views/components/basic_component.rb +1 -5
- data/lib/tiny_admin/views/components/field_value.rb +14 -3
- data/lib/tiny_admin/views/components/filters_form.rb +20 -20
- data/lib/tiny_admin/views/components/flash.rb +4 -4
- data/lib/tiny_admin/views/components/head.rb +3 -3
- data/lib/tiny_admin/views/components/navbar.rb +16 -16
- data/lib/tiny_admin/views/components/pagination.rb +14 -14
- data/lib/tiny_admin/views/components/widgets.rb +22 -7
- data/lib/tiny_admin/views/default_layout.rb +7 -7
- data/lib/tiny_admin/views/pages/content.rb +3 -3
- data/lib/tiny_admin/views/pages/error_page.rb +26 -0
- data/lib/tiny_admin/views/pages/page_not_allowed.rb +2 -10
- data/lib/tiny_admin/views/pages/page_not_found.rb +2 -10
- data/lib/tiny_admin/views/pages/record_not_found.rb +2 -10
- data/lib/tiny_admin/views/pages/root.rb +2 -2
- data/lib/tiny_admin/views/pages/simple_auth_login.rb +11 -11
- data/lib/tiny_admin.rb +8 -8
- metadata +7 -6
|
@@ -15,22 +15,22 @@ module TinyAdmin
|
|
|
15
15
|
|
|
16
16
|
def view_template
|
|
17
17
|
super do
|
|
18
|
-
div(class:
|
|
19
|
-
div(class:
|
|
20
|
-
div(class:
|
|
21
|
-
h1(class:
|
|
18
|
+
div(class: "index") {
|
|
19
|
+
div(class: "row") {
|
|
20
|
+
div(class: "col-4") {
|
|
21
|
+
h1(class: "title") {
|
|
22
22
|
title
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
div(class:
|
|
25
|
+
div(class: "col-8") {
|
|
26
26
|
actions_buttons
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
div(class:
|
|
31
|
-
div_class = filters&.any? ?
|
|
30
|
+
div(class: "row") {
|
|
31
|
+
div_class = filters&.any? ? "col-9" : "col-12"
|
|
32
32
|
div(class: div_class) {
|
|
33
|
-
table(class:
|
|
33
|
+
table(class: "table") {
|
|
34
34
|
table_header if fields.any?
|
|
35
35
|
|
|
36
36
|
table_body
|
|
@@ -40,7 +40,7 @@ module TinyAdmin
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
if filters&.any?
|
|
43
|
-
div(class:
|
|
43
|
+
div(class: "col-3") {
|
|
44
44
|
filters_form = TinyAdmin::Views::Components::FiltersForm.new
|
|
45
45
|
filters_form.update_attributes(section_path: TinyAdmin.route_for(slug), filters: filters)
|
|
46
46
|
render filters_form
|
|
@@ -48,7 +48,8 @@ module TinyAdmin
|
|
|
48
48
|
end
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
context = { slug: slug, records: records, params: params }
|
|
52
|
+
render TinyAdmin::Views::Components::Widgets.new(widgets, context: context)
|
|
52
53
|
}
|
|
53
54
|
end
|
|
54
55
|
end
|
|
@@ -75,20 +76,22 @@ module TinyAdmin
|
|
|
75
76
|
attributes = prepare_record.call(record)
|
|
76
77
|
attributes.each do |key, value|
|
|
77
78
|
field = fields[key]
|
|
79
|
+
next unless field
|
|
80
|
+
|
|
78
81
|
td(class: "field-value-#{field.name} field-value-type-#{field.type}") {
|
|
79
82
|
render TinyAdmin.settings.components[:field_value].new(field, value, record: record)
|
|
80
83
|
}
|
|
81
84
|
end
|
|
82
85
|
|
|
83
|
-
td(class:
|
|
84
|
-
div(class:
|
|
85
|
-
link_class =
|
|
86
|
+
td(class: "actions p-1") {
|
|
87
|
+
div(class: "btn-group btn-group-sm") {
|
|
88
|
+
link_class = "btn btn-outline-secondary"
|
|
86
89
|
if links
|
|
87
90
|
links.each do |link|
|
|
88
91
|
whitespace
|
|
89
|
-
if link ==
|
|
92
|
+
if link == "show"
|
|
90
93
|
a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) {
|
|
91
|
-
label_for(
|
|
94
|
+
label_for("Show", options: ["actions.index.links.show"])
|
|
92
95
|
}
|
|
93
96
|
else
|
|
94
97
|
a(href: TinyAdmin.route_for(slug, reference: record.id, action: link), class: link_class) {
|
|
@@ -99,7 +102,7 @@ module TinyAdmin
|
|
|
99
102
|
end
|
|
100
103
|
else
|
|
101
104
|
a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) {
|
|
102
|
-
label_for(
|
|
105
|
+
label_for("Show", options: ["actions.index.links.show"])
|
|
103
106
|
}
|
|
104
107
|
end
|
|
105
108
|
}
|
|
@@ -110,16 +113,9 @@ module TinyAdmin
|
|
|
110
113
|
end
|
|
111
114
|
|
|
112
115
|
def actions_buttons
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
href = TinyAdmin.route_for(slug, action: action)
|
|
117
|
-
a(href: href, class: 'nav-link btn btn-outline-secondary') {
|
|
118
|
-
action_class.respond_to?(:title) ? action_class.title : action
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
end
|
|
122
|
-
}
|
|
116
|
+
buttons = TinyAdmin::Views::Components::ActionsButtons.new
|
|
117
|
+
buttons.update_attributes(actions: actions, slug: slug)
|
|
118
|
+
render buttons
|
|
123
119
|
end
|
|
124
120
|
end
|
|
125
121
|
end
|
|
@@ -13,29 +13,30 @@ module TinyAdmin
|
|
|
13
13
|
|
|
14
14
|
def view_template
|
|
15
15
|
super do
|
|
16
|
-
div(class:
|
|
17
|
-
div(class:
|
|
18
|
-
div(class:
|
|
19
|
-
h1(class:
|
|
16
|
+
div(class: "show") {
|
|
17
|
+
div(class: "row") {
|
|
18
|
+
div(class: "col-4") {
|
|
19
|
+
h1(class: "title") { title }
|
|
20
20
|
}
|
|
21
|
-
div(class:
|
|
21
|
+
div(class: "col-8") {
|
|
22
22
|
actions_buttons
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
prepare_record.call(record).each do |key, value|
|
|
27
27
|
field = fields[key]
|
|
28
|
+
next unless field
|
|
29
|
+
|
|
28
30
|
div(class: "field-#{field.name} row lh-lg") {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
div(class: 'field-value col-10') {
|
|
31
|
+
div(class: "field-header col-2") { field.options[:header] || field.title }
|
|
32
|
+
div(class: "field-value col-10") {
|
|
33
33
|
render TinyAdmin.settings.components[:field_value].new(field, value, record: record)
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
context = { slug: slug, record: record, reference: reference, params: params }
|
|
39
|
+
render TinyAdmin::Views::Components::Widgets.new(widgets, context: context)
|
|
39
40
|
}
|
|
40
41
|
end
|
|
41
42
|
end
|
|
@@ -43,16 +44,9 @@ module TinyAdmin
|
|
|
43
44
|
private
|
|
44
45
|
|
|
45
46
|
def actions_buttons
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
href = TinyAdmin.route_for(slug, reference: reference, action: action)
|
|
50
|
-
a(href: href, class: 'nav-link btn btn-outline-secondary') {
|
|
51
|
-
action_class.respond_to?(:title) ? action_class.title : action
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
end
|
|
55
|
-
}
|
|
47
|
+
buttons = TinyAdmin::Views::Components::ActionsButtons.new
|
|
48
|
+
buttons.update_attributes(actions: actions, slug: slug, reference: reference)
|
|
49
|
+
render buttons
|
|
56
50
|
end
|
|
57
51
|
end
|
|
58
52
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TinyAdmin
|
|
4
|
+
module Views
|
|
5
|
+
module Attributes
|
|
6
|
+
def update_attributes(attributes)
|
|
7
|
+
attributes.each do |key, value|
|
|
8
|
+
setter = "#{key}="
|
|
9
|
+
unless respond_to?(setter)
|
|
10
|
+
raise ArgumentError, "#{self.class.name} does not support attribute '#{key}'"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
send(setter, value)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module TinyAdmin
|
|
4
4
|
module Views
|
|
5
5
|
class BasicLayout < Phlex::HTML
|
|
6
|
+
include Attributes
|
|
6
7
|
include Utils
|
|
7
8
|
|
|
8
9
|
attr_accessor :content, :params, :widgets
|
|
@@ -10,12 +11,6 @@ module TinyAdmin
|
|
|
10
11
|
def label_for(value, options: [])
|
|
11
12
|
TinyAdmin.settings.helper_class.label_for(value, options: options)
|
|
12
13
|
end
|
|
13
|
-
|
|
14
|
-
def update_attributes(attributes)
|
|
15
|
-
attributes.each do |key, value|
|
|
16
|
-
send("#{key}=", value)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
14
|
end
|
|
20
15
|
end
|
|
21
16
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TinyAdmin
|
|
4
|
+
module Views
|
|
5
|
+
module Components
|
|
6
|
+
class ActionsButtons < BasicComponent
|
|
7
|
+
attr_accessor :actions, :slug, :reference
|
|
8
|
+
|
|
9
|
+
def view_template
|
|
10
|
+
ul(class: "nav justify-content-end") {
|
|
11
|
+
(actions || {}).each do |action, action_class|
|
|
12
|
+
li(class: "nav-item mx-1") {
|
|
13
|
+
href = TinyAdmin.route_for(slug, reference: reference, action: action)
|
|
14
|
+
a(href: href, class: "nav-link btn btn-outline-secondary") {
|
|
15
|
+
action_class.respond_to?(:title) ? action_class.title : action
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -14,19 +14,30 @@ module TinyAdmin
|
|
|
14
14
|
|
|
15
15
|
def view_template
|
|
16
16
|
translated_value = field.translate_value(value)
|
|
17
|
-
|
|
17
|
+
display_value = field.apply_call_option(record) || translated_value
|
|
18
|
+
value_class = field.options[:options]&.include?("value_class") ? "value-#{value}" : nil
|
|
18
19
|
if field.options[:link_to]
|
|
19
20
|
a(href: TinyAdmin.route_for(field.options[:link_to], reference: translated_value)) {
|
|
20
21
|
span(class: value_class) {
|
|
21
|
-
|
|
22
|
+
render_value(display_value)
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
else
|
|
25
26
|
span(class: value_class) {
|
|
26
|
-
|
|
27
|
+
render_value(display_value)
|
|
27
28
|
}
|
|
28
29
|
end
|
|
29
30
|
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def render_value(val)
|
|
35
|
+
if val.is_a?(TinyAdmin::RawHtml)
|
|
36
|
+
unsafe_raw(val.to_s)
|
|
37
|
+
else
|
|
38
|
+
val
|
|
39
|
+
end
|
|
40
|
+
end
|
|
30
41
|
end
|
|
31
42
|
end
|
|
32
43
|
end
|
|
@@ -7,49 +7,49 @@ module TinyAdmin
|
|
|
7
7
|
attr_accessor :filters, :section_path
|
|
8
8
|
|
|
9
9
|
def view_template
|
|
10
|
-
form(class:
|
|
10
|
+
form(class: "form_filters", method: "get") {
|
|
11
11
|
filters.each do |field, filter|
|
|
12
12
|
name = field.name
|
|
13
13
|
filter_data = filter[:filter]
|
|
14
|
-
div(class:
|
|
15
|
-
label(for: "filter-#{name}", class:
|
|
14
|
+
div(class: "mb-3") {
|
|
15
|
+
label(for: "filter-#{name}", class: "form-label") { field.title }
|
|
16
16
|
case filter_data[:type]&.to_sym || field.type
|
|
17
17
|
when :boolean
|
|
18
|
-
select(class:
|
|
19
|
-
option(value:
|
|
20
|
-
option(value:
|
|
21
|
-
TinyAdmin.settings.helper_class.label_for(
|
|
18
|
+
select(class: "form-select", id: "filter-#{name}", name: "q[#{name}]") {
|
|
19
|
+
option(value: "") { "-" }
|
|
20
|
+
option(value: "0", selected: filter[:value] == "0") {
|
|
21
|
+
TinyAdmin.settings.helper_class.label_for("false", options: ["components.filters_form.boolean.false"])
|
|
22
22
|
}
|
|
23
|
-
option(value:
|
|
24
|
-
TinyAdmin.settings.helper_class.label_for(
|
|
23
|
+
option(value: "1", selected: filter[:value] == "1") {
|
|
24
|
+
TinyAdmin.settings.helper_class.label_for("true", options: ["components.filters_form.boolean.true"])
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
when :date
|
|
28
|
-
input(type:
|
|
28
|
+
input(type: "date", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value])
|
|
29
29
|
when :datetime
|
|
30
|
-
input(type:
|
|
30
|
+
input(type: "datetime-local", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value])
|
|
31
31
|
when :integer
|
|
32
|
-
input(type:
|
|
32
|
+
input(type: "number", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value])
|
|
33
33
|
when :select
|
|
34
|
-
select(class:
|
|
35
|
-
option(value:
|
|
34
|
+
select(class: "form-select", id: "filter-#{name}", name: "q[#{name}]") {
|
|
35
|
+
option(value: "") { "-" }
|
|
36
36
|
filter_data[:values].each do |value|
|
|
37
37
|
option(selected: filter[:value] == value) { value }
|
|
38
38
|
end
|
|
39
39
|
}
|
|
40
40
|
else
|
|
41
|
-
input(type:
|
|
41
|
+
input(type: "text", class: "form-control", id: "filter-#{name}", name: "q[#{name}]", value: filter[:value])
|
|
42
42
|
end
|
|
43
43
|
}
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
div(class:
|
|
47
|
-
a(href: section_path, class:
|
|
48
|
-
TinyAdmin.settings.helper_class.label_for(
|
|
46
|
+
div(class: "mt-3") {
|
|
47
|
+
a(href: section_path, class: "button_clear btn btn-secondary text-white") {
|
|
48
|
+
TinyAdmin.settings.helper_class.label_for("Clear", options: ["components.filters_form.buttons.clear"])
|
|
49
49
|
}
|
|
50
50
|
whitespace
|
|
51
|
-
button(type:
|
|
52
|
-
TinyAdmin.settings.helper_class.label_for(
|
|
51
|
+
button(type: "submit", class: "button_filter btn btn-secondary") {
|
|
52
|
+
TinyAdmin.settings.helper_class.label_for("Filter", options: ["components.filters_form.buttons.submit"])
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -12,10 +12,10 @@ module TinyAdmin
|
|
|
12
12
|
warnings = messages[:warnings]
|
|
13
13
|
errors = messages[:errors]
|
|
14
14
|
|
|
15
|
-
div(class:
|
|
16
|
-
div(class:
|
|
17
|
-
div(class:
|
|
18
|
-
div(class:
|
|
15
|
+
div(class: "flash") {
|
|
16
|
+
div(class: "notices alert alert-success", role: "alert") { notices.join(", ") } if notices&.any?
|
|
17
|
+
div(class: "warnings alert alert-warning", role: "alert") { warnings.join(", ") } if warnings&.any?
|
|
18
|
+
div(class: "errors alert alert-danger", role: "alert") { errors.join(", ") } if errors&.any?
|
|
19
19
|
}
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -8,12 +8,12 @@ module TinyAdmin
|
|
|
8
8
|
|
|
9
9
|
def view_template
|
|
10
10
|
head {
|
|
11
|
-
meta charset:
|
|
12
|
-
meta name:
|
|
11
|
+
meta charset: "utf-8"
|
|
12
|
+
meta name: "viewport", content: "width=device-width, initial-scale=1"
|
|
13
13
|
title {
|
|
14
14
|
page_title
|
|
15
15
|
}
|
|
16
|
-
style_links.each do |style_link|
|
|
16
|
+
(style_links || []).each do |style_link|
|
|
17
17
|
link(**style_link)
|
|
18
18
|
end
|
|
19
19
|
style { extra_styles } if extra_styles
|
|
@@ -7,29 +7,29 @@ module TinyAdmin
|
|
|
7
7
|
attr_accessor :current_slug, :items, :root_path, :root_title
|
|
8
8
|
|
|
9
9
|
def view_template
|
|
10
|
-
nav(class:
|
|
11
|
-
div(class:
|
|
12
|
-
a(class:
|
|
10
|
+
nav(class: "navbar navbar-expand-lg") {
|
|
11
|
+
div(class: "container") {
|
|
12
|
+
a(class: "navbar-brand", href: root_path) { root_title }
|
|
13
13
|
button(
|
|
14
|
-
class:
|
|
15
|
-
type:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
class: "navbar-toggler",
|
|
15
|
+
type: "button",
|
|
16
|
+
"data-bs-toggle" => "collapse",
|
|
17
|
+
"data-bs-target" => "#navbarNav",
|
|
18
|
+
"aria-controls" => "navbarNav",
|
|
19
|
+
"aria-expanded" => "false",
|
|
20
|
+
"aria-label" => "Toggle navigation"
|
|
21
21
|
) {
|
|
22
|
-
span(class:
|
|
22
|
+
span(class: "navbar-toggler-icon")
|
|
23
23
|
}
|
|
24
|
-
div(class:
|
|
25
|
-
ul(class:
|
|
24
|
+
div(class: "collapse navbar-collapse", id: "navbarNav") {
|
|
25
|
+
ul(class: "navbar-nav") {
|
|
26
26
|
items.each do |item|
|
|
27
27
|
classes = %w[nav-link]
|
|
28
|
-
classes <<
|
|
29
|
-
link_attributes = { class: classes.join(
|
|
28
|
+
classes << "active" if item.slug == current_slug
|
|
29
|
+
link_attributes = { class: classes.join(" "), href: item.path, "aria-current" => "page" }
|
|
30
30
|
link_attributes.merge!(item.options) if item.options
|
|
31
31
|
|
|
32
|
-
li(class:
|
|
32
|
+
li(class: "nav-item") {
|
|
33
33
|
a(**link_attributes) { item.name }
|
|
34
34
|
}
|
|
35
35
|
end
|
|
@@ -7,28 +7,28 @@ module TinyAdmin
|
|
|
7
7
|
attr_accessor :current, :pages, :query_string, :total_count
|
|
8
8
|
|
|
9
9
|
def view_template
|
|
10
|
-
div(class:
|
|
11
|
-
div(class:
|
|
12
|
-
div(class:
|
|
10
|
+
div(class: "container") {
|
|
11
|
+
div(class: "row") {
|
|
12
|
+
div(class: "col total-count") {
|
|
13
13
|
"#{total_count} items"
|
|
14
14
|
}
|
|
15
|
-
div(class:
|
|
16
|
-
nav(class:
|
|
17
|
-
ul(class:
|
|
15
|
+
div(class: "col col-6 text-center pagination-div") {
|
|
16
|
+
nav(class: "d-inline-block", "aria-label": "Pagination") {
|
|
17
|
+
ul(class: "pagination") {
|
|
18
18
|
if pages <= 10
|
|
19
19
|
pages_range(1..pages)
|
|
20
20
|
elsif current <= 4 || current >= pages - 3
|
|
21
|
-
pages_range(1..(current <= 4 ? current + 2 : 4), with_dots: true)
|
|
22
|
-
pages_range((current > pages - 4 ? current - 2 : pages - 2)..pages)
|
|
21
|
+
pages_range(1..(current <= 4 ? (current + 2) : 4), with_dots: true)
|
|
22
|
+
pages_range((current > pages - 4 ? (current - 2) : (pages - 2))..pages)
|
|
23
23
|
else
|
|
24
24
|
pages_range(1..1, with_dots: true)
|
|
25
|
-
pages_range(current - 2..current + 2, with_dots: true)
|
|
25
|
+
pages_range((current - 2)..(current + 2), with_dots: true)
|
|
26
26
|
pages_range(pages..pages)
|
|
27
27
|
end
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
div(class:
|
|
31
|
+
div(class: "col")
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
end
|
|
@@ -37,17 +37,17 @@ module TinyAdmin
|
|
|
37
37
|
|
|
38
38
|
def pages_range(range, with_dots: false)
|
|
39
39
|
range.each do |page|
|
|
40
|
-
li(class: page == current ?
|
|
40
|
+
li(class: page == current ? "page-item active" : "page-item") {
|
|
41
41
|
href = query_string.empty? ? "?p=#{page}" : "?#{query_string}&p=#{page}"
|
|
42
|
-
a(class:
|
|
42
|
+
a(class: "page-link", href: href) { page.to_s }
|
|
43
43
|
}
|
|
44
44
|
end
|
|
45
45
|
dots if with_dots
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def dots
|
|
49
|
-
li(class:
|
|
50
|
-
a(class:
|
|
49
|
+
li(class: "page-item disabled") {
|
|
50
|
+
a(class: "page-link") { "..." }
|
|
51
51
|
}
|
|
52
52
|
end
|
|
53
53
|
end
|
|
@@ -4,23 +4,24 @@ module TinyAdmin
|
|
|
4
4
|
module Views
|
|
5
5
|
module Components
|
|
6
6
|
class Widgets < BasicComponent
|
|
7
|
-
def initialize(widgets)
|
|
7
|
+
def initialize(widgets, context: {})
|
|
8
8
|
@widgets = widgets
|
|
9
|
+
@context = context
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def view_template
|
|
12
13
|
return if @widgets.nil? || @widgets.empty?
|
|
13
14
|
|
|
14
|
-
div(class:
|
|
15
|
+
div(class: "container widgets") {
|
|
15
16
|
@widgets.each_slice(2).each do |row|
|
|
16
|
-
div(class:
|
|
17
|
+
div(class: "row") {
|
|
17
18
|
row.each do |widget|
|
|
18
19
|
next unless widget < Phlex::HTML
|
|
19
20
|
|
|
20
|
-
div(class:
|
|
21
|
-
div(class:
|
|
22
|
-
div(class:
|
|
23
|
-
render widget
|
|
21
|
+
div(class: "col") {
|
|
22
|
+
div(class: "card") {
|
|
23
|
+
div(class: "card-body") {
|
|
24
|
+
render build_widget(widget)
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
}
|
|
@@ -29,6 +30,20 @@ module TinyAdmin
|
|
|
29
30
|
end
|
|
30
31
|
}
|
|
31
32
|
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def build_widget(widget)
|
|
37
|
+
key_params = [:key, :keyreq]
|
|
38
|
+
if widget.instance_method(:initialize).arity != 0 ||
|
|
39
|
+
widget.instance_method(:initialize).parameters.any? { |type, _| key_params.include?(type) }
|
|
40
|
+
widget.new(context: @context)
|
|
41
|
+
else
|
|
42
|
+
widget.new
|
|
43
|
+
end
|
|
44
|
+
rescue ArgumentError
|
|
45
|
+
widget.new
|
|
46
|
+
end
|
|
32
47
|
end
|
|
33
48
|
end
|
|
34
49
|
end
|
|
@@ -35,10 +35,10 @@ module TinyAdmin
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def main_content
|
|
38
|
-
div(class:
|
|
38
|
+
div(class: "container main-content py-4") do
|
|
39
39
|
if options&.include?(:compact_layout)
|
|
40
|
-
div(class:
|
|
41
|
-
div(class:
|
|
40
|
+
div(class: "row justify-content-center") {
|
|
41
|
+
div(class: "col-6") {
|
|
42
42
|
yield
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -52,10 +52,10 @@ module TinyAdmin
|
|
|
52
52
|
TinyAdmin.settings.style_links || [
|
|
53
53
|
# Bootstrap CDN
|
|
54
54
|
{
|
|
55
|
-
href:
|
|
56
|
-
rel:
|
|
57
|
-
integrity:
|
|
58
|
-
crossorigin:
|
|
55
|
+
href: "https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css",
|
|
56
|
+
rel: "stylesheet",
|
|
57
|
+
integrity: "sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65",
|
|
58
|
+
crossorigin: "anonymous"
|
|
59
59
|
}
|
|
60
60
|
]
|
|
61
61
|
end
|
|
@@ -6,12 +6,12 @@ module TinyAdmin
|
|
|
6
6
|
class Content < DefaultLayout
|
|
7
7
|
def view_template
|
|
8
8
|
super do
|
|
9
|
-
div(class:
|
|
10
|
-
div(class:
|
|
9
|
+
div(class: "content") {
|
|
10
|
+
div(class: "content-data") {
|
|
11
11
|
unsafe_raw(content)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
render TinyAdmin::Views::Components::Widgets.new(widgets)
|
|
14
|
+
render TinyAdmin::Views::Components::Widgets.new(widgets, context: { params: params })
|
|
15
15
|
}
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TinyAdmin
|
|
4
|
+
module Views
|
|
5
|
+
module Pages
|
|
6
|
+
class ErrorPage < DefaultLayout
|
|
7
|
+
def view_template
|
|
8
|
+
super do
|
|
9
|
+
div(class: css_class) {
|
|
10
|
+
h1(class: "title") { title }
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def css_class
|
|
18
|
+
self.class.name.split("::").last
|
|
19
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
20
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
21
|
+
.downcase
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -3,17 +3,9 @@
|
|
|
3
3
|
module TinyAdmin
|
|
4
4
|
module Views
|
|
5
5
|
module Pages
|
|
6
|
-
class PageNotAllowed <
|
|
7
|
-
def view_template
|
|
8
|
-
super do
|
|
9
|
-
div(class: 'page_not_allowed') {
|
|
10
|
-
h1(class: 'title') { title }
|
|
11
|
-
}
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
6
|
+
class PageNotAllowed < ErrorPage
|
|
15
7
|
def title
|
|
16
|
-
|
|
8
|
+
"Page not allowed"
|
|
17
9
|
end
|
|
18
10
|
end
|
|
19
11
|
end
|