tiny_admin 0.7.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8059ea24a18bfb14f8e868a70203db8045099e20196f5098f1c63b121421e49
4
- data.tar.gz: d0da80d718362c58a50e963b2e79dff550e77a763d7872a0ba96efea43f408b3
3
+ metadata.gz: de3ed265839998db96c8e220f1b66576a8a37325e0726f3597e0b1ef315087a4
4
+ data.tar.gz: 828309ff8139a11c3e73fcbeb82ffea7f752191e5c4e99e9dc19fbaa29a2180e
5
5
  SHA512:
6
- metadata.gz: 3067f890f10f10f5dc7379c7b147f01f5cb62b8d59f06ad7b4387c685cd2e32cdeb1f87fbfe36b0e2c388c854ce461f1a18b2659ee479e401ba74ed3c5559a3a
7
- data.tar.gz: 0a4b4129b33e0dbf2ab2d01df14ead0ec3971a098dbed39a5b50c287e2a00c5c8448011de81a233c7bb1dda58bb42b648d44069684a65cdb4e42e3faf2a453bb
6
+ metadata.gz: 3648b175fd028a82bc7c3ae35fc51d3380a4d22fc6dd38dfd5da5ed375d94b4b45358b36c17c955482574756700bd2889ba57348e4ed3453491e2112c9d1471f
7
+ data.tar.gz: 4ea2a1301b70a3b88e07829e5755976482d22b2f18c1752ab7b7626e93b19b20527a7944c9da634fdf92a4bed53cf20d56c1e7e6738bc8c3b519de4147cd810b
data/README.md CHANGED
@@ -19,7 +19,7 @@ Please ⭐ if you like it.
19
19
 
20
20
  ## Install
21
21
 
22
- - Add to your Gemfile: `gem 'tiny_admin', '~> 0.7'`
22
+ - Add to your Gemfile: `gem 'tiny_admin', '~> 0.9'`
23
23
  - Mount the app in a route (check some examples with: Hanami, Rails, Roda and standalone in [extra](extra))
24
24
  + in Rails, update _config/routes.rb_: `mount TinyAdmin::Router => '/admin'`
