base_editing_bootstrap 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +13 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/Dockerfile +57 -0
  7. data/LICENSE.txt +21 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +130 -0
  10. data/Rakefile +8 -0
  11. data/app/assets/config/base_editing_bootstrap_manifest.js +0 -0
  12. data/app/assets/images/base_editing_bootstrap/.keep +0 -0
  13. data/app/assets/stylesheets/base_editing_bootstrap/.keep +0 -0
  14. data/app/controllers/.keep +0 -0
  15. data/app/controllers/base_editing_controller.rb +209 -0
  16. data/app/controllers/concerns/.keep +0 -0
  17. data/app/controllers/restricted_area_controller.rb +26 -0
  18. data/app/helpers/.keep +0 -0
  19. data/app/helpers/base_editing_helper.rb +22 -0
  20. data/app/helpers/utilities/enum_helper.rb +24 -0
  21. data/app/helpers/utilities/form_helper.rb +61 -0
  22. data/app/helpers/utilities/modal_helper.rb +11 -0
  23. data/app/helpers/utilities/page_helper.rb +51 -0
  24. data/app/helpers/utilities/search_helper.rb +110 -0
  25. data/app/helpers/utilities/template_helper.rb +22 -0
  26. data/app/jobs/.keep +0 -0
  27. data/app/mailers/.keep +0 -0
  28. data/app/models/.keep +0 -0
  29. data/app/models/concerns/.keep +0 -0
  30. data/app/policies/base_model_policy.rb +42 -0
  31. data/app/views/.keep +0 -0
  32. data/app/views/base_editing/_edit_page_title_header.html.erb +3 -0
  33. data/app/views/base_editing/_editing_form_measure_unit.html.erb +15 -0
  34. data/app/views/base_editing/_form.html.erb +17 -0
  35. data/app/views/base_editing/_form_field.html.erb +6 -0
  36. data/app/views/base_editing/_form_field_header.html.erb +1 -0
  37. data/app/views/base_editing/_form_footer.html.erb +3 -0
  38. data/app/views/base_editing/_index_body.html.erb +17 -0
  39. data/app/views/base_editing/_index_main_buttons.html.erb +1 -0
  40. data/app/views/base_editing/_index_title_header.html.erb +10 -0
  41. data/app/views/base_editing/_navbar.html.erb +0 -0
  42. data/app/views/base_editing/_new_page_title_header.html.erb +3 -0
  43. data/app/views/base_editing/_search.html.erb +17 -0
  44. data/app/views/base_editing/_search_field.erb +4 -0
  45. data/app/views/base_editing/_search_footer.html.erb +1 -0
  46. data/app/views/base_editing/_search_result.html.erb +13 -0
  47. data/app/views/base_editing/_search_result_row.html.erb +8 -0
  48. data/app/views/base_editing/_tabs.html.erb +2 -0
  49. data/app/views/base_editing/cell_field/_base.html.erb +3 -0
  50. data/app/views/base_editing/cell_field/_timestamps.html.erb +3 -0
  51. data/app/views/base_editing/edit.html.erb +3 -0
  52. data/app/views/base_editing/form_field/_base.html.erb +7 -0
  53. data/app/views/base_editing/form_field/_date.html.erb +2 -0
  54. data/app/views/base_editing/form_field/_datetime.html.erb +2 -0
  55. data/app/views/base_editing/form_field/_decimal.html.erb +2 -0
  56. data/app/views/base_editing/form_field/_integer.html.erb +2 -0
  57. data/app/views/base_editing/index.html.erb +5 -0
  58. data/app/views/base_editing/new.html.erb +3 -0
  59. data/app/views/base_editing/show.html.erb +1 -0
  60. data/app/views/kaminari/_first_page.html.erb +3 -0
  61. data/app/views/kaminari/_gap.html.erb +3 -0
  62. data/app/views/kaminari/_last_page.html.erb +3 -0
  63. data/app/views/kaminari/_next_page.html.erb +3 -0
  64. data/app/views/kaminari/_page.html.erb +9 -0
  65. data/app/views/kaminari/_paginator.html.erb +17 -0
  66. data/app/views/kaminari/_prev_page.html.erb +3 -0
  67. data/base_editing_bootstrap.gemspec +39 -0
  68. data/cog.toml +26 -0
  69. data/config/initializers/base_field_error_proc.rb +1 -0
  70. data/config/locales/it.yml +67 -0
  71. data/config/routes.rb +2 -0
  72. data/docker-compose.yml +20 -0
  73. data/lib/base_editing_bootstrap/base_model.rb +30 -0
  74. data/lib/base_editing_bootstrap/engine.rb +15 -0
  75. data/lib/base_editing_bootstrap/forms/base.rb +101 -0
  76. data/lib/base_editing_bootstrap/is_validated.rb +20 -0
  77. data/lib/base_editing_bootstrap/searches/base.rb +47 -0
  78. data/lib/base_editing_bootstrap/searches/field.rb +18 -0
  79. data/lib/base_editing_bootstrap/version.rb +3 -0
  80. data/lib/base_editing_bootstrap.rb +26 -0
  81. data/lib/tasks/base_editing_bootstrap_tasks.rake +4 -0
  82. data/spec/support/external_shared/base_editing_controller_helpers.rb +154 -0
  83. data/spec/support/external_shared/base_model.rb +62 -0
  84. data/spec/support/external_shared/factory_bot.rb +28 -0
  85. data/spec/support/external_shared/pundit.rb +14 -0
  86. metadata +214 -0
