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 +4 -4
- data/app/components/easy_admin/fields/base_component.rb +23 -0
- data/app/components/easy_admin/fields/form/belongs_to_component.rb +34 -1
- data/app/components/easy_admin/fields/form/boolean_component.rb +1 -0
- data/app/components/easy_admin/fields/form/date_component.rb +3 -2
- data/app/components/easy_admin/fields/form/datetime_component.rb +3 -2
- data/app/components/easy_admin/fields/form/email_component.rb +3 -2
- data/app/components/easy_admin/fields/form/file_component.rb +6 -7
- data/app/components/easy_admin/fields/form/number_component.rb +3 -2
- data/app/components/easy_admin/fields/form/select_component.rb +6 -4
- data/app/components/easy_admin/fields/form/text_component.rb +3 -2
- data/app/components/easy_admin/fields/form/textarea_component.rb +3 -2
- data/app/controllers/easy_admin/resources_controller.rb +20 -4
- data/lib/easy_admin/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fae1a9ba75446f8dc4e7992b6f1ff01fb30a06d081de559df45ad8fb6c2a504
|
4
|
+
data.tar.gz: a157543ef039c9c75057eb66baef77ef7cd81b46462b49809611aab679ab1793
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
#
|
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
|
@@ -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
|
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
|
116
|
-
|
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
|
-
|
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:
|
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(
|
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(
|
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
|
data/lib/easy_admin/version.rb
CHANGED