25
25
  - Configure the dashboard using `TinyAdmin.configure` and/or `TinyAdmin.configure_from_file` with a YAML config file (see [configuration](#configuration) below):
@@ -85,6 +85,8 @@ The following options are supported:
85
85
  - `redirect` (String): alternative to _page_ option - redirects to a specific slug;
86
86
  - `widgets` (Array): list of widgets (as View components) to present.
87
87
 
88
+ > 📚 [Wiki Root page](https://github.com/blocknotes/tiny_admin/wiki/Root) available
89
+
88
90
  Example:
89
91
 
90
92
  ```yml
@@ -98,6 +100,8 @@ root:
98
100
 
99
101
  `helper_class` (String): class or module with helper methods, used for attributes' formatters.
100
102
 
103
+ > 📚 [Wiki Helper methods page](https://github.com/blocknotes/tiny_admin/wiki/Helper-methods) available
104
+
101
105
  `page_not_found` (String): a view object to render when a missing page is requested.
102
106
 
103
107
  `record_not_found` (String): a view object to render when a missing record is requested.
@@ -113,11 +117,15 @@ root:
113
117
 
114
118
  `extra_styles` (String): inline CSS styles.
115
119
 
120
+ > 📚 [Wiki Styles and scripts page](https://github.com/blocknotes/tiny_admin/wiki/Styles-and-scripts) available
121
+
116
122
  `authentication` (Hash): define the authentication method, properties:
117
123
 
118
124
  - `plugin` (String): a plugin class to use (ex. `TinyAdmin::Plugins::SimpleAuth`);
119
125
  - `password` (String): a password hash used by _SimpleAuth_ plugin (generated with `Digest::SHA512.hexdigest("some password")`).
120
126
 
127
+ > 📚 [Wiki Authentication page](https://github.com/blocknotes/tiny_admin/wiki/Authentication) available
128
+
121
129
  Example:
122
130
 
123
131
  ```yml
@@ -134,6 +142,8 @@ authentication:
134
142
  - `widgets` (Array): list of widgets (as View components) to present;
135
143
  - other properties depends on the section's type.
136
144
 
145
+ > 📚 [Wiki Pages page](https://github.com/blocknotes/tiny_admin/wiki/Pages) available
146
+
137
147
  For _content_ sections:
138
148
 
139
149
  - `content` (String): the HTML content to present.
@@ -186,6 +196,9 @@ For _resource_ sections:
186
196
 
187
197
  - `model` (String): the class to use to fetch the data on an item of a collection;
188
198
  - `repository` (String): the class to get the properties related to the model;
199
+
200
+ > 📚 [Wiki Repository page](https://github.com/blocknotes/tiny_admin/wiki/Repository) available
201
+
189
202
  - `index` (Hash): collection's action options (see below);
190
203
  - `show` (Hash): detail's action options (see below);
191
204
  - `collection_actions` (Array of hashes): custom collection's actions;
@@ -205,6 +218,8 @@ model: Post
205
218
 
206
219
  #### Resource index options
207
220
 
221
+ > 📚 [Wiki Resource index page](https://github.com/blocknotes/tiny_admin/wiki/Resource-index) available
222
+
208
223
  The Index hash supports the following options:
209
224
 
210
225
  - `attributes` (Array): fields to expose in the resource list page;
@@ -244,6 +259,8 @@ Example:
244
259
 
245
260
  #### Resource show options
246
261
 
262
+ > 📚 [Wiki Resource show page](https://github.com/blocknotes/tiny_admin/wiki/Resource-show) available
263
+
247
264
  The Show hash supports the following options:
248
265
 
249
266
  - `attributes` (Array): fields to expose in the resource details page.
@@ -62,8 +62,9 @@ module TinyAdmin
62
62
  @pages = (total_count / pagination.to_f).ceil
63
63
  return if pages <= 1 || !pagination_component_class
64
64
 
65
+ attributes = { current: current_page, pages: pages, query_string: query_string, total_count: total_count }
65
66
  page.pagination_component = pagination_component_class.new
66
- page.pagination_component.update_attributes(current: current_page, pages: pages, query_string: query_string)
67
+ page.pagination_component.update_attributes(attributes)
67
68
  end
68
69
  end
69
70
  end
@@ -12,7 +12,11 @@ module TinyAdmin
12
12
  end
13
13
 
14
14
  r.post 'unauthenticated' do
15
- render_login(warnings: ['Failed to authenticate'])
15
+ warning = TinyAdmin.settings.helper_class.label_for(
16
+ 'Failed to authenticate',
17
+ options: ['authentication.unauthenticated']
18
+ )
19
+ render_login(warnings: [warning])
16
20
  end
17
21
 
18
22
  r.get 'logout' do
@@ -16,6 +16,19 @@ module TinyAdmin
16
16
  messages.inject(target) { |result, msg| result&.send(msg) } if messages.any?
17
17
  end
18
18
 
19
+ def translate_value(value)
20
+ if options && options[:method]
21
+ method, *args = options[:method].split(',').map(&:strip)
22
+ if options[:converter]
23
+ Object.const_get(options[:converter]).send(method, value, options: args || [])
24
+ else
25
+ TinyAdmin.settings.helper_class.send(method, value, options: args || [])
26
+ end
27
+ else
28
+ value&.to_s
29
+ end
30
+ end
31
+
19
32
  class << self
20
33
  def create_field(name:, title: nil, type: nil, options: {})
21
34
  field_name = name.to_s
@@ -6,10 +6,7 @@ module TinyAdmin
6
6
  def index_record_attrs(record, fields: nil)
7
7
  return record.attributes.transform_values(&:to_s) unless fields
8
8
 
9
- fields.to_h do |name, field|
10
- value = record.send(name)
11
- [name, translate_value(value, field)]
12
- end
9
+ fields.to_h { [_1, record.send(_1)] }
13
10
  end
14
11
 
15
12
  def index_title
@@ -10,20 +10,6 @@ module TinyAdmin
10
10
  def initialize(model)
11
11
  @model = model
12
12
  end
13
-
14
- def translate_value(value, field)
15
- if field[:method]
16
- method, *options = field[:method].split(',').map(&:strip)
17
- if field[:converter]
18
- converter = Object.const_get(field[:converter])
19
- converter.send(method, value, options: options || [])
20
- else
21
- TinyAdmin.settings.helper_class.send(method, value, options: options || [])
22
- end
23
- else
24
- value&.to_s
25
- end
26
- end
27
13
  end
28
14
  end
29
15
  end
@@ -58,14 +58,15 @@ module TinyAdmin
58
58
  router.redirect route_for(TinyAdmin.settings.root[:redirect])
59
59
  else
60
60
  page_class = to_class(TinyAdmin.settings.root[:page])
61
- render_page prepare_page(page_class, attributes: TinyAdmin.settings.root.slice(:content, :title, :widgets))
61
+ attributes = TinyAdmin.settings.root.slice(:content, :title, :widgets)
62
+ render_page prepare_page(page_class, attributes: attributes, params: request.params)
62
63
  end
63
64
  end
64
65
 
65
66
  def setup_page_route(router, slug, page_data)
66
67
  router.get slug do
67
68
  attributes = page_data.slice(:content, :title, :widgets)
68
- render_page prepare_page(page_data[:class], slug: slug, attributes: attributes)
69
+ render_page prepare_page(page_data[:class], slug: slug, attributes: attributes, params: request.params)
69
70
  end
70
71
  end
71
72
 
@@ -7,6 +7,7 @@ module TinyAdmin
7
7
  DEFAULTS = {
8
8
  %i[authentication plugin] => Plugins::NoAuth,
9
9
  %i[authentication login] => Views::Pages::SimpleAuthLogin,
10
+ %i[components field_value] => Views::Components::FieldValue,
10
11
  %i[components flash] => Views::Components::Flash,
11
12
  %i[components head] => Views::Components::Head,
12
13
  %i[components navbar] => Views::Components::Navbar,
@@ -15,6 +15,10 @@ module TinyAdmin
15
15
  Kernel.format(options.first, value) if value && options&.any?
16
16
  end
17
17
 
18
+ def label_for(value, options: [])
19
+ value
20
+ end
21
+
18
22
  def round(value, options: [])
19
23
  value&.round(options&.first&.to_i || 2)
20
24
  end
@@ -14,7 +14,7 @@ module TinyAdmin
14
14
  list.join('&')
15
15
  end
16
16
 
17
- def prepare_page(page_class, slug: nil, attributes: nil, options: nil)
17
+ def prepare_page(page_class, slug: nil, attributes: nil, options: nil, params: nil)
18
18
  page_class.new.tap do |page|
19
19
  page.options = options
20
20
  page.head_component = TinyAdmin.settings.components[:head]&.new
@@ -27,9 +27,11 @@ module TinyAdmin
27
27
  items: options&.include?(:no_menu) ? [] : TinyAdmin.settings.store&.navbar
28
28
  )
29
29
  attrs = attributes || {}
30
+ attrs[:params] = params if params
30
31
  attrs[:widgets] = attrs[:widgets].map { to_class(_1) } if attrs[:widgets]
31
32
  page.update_attributes(attrs) unless attrs.empty?
32
33
  yield(page) if block_given?
34
+ page.setup if page.respond_to?(:setup)
33
35
  end
34
36
  end
35
37
 
@@ -37,7 +39,7 @@ module TinyAdmin
37
39
  klass.is_a?(String) ? Object.const_get(klass) : klass
38
40
  end
39
41
 
40
- def to_label(string)
42
+ def humanize(string)
41
43
  return '' unless string
42
44
 
43
45
  string.respond_to?(:humanize) ? string.humanize : string.tr('_', ' ').capitalize
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinyAdmin
4
- VERSION = '0.7.0'
4
+ VERSION = '0.9.0'
5
5
  end
@@ -28,6 +28,8 @@ module TinyAdmin
28
28
 
29
29
  table_body
30
30
  }
31
+
32
+ render pagination_component if pagination_component
31
33
  }
32
34
 
33
35
  if filters&.any?
@@ -39,8 +41,6 @@ module TinyAdmin
39
41
  end
40
42
  }
41
43
 
42
- render pagination_component if pagination_component
43
-
44
44
  render TinyAdmin::Views::Components::Widgets.new(widgets)
45
45
  }
46
46
  end
@@ -69,13 +69,7 @@ module TinyAdmin
69
69
  attributes.each do |key, value|
70
70
  field = fields[key]
71
71
  td(class: "field-value-#{field.name} field-value-type-#{field.type}") {
72
- if field.options && field.options[:link_to]
73
- a(href: TinyAdmin.route_for(field.options[:link_to], reference: value)) {
74
- field.apply_call_option(record) || value
75
- }
76
- else
77
- value
78
- end
72
+ render TinyAdmin.settings.components[:field_value].new(field, value, record: record)
79
73
  }
80
74
  end
81
75
 
@@ -86,15 +80,20 @@ module TinyAdmin
86
80
  links.each do |link|
87
81
  whitespace
88
82
  if link == 'show'
89
- a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) { 'show' }
83
+ a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) {
84
+ label_for('Show', options: ['actions.index.links.show'])
85
+ }
90
86
  else
91
87
  a(href: TinyAdmin.route_for(slug, reference: record.id, action: link), class: link_class) {
92
- to_label(link)
88
+ fallback = humanize(link)
89
+ label_for(fallback, options: ["actions.index.links.#{link}"])
93
90
  }
94
91
  end
95
92
  end
96
93
  else
97
- a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) { 'show' }
94
+ a(href: TinyAdmin.route_for(slug, reference: record.id), class: link_class) {
95
+ label_for('Show', options: ['actions.index.links.show'])
96
+ }
98
97
  end
