easy-admin-rails 0.1.9 → 0.1.11

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: d516d9564b3e2e33581e101ed5f5fed1fb294407f6de918e2532a3fcef1acea5
4
- data.tar.gz: f3f23ffc0489acddce45c29f4324d38397e088fc4b7fc872fb06ed6cf4d07c64
3
+ metadata.gz: 0fae1a9ba75446f8dc4e7992b6f1ff01fb30a06d081de559df45ad8fb6c2a504
4
+ data.tar.gz: a157543ef039c9c75057eb66baef77ef7cd81b46462b49809611aab679ab1793
5
5
  SHA512:
6
- metadata.gz: 3632ce6f54bb99a75db6a45471f53f01eb34c132480367f84017c90ab45f4605527f2a87f89a4446e41ff3182decf590c9df0e3d6178034cc713421b41d30ff6
7
- data.tar.gz: 20b25f16081adfd5eea8cbbf62d96c35aee0b38da356befed86132d576d20819c9985987ae1d04e557f49b61964492f2c714b1fe9dca981c4867b9dce8051d60
6
+ metadata.gz: 26f11cd96fd9e5c390adc97c948a576bc2d6c9c09c9f15fb432082ecc321846cdbcd89d6ae4c19fe92624275cb998974bd3fa82adb968109ea5aa7db653ad66e
7
+ data.tar.gz: 05b41e08e8e519c6aca2dd6d7f3a19b8da10b47ba8b484852f1069bcbfd34e938b65123e1ed291708a588101316e5ae091e200053668787e839df32b52844f05
@@ -78,6 +78,29 @@ module EasyAdmin
78
78
  classes.join(" ")
79
79
  end
80
80
 
81
+ def field_errors
82
+ return [] unless form&.object&.errors
83
+ form.object.errors[field_name]
84
+ end
85
+
86
+ def has_field_errors?
87
+ field_errors.any?
88
+ end
89
+
90
+ def render_field_errors
91
+ return unless has_field_errors?
92
+
93
+ div(class: "mt-1") do
94
+ field_errors.each do |error|
95
+ p(class: "text-red-600 text-sm") { error }
96
+ end
97
+ end
98
+ end
99
+
100
+ def input_error_classes
101
+ has_field_errors? ? "border-red-300 focus:border-red-500 focus:ring-red-500" : ""
102
+ end
103
+
81
104
  def format_value(val = value)
82
105
  return "" if val.blank?
83
106
 
@@ -17,7 +17,18 @@ module EasyAdmin
17
17
 
18
18
  # Override to handle belongs_to association field name
19
19
  def association_key
20
- # Convert belongs_to association name to foreign key
20
+ # If field specifies a custom foreign_key, use that
21
+ if field[:foreign_key]
22
+ return field[:foreign_key]
23
+ end
24
+
25
+ # If field specifies an association, get the foreign key from Rails reflection
26
+ if field[:association]
27
+ reflection = form.object.class.reflect_on_association(field[:association])
28
+ return reflection.foreign_key if reflection
29
+ end
30
+
31
+ # Default behavior: Convert field name to foreign key
21
32
  # e.g., user -> user_id, category -> category_id
22
33
  if field_name.to_s.end_with?('_id')
23
34
  field_name
@@ -74,6 +85,28 @@ module EasyAdmin
74
85
  current_value.present? ? [current_value] : []
75
86
  end
76
87
 
88
+ # Override to get current display value for suggest mode
89
+ def current_display_value
90
+ # Get the associated record
91
+ association_name = field[:association] || field_name
92
+ associated_record = form.object.public_send(association_name) if form.object.respond_to?(association_name)
93
+
94
+ return "" unless associated_record
95
+
96
+ # Determine how to display the associated record
97
+ if field[:display_method]
98
+ associated_record.public_send(field[:display_method])
99
+ elsif associated_record.respond_to?(:name)
100
+ associated_record.name
101
+ elsif associated_record.respond_to?(:title)
102
+ associated_record.title
103
+ elsif associated_record.respond_to?(:to_label)
104
+ associated_record.to_label
105
+ else
106
+ "##{associated_record.id}"
107
+ end
108
+ end
109
+
77
110
  # Override to ensure hidden input uses the foreign key value