@@ -0,0 +1,61 @@
1
+ module Utilities
2
+ module FormHelper
3
+ include TemplateHelper
4
+ ##
5
+ # Metodo su cui eseguire override per i campi specifici rispetto all'oggetto gestito dal controller
6
+ # @deprecated Utilizza form_print_field(form, field) senza sovrascriverlo
7
+ # @param [Forms::Base] form
8
+ # @param [Symbol] field
9
+ def editing_form_print_field(form, field)
10
+ form_print_field(form, field)
11
+ end
12
+
13
+ ##
14
+ # Metodo per il partial corretto per eseguire il render del campo della form
15
+ #
16
+ # @param [Forms::Base] form
17
+ # @param [Symbol] field
18
+ def form_print_field(form, field)
19
+ locals = {form:, field:}
20
+ case form.object.class.type_for_attribute(field).type
21
+ when :datetime
22
+ generic_field = "datetime"
23
+ when :date
24
+ generic_field = "date"
25
+ when :decimal
26
+ locals[:scale] = form.object.class.type_for_attribute(field).scale || 2
27
+ generic_field = "decimal"
28
+ when :float
29
+ locals[:scale] = 2 # usiamo il default dato che non abbiamo questa informazione negli attributes di rails
30
+ generic_field = "decimal"
31
+ when :integer
32
+ generic_field = "integer"
33
+ else
34
+ generic_field = "base"
35
+ end
36
+
37
+ template = find_template_with_fallbacks(
38
+ form.object,
39
+ field,
40
+ "form_field",
41
+ generic_field
42
+ )
43
+ Rails.logger.debug { "#{template}->#{ locals.inspect}" }
44
+ render template, **locals
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ BaseEditingBootstrap.deprecator.deprecate_methods(Utilities::FormHelper, editing_form_print_field: <<-MESSAGE
51
+
52
+ Non vogliamo utilizzare più il sistema degli helpers ma direttamente le view,
53
+ creare nella cartella del relativo modello la struttura di cartelle derivato
54
+ dal to_partial_path chiamato sull'oggetto del modello che stiamo generando
55
+ `nome_modello_plurale/nome_modello_singolare/form_field/_nomeField.html.erb`
56
+ a cui vengono passati i parametri form e field
57
+
58
+ <\%\# \locals: (form:, field:) -%\>
59
+ <\%\= form.check_box(:field_name, class: "form-control") \%\>
60
+ MESSAGE
61
+ )
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Utilities::ModalHelper
4
+ ##
5
+ # Metodo speciale per l'inclusione del contenuto nelle modal, forzando il flush in modo da poter utilizzare
6
+ # più modal contemporaneamente
7
+ def content_for_modal(*args, &block)
8
+ opts = args.extract_options!
9
+ content_for(*args, opts.merge(flush: true), &block)
10
+ end
11
+ end
@@ -0,0 +1,51 @@
1
+ module Utilities::PageHelper
2
+ # @param [BaseModel] base_class
3
+ def title_mod_g(base_class)
4
+ "#{t("edit")} #{base_class.model_name.human}"
5
+ end
6
+
7
+ # @param [BaseModel] base_class
8
+ def title_new_g(base_class)
9
+ "#{t("new")} #{base_class.model_name.human}"
10
+ end
11
+
12
+ # Quando e se servirà verrà testato:
13
+ # - form_field dovrebbe essere il campo del modello che ha associato il has_one_attached
14
+ # def link_download(form_field)
15
+ # link_to rails_blob_path(form_field, disposition: 'attachment'), class: "btn btn-primary", style: "margin:5px;" do
16
+ # icon("fas", "eye") + content_tag(:span, " #{I18n.t('download')} #{form_field.filename.to_s}")
17
+ # end
18
+ # end
19
+ #
20
+ # def link_delete(form_field, delete_link)
21
+ # link_to delete_link, data: {turbo_method: :delete, turbo_confirm: t('are_you_sure')},
22
+ # class: "btn btn-danger", style: "margin:5px;" do
23
+ # icon("fas", "times") + content_tag(:span, " #{I18n.t('delete')} #{form_field.filename.to_s}")
24
+ # end
25
+ # end
26
+
27
+ # @param [TrueClass, FalseClass] valore
28
+ def boolean_to_icon(valore)
29
+ if valore
30
+ icon("check-lg", class: "text-success")
31
+ else
32
+ icon("x-lg", class: "text-danger")
33
+ end
34
+ end
35
+
36
+ # @param [String] path
37
+ # @param [Hash] options
38
+ def new_button(path, options = {})
39
+ options.merge!({class: 'btn btn-success btn-sm'})
40
+ link_to icon("plus-lg", I18n.t(:new)), path, options
41
+ end
42
+
43
+ # @param [BaseModel] obj instance
44
+ # @param [Symbol] field
45
+ def error_messages_for(obj, field)
46
+ if obj.errors.include?(field)
47
+ msg = obj.errors.full_messages_for(field).join(",")
48
+ content_tag(:div, icon("x-circle-fill", msg), class: "invalid-feedback")
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,110 @@
1
+ module Utilities
2
+ module SearchHelper
3
+ include TemplateHelper
4
+
5
+ ##
6
+ # Per aggiungere bottoni:
7
+ # ES:
8
+ # def search_form_buttons(ransack_form, &block)
9
+ # super #<- questo serve per costruiri i bottoni definiti da super
10
+ # content_for(:search_form_buttons) do #<- questo serve per aggiungere al content_for un'altro bottone
11
+ # link_to "xls", admins_log_alarms_path(params: {q: params.permit(q:{})[:q]}, format: :xlsx), class: "btn btn-info", target: :_blank
12
+ # end
13
+ # end
14
+ # @return [ActiveSupport::SafeBuffer]
15
+ # @param [Ransack::Helpers::FormBuilder] ransack_form
16
+ def search_form_buttons(ransack_form)
17
+ content_for(:search_form_buttons) do
18
+ ransack_form.submit(I18n.translate('.search'), class: "btn btn-primary")
19
+ end
20
+ end
21
+
22
+ ##
23
+ # Renderizza la cella della tabella nella pagina della index
24
+ # @param [BaseModel] obj
25
+ # @param [Symbol] field
26
+ # @return [ActiveSupport::SafeBuffer]
27
+ def render_cell_field(obj, field)
28
+ generic_field = case field
29
+ when :created_at, :updated_at
30
+ "timestamps"
31
+ else
32
+ "base"
33
+ end
34
+ template = find_template_with_fallbacks(
35
+ obj,
36
+ field,
37
+ "cell_field",
38
+ generic_field
39
+ )
40
+ render template, obj:, field:
41
+ end
42
+
43
+ ##
44
+ # Renderizza header della tabella della index
45
+ # @param [BaseModel] obj
46
+ # @param [Symbol] field
47
+ # @return [ActiveSupport::SafeBuffer]
48
+ def render_header_cell_field(obj, field)
49
+ content_tag(:th, obj.human_attribute_name(field))
50
+ end
51
+
52
+ ##
53
+ # Restituisce il valore che vogliamo mostrare
54
+ def render_raw_field(obj, field)
55
+ case field
56
+ when :created_at, :updated_at
57
+ l(obj.read_attribute(field), format: :long)
58
+ else
59
+ obj[field]
60
+ end
61
+ end
62
+
63
+ def search_result_buttons(rec)
64
+ btns = ActiveSupport::SafeBuffer.new
65
+
66
+ if policy(rec).edit?
67
+ btns << link_to(icon("pencil-square"),
68
+ edit_custom_polymorphic_path(rec),
69
+ class: "btn btn-sm btn-primary me-1")
70
+ end
71
+
72
+ if policy(rec).show?
73
+ btns << link_to(icon(:eye),
74
+ show_custom_polymorphic_path(rec),
75
+ class: "btn btn-sm btn-primary me-1")
76
+ end
77
+
78
+ if policy(rec).destroy?
79
+ btns << link_to(icon(:trash),
80
+ destroy_custom_polymorphic_path(rec),
81
+ data: {
82
+ turbo_method: :delete,
83
+ turbo_confirm: t("are_you_sure")
84
+ },
85
+ class: "btn btn-sm btn-danger me-1")
86
+ end
87
+ btns
88
+ end
89
+
90
+ ##
91
+ # Possibile override dei parametri da passare a ransack nella form
92
+ def search_form_for_params(ransack_instance)
93
+ [ransack_instance.ransack_query]
94
+ end
95
+ end
96
+ end
97
+
98
+ BaseEditingBootstrap.deprecator.deprecate_methods(Utilities::SearchHelper, render_raw_field: <<-MESSAGE
99
+ Abbiamo migrato ad un sistema di rendering tramite views,
100
+ è stato lasciato come memo per una migrazione semplificata
101
+ nel caso si voglia renderizzare un determinato campo in modo differente dal normale dato del DB
102
+ creare nalla path del modello la cartella cell_field e creare al suo interno il file con il nome
103
+ del _campo.html.erb e quindi inserire li il rendering (ES modello User, campo :name):
104
+ app/views/users/user/cell_field/_campo.html.erb
105
+ ```
106
+ <%# locals: (obj:,field:) -%>
107
+ <td><%= obj.name.upcase %></td>
108
+ ```
109
+ MESSAGE
110
+ )
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Utilities::TemplateHelper
4
+
5
+ ##
6
+ # Ricerca template con fallbacks.
7
+ # In ordine, cerca di trovare il partial per l'oggetto(tramite il metodo to_partial_path) e il campo specifico.
8
+ # In successione cerca poi per il partial con nome relativo al tipo di dato
9
+ # sempre nella cartella dell'oggetto
10
+ # ed infine nella cerca nella cartella del base editing
11
+ # @param [Object#to_partial_path] obj
12
+ # @param [Symbol] field
13
+ # @param [String] base_path
14
+ # @param [String] generic_field
15
+ def find_template_with_fallbacks(obj, field, base_path, generic_field)
16
+ obj_base_path = "#{obj.to_partial_path}/#{base_path}"
17
+ return "#{obj_base_path}/#{field}" if lookup_context.exists?(field, [obj_base_path], true)
18
+ return "#{obj_base_path}/#{generic_field}" if lookup_context.exists?(generic_field, [obj_base_path], true)
19
+ "base_editing/#{base_path}/#{generic_field}"
20
+ end
21
+
22
+ end
data/app/jobs/.keep ADDED
File without changes
data/app/mailers/.keep ADDED
File without changes
data/app/models/.keep ADDED
File without changes
File without changes
@@ -0,0 +1,42 @@
1
+ class BaseModelPolicy < ApplicationPolicy
2
+ def index? = general_rule
3
+
4
+ def create? = general_rule
5
+
6
+ def update? = general_rule
7
+
8
+ def destroy? = general_rule
9
+
10
+ def show? = false
11
+
12
+ # Questo metodo può essere anche scritto specifico per azione:
13
+ # - permitted_attributes_for_create
14
+ # - permitted_attributes_for_update
15
+ def permitted_attributes = []
16
+
17
+ def editable_attributes = []
18
+
19
+ def permitted_attributes_for_ransack
20
+ record.class.column_names + record.class._ransackers.keys
21
+ end
22
+
23
+ def permitted_associations_for_ransack
24
+ []
25
+ end
26
+
27
+ def search_fields = []
28
+
29
+ def search_result_fields = []
30
+
31
+ class Scope < Scope
32
+ def resolve
33
+ scope.all
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def general_rule
40
+ true
41
+ end
42
+ end
data/app/views/.keep ADDED
File without changes
@@ -0,0 +1,3 @@
1
+ <h2>
2
+ <%= title_mod_g(base_class) %>
3
+ </h2>
@@ -0,0 +1,15 @@
1
+ <%
2
+ # LOCALS disponibili per rendering del flag dell'unità di misura
3
+ # object: classe active_model che mi serve per cercare la traduzione dell'unità
4
+ # field: campo che dobbiamo tradurre
5
+ %>
6
+ <%# locals: (object:,field:) -%>
7
+ <%
8
+ translation = object.class.human_attribute_name("#{field}/unit", default: "")
9
+ unless translation.blank?
10
+ %>
11
+ <span class="input-group-text"><%= translation %></span>
12
+ <%
13
+ end
14
+ %>
15
+
@@ -0,0 +1,17 @@
1
+ <div class="card" id="card_id">
2
+ <div class="card-header">
3
+ <%= form_for @object, builder: form_builder do |form| %>
4
+
5
+ <div class="card-body">
6
+ <%= render partial: "form_field_header", local: {form:} %>
7
+ <%= render collection: form_attributes(form.object),
8
+ partial: "form_field", locals: {form:} %>
9
+ </div>
10
+
11
+ <div class="card-footer">
12
+ <%= render partial: "form_footer", locals: {form: form} %>
13
+ </div>
14
+
15
+ <% end %>
16
+ </div>
17
+ </div>
@@ -0,0 +1,6 @@
1
+ <%= form.label(form_field, class: "form-label") %>
2
+ <div class="input-group mb-2 <%= form.object.validated? ? "has-validation" : "" %>">
3
+ <%= render partial: "editing_form_measure_unit", locals: {object: form.object, field: form_field} %>
4
+ <%= form_print_field(form, form_field) %>
5
+ <%= error_messages_for(form.object, form_field) %>
6
+ </div>
@@ -0,0 +1 @@
1
+ <%# header degli elementi della form, nel caso dovessimo fare una testata %>
@@ -0,0 +1,3 @@
1
+ <div class="row justify-content-end">
2
+ <%= form.submit %>
3
+ </div>
@@ -0,0 +1,17 @@
1
+ <div class="card">
2
+ <% if @search_instance.search_fields.count > 0 %>
3
+ <div class="card-header">
4
+ <%= render partial: "search" %>
5
+ </div>
6
+ <% end %>
7
+
8
+ <% if @search_instance.results.count > 0 %>
9
+ <div class="card-body table-responsive p-0">
10
+ <%= render partial: "search_result" %>
11
+ </div>
12
+
13
+ <div class="card-footer clearfix">
14
+ <%= render partial: "search_footer" %>
15
+ </div>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1 @@
1
+ <%= new_button new_custom_polymorphic_path(base_class) if policy(base_class.new).create? %>
@@ -0,0 +1,10 @@
1
+ <div>
2
+ <div class="row align-items-center">
3
+ <div class="col-md-8 col-xs-8">
4
+ <h2><%= base_class.model_name.human(count: 2) %></h2>
5
+ </div>
6
+ <div class="col-md-4 col-xs-4 text-end">
7
+ <%= render 'index_main_buttons' %>
8
+ </div>
9
+ </div>
10
+ </div>
File without changes
@@ -0,0 +1,3 @@
1
+ <h2>
2
+ <%= title_new_g(base_class) %>
3
+ </h2>
@@ -0,0 +1,17 @@
1
+ <%= search_form_for *search_form_for_params(@search_instance) do |f| %>
2
+
3
+ <div class="row g-2">
4
+ <%= render @search_instance.search_fields, ransack_form_builder: f %>
5
+ </div>
6
+
7
+ <div class="row mt-4">
8
+ <div class="col-1">
9
+ <div class="btn-group mr-1">
10
+ <% search_form_buttons(f) %>
11
+ <%= content_for :search_form_buttons %>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ <% end %>
16
+
17
+
@@ -0,0 +1,4 @@
1
+ <div class="form-group col-xs-6 col-sm-4 col-md-3">
2
+ <%= ransack_form_builder.label(search_field.name) %>
3
+ <%= ransack_form_builder.search_field(search_field.name, class: "form-control form-control-sm") %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= paginate @search_instance.results %>
@@ -0,0 +1,13 @@
1
+ <table class="table table-head-fixed text-nowrap <%= dom_class(@search_instance.model_klass,:search_results) %>">
2
+ <thead>
3
+ <tr>
4
+ <% @search_instance.search_result_fields.each do |srf| %>
5
+ <%= render_header_cell_field(@search_instance.model_klass, srf) %>
6
+ <% end %>
7
+ <th class="action_col"></th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <%= render partial: 'search_result_row', collection: @search_instance.results, as: :obj %>
12
+ </tbody>
13
+ </table>
@@ -0,0 +1,8 @@
1
+ <tr>
2
+ <% @search_instance.search_result_fields.each do |srf| %>
3
+ <%= render_cell_field(obj, srf) %>
4
+ <% end %>
5
+ <td>
6
+ <%= search_result_buttons(obj) %>
7
+ </td>
8
+ </tr>
@@ -0,0 +1,2 @@
1
+ <div class="row" id="tab_row">
2
+ </div>
@@ -0,0 +1,3 @@
1
+ <%# Renderizza il campo nella tabella della pagina dei risultati %>
2
+ <%# locals: (obj:,field:) -%>
3
+ <td><%= obj.read_attribute(field) %></td>
@@ -0,0 +1,3 @@
1
+ <%# Renderizza il campo nella tabella della pagina dei risultati %>
2
+ <%# locals: (obj:,field:) -%>
3
+ <td><%= l(obj.read_attribute(field), format: :long) %></td>
@@ -0,0 +1,3 @@
1
+ <%= render partial: "navbar" %>
2
+ <%= render 'edit_page_title_header' %>
3
+ <%= render partial: "form" %>
@@ -0,0 +1,7 @@
1
+ <%
2
+ ##
3
+ # Template per il rendering del vero campo input
4
+ # eseguire override nei casi in cui si voglia renderizzare qualcosa di differente
5
+ %>
6
+ <%# locals: (form:, field:) -%>
7
+ <%= form.text_field(field) %>
@@ -0,0 +1,2 @@
1
+ <%# locals: (form:, field:) -%>
2
+ <%= form.date_field(field) %>
@@ -0,0 +1,2 @@
1
+ <%# locals: (form:, field:) -%>
2
+ <%= form.datetime_field(field) %>
@@ -0,0 +1,2 @@
1
+ <%# locals: (form:, field:, scale:2) -%>
2
+ <%= form.number_field(field, step: "0.#{"0" * (scale - 1)}1") %>
@@ -0,0 +1,2 @@
1
+ <%# locals: (form:, field:) -%>
2
+ <%= form.number_field(field, step: "1") %>
@@ -0,0 +1,5 @@
1
+ <%= render partial: "navbar" %>
2
+
3
+ <%= render partial: "index_title_header" %>
4
+
5
+ <%= render 'index_body' %>
@@ -0,0 +1,3 @@
1
+ <%= render partial: "navbar" %>
2
+ <%= render 'new_page_title_header' %>
3
+ <%= render 'form' %>
@@ -0,0 +1 @@
1
+ <h1>Show</h1>
@@ -0,0 +1,3 @@
1
+ <li class="page-item">
2
+ <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link' %>
3
+ </li>
@@ -0,0 +1,3 @@
1
+ <li class='page-item disabled'>
2
+ <%= link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link' %>
3
+ </li>
@@ -0,0 +1,3 @@
1
+ <li class="page-item">
2
+ <%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, remote: remote, class: 'page-link' %>
3
+ </li>
@@ -0,0 +1,3 @@
1
+ <li class="page-item">
2
+ <%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link' %>
3
+ </li>
@@ -0,0 +1,9 @@
1
+ <% if page.current? %>
2
+ <li class="page-item active">
3
+ <%= content_tag :a, page, data: {remote: remote}, rel: page.rel, class: 'page-link' %>
4
+ </li>
5
+ <% else %>
6
+ <li class="page-item">
7
+ <%= link_to page, url, remote: remote, rel: page.rel, class: 'page-link' %>
8
+ </li>
9
+ <% end %>
@@ -0,0 +1,17 @@
1
+ <%= paginator.render do %>
2
+ <nav>
3
+ <ul class="pagination">
4
+ <%= first_page_tag unless current_page.first? %>
5
+ <%= prev_page_tag unless current_page.first? %>
6
+ <% each_page do |page| %>
7
+ <% if page.left_outer? || page.right_outer? || page.inside_window? %>
8
+ <%= page_tag page %>
9
+ <% elsif !page.was_truncated? -%>
10
+ <%= gap_tag %>
11
+ <% end %>
12
+ <% end %>
13
+ <%= next_page_tag unless current_page.last? %>
14
+ <%= last_page_tag unless current_page.last? %>
15
+ </ul>
16
+ </nav>
17
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <li class="page-item">
2
+ <%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link' %>
3
+ </li>
@@ -0,0 +1,39 @@
1
+ require_relative "lib/base_editing_bootstrap/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "base_editing_bootstrap"
5
+ spec.version = BaseEditingBootstrap::VERSION
6
+ spec.authors = ["Marino Bonetti"]
7
+ spec.email = ["marinobonetti@gmail.com"]
8
+ spec.summary = "BaseEditing: funzionalità di base per cms rails"
9
+ spec.description = "Raccolta di utility per semplificare costruzione cms in rails"
10
+ spec.homepage = "https://github.com/oniram88/BaseEditingBootstrap"
11
+ spec.license = "MIT"
12
+ spec.required_ruby_version = ">= 3.1"
13
+
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+ spec.metadata["source_code_uri"] = "https://github.com/oniram88/BaseEditingBootstrap"
16
+ spec.metadata["changelog_uri"] = "https://github.com/oniram88/BaseEditingBootstrap/CHANGELOG"
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(__dir__) do
21
+ `git ls-files -z`.split("\x0").reject do |f|
22
+ (File.expand_path(f) == __FILE__) ||
23
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .gitlab-ci.yml appveyor Gemfile])
24
+ end
25
+ end
26
+ spec.files += Dir['spec/support/external_shared/*.rb']
27
+
28
+ spec.add_dependency "rails", ">= 7.0"
29
+ spec.add_dependency "pundit", ">= 2.3.1"
30
+
31
+ # Search
32
+ spec.add_dependency 'ransack', '>= 4.0.0'
33
+ # Pagination
34
+ spec.add_dependency 'kaminari', '>= 1.2.2'
35
+
36
+ spec.add_development_dependency "rspec-rails"
37
+ spec.add_development_dependency "factory_bot_rails"
38
+
39
+ end
data/cog.toml ADDED
@@ -0,0 +1,26 @@
1
+ from_latest_tag = false
2
+ ignore_merge_commits = false
3
+ disable_changelog = false
4
+ generate_mono_repository_global_tag = true
5
+ branch_whitelist = []
6
+ skip_ci = "[skip ci]"
7
+ skip_untracked = false
8
+ pre_bump_hooks = []
9
+ post_bump_hooks = [
10
+ "git push",
11
+ "git push origin {{version}}"
12
+ ]
13
+ pre_package_bump_hooks = []
14
+ post_package_bump_hooks = []
15
+
16
+ [git_hooks]
17
+
18
+ [commit_types]
19
+
20
+ [changelog]
21
+ path = "CHANGELOG.md"
22
+ authors = []
23
+
24
+ [bump_profiles]
25
+
26
+ [packages]
@@ -0,0 +1 @@
1
+ ActionView::Base.field_error_proc = Proc.new { |html_tag, instance| html_tag }