99
98
  }
100
99
  }
@@ -25,13 +25,7 @@ module TinyAdmin
25
25
  div(class: 'field-header col-2') { field.options[:header] || field.title }
26
26
  end
27
27
  div(class: 'field-value col-10') {
28
- if field.options[:link_to]
29
- a(href: TinyAdmin.route_for(field.options[:link_to], reference: value)) {
30
- field.apply_call_option(record) || value
31
- }
32
- else
33
- value
34
- end
28
+ render TinyAdmin.settings.components[:field_value].new(field, value, record: record)
35
29
  }
36
30
  }
37
31
  end
@@ -5,7 +5,11 @@ module TinyAdmin
5
5
  class BasicLayout < Phlex::HTML
6
6
  include Utils
7
7
 
8
- attr_accessor :content, :widgets
8
+ attr_accessor :content, :params, :widgets
9
+
10
+ def label_for(value, options: [])
11
+ TinyAdmin.settings.helper_class.label_for(value, options: options)
12
+ end
9
13
 
10
14
  def update_attributes(attributes)
11
15
  attributes.each do |key, value|
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TinyAdmin
4
+ module Views
5
+ module Components
6
+ class FieldValue < BasicComponent
7
+ attr_reader :field, :value, :record
8
+
9
+ def initialize(field, value, record:)
10
+ @field = field
11
+ @value = value
12
+ @record = record
13
+ end
14
+
15
+ def template
16
+ translated_value = field.translate_value(value)
17
+ value_class = field.options[:options]&.include?('value_class') ? "value-#{value}" : nil
18
+ if field.options[:link_to]
19
+ a(href: TinyAdmin.route_for(field.options[:link_to], reference: translated_value)) {
20
+ span(class: value_class) {
21
+ field.apply_call_option(record) || translated_value
22
+ }
23
+ }
24
+ else
25
+ span(class: value_class) {
26
+ translated_value
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -17,8 +17,12 @@ module TinyAdmin
17
17
  when :boolean
18
18
  select(class: 'form-select', id: "filter-#{name}", name: "q[#{name}]") {
19
19
  option(value: '') { '-' }
20
- option(value: '0', selected: filter[:value] == '0') { 'false' }
21
- option(value: '1', selected: filter[:value] == '1') { 'true' }
20
+ option(value: '0', selected: filter[:value] == '0') {
21
+ TinyAdmin.settings.helper_class.label_for('false', options: ['components.filters_form.boolean.false'])
22
+ }
23
+ option(value: '1', selected: filter[:value] == '1') {
24
+ TinyAdmin.settings.helper_class.label_for('true', options: ['components.filters_form.boolean.true'])
25
+ }
22
26
  }
23
27
  when :date
24
28
  input(type: 'date', class: 'form-control', id: "filter-#{name}", name: "q[#{name}]", value: filter[:value])
@@ -40,9 +44,13 @@ module TinyAdmin
40
44
  end
41
45
 
42
46
  div(class: 'mt-3') {
43
- a(href: section_path, class: 'button_clear btn btn-secondary text-white') { 'clear' }
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
+ }
44
50
  whitespace
45
- button(type: 'submit', class: 'button_filter btn btn-secondary') { 'filter' }
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
+ }
46
54
  }
