base_editing_bootstrap 1.15.1 → 1.16.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: 80fc468a9d1b88f86141bbec31daa80a9ad21251177ad905e09795a1728106e1
4
- data.tar.gz: d7315c0afddb62fc17d4a27ca40f33abb107033e4040e6e7b2d95ab25851203f
3
+ metadata.gz: 8bd43711d49d65d4d703fb15361b66e41699844894e210b6509e7f6d35699b73
4
+ data.tar.gz: e22898cbe35cfe6c2545c4f5fe711ef4354e6943376699057e9a814da6f778e5
5
5
  SHA512:
6
- metadata.gz: 94581a8e80610a056bcfcc2f88699e4dff56bcbd1fdf9b835dc822ed0ed7dc8fbab9a34a01ec42c64932eeb637254285530a64eb5847a3cb5c14350ada7a927b
7
- data.tar.gz: 5f752eb62c62fc7fb697443da46fa911801fdf90fcad8af88a778994c05bf964fcf3f9ee4e4cc21bfd2c4a825bd06ffdca4f282b590977068b0296f9ada4a44a
6
+ metadata.gz: ad5021b0cdc14d54b8c88e3f35e9d2f9ad897b977f245553959fb1b6a560b7773a085c40b3a42cb1cccdc307c3b3d87e0586679b1032515dae67e75c3b14beb2
7
+ data.tar.gz: 4bd0b6718b83b4c8b7041e3ad94b229059909e7962ca361659230ac96b11df57c89c04e205ef6dd9fc3fd6d92e2f23445711197d0df0c3ec0d8da784fc7c5d2f
data/AGENTS.md ADDED
@@ -0,0 +1,56 @@
1
+ # AGENTS.md
2
+
3
+ This file provides context and instructions for AI coding agents working on the **BaseEditingBootstrap** project.
4
+
5
+ ## Project Overview
6
+ BaseEditingBootstrap is a Rails engine designed to provide a standardized, Bootstrap-based administrative interface for Rails models. It integrates with Pundit for authorization and Ransack for searching/sorting.
7
+
8
+ - **Main Components**:
9
+ - `BaseEditingController`: The base controller for all CRUD operations.
10
+ - `BaseModel`: A concern for models that should support standard editing.
11
+ - `BaseModelPolicy`: A base Pundit policy with specific methods for controlling UI elements.
12
+
13
+ ## Build & Test
14
+ The project uses Docker for environment setup and testing.
15
+
16
+ - **Setup Environment**:
17
+ ```bash
18
+ docker compose run app spec/dummy/bin/setup
19
+ ```
20
+ - **Run Tests**:
21
+ ```bash
22
+ docker compose run app bundle exec rspec
23
+ ```
24
+ - **Start Development Server**:
25
+ ```bash
26
+ docker compose up
27
+ ```
28
+
29
+ ## Development Workflow
30
+ - **Naming Conventions**: Follow standard Rails/Ruby naming conventions (snake_case for files and methods, CamelCase for classes).
31
+ - **Git Flow**: Use descriptive commit messages. No specific branching strategy is enforced, but use feature branches.
32
+ - **Testing**:
33
+ - **Controllers**: Use `it_behaves_like "base editing controller"`.
34
+ - **Models**: Use `it_behaves_like "a base model"`.
35
+ - **Policies**: Use `it_behaves_like "a standard base model policy"`.
36
+ - Ensure all new features or bug fixes include corresponding RSpec tests.
37
+
38
+ ## Coding Conventions & Patterns
39
+ - **Pundit Policies**:
40
+ - Implement `editable_attributes` to define fields visible/editable in forms.
41
+ - Implement `search_result_fields` to define columns in the index table.
42
+ - Implement `search_fields` for Ransack search form fields.
43
+ - Implement `permitted_attributes` for Pundit strong parameters.
44
+ - **Factories**:
45
+ - Every model factory should include a trait `:with_invalid_attributes` for testing validation failures.
46
+ - **Form/Cell Overrides**:
47
+ - Use the provided generators for field/cell overrides:
48
+ ```bash
49
+ rails g base_editing_bootstrap:field_override ModelName field1 field2:type
50
+ rails g base_editing_bootstrap:cell_override ModelName field1 field2:type
51
+ ```
52
+ - **I18n**: Follow the project's translation structure for messages and labels (see `README.md`).
53
+
54
+ ## Security
55
+ - Always use Pundit for authorization (`include Pundit::Authorization` in `ApplicationController`).
56
+ - Ensure `permitted_attributes` in policies correctly restrict user input.
data/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
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.16.0 - 2026-06-24
6
+ #### Features
7
+ - Aggiunta possibilità di customizzare label in checkbox - (9c96ddf) - Marino Bonetti
8
+ - Add option to hide fields in form by policy - (ec2a103) - Marino Bonetti
9
+ #### Bug Fixes
10
+ - Rimossa versione i18n non valida - (8e52029) - Marino Bonetti
11
+ - Visualizzazione validazione su file upload - (69223c1) - Marino Bonetti
12
+ - Update expectation to use be_a for search instance type - (3cc4acc) - Marino Bonetti
13
+ #### Miscellaneous Chores
14
+ - Fix Broken cogs configs - (da27444) - Marino Bonetti
15
+
16
+ - - -
17
+
5
18
  ## 1.15.1 - 2026-04-13
