base_editing_bootstrap 0.16.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +4 -0
- data/app/helpers/utilities/search_helper.rb +32 -22
- data/app/helpers/utilities/template_helper.rb +6 -2
- data/app/policies/base_model_policy.rb +6 -0
- data/app/views/base_editing/_form.html.erb +1 -0
- data/app/views/base_editing/_form_field.html.erb +9 -4
- data/app/views/base_editing/_form_field_container.html.erb +3 -0
- data/app/views/base_editing/_index_body.html.erb +1 -1
- data/app/views/base_editing/_search_result.html.erb +1 -1
- data/app/views/base_editing/form_field/_boolean.html.erb +1 -1
- data/app/views/base_editing/header_field/_base.html.erb +9 -0
- data/base_editing_bootstrap.gemspec +2 -2
- data/lib/base_editing_bootstrap/VERSION +1 -1
- data/lib/base_editing_bootstrap/forms/base.rb +1 -1
- data/lib/base_editing_bootstrap/searches/base.rb +11 -3
- data/lib/generators/base_editing_bootstrap/header_override/header_override_generator.rb +38 -0
- data/spec/support/external_shared/pundit.rb +20 -0
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1e80d543ff93c2a170069bb78b4f78488819804458f1e5a36c87fd7d0975476
|
4
|
+
data.tar.gz: b65c0f800fe834ac24794e292c8e09c7e2910e2f5e1b0ba215aadd69ee7ff168
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 776c45e8aab54bb0208bf9b0af8728a2467b9943dec257f6e55527be03c53cfd7996e7f370a63ef29d769fe318a4937435bb7759eabf130c08f070d88c8b0eb8
|
7
|
+
data.tar.gz: 749586e54204dab5ad28c227d03fab252a79483e63a7f6cf07cb6ce84aca05aded2408f6092578ce3f39fca61ac4708b4c4692a3fb67c3722a1ca350dada2392
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,32 @@
|
|
2
2
|
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
|
3
3
|
|
4
4
|
- - -
|
5
|
+
## 1.1.0 - 2025-01-03
|
6
|
+
#### Continuous Integration
|
7
|
+
- Add ruby 3.4 - (5658bb0) - Marino Bonetti
|
8
|
+
#### Features
|
9
|
+
- Boolean switch render right side label - (d448ef7) - Marino Bonetti
|
10
|
+
- Add a new layout container for form_field - (77dec9f) - Marino Bonetti
|
11
|
+
#### Tests
|
12
|
+
- Add help text example for enabled - (efd4aff) - Marino Bonetti
|
13
|
+
|
14
|
+
- - -
|
15
|
+
|
16
|
+
## 1.0.0 - 2024-11-26
|
17
|
+
#### Bug Fixes
|
18
|
+
- Remove fixed versions - (f8dc4b8) - Marino Bonetti
|
19
|
+
- Utilizziamo metodo di kaminari per totale pagine - (4451592) - Marino Bonetti
|
20
|
+
#### Documentation
|
21
|
+
- Add debug info for ransack - (e1355ef) - Marino Bonetti
|
22
|
+
#### Features
|
23
|
+
- Print header search results - (20fc7be) - Marino Bonetti
|
24
|
+
#### Miscellaneous Chores
|
25
|
+
- Rails 8.0 stable in test case - (87aff45) - Marino Bonetti
|
26
|
+
#### Tests
|
27
|
+
- Debugging - (663d5e9) - Marino Bonetti
|
28
|
+
|
29
|
+
- - -
|
30
|
+
|
5
31
|
## 0.16.1 - 2024-11-22
|
6
32
|
#### Bug Fixes
|
7
33
|
- Correct case when attribute to print is virtual - (b86e478) - Marino Bonetti
|
data/README.md
CHANGED
@@ -133,6 +133,10 @@ Utilizzo per modello base, in questo esempio prendiamo come modello Post come es
|
|
133
133
|
```shell
|
134
134
|
rails g base_editing_bootstrap:cell_override ModelName field1 field2:type
|
135
135
|
```
|
136
|
+
- [OPTIONAL] e per fare il rendering dell'header della tabella della index
|
137
|
+
```shell
|
138
|
+
rails g base_editing_bootstrap:header_override ModelName field1 field2:type
|
139
|
+
```
|
136
140
|
- [OPTIONAL] Base overrides:
|
137
141
|
E' possibile anche fare un override generico dei campi, sono previsti questi tipi di partial
|
138
142
|
legati al tipo di dati:
|
@@ -30,35 +30,18 @@ module Utilities
|
|
30
30
|
# @param [Symbol] field
|
31
31
|
# @return [ActiveSupport::SafeBuffer]
|
32
32
|
def render_cell_field(obj, field)
|
33
|
-
|
34
|
-
when :created_at, :updated_at
|
35
|
-
"timestamps"
|
36
|
-
else
|
37
|
-
type = obj.class.type_for_attribute(field).type
|
38
|
-
case type
|
39
|
-
when :boolean
|
40
|
-
"boolean"
|
41
|
-
else
|
42
|
-
"base"
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
template = find_template_with_fallbacks(
|
47
|
-
obj,
|
48
|
-
field,
|
49
|
-
"cell_field",
|
50
|
-
generic_field
|
51
|
-
)
|
33
|
+
template = template_for_column(obj.class, field, "cell_field")
|
52
34
|
render template, obj:, field:
|
53
35
|
end
|
54
36
|
|
55
37
|
##
|
56
38
|
# Renderizza header della tabella della index
|
57
|
-
# @param [
|
39
|
+
# @param [BaseEditingBootstrap::Searches::Base] search_instance
|
58
40
|
# @param [Symbol] field
|
59
41
|
# @return [ActiveSupport::SafeBuffer]
|
60
|
-
def render_header_cell_field(
|
61
|
-
|
42
|
+
def render_header_cell_field(search_instance, field)
|
43
|
+
template = template_for_column(search_instance.model_klass, field, "header_field")
|
44
|
+
render template, obj: search_instance.model_klass, field:, search_instance: search_instance
|
62
45
|
end
|
63
46
|
|
64
47
|
##
|
@@ -77,6 +60,33 @@ module Utilities
|
|
77
60
|
def search_form_for_params(ransack_instance)
|
78
61
|
[ransack_instance.ransack_query]
|
79
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
##
|
67
|
+
# Restituisce il template corretto per la tripletta, andando a ricercare il tipo di campo attraverso le informazioni
|
68
|
+
# che type_for_attribute può restituirci
|
69
|
+
def template_for_column(klazz, field, partial_type)
|
70
|
+
generic_field = case field
|
71
|
+
when :created_at, :updated_at
|
72
|
+
"timestamps"
|
73
|
+
else
|
74
|
+
type = klazz.type_for_attribute(field).type
|
75
|
+
case type
|
76
|
+
when :boolean
|
77
|
+
"boolean"
|
78
|
+
else
|
79
|
+
"base"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
find_template_with_fallbacks(
|
84
|
+
klazz,
|
85
|
+
field,
|
86
|
+
partial_type,
|
87
|
+
generic_field
|
88
|
+
)
|
89
|
+
end
|
80
90
|
end
|
81
91
|
end
|
82
92
|
|
@@ -13,10 +13,14 @@ module Utilities::TemplateHelper
|
|
13
13
|
# @param [String] base_path
|
14
14
|
# @param [String] generic_field
|
15
15
|
def find_template_with_fallbacks(obj, field, base_path, generic_field)
|
16
|
-
|
16
|
+
# nei casi in cui passiamo la classe e non l'oggetto, dobbiamo utilizzare un metodo interno a rails per
|
17
|
+
# avere la partial_path
|
18
|
+
partial_path = (obj.respond_to? :to_partial_path) ? obj.to_partial_path : obj._to_partial_path
|
19
|
+
obj_base_path = "#{partial_path}/#{base_path}"
|
17
20
|
return "#{obj_base_path}/#{field}" if lookup_context.exists?(field, [obj_base_path], true)
|
18
21
|
return "#{obj_base_path}/#{generic_field}" if lookup_context.exists?(generic_field, [obj_base_path], true)
|
19
|
-
"base_editing/#{base_path}/#{generic_field}"
|
22
|
+
return "base_editing/#{base_path}/#{generic_field}" if lookup_context.find_all("base_editing/#{base_path}/_#{generic_field}").any?
|
23
|
+
"base_editing/#{base_path}/base"
|
20
24
|
end
|
21
25
|
|
22
26
|
end
|
@@ -28,6 +28,12 @@ class BaseModelPolicy < ApplicationPolicy
|
|
28
28
|
|
29
29
|
def search_result_fields = []
|
30
30
|
|
31
|
+
##
|
32
|
+
# List of attributes in index to make it sortable
|
33
|
+
def sortable_search_result_fields
|
34
|
+
search_result_fields
|
35
|
+
end
|
36
|
+
|
31
37
|
class Scope < Scope
|
32
38
|
def resolve
|
33
39
|
scope.all
|
@@ -5,20 +5,25 @@
|
|
5
5
|
# - form_field -> Array[String]
|
6
6
|
%>
|
7
7
|
<%# locals: (form:, form_field:) -%>
|
8
|
-
<%= form.label(form_field, class: ["form-label", "form-#{form_field}-label"]) %>
|
9
|
-
|
10
8
|
<%
|
11
|
-
button_group_classes = ["mb-
|
9
|
+
button_group_classes = ["mb-1"]
|
12
10
|
|
13
11
|
content = form_print_field(form, form_field)
|
14
12
|
unless content.match "checkbox"
|
15
13
|
button_group_classes << "input-group"
|
16
14
|
end
|
17
|
-
|
18
15
|
button_group_classes << (form.object.validated? ? "has-validation" : "")
|
19
16
|
button_group_classes << "form-#{form_field}-input-group"
|
20
17
|
|
18
|
+
# Non renderizziamo il contenuto del label in questa vista se siamo nello switch
|
19
|
+
if content.match "form-switch"
|
20
|
+
label_content = nil
|
21
|
+
else
|
22
|
+
label_content = form.label(form_field, class: ["form-label", "form-#{form_field}-label"])
|
23
|
+
end
|
24
|
+
|
21
25
|
%>
|
26
|
+
<%= label_content %>
|
22
27
|
<%= content_tag :div, class: button_group_classes.join(" ") do %>
|
23
28
|
<%= render partial: "editing_form_measure_unit", locals: {object: form.object, field: form_field} %>
|
24
29
|
<%= content %>
|
@@ -1,2 +1,2 @@
|
|
1
1
|
<%# locals: (form:, field:) -%>
|
2
|
-
<%= form.switch_box(field) %>
|
2
|
+
<%= form.switch_box(field,label: field) %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%# Renderizza il campo header della tabella della pagina dei risultati %>
|
2
|
+
<%# locals: (obj:,field:,search_instance:) -%>
|
3
|
+
<th scope="col">
|
4
|
+
<% if search_instance.sortable?(field) %>
|
5
|
+
<%= sort_link(search_instance.ransack_query, field, obj.human_attribute_name(field)) %>
|
6
|
+
<% else %>
|
7
|
+
<%= obj.human_attribute_name(field) %>
|
8
|
+
<% end %>
|
9
|
+
</th>
|
@@ -42,9 +42,9 @@ Gem::Specification.new do |spec|
|
|
42
42
|
spec.add_development_dependency "factory_bot_rails", '~> 6.4'
|
43
43
|
spec.add_development_dependency 'faker', '~> 3.3'
|
44
44
|
spec.add_development_dependency "puma", '~> 6.4'
|
45
|
-
spec.add_development_dependency "sqlite3"
|
45
|
+
spec.add_development_dependency "sqlite3"
|
46
46
|
spec.add_development_dependency "sprockets-rails", '~> 3.4'
|
47
|
-
spec.add_development_dependency 'rails-i18n'
|
47
|
+
spec.add_development_dependency 'rails-i18n'
|
48
48
|
spec.add_development_dependency "i18n-debug", '~> 1.2'
|
49
49
|
spec.add_development_dependency "cssbundling-rails", '~> 1.4'
|
50
50
|
spec.add_development_dependency "rspec-parameterized", "~> 1.0", ">= 1.0.0" # https://github.com/tomykaira/rspec-parameterized
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.1.0
|
@@ -64,7 +64,7 @@ module BaseEditingBootstrap::Forms
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def switch_box(method, options = {}, checked_value = "1", unchecked_value = "0")
|
67
|
-
options[:class] = (["form-switch"] + (options[:class] || "").split(" ")).join(" ")
|
67
|
+
options[:class] = (["form-check form-switch"] + (options[:class] || "").split(" ")).join(" ")
|
68
68
|
self.check_box(method, options, checked_value, unchecked_value)
|
69
69
|
end
|
70
70
|
|
@@ -24,9 +24,11 @@ module BaseEditingBootstrap::Searches
|
|
24
24
|
# Risultato della ricerca, fa da pipeline verso ransack
|
25
25
|
# Impostando il sort nel caso in cui non sia già stato impostato da ransack
|
26
26
|
def results
|
27
|
-
ransack_query
|
28
|
-
r.sorts = @sorts if r.sorts.empty?
|
29
|
-
|
27
|
+
ransack_query
|
28
|
+
.tap { |r| r.sorts = @sorts if r.sorts.empty? }
|
29
|
+
.result(distinct: true)
|
30
|
+
.tap { |q| Rails.logger.debug { "[Ransack] params:#{params} - sql: #{q.to_sql}" } }
|
31
|
+
.page(params[:page])
|
30
32
|
end
|
31
33
|
|
32
34
|
def ransack_query
|
@@ -42,6 +44,12 @@ module BaseEditingBootstrap::Searches
|
|
42
44
|
Pundit.policy(@user, @model_klass).search_result_fields
|
43
45
|
end
|
44
46
|
|
47
|
+
##
|
48
|
+
# Ritorna se il campo deve essere ordinabile o meno
|
49
|
+
def sortable?(field)
|
50
|
+
Pundit.policy(@user, @model_klass).sortable_search_result_fields.include?(field)
|
51
|
+
end
|
52
|
+
|
45
53
|
def persisted?
|
46
54
|
false
|
47
55
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BaseEditingBootstrap
|
4
|
+
module Generators
|
5
|
+
class HeaderOverrideGenerator < ::Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../../../../app/views/base_editing", __dir__)
|
7
|
+
argument :name, type: :string, banner: "Post", required: true
|
8
|
+
argument :attributes, type: :array, default: [], banner: "field field:type"
|
9
|
+
|
10
|
+
TYPES = %i[base]
|
11
|
+
|
12
|
+
desc <<-DESCRIPTION.strip_heredoc
|
13
|
+
Description:
|
14
|
+
Copy partial files for a defined fields,
|
15
|
+
the possible types are #{TYPES}
|
16
|
+
Default to base
|
17
|
+
DESCRIPTION
|
18
|
+
|
19
|
+
def copy_form_partials
|
20
|
+
if attributes.empty?
|
21
|
+
say "Need one field"
|
22
|
+
else
|
23
|
+
singular_name = name.underscore.downcase.singularize
|
24
|
+
plural_name = singular_name.pluralize
|
25
|
+
attributes.each do |a|
|
26
|
+
attr_name, type = a.split(":")
|
27
|
+
|
28
|
+
type = :base if type.nil?
|
29
|
+
type = type.to_sym
|
30
|
+
raise "Type #{type} not found in #{TYPES}" unless TYPES.include?(type)
|
31
|
+
copy_file "header_field/_#{type}.html.erb", File.join("app/views", plural_name, singular_name, 'header_field', "_#{attr_name}.html.erb")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -17,6 +17,26 @@ RSpec.shared_examples "a standard base model policy" do |factory, check_default_
|
|
17
17
|
let(:user) { create(:user) }
|
18
18
|
let(:instance) { described_class.new(user, build(factory)) }
|
19
19
|
|
20
|
+
describe "response to all necessary methods" do
|
21
|
+
where(:method) do
|
22
|
+
[
|
23
|
+
[:sortable_search_result_fields],
|
24
|
+
[:search_result_fields],
|
25
|
+
[:search_fields],
|
26
|
+
[:permitted_associations_for_ransack],
|
27
|
+
[:permitted_attributes_for_ransack],
|
28
|
+
[:editable_attributes],
|
29
|
+
[:permitted_attributes],
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
with_them do
|
34
|
+
it "should " do
|
35
|
+
expect(instance).to respond_to(method)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
20
40
|
describe "standard_methods" do
|
21
41
|
where(:method, :response) do
|
22
42
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: base_editing_bootstrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marino Bonetti
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -166,14 +166,14 @@ dependencies:
|
|
166
166
|
requirements:
|
167
167
|
- - ">="
|
168
168
|
- !ruby/object:Gem::Version
|
169
|
-
version:
|
169
|
+
version: '0'
|
170
170
|
type: :development
|
171
171
|
prerelease: false
|
172
172
|
version_requirements: !ruby/object:Gem::Requirement
|
173
173
|
requirements:
|
174
174
|
- - ">="
|
175
175
|
- !ruby/object:Gem::Version
|
176
|
-
version:
|
176
|
+
version: '0'
|
177
177
|
- !ruby/object:Gem::Dependency
|
178
178
|
name: sprockets-rails
|
179
179
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,16 +192,16 @@ dependencies:
|
|
192
192
|
name: rails-i18n
|
193
193
|
requirement: !ruby/object:Gem::Requirement
|
194
194
|
requirements:
|
195
|
-
- - "
|
195
|
+
- - ">="
|
196
196
|
- !ruby/object:Gem::Version
|
197
|
-
version: '
|
197
|
+
version: '0'
|
198
198
|
type: :development
|
199
199
|
prerelease: false
|
200
200
|
version_requirements: !ruby/object:Gem::Requirement
|
201
201
|
requirements:
|
202
|
-
- - "
|
202
|
+
- - ">="
|
203
203
|
- !ruby/object:Gem::Version
|
204
|
-
version: '
|
204
|
+
version: '0'
|
205
205
|
- !ruby/object:Gem::Dependency
|
206
206
|
name: i18n-debug
|
207
207
|
requirement: !ruby/object:Gem::Requirement
|
@@ -317,6 +317,7 @@ files:
|
|
317
317
|
- app/views/base_editing/_editing_form_measure_unit.html.erb
|
318
318
|
- app/views/base_editing/_form.html.erb
|
319
319
|
- app/views/base_editing/_form_field.html.erb
|
320
|
+
- app/views/base_editing/_form_field_container.html.erb
|
320
321
|
- app/views/base_editing/_form_field_header.html.erb
|
321
322
|
- app/views/base_editing/_form_footer.html.erb
|
322
323
|
- app/views/base_editing/_index_body.html.erb
|
@@ -342,6 +343,7 @@ files:
|
|
342
343
|
- app/views/base_editing/form_field/_decimal.html.erb
|
343
344
|
- app/views/base_editing/form_field/_enum.html.erb
|
344
345
|
- app/views/base_editing/form_field/_integer.html.erb
|
346
|
+
- app/views/base_editing/header_field/_base.html.erb
|
345
347
|
- app/views/base_editing/index.html.erb
|
346
348
|
- app/views/base_editing/new.html.erb
|
347
349
|
- app/views/base_editing/show.html.erb
|
@@ -369,6 +371,7 @@ files:
|
|
369
371
|
- lib/base_editing_bootstrap/version.rb
|
370
372
|
- lib/generators/base_editing_bootstrap/cell_override/cell_override_generator.rb
|
371
373
|
- lib/generators/base_editing_bootstrap/field_override/field_override_generator.rb
|
374
|
+
- lib/generators/base_editing_bootstrap/header_override/header_override_generator.rb
|
372
375
|
- lib/generators/base_editing_bootstrap/install/USAGE
|
373
376
|
- lib/generators/base_editing_bootstrap/install/install_generator.rb
|
374
377
|
- lib/generators/base_editing_bootstrap/install/templates/initializer.rb
|
@@ -403,7 +406,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
403
406
|
- !ruby/object:Gem::Version
|
404
407
|
version: '0'
|
405
408
|
requirements: []
|
406
|
-
rubygems_version: 3.5.
|
409
|
+
rubygems_version: 3.5.16
|
407
410
|
signing_key:
|
408
411
|
specification_version: 4
|
409
412
|
summary: 'BaseEditing: funzionalità di base per cms rails'
|