47
55
  }
48
56
  end
@@ -4,23 +4,31 @@ module TinyAdmin
4
4
  module Views
5
5
  module Components
6
6
  class Pagination < BasicComponent
7
- attr_accessor :current, :pages, :query_string
7
+ attr_accessor :current, :pages, :query_string, :total_count
8
8
 
9
9
  def template
10
- div(class: 'pagination-div') {
11
- nav('aria-label' => 'Pagination') {
12
- ul(class: 'pagination justify-content-center') {
13
- if pages <= 10
14
- pages_range(1..pages)
15
- elsif current <= 4 || current >= pages - 3
16
- pages_range(1..(current <= 4 ? current + 2 : 4), with_dots: true)
17
- pages_range((current > pages - 4 ? current - 2 : pages - 2)..pages)
18
- else
19
- pages_range(1..1, with_dots: true)
20
- pages_range(current - 2..current + 2, with_dots: true)
21
- pages_range(pages..pages)
22
- end
10
+ div(class: 'container') {
11
+ div(class: 'row') {
12
+ div(class: 'col total-count') {
13
+ "#{total_count} items"
23
14
  }
15
+ div(class: 'col col-6 text-center pagination-div') {
16
+ nav(class: 'd-inline-block', 'aria-label': 'Pagination') {
17
+ ul(class: 'pagination') {
18
+ if pages <= 10
19
+ pages_range(1..pages)
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)
23
+ else
24
+ pages_range(1..1, with_dots: true)
25
+ pages_range(current - 2..current + 2, with_dots: true)
26
+ pages_range(pages..pages)
27
+ end
28
+ }
29
+ }
30
+ }
31
+ div(class: 'col')
24
32
  }
25
33
  }
26
34
  end
@@ -11,12 +11,16 @@ module TinyAdmin
11
11
 
12
12
  form(class: 'form_login', method: 'post') {
13
13
  div(class: 'mt-3') {
14
- label(for: 'secret', class: 'form-label') { 'Password' }
14
+ label(for: 'secret', class: 'form-label') {
15
+ label_for('Password', options: ['pages.simple_auth_login.inputs.password'])
16
+ }
15
17
  input(type: 'password', name: 'secret', class: 'form-control', id: 'secret')
16
18
  }
17
19
 
18
20
  div(class: 'mt-3') {
19
- button(type: 'submit', class: 'button_login btn btn-primary') { 'login' }
21
+ button(type: 'submit', class: 'button_login btn btn-primary') {
22
+ label_for('Login', options: ['pages.simple_auth_login.buttons.submit'])
23
+ }
20
24
  }
21
25
  }
22
26
  }
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.7.0
4
+ version: 0.9.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-05-01 00:00:00.000000000 Z
11
+ date: 2023-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -98,6 +98,7 @@ files:
98
98
  - lib/tiny_admin/views/basic_layout.rb
99
99
  - lib/tiny_admin/views/basic_widget.rb
100
100
  - lib/tiny_admin/views/components/basic_component.rb
101
+ - lib/tiny_admin/views/components/field_value.rb
101
102
  - lib/tiny_admin/views/components/filters_form.rb
102
103
  - lib/tiny_admin/views/components/flash.rb
103
104
  - lib/tiny_admin/views/components/head.rb