78
111
  def render_hidden_inputs
79
112
  # Single select - one hidden input with foreign key value
@@ -20,6 +20,7 @@ module EasyAdmin
20
20
 
21
21
  render_toggle_switch
22
22
  end
23
+ render_field_errors
23
24
  end
24
25
  end
25
26
 
@@ -18,6 +18,7 @@ module EasyAdmin
18
18
  class: input_classes,
19
19
  required: required?
20
20
  )
21
+ render_field_errors
21
22
  if field[:help_text]
22
23
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
23
24
  end
@@ -32,8 +33,8 @@ module EasyAdmin
32
33
 
33
34
  def input_classes
34
35
  base_classes = "block w-full px-3 py-2 border rounded-md shadow-sm text-sm"
35
- state_classes = "border-gray-300 placeholder-gray-400"
36
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
36
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400" : "border-gray-300 placeholder-gray-400"
37
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
37
38
  hover_classes = "hover:border-gray-400"
38
39
  transition_classes = "transition-colors duration-200"
39
40
 
@@ -18,6 +18,7 @@ module EasyAdmin
18
18
  class: input_classes,
19
19
  required: required?
20
20
  )
21
+ render_field_errors
21
22
  if field[:help_text]
22
23
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
23
24
  end
@@ -32,8 +33,8 @@ module EasyAdmin
32
33
 
33
34
  def input_classes
34
35
  base_classes = "block w-full px-3 py-2 border rounded-md shadow-sm text-sm"
35
- state_classes = "border-gray-300 placeholder-gray-400"
36
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
36
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400" : "border-gray-300 placeholder-gray-400"
37
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
37
38
  hover_classes = "hover:border-gray-400"
38
39
  transition_classes = "transition-colors duration-200"
39
40
 
@@ -19,6 +19,7 @@ module EasyAdmin
19
19
  required: required?,
20
20
  placeholder: field[:placeholder] || "Enter #{field_label.downcase}"
21
21
  )
22
+ render_field_errors
22
23
  if field[:help_text]
23
24
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
24
25
  end
@@ -33,8 +34,8 @@ module EasyAdmin
33
34
 
34
35
  def input_classes
35
36
  base_classes = "block w-full px-3 py-2 border rounded-md shadow-sm text-sm"
36
- state_classes = "border-gray-300 placeholder-gray-400"
37
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
37
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400" : "border-gray-300 placeholder-gray-400"
38
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
38
39
  hover_classes = "hover:border-gray-400"
39
40
  transition_classes = "transition-colors duration-200"
40
41
 
@@ -8,6 +8,7 @@ module EasyAdmin
8
8
  div(class: "mb-6", data: { controller: "file" }) do
9
9
  render_label if field_label
10
10
  render_file_input
11
+ render_field_errors
11
12
  render_preview_area
12
13
  render_help_text if field[:help_text]
13
14
  render_current_file if current_file_exists?
@@ -28,7 +29,7 @@ module EasyAdmin
28
29
  type: "file",
29
30
  id: field_id,
30
31
  name: form_field_name,
31
- class: css_classes("block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 file:me-4 file:py-2 file:px-4 file:rounded-s-lg file:border-0 file:text-sm file:font-medium file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100", size_class, validation_classes),
32
+ class: css_classes("block w-full text-sm text-gray-900 border rounded-lg cursor-pointer bg-gray-50 file:me-4 file:py-2 file:px-4 file:rounded-s-lg file:border-0 file:text-sm file:font-medium file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100", size_class, file_input_error_classes),
32
33
  data: { file_target: "input" },
33
34
  **file_input_attributes
34
35
  )
@@ -112,13 +113,11 @@ module EasyAdmin
112
113
  end
113
114
  end
114
115
 