6
19
  #### Bug Fixes
7
20
  - Correzione pattern per decimali - (08847c0) - Marino Bonetti
data/README.md CHANGED
@@ -305,6 +305,11 @@ Al generator per i campi standard basta aggiungere il parametro `--readonly` per
305
305
  rails g base_editing_bootstrap:field_override ModelName field1 field2:type --readonly
306
306
  ```
307
307
 
308
+ ### Hidden Fields
309
+ E' possibile renderizzare i campi di un modello in modalità nascosta,
310
+ andando a ridefinire nella policy il metodo `attribute_is_hidden(attribute_name)`.
311
+ I campi nascosti verranno renderizzati tutti assieme all'inizio della form.
312
+
308
313
 
309
314
  ### Translations
310
315
 
@@ -5,7 +5,9 @@ class BaseEditingController < RestrictedAreaController
5
5
  :edit_custom_polymorphic_path,
6
6
  :form_attributes,
7
7
  :form_builder,
8
+ :field_renderer_class,
8
9
  :readonly_attribute?,
10
+ :hidden_attribute?,
9
11
  :index_custom_polymorphic_path,
10
12
  :new_custom_polymorphic_path,
11
13
  :show_custom_polymorphic_path
@@ -122,6 +124,10 @@ class BaseEditingController < RestrictedAreaController
122
124
  BaseEditingBootstrap::Forms::Base
123
125
  end
124
126
 
127
+ def field_renderer_class
128
+ BaseEditingBootstrap::Forms::FieldRenderer
129
+ end
130
+
125
131
  def form_attributes(model = base_class.new, action = override_pundit_action_name)
126
132
  policy = policy(model)
127
133
  method_name = if policy.respond_to?("editable_attributes_for_#{action}")
@@ -142,6 +148,16 @@ class BaseEditingController < RestrictedAreaController
142
148
  policy.public_send(method_name, attribute)
143
149
  end
144
150
 
151
+ def hidden_attribute?(attribute, model = base_class.new, action = override_pundit_action_name)
152
+ policy = policy(model)
153
+ method_name = if policy.respond_to?("attribute_is_hidden_for_#{action}")
154
+ "attribute_is_hidden_for_#{action}"
155
+ else
156
+ "attribute_is_hidden"
157
+ end
158
+ policy.public_send(method_name, attribute)
159
+ end
160
+
145
161
  def load_object
146
162
  @object = base_class.find(params[:id])
147
163
 
@@ -15,95 +15,29 @@ module Utilities
15
15
  end
16
16
 
17
17
  ##
18
- # Metodo per il partial corretto per eseguire il render del campo della form
18
+ # Metodo per il partial corretto per restituire l'oggetto della form con le logiche per
19
+ # trovare il template e le informazioni necessarie
19
20
  #
20
21
  # @param [Forms::Base] form
21
22
  # @param [Symbol] field
22
23
  # @param [Boolean] readonly -> rende possibile nelle nested form, nel caso arrivi da un field padre che definisce
23
24
  # il campo come readonly di non controllare nemmeno la policy(il padre ha priorità su figlio)
24
- # @return [ActiveSupport::SafeBuffer]
25
- def form_print_field(form, field, readonly: nil)
26
- locals = {form:, field:}
27
- if form.object.class.respond_to?(:field_to_form_partial) and (generic_field = form.object.class.field_to_form_partial(field))
28
- type = :custom
29
- elsif form.object.class.respond_to?(:defined_enums) && form.object.class.defined_enums.key?(field.to_s)
30
- type = :enum
31
- generic_field = "enum"
32
- elsif form.object.class.respond_to?(:reflect_on_association) &&
33
- form.object.class.reflect_on_association(field.to_s).is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
34
- !form.object.class.reflect_on_association(field.to_s).polymorphic? # non deve essere polymorphic
35
- # Abbiamo una relazione belongs_to da gestire
36
- reflection = form.object.class.reflect_on_association(field.to_s)
37
- type = :belongs_to
38
- generic_field = "belongs_to_select"
39
- locals[:relation_class] = reflection.klass
40
- locals[:foreign_key] = reflection.foreign_key
41
- elsif form.object.class.respond_to?(:nested_attributes_options) &&
42
- form.object.class.nested_attributes_options.key?(field.to_sym)
43
- type = :nested_attributes
44
- reflection = form.object.class.reflect_on_association(field.to_s)
45
- case reflection
46
- when ActiveRecord::Reflection::HasManyReflection
47
- locals[:new_object] = reflection.klass.new(reflection.foreign_key => form.object)
48
- generic_field = "accept_has_many_nested_field"
49
- when ActiveRecord::Reflection::HasOneReflection
50
- form.object.send(:"build_#{field}") unless form.object.send(field).present?
51
- generic_field = "accept_has_one_nested_field"
52
- else
53
- raise "Unknown reflection for nested attributes #{field}->#{reflection.class}"
54
- end
55
- else
56
- if form.object.class.respond_to?(:type_for_attribute)
57
- type = form.object.class.type_for_attribute(field).type
58
-
59
- # Se non abbiamo ancora il type tentiamo di capire se è di tipo attachment SINGOLO
60
- if type.nil? and form.object.respond_to?(:"#{field}_attachment")
61
- type = :has_one_attachment
62
- end
63
- else
64
- type = :string
65
- end
25
+ # @return [BaseEditingBootstrap::Forms::FormFieldRenderer]
26
+ def form_print_field_object(form, field, readonly: nil)
27
+ field_renderer_class.new(self, form, field, readonly: readonly)
28
+ end
66
29
 
67
- case type
68
- when :datetime
69
- generic_field = "datetime"
70
- when :date
71
- generic_field = "date"
72
- when :decimal
73
- locals[:scale] = form.object.class.type_for_attribute(field).scale || 2
74
- generic_field = "decimal"
75
- when :float
76
- locals[:scale] = 2 # usiamo il default dato che non abbiamo questa informazione negli attributes di rails
77
- generic_field = "decimal"
78
- when :integer
79
- generic_field = "integer"
80
- when :boolean
81
- generic_field = "boolean"
82
- when :has_one_attachment
83
- generic_field = "has_one_attachment"
84
- when :text
85
- generic_field = "textarea"
86
- else
87
- generic_field = "base"
88
- end
89
- end
90
30
 
91
- template = find_template_with_fallbacks(
92
- form.object,
93
- field,
94
- "form_field",
95
- generic_field,
96
- readonly: (readonly.nil? ? readonly_attribute?(field, form.object) : readonly)
97
- )
98
- bs_logger.debug do
99
- <<~TEXT
100
- TYPE: #{type}
101
- GENERIC_FIELD: #{generic_field}
102
- TEMPLATE: #{template.short_identifier}
103
- LOCALS:#{locals}
104
- TEXT
105
- end
106
- template.render(self, locals)
31
+ ##
32
+ # Metodo per il partial corretto per eseguire il render del campo della form
33
+ #
34
+ # @param [Forms::Base] form
35
+ # @param [Symbol] field
36
+ # @param [Boolean] readonly -> rende possibile nelle nested form, nel caso arrivi da un field padre che definisce
37
+ # il campo come readonly di non controllare nemmeno la policy(il padre ha priorità su figlio)
38
+ # @return [ActiveSupport::SafeBuffer]
39
+ def form_print_field(...)
40
+ form_print_field_object(...).render
107
41
  end
108
42
 
109
43
  end
@@ -36,6 +36,18 @@ class BaseModelPolicy < ApplicationPolicy
36
36
  # @return [Boolean] true se l'attributo è di sola lettura, false altrimenti
37
37
  def attribute_is_readonly(_attribute) = false
38
38
 
39
+ ##
40
+ # Permette di specificare se un attributo deve essere trattato come hidden durante il rendering della form.
41
+ # Analogamente a attribute_is_readonly è possibile definire la versione specifica per azione:
42
+ # - attribute_is_hidden_for_create?
43
+ # - attribute_is_hidden_for_update?
44
+ # - attribute_is_hidden_for_ACTION_NAME?
45
+ #
46
+ # @param attribute [Symbol] nome dell'attributo
47
+ # @param action_name [String] nome dell'azione
48
+ # @return [Boolean] true se l'attributo è hidden (deve essere renderizzato come hidden_field), false altrimenti
49
+ def attribute_is_hidden(_attribute) = false
50
+
39
51
  def permitted_attributes_for_ransack
40
52
  record.class.column_names + record.class._ransackers.keys
41
53
  end
@@ -7,7 +7,8 @@
7
7
  <%# locals: (form:, form_field:,readonly:nil) -%>
8
8
  <%
9
9
  input_group_classes = ["mb-1"]
10
- content = form_print_field(form, form_field, readonly: readonly)
10
+ renderer = form_print_field_object(form, form_field, readonly: readonly)
11
+ content = renderer.render
11
12
  unless content.match "checkbox"
12
13
  input_group_classes << "input-group"
13
14
  end
@@ -18,7 +19,11 @@
18
19
  if content.match "form-switch"
19
20
  label_content = nil
20
21
  else
21
- label_content = form.label(form_field, class: ["form-label", "form-#{form_field}-label"])
22
+ if renderer.type == :belongs_to
23
+ label_content = form.label(renderer.locals[:foreign_key], class: ["form-label", "form-#{form_field}-label"] )
24
+ else
25
+ label_content = form.label(form_field, class: ["form-label", "form-#{form_field}-label"])
26
+ end
22
27
  end
23
28
 
24
29
  %>
@@ -1,3 +1,3 @@
1
- <div class="mb-3">
1
+ <div class="mb-3 <%= dom_class(form.object,"form_field_container_#{form_field}") %>">
2
2
  <%= yield %>
3
3
  </div>
@@ -7,7 +7,13 @@
7
7
  <%= render partial: "form_field_header", locals: {form:} %>
8
8
  <%= render partial: "form_base_errors", locals: {form:} if form.object.errors.key?(:base) %>
9
9
  <%= render layout: "form_fields_container" do %>
10
- <%= render collection: form_attributes(form.object),
10
+
11
+ <% hidden_fields = form_attributes(form.object).select { |field| hidden_attribute?(field) } %>
12
+ <% hidden_fields.each do |form_field| %>
13
+ <%= form.hidden_field(form_field) %>
14
+ <% end %>
15
+
16
+ <%= render collection: form_attributes(form.object) - hidden_fields,
11
17
  layout: "form_field_container",
12
18
  partial: "form_field", locals: {form:, readonly: readonly} %>
13
19
  <% end %>
@@ -1,6 +1,9 @@
1
1
  <%# locals: (form:, field:) -%>
2
2
  <%
3
- is_attached = form.object.send(field).attached?
3
+ attachment = form.object.send(field)
4
+ is_attached = attachment.attached?
5
+ blob = attachment.attachment&.blob
6
+ is_persisted_blob = blob&.persisted?
4
7
  hidden_field_id = dom_id(form.object, "hidden_#{field}")
5
8
  preview_image_id = dom_id(form.object, "preview_image_#{field}")
6
9
  filename_id = dom_id(form.object, "filename_#{field}")
@@ -13,22 +16,22 @@
13
16
  JAVASCRIPT
14
17
 
15
18
  %>
16
- <div class="d-flex">
17
- <%= form.hidden_field field, value: form.object.send(field).signed_id, id: hidden_field_id if is_attached %>
19
+ <div class="d-flex <%= form.object.errors.include?(field) ? "is-invalid" : "" %>">
20
+ <%= form.hidden_field field, value: attachment.signed_id, id: hidden_field_id if is_attached && is_persisted_blob %>
18
21
 
19
22
  <%= form.file_field field, direct_upload: true %>
20
23
 
21
24
  <% if is_attached %>
22
25
 
23
- <%= content_tag :span, form.object.send(field).attachment.blob.filename, class: "input-group-text flex-grow-1", id: filename_id %>
26
+ <%= content_tag :span, blob.filename, class: "input-group-text flex-grow-1", id: filename_id if blob.present? %>
24
27
  <%= content_tag :button, icon(:trash),
25
28
  onclick: javascript_clear_event,
26
29
  class: "btn btn-outline-secondary rounded-0" %>
27
- <%= link_to icon(:download), form.object.send(field), class: "btn btn-outline-secondary", target: :_blank %>
30
+ <%= link_to icon(:download), attachment, class: "btn btn-outline-secondary", target: :_blank if is_persisted_blob %>
28
31
 
29
- <% if form.object.send(field).representable? %>
32
+ <% if is_persisted_blob && attachment.representable? %>
30
33
  <% content_for :form_field_ending, flush: true do %>
31
- <%= content_tag :div, image_tag(form.object.send(field).representation(resize_to_limit: [100, 100])), id: preview_image_id %>
34
+ <%= content_tag :div, image_tag(attachment.representation(resize_to_limit: [100, 100])), id: preview_image_id %>
32
35
  <% end %>
33
36
  <% end %>
34
37
  <% end %>
@@ -1 +1 @@
1
- 1.15.1
1
+ 1.16.0
@@ -60,6 +60,8 @@ module BaseEditingBootstrap::Forms
60
60
  label = options.extract!(:label)[:label] || nil
61
61
  if label
62
62
  label_tag = label(label, class: "form-check-label")
63
+ elsif block_given?
64
+ label_tag = yield
63
65
  else
64
66
  label_tag = nil
65
67
  end
@@ -0,0 +1,129 @@
1
+ module BaseEditingBootstrap::Forms
2
+ # Responsible for deciding which template and locals to use for form fields
3
+ # Usage: Utilities::FormFieldRenderer.new(view_context, form, field, readonly:).render
4
+ class FieldRenderer
5
+ attr_reader :view, :form, :field, :locals, :type, :generic_field
6
+
7
+ def initialize(view, form, field, readonly: nil)
8
+ @view = view
9
+ @form = form
10
+ @field = field
11
+ @readonly = readonly
12
+ @locals = { form: form, field: field }
13
+ @type = nil
14
+ @generic_field = nil
15
+ determine_field_and_locals
16
+ end
17
+
18
+ # Perform full rendering and return SafeBuffer
19
+ def render
20
+ tmpl = template
21
+ view.bs_logger.debug do
22
+ <<~TEXT
23
+ TYPE: #{type}
24
+ GENERIC_FIELD: #{generic_field}
25
+ TEMPLATE: #{tmpl.short_identifier}
26
+ LOCALS:#{locals}
27
+ TEXT
28
+ end
29
+ tmpl.render(view, locals)
30
+ end
31
+
32
+ # Public helpers for tests or external callers
33
+ def template
34
+ view.find_template_with_fallbacks(
35
+ form.object,
36
+ field,
37
+ "form_field",
38
+ generic_field,
39
+ readonly: readonly_value
40
+ )
41
+ end
42
+
43
+ def readonly_value
44
+ @readonly.nil? ? view.readonly_attribute?(field, form.object) : @readonly
45
+ end
46
+
47
+ private
48
+
49
+ def determine_field_and_locals
50
+ if form.object.class.respond_to?(:field_to_form_partial) &&
51
+ (generic = form.object.class.field_to_form_partial(field)
52
+ )
53
+ @type = :custom
54
+ @generic_field = generic
55
+ elsif form.object.class.respond_to?(:defined_enums) && form.object.class.defined_enums.key?(field.to_s)
56
+ @type = :enum
57
+ @generic_field = "enum"
58
+ elsif belongs_to_reflection?
59
+ reflection = form.object.class.reflect_on_association(field.to_s)
60
+ @type = :belongs_to
61
+ @generic_field = "belongs_to_select"
62
+ locals[:relation_class] = reflection.klass
63
+ locals[:foreign_key] = reflection.foreign_key
64
+ elsif nested_attributes?
65
+ @type = :nested_attributes
66
+ reflection = form.object.class.reflect_on_association(field.to_s)
67
+ case reflection
68
+ when ActiveRecord::Reflection::HasManyReflection
69
+ locals[:new_object] = reflection.klass.new(reflection.foreign_key => form.object)
70
+ @generic_field = "accept_has_many_nested_field"
71
+ when ActiveRecord::Reflection::HasOneReflection
72
+ form.object.send(:"build_#{field}") unless form.object.send(field).present?
73
+ @generic_field = "accept_has_one_nested_field"
74
+ else
75
+ raise "Unknown reflection for nested attributes #{field}->#{reflection.class}"
76
+ end
77
+ else
78
+ determine_by_attribute_type
79
+ end
80
+ end
81
+
82
+ def belongs_to_reflection?
83
+ form.object.class.respond_to?(:reflect_on_association) &&
84
+ (ref = form.object.class.reflect_on_association(field.to_s)).is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
85
+ !ref.polymorphic?
86
+ end
87
+
88
+ def nested_attributes?
89
+ form.object.class.respond_to?(:nested_attributes_options) &&
90
+ form.object.class.nested_attributes_options.key?(field.to_sym)
91
+ end
92
+
93
+ def determine_by_attribute_type
94
+ if form.object.class.respond_to?(:type_for_attribute)
95
+ @type = form.object.class.type_for_attribute(field).type
96
+
97
+ # If nil, check for single attachment
98
+ if @type.nil? && form.object.respond_to?(:"#{field}_attachment")
99
+ @type = :has_one_attachment
100
+ end
101
+ else
102
+ @type = :string
103
+ end
104
+
105
+ case type
106
+ when :datetime
107
+ @generic_field = "datetime"
108
+ when :date
109
+ @generic_field = "date"
110
+ when :decimal
111
+ locals[:scale] = form.object.class.type_for_attribute(field).scale || 2
112
+ @generic_field = "decimal"
113
+ when :float
114
+ locals[:scale] = 2
115
+ @generic_field = "decimal"
116
+ when :integer
117
+ @generic_field = "integer"
118
+ when :boolean
119
+ @generic_field = "boolean"
120
+ when :has_one_attachment
121
+ @generic_field = "has_one_attachment"
122
+ when :text
123
+ @generic_field = "textarea"
124
+ else
125
+ @generic_field = "base"
126
+ end
127
+ end
128
+ end
129
+ end
@@ -114,7 +114,7 @@ RSpec.shared_examples "base editing controller" do |factory: nil, only: [], exce
114
114
  params = {q: {"foo_eq": "foo"}}
115
115
  get url_for_index, params: params
116
116
  expect(response).to have_http_status(200)
117
- expect(assigns[:search_instance]).to be_an_instance_of(BaseEditingBootstrap::Searches::Base)
117
+ expect(assigns[:search_instance]).to be_a(BaseEditingBootstrap::Searches::Base)
118
118
  .and(have_attributes(
119
119
  user: user,
120
120
  params: ActionController::Parameters.new(params).permit!,
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: 1.15.1
4
+ version: 1.16.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: 2026-04-13 00:00:00.000000000 Z
11
+ date: 2026-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -313,6 +313,7 @@ executables: []
313
313
  extensions: []
314
314
  extra_rdoc_files: []
315
315
  files:
316
+ - AGENTS.md
316
317
  - CHANGELOG.md
317
318
  - CODE_OF_CONDUCT.md
318
319
  - LICENSE.txt
@@ -413,6 +414,7 @@ files:
413
414
  - lib/base_editing_bootstrap/base_model.rb
414
415
  - lib/base_editing_bootstrap/engine.rb
415
416
  - lib/base_editing_bootstrap/forms/base.rb
417
+ - lib/base_editing_bootstrap/forms/field_renderer.rb
416
418
  - lib/base_editing_bootstrap/generators_helpers.rb
417
419
  - lib/base_editing_bootstrap/is_validated.rb
418
420
  - lib/base_editing_bootstrap/logging.rb