115
- def validation_classes
116
- return "" unless form&.object&.errors
117
-
118
- if form.object.errors[field_name].any?
119
- "border-red-300 focus:border-red-500 focus:ring-red-500"
116
+ def file_input_error_classes
117
+ if has_field_errors?
118
+ "border-red-300 focus:border-red-500 focus:ring-2 focus:ring-red-500"
120
119
  else
121
- ""
120
+ "border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
122
121
  end
123
122
  end
124
123
 
@@ -19,6 +19,7 @@ module EasyAdmin
19
19
  required: required?,
20
20
  placeholder: field[:placeholder] || "Enter #{field_label.downcase}"
21
21
  )
22
+ render_field_errors
22
23
  if field[:help_text]
23
24
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
24
25
  end
@@ -33,8 +34,8 @@ module EasyAdmin
33
34
 
34
35
  def input_classes
35
36
  base_classes = "block w-full px-3 py-2 border rounded-md shadow-sm text-sm"
36
- state_classes = "border-gray-300 placeholder-gray-400"
37
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
37
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400" : "border-gray-300 placeholder-gray-400"
38
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
38
39
  hover_classes = "hover:border-gray-400"
39
40
  transition_classes = "transition-colors duration-200"
40
41
 
@@ -32,6 +32,7 @@ module EasyAdmin
32
32
  render_hidden_inputs
33
33
  end
34
34
 
35
+ render_field_errors
35
36
  if field[:help_text]
36
37
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
37
38
  end
@@ -91,7 +92,8 @@ module EasyAdmin
91
92
  end
92
93
 
93
94
  def render_multiple_select_container
94
- div(class: "relative border border-gray-300 rounded-md bg-white min-h-10 focus-within:ring-1 focus-within:ring-blue-500 focus-within:border-blue-500 transition-colors duration-200") do
95
+ error_classes = has_field_errors? ? "border-red-300 focus-within:ring-red-500 focus-within:border-red-500" : "border-gray-300 focus-within:ring-blue-500 focus-within:border-blue-500"
96
+ div(class: "relative border #{error_classes} rounded-md bg-white min-h-10 focus-within:ring-1 transition-colors duration-200") do
95
97
  div(class: "flex flex-wrap items-center gap-1 p-2 pr-8") do
96
98
  # Selected items container - will be populated by Stimulus controller
97
99
  div(class: "flex flex-wrap items-center gap-1", data: { select_field_target: "selectedItems" }) do
@@ -133,7 +135,7 @@ module EasyAdmin
133
135
  class: single_select_input_classes,
134
136
  placeholder: suggest_mode? ? placeholder : (field[:placeholder] || "Select #{field_label.downcase}..."),
135
137
  readonly: !suggest_mode?,
136
- value: suggest_mode? ? "" : current_display_value,
138
+ value: current_display_value,
137
139
  data: suggest_mode? ? {
138
140
  select_field_target: "search",
139
141
  action: "input->select-field#filter keydown->select-field#handleKeydown focus->select-field#openDropdown"
@@ -163,8 +165,8 @@ module EasyAdmin
163
165
 
164
166
  def single_select_input_classes
165
167
  base_classes = "block w-full px-3 py-2 pr-10 text-sm border rounded-md cursor-pointer"
166
- state_classes = "border-gray-300 placeholder-gray-400 bg-white"
167
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
168
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400 bg-white" : "border-gray-300 placeholder-gray-400 bg-white"
169
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
168
170
  hover_classes = "hover:border-gray-400"
169
171
  transition_classes = "transition-colors duration-200"
170
172
 
@@ -19,6 +19,7 @@ module EasyAdmin
19
19
  required: required?,
20
20
  placeholder: field[:placeholder] || "Enter #{field_label.downcase}"
21
21
  )
22
+ render_field_errors
22
23
  if field[:help_text]
23
24
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
24
25
  end
@@ -33,8 +34,8 @@ module EasyAdmin
33
34
 
34
35
  def input_classes
35
36
  base_classes = "block w-full px-3 py-2 border rounded-md shadow-sm text-sm"
36
- state_classes = "border-gray-300 placeholder-gray-400"
37
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
37
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400" : "border-gray-300 placeholder-gray-400"
38
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
38
39
  hover_classes = "hover:border-gray-400"
39
40
  transition_classes = "transition-colors duration-200"
40
41
 
@@ -18,6 +18,7 @@ module EasyAdmin
18
18
  rows: field[:rows] || 4,
19
19
  placeholder: field[:placeholder] || "Enter #{field_label.downcase}"
20
20
  ) { current_value }
21
+ render_field_errors
21
22
  if field[:help_text]
22
23
  p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
23
24
  end
@@ -32,8 +33,8 @@ module EasyAdmin
32
33
 
33
34
  def textarea_classes
34
35
  base_classes = "block w-full px-3 py-2 border rounded-md shadow-sm text-sm resize-y"
35
- state_classes = "border-gray-300 placeholder-gray-400"
36
- focus_classes = "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
36
+ state_classes = has_field_errors? ? "border-red-300 placeholder-red-400" : "border-gray-300 placeholder-gray-400"
37
+ focus_classes = has_field_errors? ? "focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500" : "focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
37
38
  hover_classes = "hover:border-gray-400"
38
39
  transition_classes = "transition-colors duration-200"
39
40
 
@@ -151,7 +151,7 @@ module EasyAdmin
151
151
  redirect_to easy_admin.resource_path(@resource_class.route_key, @record),
152
152
  notice: "#{@resource_class.singular_title} was successfully created."
153
153
  else
154
- render :new
154
+ render :new, status: :unprocessable_entity
155
155
  end
156
156
  end
157
157
 
@@ -182,7 +182,7 @@ module EasyAdmin
182
182
  }
183
183
  end
184
184
  else
185
- render :edit
185
+ render :edit, status: :unprocessable_entity
186
186
  end
187
187
  end
188
188
 
@@ -231,18 +231,21 @@ module EasyAdmin
231
231
  return
232
232
  end
233
233
 
234
+ # Determine the correct parameter key (handle complex model names)
235
+ param_key = determine_param_key_for_update_field
236
+
234
237
  # For belongs_to fields, we need to handle foreign key updates
235
238
  if @field_config[:type] == :belongs_to
236
239
  association_name = @field_config[:name]
237
240
  foreign_key = get_foreign_key_name(association_name)
238
- field_value = params.dig(@resource_class.param_key, foreign_key)
241
+ field_value = params.dig(param_key, foreign_key)
239
242
  update_attrs = { foreign_key.to_sym => field_value }
240
243
  else
241
244
  # Create a field object to handle normalization
242
245
  field_obj = EasyAdmin::Field.new(@field_name, @field_config[:type], @field_config)
243
246
 
244
247
  # Get the field value from params
245
- field_value = params.dig(@resource_class.param_key, @field_name)
248
+ field_value = params.dig(param_key, @field_name)
246
249
 
247
250
  # Normalize the input
248
251
  update_attrs = { @field_name => field_value }
@@ -913,5 +916,18 @@ module EasyAdmin
913
916
  params[:period].present? ||
914
917
  (params[:scope].present? && params[:scope] != determine_current_scope[:scope])
915
918
  end
919
+
920
+ def determine_param_key_for_update_field
921
+ # Try resource param_key first, then fall back to model's natural param key
922
+ if params.key?(@resource_class.param_key)
923
+ @resource_class.param_key
924
+ elsif params.key?(@resource_class.model_class.model_name.param_key)
925
+ @resource_class.model_class.model_name.param_key
926
+ else
927
+ # Handle namespaced models that use slash format (e.g., "catalog/payment_method")
928
+ namespaced_param_key = @resource_class.model_class.name.underscore
929
+ params.key?(namespaced_param_key) ? namespaced_param_key : @resource_class.param_key
930
+ end
931
+ end
916
932
  end
917
933
  end
@@ -1,3 +1,3 @@
1
1
  module EasyAdmin
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.11"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy-admin-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Slaurmagan