admin_suite 0.2.1 → 0.2.3
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/assets/admin_suite.css +129 -0
- data/app/controllers/admin_suite/application_controller.rb +31 -0
- data/app/controllers/admin_suite/dashboard_controller.rb +59 -226
- data/app/controllers/admin_suite/resources_controller.rb +14 -4
- data/app/helpers/admin_suite/base_helper.rb +147 -108
- data/app/helpers/admin_suite/panels_helper.rb +1 -1
- data/app/javascript/controllers/admin_suite/file_upload_controller.js +9 -9
- data/app/javascript/controllers/admin_suite/flash_controller.js +45 -0
- data/app/javascript/controllers/admin_suite/json_editor_controller.js +8 -8
- data/app/javascript/controllers/admin_suite/searchable_select_controller.js +2 -2
- data/app/javascript/controllers/admin_suite/tag_select_controller.js +1 -1
- data/app/javascript/controllers/admin_suite/toggle_switch_controller.js +25 -16
- data/app/views/admin_suite/dashboard/index.html.erb +6 -15
- data/app/views/admin_suite/panels/_cards.html.erb +6 -6
- data/app/views/admin_suite/panels/_chart.html.erb +12 -12
- data/app/views/admin_suite/panels/_health.html.erb +14 -14
- data/app/views/admin_suite/panels/_recent.html.erb +11 -11
- data/app/views/admin_suite/panels/_stat.html.erb +24 -24
- data/app/views/admin_suite/panels/_table.html.erb +10 -10
- data/app/views/admin_suite/portals/show.html.erb +1 -1
- data/app/views/admin_suite/resources/_form.html.erb +1 -1
- data/app/views/admin_suite/resources/edit.html.erb +4 -4
- data/app/views/admin_suite/resources/index.html.erb +23 -23
- data/app/views/admin_suite/resources/new.html.erb +4 -4
- data/app/views/admin_suite/resources/show.html.erb +17 -17
- data/app/views/admin_suite/shared/_flash.html.erb +15 -2
- data/app/views/admin_suite/shared/_form.html.erb +8 -8
- data/app/views/admin_suite/shared/_json_editor_field.html.erb +4 -4
- data/app/views/admin_suite/shared/_sidebar.html.erb +4 -4
- data/app/views/admin_suite/shared/_toggle_cell.html.erb +4 -2
- data/app/views/admin_suite/shared/_topbar.html.erb +14 -1
- data/app/views/layouts/admin_suite/application.html.erb +4 -4
- data/docs/configuration.md +55 -0
- data/docs/portals.md +42 -0
- data/lib/admin_suite/configuration.rb +16 -0
- data/lib/admin_suite/engine.rb +9 -0
- data/lib/admin_suite/ui/field_renderer_registry.rb +2 -2
- data/lib/admin_suite/ui/form_field_renderer.rb +2 -2
- data/lib/admin_suite/ui/show_formatter_registry.rb +5 -5
- data/lib/admin_suite/ui/show_value_formatter.rb +31 -3
- data/lib/admin_suite/version.rb +1 -1
- data/lib/admin_suite.rb +31 -0
- data/lib/generators/admin_suite/install/templates/admin_suite.rb +5 -0
- data/test/integration/dashboard_test.rb +57 -1
- metadata +7 -5
- data/test/dummy/log/test.log +0 -624
- data/test/dummy/tmp/local_secret.txt +0 -1
|
@@ -28,6 +28,45 @@ module AdminSuite
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# Logout path/method/label in the topbar are host-configurable.
|
|
32
|
+
def admin_suite_logout_path
|
|
33
|
+
value = AdminSuite.config.respond_to?(:logout_path) ? AdminSuite.config.logout_path : nil
|
|
34
|
+
resolve_admin_suite_view_config(value).presence
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def admin_suite_logout_method
|
|
38
|
+
value = AdminSuite.config.respond_to?(:logout_method) ? AdminSuite.config.logout_method : :delete
|
|
39
|
+
resolved = resolve_admin_suite_view_config(value)
|
|
40
|
+
resolved = resolved.to_sym if resolved.respond_to?(:to_sym)
|
|
41
|
+
resolved.presence || :delete
|
|
42
|
+
rescue StandardError
|
|
43
|
+
:delete
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def admin_suite_logout_label
|
|
47
|
+
value = AdminSuite.config.respond_to?(:logout_label) ? AdminSuite.config.logout_label : nil
|
|
48
|
+
resolved = resolve_admin_suite_view_config(value)
|
|
49
|
+
resolved.to_s.presence || "Log out"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def resolve_admin_suite_view_config(value)
|
|
53
|
+
return nil if value.nil?
|
|
54
|
+
|
|
55
|
+
if value.respond_to?(:call)
|
|
56
|
+
return value.call if value.arity.zero?
|
|
57
|
+
return value.call(self)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if value.is_a?(Symbol)
|
|
61
|
+
return nil unless respond_to?(value, true)
|
|
62
|
+
return public_send(value)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
value
|
|
66
|
+
rescue StandardError
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
|
|
31
70
|
# Lookup the DSL field definition for a given attribute (if present).
|
|
32
71
|
#
|
|
33
72
|
# Used to render show values with type awareness (e.g. markdown/json/label).
|
|
@@ -130,7 +169,7 @@ module AdminSuite
|
|
|
130
169
|
content_tag(:span, class: "inline-flex items-center gap-1") do
|
|
131
170
|
svg = '<svg class="w-4 h-4 text-green-500" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>'.html_safe
|
|
132
171
|
concat(svg)
|
|
133
|
-
concat(content_tag(:span, "Yes", class: "text-green-600
|
|
172
|
+
concat(content_tag(:span, "Yes", class: "text-green-600 font-medium"))
|
|
134
173
|
end
|
|
135
174
|
when false
|
|
136
175
|
content_tag(:span, class: "inline-flex items-center gap-1") do
|
|
@@ -141,13 +180,13 @@ module AdminSuite
|
|
|
141
180
|
when Time, DateTime
|
|
142
181
|
content_tag(:span, class: "inline-flex items-center gap-2") do
|
|
143
182
|
concat(content_tag(:span, value.strftime("%B %d, %Y at %H:%M"), class: "font-medium"))
|
|
144
|
-
concat(content_tag(:span, "(#{time_ago_in_words(value)} ago)", class: "text-slate-500
|
|
183
|
+
concat(content_tag(:span, "(#{time_ago_in_words(value)} ago)", class: "text-slate-500 text-xs"))
|
|
145
184
|
end
|
|
146
185
|
when Date
|
|
147
186
|
value.strftime("%B %d, %Y")
|
|
148
187
|
when ActiveRecord::Base
|
|
149
188
|
link_text = value.respond_to?(:name) ? value.name : "#{value.class.name} ##{value.id}"
|
|
150
|
-
content_tag(:span, link_text, class: "text-indigo-600
|
|
189
|
+
content_tag(:span, link_text, class: "text-indigo-600")
|
|
151
190
|
when Hash
|
|
152
191
|
render_json_block(value)
|
|
153
192
|
when Array
|
|
@@ -158,7 +197,7 @@ module AdminSuite
|
|
|
158
197
|
else
|
|
159
198
|
content_tag(:div, class: "flex flex-wrap gap-1") do
|
|
160
199
|
value.each do |item|
|
|
161
|
-
concat(content_tag(:span, item.to_s, class: "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-slate-100
|
|
200
|
+
concat(content_tag(:span, item.to_s, class: "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-slate-100 text-slate-700"))
|
|
162
201
|
end
|
|
163
202
|
end
|
|
164
203
|
end
|
|
@@ -197,27 +236,27 @@ module AdminSuite
|
|
|
197
236
|
end
|
|
198
237
|
|
|
199
238
|
content_tag(:div, class: "space-y-2") do
|
|
200
|
-
concat(content_tag(:div, class: "inline-block rounded-lg overflow-hidden border border-slate-200
|
|
239
|
+
concat(content_tag(:div, class: "inline-block rounded-lg overflow-hidden border border-slate-200") do
|
|
201
240
|
image_tag(variant_url,
|
|
202
241
|
class: "max-w-full h-auto max-h-64 object-contain",
|
|
203
242
|
alt: blob.filename.to_s)
|
|
204
243
|
end)
|
|
205
|
-
concat(content_tag(:div, class: "flex items-center gap-3 text-sm text-slate-500
|
|
206
|
-
concat(content_tag(:span, blob.filename.to_s, class: "font-medium text-slate-700
|
|
244
|
+
concat(content_tag(:div, class: "flex items-center gap-3 text-sm text-slate-500") do
|
|
245
|
+
concat(content_tag(:span, blob.filename.to_s, class: "font-medium text-slate-700"))
|
|
207
246
|
concat(content_tag(:span, "•"))
|
|
208
247
|
concat(content_tag(:span, number_to_human_size(blob.byte_size)))
|
|
209
248
|
concat(content_tag(:span, "•"))
|
|
210
|
-
concat(link_to("View full size", admin_suite_rails_blob_path(blob, disposition: :inline), target: "_blank", class: "text-indigo-600
|
|
249
|
+
concat(link_to("View full size", admin_suite_rails_blob_path(blob, disposition: :inline), target: "_blank", class: "text-indigo-600 hover:underline"))
|
|
211
250
|
end)
|
|
212
251
|
end
|
|
213
252
|
else
|
|
214
|
-
content_tag(:div, class: "flex items-center gap-3 p-3 bg-slate-50
|
|
215
|
-
concat(content_tag(:div, class: "flex-shrink-0 w-10 h-10 bg-slate-200
|
|
253
|
+
content_tag(:div, class: "flex items-center gap-3 p-3 bg-slate-50 rounded-lg border border-slate-200") do
|
|
254
|
+
concat(content_tag(:div, class: "flex-shrink-0 w-10 h-10 bg-slate-200 rounded-lg flex items-center justify-center") do
|
|
216
255
|
'<svg class="w-5 h-5 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>'.html_safe
|
|
217
256
|
end)
|
|
218
257
|
concat(content_tag(:div, class: "flex-1 min-w-0") do
|
|
219
|
-
concat(content_tag(:p, blob.filename.to_s, class: "font-medium text-slate-700
|
|
220
|
-
concat(content_tag(:p, number_to_human_size(blob.byte_size), class: "text-sm text-slate-500
|
|
258
|
+
concat(content_tag(:p, blob.filename.to_s, class: "font-medium text-slate-700 truncate"))
|
|
259
|
+
concat(content_tag(:p, number_to_human_size(blob.byte_size), class: "text-sm text-slate-500"))
|
|
221
260
|
end)
|
|
222
261
|
concat(link_to("Download", admin_suite_rails_blob_path(blob, disposition: :attachment),
|
|
223
262
|
class: "flex-shrink-0 px-3 py-1.5 bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-medium rounded-lg transition-colors"))
|
|
@@ -240,11 +279,11 @@ module AdminSuite
|
|
|
240
279
|
|
|
241
280
|
content_tag(:div, class: "relative group") do
|
|
242
281
|
concat(content_tag(:div, class: "absolute top-2 right-2 flex items-center gap-2") do
|
|
243
|
-
concat(content_tag(:span, "JSON", class: "text-xs font-medium text-slate-400
|
|
282
|
+
concat(content_tag(:span, "JSON", class: "text-xs font-medium text-slate-400 uppercase tracking-wider"))
|
|
244
283
|
concat(content_tag(:button,
|
|
245
284
|
'<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>'.html_safe,
|
|
246
285
|
type: "button",
|
|
247
|
-
class: "p-1 text-slate-400 hover:text-slate-600
|
|
286
|
+
class: "p-1 text-slate-400 hover:text-slate-600 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
248
287
|
data: { controller: "admin-suite--clipboard", action: "click->admin-suite--clipboard#copy", "admin-suite--clipboard-text-value": json_str },
|
|
249
288
|
title: "Copy to clipboard"))
|
|
250
289
|
end)
|
|
@@ -260,11 +299,11 @@ module AdminSuite
|
|
|
260
299
|
def render_text_block(text, language = nil)
|
|
261
300
|
content_tag(:div, class: "relative group") do
|
|
262
301
|
concat(content_tag(:div, class: "absolute top-2 right-2 flex items-center gap-2") do
|
|
263
|
-
concat(content_tag(:span, language.to_s.upcase, class: "text-xs font-medium text-slate-400
|
|
302
|
+
concat(content_tag(:span, language.to_s.upcase, class: "text-xs font-medium text-slate-400 uppercase tracking-wider")) if language
|
|
264
303
|
concat(content_tag(:button,
|
|
265
304
|
'<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>'.html_safe,
|
|
266
305
|
type: "button",
|
|
267
|
-
class: "p-1 text-slate-400 hover:text-slate-600
|
|
306
|
+
class: "p-1 text-slate-400 hover:text-slate-600 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
268
307
|
data: { controller: "admin-suite--clipboard", action: "click->admin-suite--clipboard#copy", "admin-suite--clipboard-text-value": text },
|
|
269
308
|
title: "Copy to clipboard"))
|
|
270
309
|
end)
|
|
@@ -335,11 +374,11 @@ module AdminSuite
|
|
|
335
374
|
|
|
336
375
|
content_tag(:div, class: "relative group") do
|
|
337
376
|
concat(content_tag(:div, class: "absolute top-2 right-2 flex items-center gap-2") do
|
|
338
|
-
concat(content_tag(:span, "TEMPLATE", class: "text-xs font-medium text-slate-400
|
|
377
|
+
concat(content_tag(:span, "TEMPLATE", class: "text-xs font-medium text-slate-400 uppercase tracking-wider"))
|
|
339
378
|
concat(content_tag(:button,
|
|
340
379
|
'<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>'.html_safe,
|
|
341
380
|
type: "button",
|
|
342
|
-
class: "p-1 text-slate-400 hover:text-slate-600
|
|
381
|
+
class: "p-1 text-slate-400 hover:text-slate-600 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
343
382
|
data: { controller: "admin-suite--clipboard", action: "click->admin-suite--clipboard#copy", "admin-suite--clipboard-text-value": template },
|
|
344
383
|
title: "Copy to clipboard"))
|
|
345
384
|
end)
|
|
@@ -395,11 +434,11 @@ module AdminSuite
|
|
|
395
434
|
end
|
|
396
435
|
|
|
397
436
|
role_class = case role.to_s
|
|
398
|
-
when "user" then "bg-blue-50
|
|
399
|
-
when "assistant" then "bg-emerald-50
|
|
400
|
-
when "tool" then "bg-amber-50
|
|
401
|
-
when "system" then "bg-slate-50
|
|
402
|
-
else "bg-slate-50
|
|
437
|
+
when "user" then "bg-blue-50 border-blue-200"
|
|
438
|
+
when "assistant" then "bg-emerald-50 border-emerald-200"
|
|
439
|
+
when "tool" then "bg-amber-50 border-amber-200"
|
|
440
|
+
when "system" then "bg-slate-50 border-slate-200"
|
|
441
|
+
else "bg-slate-50 border-slate-200"
|
|
403
442
|
end
|
|
404
443
|
|
|
405
444
|
role_icon = case role.to_s
|
|
@@ -417,7 +456,7 @@ module AdminSuite
|
|
|
417
456
|
concat(content_tag(:div, class: "flex items-center justify-between mb-3") do
|
|
418
457
|
concat(content_tag(:div, class: "flex items-center gap-2") do
|
|
419
458
|
concat(role_icon)
|
|
420
|
-
concat(content_tag(:span, role.to_s.capitalize, class: "text-sm font-medium text-slate-700
|
|
459
|
+
concat(content_tag(:span, role.to_s.capitalize, class: "text-sm font-medium text-slate-700"))
|
|
421
460
|
end)
|
|
422
461
|
concat(content_tag(:div, class: "flex items-center gap-2 text-xs text-slate-400") do
|
|
423
462
|
concat(content_tag(:span, created_at.strftime("%H:%M:%S"))) if created_at.respond_to?(:strftime)
|
|
@@ -431,10 +470,10 @@ module AdminSuite
|
|
|
431
470
|
parsed = JSON.parse(content_str)
|
|
432
471
|
concat(render_json_block(parsed))
|
|
433
472
|
rescue JSON::ParserError
|
|
434
|
-
concat(content_tag(:div, simple_format(h(content_str)), class: "prose
|
|
473
|
+
concat(content_tag(:div, simple_format(h(content_str)), class: "prose prose-sm max-w-none"))
|
|
435
474
|
end
|
|
436
475
|
else
|
|
437
|
-
concat(content_tag(:div, simple_format(h(content_str)), class: "prose
|
|
476
|
+
concat(content_tag(:div, simple_format(h(content_str)), class: "prose prose-sm max-w-none"))
|
|
438
477
|
end
|
|
439
478
|
end)
|
|
440
479
|
end
|
|
@@ -448,7 +487,7 @@ module AdminSuite
|
|
|
448
487
|
|
|
449
488
|
content_tag(:div, class: "space-y-6") do
|
|
450
489
|
concat(content_tag(:div) do
|
|
451
|
-
concat(content_tag(:h4, "Arguments", class: "text-sm font-medium text-slate-500
|
|
490
|
+
concat(content_tag(:h4, "Arguments", class: "text-sm font-medium text-slate-500 mb-2"))
|
|
452
491
|
if args.present? && args != {}
|
|
453
492
|
concat(render_json_block(args))
|
|
454
493
|
else
|
|
@@ -457,17 +496,17 @@ module AdminSuite
|
|
|
457
496
|
end)
|
|
458
497
|
|
|
459
498
|
if result.present? && result != {}
|
|
460
|
-
concat(content_tag(:div, class: "pt-4 border-t border-slate-200
|
|
461
|
-
concat(content_tag(:h4, "Result", class: "text-sm font-medium text-slate-500
|
|
499
|
+
concat(content_tag(:div, class: "pt-4 border-t border-slate-200") do
|
|
500
|
+
concat(content_tag(:h4, "Result", class: "text-sm font-medium text-slate-500 mb-2"))
|
|
462
501
|
concat(render_json_block(result))
|
|
463
502
|
end)
|
|
464
503
|
end
|
|
465
504
|
|
|
466
505
|
if error.present?
|
|
467
|
-
concat(content_tag(:div, class: "pt-4 border-t border-slate-200
|
|
468
|
-
concat(content_tag(:h4, "Error", class: "text-sm font-medium text-red-500
|
|
469
|
-
concat(content_tag(:div, class: "bg-red-50
|
|
470
|
-
content_tag(:pre, h(error.to_s), class: "text-sm text-red-700
|
|
506
|
+
concat(content_tag(:div, class: "pt-4 border-t border-slate-200") do
|
|
507
|
+
concat(content_tag(:h4, "Error", class: "text-sm font-medium text-red-500 mb-2"))
|
|
508
|
+
concat(content_tag(:div, class: "bg-red-50 border border-red-200 rounded-lg p-4") do
|
|
509
|
+
content_tag(:pre, h(error.to_s), class: "text-sm text-red-700 whitespace-pre-wrap font-mono")
|
|
471
510
|
end)
|
|
472
511
|
end)
|
|
473
512
|
end
|
|
@@ -480,22 +519,22 @@ module AdminSuite
|
|
|
480
519
|
|
|
481
520
|
content_tag(:div, class: "space-y-4") do
|
|
482
521
|
if user_msg
|
|
483
|
-
concat(content_tag(:div, class: "rounded-lg border p-4 bg-blue-50
|
|
522
|
+
concat(content_tag(:div, class: "rounded-lg border p-4 bg-blue-50 border-blue-200") do
|
|
484
523
|
concat(content_tag(:div, class: "flex items-center gap-2 mb-2") do
|
|
485
524
|
concat('<svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>'.html_safe)
|
|
486
|
-
concat(content_tag(:span, "User", class: "text-sm font-medium text-slate-700
|
|
525
|
+
concat(content_tag(:span, "User", class: "text-sm font-medium text-slate-700"))
|
|
487
526
|
end)
|
|
488
|
-
concat(content_tag(:div, simple_format(h(user_msg.respond_to?(:content) ? user_msg.content.to_s : user_msg.to_s)), class: "prose
|
|
527
|
+
concat(content_tag(:div, simple_format(h(user_msg.respond_to?(:content) ? user_msg.content.to_s : user_msg.to_s)), class: "prose prose-sm max-w-none"))
|
|
489
528
|
end)
|
|
490
529
|
end
|
|
491
530
|
|
|
492
531
|
if asst_msg
|
|
493
|
-
concat(content_tag(:div, class: "rounded-lg border p-4 bg-emerald-50
|
|
532
|
+
concat(content_tag(:div, class: "rounded-lg border p-4 bg-emerald-50 border-emerald-200") do
|
|
494
533
|
concat(content_tag(:div, class: "flex items-center gap-2 mb-2") do
|
|
495
534
|
concat('<svg class="w-4 h-4 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"/></svg>'.html_safe)
|
|
496
|
-
concat(content_tag(:span, "Assistant", class: "text-sm font-medium text-slate-700
|
|
535
|
+
concat(content_tag(:span, "Assistant", class: "text-sm font-medium text-slate-700"))
|
|
497
536
|
end)
|
|
498
|
-
concat(content_tag(:div, simple_format(h(asst_msg.respond_to?(:content) ? asst_msg.content.to_s : asst_msg.to_s)), class: "prose
|
|
537
|
+
concat(content_tag(:div, simple_format(h(asst_msg.respond_to?(:content) ? asst_msg.content.to_s : asst_msg.to_s)), class: "prose prose-sm max-w-none"))
|
|
499
538
|
end)
|
|
500
539
|
end
|
|
501
540
|
|
|
@@ -536,19 +575,19 @@ module AdminSuite
|
|
|
536
575
|
def render_show_section(resource, section, position = :main)
|
|
537
576
|
is_association = section.association.present? && !resource.public_send(section.association).is_a?(ActiveRecord::Base) rescue false
|
|
538
577
|
|
|
539
|
-
content_tag(:div, class: "bg-white
|
|
578
|
+
content_tag(:div, class: "bg-white rounded-xl border border-slate-200 overflow-hidden") do
|
|
540
579
|
header_padding = position == :sidebar ? "px-4 py-2.5" : "px-6 py-3"
|
|
541
580
|
header_text_size = position == :sidebar ? "text-sm" : ""
|
|
542
|
-
header_border = is_association ? "" : "border-b border-slate-200
|
|
581
|
+
header_border = is_association ? "" : "border-b border-slate-200"
|
|
543
582
|
|
|
544
|
-
concat(content_tag(:div, class: "#{header_padding} #{header_border} bg-slate-50
|
|
545
|
-
concat(content_tag(:h3, section.title, class: "font-medium text-slate-900
|
|
583
|
+
concat(content_tag(:div, class: "#{header_padding} #{header_border} bg-slate-50 flex items-center justify-between") do
|
|
584
|
+
concat(content_tag(:h3, section.title, class: "font-medium text-slate-900 #{header_text_size}"))
|
|
546
585
|
|
|
547
586
|
if section.association.present?
|
|
548
587
|
assoc = resource.public_send(section.association) rescue nil
|
|
549
588
|
if assoc && !assoc.is_a?(ActiveRecord::Base)
|
|
550
589
|
count = assoc.count rescue 0
|
|
551
|
-
color_class = count > 0 ? "bg-indigo-100
|
|
590
|
+
color_class = count > 0 ? "bg-indigo-100 text-indigo-700" : "bg-slate-200 text-slate-600"
|
|
552
591
|
concat(content_tag(:span, number_with_delimiter(count), class: "text-xs font-semibold px-2 py-0.5 rounded-full #{color_class}"))
|
|
553
592
|
end
|
|
554
593
|
end
|
|
@@ -582,8 +621,8 @@ module AdminSuite
|
|
|
582
621
|
concat(render_sidebar_attachment(value))
|
|
583
622
|
else
|
|
584
623
|
concat(content_tag(:div, class: "flex justify-between items-start gap-2") do
|
|
585
|
-
concat(content_tag(:span, field_name.to_s.humanize, class: "text-xs font-medium text-slate-500
|
|
586
|
-
concat(content_tag(:span, class: "text-sm text-slate-900
|
|
624
|
+
concat(content_tag(:span, field_name.to_s.humanize, class: "text-xs font-medium text-slate-500 uppercase tracking-wider flex-shrink-0"))
|
|
625
|
+
concat(content_tag(:span, class: "text-sm text-slate-900 text-right") { format_show_value(resource, field_name) })
|
|
587
626
|
end)
|
|
588
627
|
end
|
|
589
628
|
end
|
|
@@ -605,21 +644,21 @@ module AdminSuite
|
|
|
605
644
|
end
|
|
606
645
|
|
|
607
646
|
content_tag(:div, class: "space-y-2") do
|
|
608
|
-
concat(content_tag(:div, class: "rounded-lg overflow-hidden border border-slate-200
|
|
647
|
+
concat(content_tag(:div, class: "rounded-lg overflow-hidden border border-slate-200") do
|
|
609
648
|
image_tag(variant_url, class: "w-full h-auto object-cover", alt: blob.filename.to_s)
|
|
610
649
|
end)
|
|
611
|
-
concat(content_tag(:div, class: "flex items-center justify-between text-xs text-slate-500
|
|
650
|
+
concat(content_tag(:div, class: "flex items-center justify-between text-xs text-slate-500") do
|
|
612
651
|
concat(content_tag(:span, number_to_human_size(blob.byte_size)))
|
|
613
|
-
concat(link_to("View full", admin_suite_rails_blob_path(blob, disposition: :inline), target: "_blank", class: "text-indigo-600
|
|
652
|
+
concat(link_to("View full", admin_suite_rails_blob_path(blob, disposition: :inline), target: "_blank", class: "text-indigo-600 hover:underline"))
|
|
614
653
|
end)
|
|
615
654
|
end
|
|
616
655
|
else
|
|
617
|
-
content_tag(:div, class: "flex items-center gap-2 p-2 bg-slate-50
|
|
618
|
-
concat(content_tag(:div, class: "flex-shrink-0 w-8 h-8 bg-slate-200
|
|
656
|
+
content_tag(:div, class: "flex items-center gap-2 p-2 bg-slate-50 rounded-lg") do
|
|
657
|
+
concat(content_tag(:div, class: "flex-shrink-0 w-8 h-8 bg-slate-200 rounded flex items-center justify-center") do
|
|
619
658
|
'<svg class="w-4 h-4 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>'.html_safe
|
|
620
659
|
end)
|
|
621
660
|
concat(content_tag(:div, class: "flex-1 min-w-0") do
|
|
622
|
-
concat(content_tag(:p, blob.filename.to_s.truncate(20), class: "text-xs font-medium text-slate-700
|
|
661
|
+
concat(content_tag(:p, blob.filename.to_s.truncate(20), class: "text-xs font-medium text-slate-700 truncate"))
|
|
623
662
|
concat(content_tag(:p, number_to_human_size(blob.byte_size), class: "text-xs text-slate-500"))
|
|
624
663
|
end)
|
|
625
664
|
end
|
|
@@ -630,8 +669,8 @@ module AdminSuite
|
|
|
630
669
|
content_tag(:dl, class: "space-y-6") do
|
|
631
670
|
fields.each do |field_name|
|
|
632
671
|
concat(content_tag(:div) do
|
|
633
|
-
concat(content_tag(:dt, field_name.to_s.humanize, class: "text-sm font-medium text-slate-500
|
|
634
|
-
concat(content_tag(:dd, class: "text-sm text-slate-900
|
|
672
|
+
concat(content_tag(:dt, field_name.to_s.humanize, class: "text-sm font-medium text-slate-500 mb-2"))
|
|
673
|
+
concat(content_tag(:dd, class: "text-sm text-slate-900") { format_show_value(resource, field_name) })
|
|
635
674
|
end)
|
|
636
675
|
end
|
|
637
676
|
end
|
|
@@ -679,7 +718,7 @@ module AdminSuite
|
|
|
679
718
|
def association_page_param(section) = "#{section.association}_page"
|
|
680
719
|
|
|
681
720
|
def render_association_pagination(pagy)
|
|
682
|
-
content_tag(:div, class: "-mx-6 border-t border-slate-200
|
|
721
|
+
content_tag(:div, class: "-mx-6 border-t border-slate-200 bg-slate-50/50 px-6 py-3") do
|
|
683
722
|
content_tag(:nav, class: "flex items-center justify-between", "aria-label" => "Pagination") do
|
|
684
723
|
concat(pagy_prev_link(pagy))
|
|
685
724
|
concat(pagy_page_links(pagy))
|
|
@@ -691,20 +730,20 @@ module AdminSuite
|
|
|
691
730
|
def pagy_prev_link(pagy)
|
|
692
731
|
if pagy.prev
|
|
693
732
|
link_to("Prev", pagy_url_for(pagy, pagy.prev),
|
|
694
|
-
class: "px-3 py-1.5 text-sm font-medium text-slate-700
|
|
733
|
+
class: "px-3 py-1.5 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50 transition-colors")
|
|
695
734
|
else
|
|
696
735
|
content_tag(:span, "Prev",
|
|
697
|
-
class: "px-3 py-1.5 text-sm font-medium text-slate-400
|
|
736
|
+
class: "px-3 py-1.5 text-sm font-medium text-slate-400 bg-slate-100 border border-slate-200 rounded-lg cursor-not-allowed")
|
|
698
737
|
end
|
|
699
738
|
end
|
|
700
739
|
|
|
701
740
|
def pagy_next_link(pagy)
|
|
702
741
|
if pagy.next
|
|
703
742
|
link_to("Next", pagy_url_for(pagy, pagy.next),
|
|
704
|
-
class: "px-3 py-1.5 text-sm font-medium text-slate-700
|
|
743
|
+
class: "px-3 py-1.5 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50 transition-colors")
|
|
705
744
|
else
|
|
706
745
|
content_tag(:span, "Next",
|
|
707
|
-
class: "px-3 py-1.5 text-sm font-medium text-slate-400
|
|
746
|
+
class: "px-3 py-1.5 text-sm font-medium text-slate-400 bg-slate-100 border border-slate-200 rounded-lg cursor-not-allowed")
|
|
708
747
|
end
|
|
709
748
|
end
|
|
710
749
|
|
|
@@ -718,11 +757,11 @@ module AdminSuite
|
|
|
718
757
|
case item
|
|
719
758
|
when Integer
|
|
720
759
|
link_to(item, pagy_url_for(pagy, item),
|
|
721
|
-
class: "px-2.5 py-1 text-sm font-medium text-slate-700
|
|
760
|
+
class: "px-2.5 py-1 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded hover:bg-slate-50 transition-colors")
|
|
722
761
|
when String
|
|
723
762
|
content_tag(:span, item, class: "px-2.5 py-1 text-sm font-semibold text-white bg-indigo-600 border border-indigo-600 rounded")
|
|
724
763
|
when :gap
|
|
725
|
-
content_tag(:span, "…", class: "px-2 text-sm text-slate-400
|
|
764
|
+
content_tag(:span, "…", class: "px-2 text-sm text-slate-400")
|
|
726
765
|
else
|
|
727
766
|
""
|
|
728
767
|
end
|
|
@@ -735,31 +774,31 @@ module AdminSuite
|
|
|
735
774
|
concat(content_tag(:div, class: "flex items-center justify-between gap-3") do
|
|
736
775
|
concat(content_tag(:div, class: "min-w-0 flex-1") do
|
|
737
776
|
title = item_display_title(item)
|
|
738
|
-
title_class = link_path ? "font-medium text-slate-900
|
|
777
|
+
title_class = link_path ? "font-medium text-slate-900 group-hover:text-indigo-600" : "font-medium text-slate-900"
|
|
739
778
|
concat(content_tag(:div, title, class: title_class))
|
|
740
779
|
|
|
741
780
|
subtitle = []
|
|
742
781
|
subtitle << item.status.to_s.humanize if item.respond_to?(:status) && item.status.present?
|
|
743
782
|
subtitle << item.email_address if item.respond_to?(:email_address) && item.email_address.present?
|
|
744
783
|
subtitle << item.tool_key if item.respond_to?(:tool_key) && item.tool_key.present?
|
|
745
|
-
concat(content_tag(:div, subtitle.first, class: "text-sm text-slate-500
|
|
784
|
+
concat(content_tag(:div, subtitle.first, class: "text-sm text-slate-500 mt-0.5")) if subtitle.any?
|
|
746
785
|
end)
|
|
747
786
|
|
|
748
787
|
if link_path
|
|
749
|
-
concat('<svg class="w-5 h-5 text-slate-300
|
|
788
|
+
concat('<svg class="w-5 h-5 text-slate-300 group-hover:text-indigo-500 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>'.html_safe)
|
|
750
789
|
end
|
|
751
790
|
end)
|
|
752
791
|
end
|
|
753
792
|
|
|
754
|
-
link_path ? link_to(card_content, link_path, class: "flex items-center -m-4 p-4 rounded-lg hover:bg-indigo-50
|
|
793
|
+
link_path ? link_to(card_content, link_path, class: "flex items-center -m-4 p-4 rounded-lg hover:bg-indigo-50 transition-colors group") : content_tag(:div, card_content, class: "flex items-center")
|
|
755
794
|
end
|
|
756
795
|
|
|
757
796
|
def render_association_list(items, section)
|
|
758
|
-
content_tag(:div, class: "divide-y divide-slate-200
|
|
797
|
+
content_tag(:div, class: "divide-y divide-slate-200 -mx-6 -mt-2 -mb-6") do
|
|
759
798
|
items.each do |item|
|
|
760
799
|
link_path = build_association_link(item, section)
|
|
761
800
|
wrapper = if link_path
|
|
762
|
-
->(content) { link_to(link_path, class: "block px-6 py-4 hover:bg-indigo-50/50
|
|
801
|
+
->(content) { link_to(link_path, class: "block px-6 py-4 hover:bg-indigo-50/50 transition-colors group") { content } }
|
|
763
802
|
else
|
|
764
803
|
->(content) { content_tag(:div, content, class: "px-6 py-4") }
|
|
765
804
|
end
|
|
@@ -769,7 +808,7 @@ module AdminSuite
|
|
|
769
808
|
concat(content_tag(:div, class: "min-w-0 flex-1") do
|
|
770
809
|
concat(content_tag(:div, class: "flex items-center gap-2") do
|
|
771
810
|
title = item_display_title(item)
|
|
772
|
-
title_class = link_path ? "text-slate-900
|
|
811
|
+
title_class = link_path ? "text-slate-900 group-hover:text-indigo-600" : "text-slate-900"
|
|
773
812
|
concat(content_tag(:span, title.truncate(60), class: "font-medium #{title_class} truncate"))
|
|
774
813
|
concat(render_status_badge(item.status, size: :sm)) if item.respond_to?(:status) && item.status.present?
|
|
775
814
|
end)
|
|
@@ -778,7 +817,7 @@ module AdminSuite
|
|
|
778
817
|
concat(content_tag(:div, class: "flex items-center gap-3 flex-shrink-0 text-xs text-slate-400") do
|
|
779
818
|
concat(content_tag(:span, time_ago_in_words(item.created_at) + " ago")) if item.respond_to?(:created_at) && item.created_at
|
|
780
819
|
if link_path
|
|
781
|
-
concat('<svg class="w-4 h-4 text-slate-300
|
|
820
|
+
concat('<svg class="w-4 h-4 text-slate-300 group-hover:text-indigo-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>'.html_safe)
|
|
782
821
|
end
|
|
783
822
|
end)
|
|
784
823
|
end)
|
|
@@ -792,28 +831,28 @@ module AdminSuite
|
|
|
792
831
|
columns = section.columns.presence || detect_table_columns(items.first)
|
|
793
832
|
|
|
794
833
|
content_tag(:div, class: "overflow-x-auto -mx-6 -mt-1") do
|
|
795
|
-
content_tag(:table, class: "min-w-full divide-y divide-slate-200
|
|
796
|
-
concat(content_tag(:thead, class: "bg-slate-50/50
|
|
834
|
+
content_tag(:table, class: "min-w-full divide-y divide-slate-200") do
|
|
835
|
+
concat(content_tag(:thead, class: "bg-slate-50/50") do
|
|
797
836
|
content_tag(:tr) do
|
|
798
837
|
Array.wrap(columns).each do |col|
|
|
799
838
|
header = col.to_s.gsub(/_id$/, "").humanize
|
|
800
|
-
concat(content_tag(:th, header, class: "px-4 py-2.5 text-left text-xs font-medium text-slate-500
|
|
839
|
+
concat(content_tag(:th, header, class: "px-4 py-2.5 text-left text-xs font-medium text-slate-500 uppercase tracking-wider first:pl-6"))
|
|
801
840
|
end
|
|
802
841
|
concat(content_tag(:th, "", class: "px-4 py-2.5 w-16"))
|
|
803
842
|
end
|
|
804
843
|
end)
|
|
805
844
|
|
|
806
|
-
concat(content_tag(:tbody, class: "divide-y divide-slate-200
|
|
845
|
+
concat(content_tag(:tbody, class: "divide-y divide-slate-200") do
|
|
807
846
|
items.each do |item|
|
|
808
847
|
link_path = build_association_link(item, section)
|
|
809
|
-
concat(content_tag(:tr, class: link_path ? "hover:bg-indigo-50/50
|
|
848
|
+
concat(content_tag(:tr, class: link_path ? "hover:bg-indigo-50/50 cursor-pointer group" : "") do
|
|
810
849
|
Array.wrap(columns).each_with_index do |col, idx|
|
|
811
850
|
value = item.public_send(col) rescue nil
|
|
812
851
|
text = format_table_cell(value)
|
|
813
852
|
concat(content_tag(:td, text, class: (idx == 0 ? "px-4 py-3 text-sm first:pl-6" : "px-4 py-3 text-sm")))
|
|
814
853
|
end
|
|
815
854
|
concat(content_tag(:td, class: "px-4 py-3 text-right pr-6") do
|
|
816
|
-
link_path ? link_to("View", link_path, class: "inline-flex items-center text-indigo-600
|
|
855
|
+
link_path ? link_to("View", link_path, class: "inline-flex items-center text-indigo-600 hover:text-indigo-800 text-sm font-medium") : ""
|
|
817
856
|
end)
|
|
818
857
|
end)
|
|
819
858
|
end
|
|
@@ -826,19 +865,19 @@ module AdminSuite
|
|
|
826
865
|
content_tag(:div, class: "grid grid-cols-1 sm:grid-cols-2 gap-3 pt-1") do
|
|
827
866
|
items.each do |item|
|
|
828
867
|
link_path = build_association_link(item, section)
|
|
829
|
-
card_class = "border border-slate-200
|
|
830
|
-
card_class += link_path ? " hover:border-indigo-300
|
|
868
|
+
card_class = "border border-slate-200 rounded-lg p-4 transition-all"
|
|
869
|
+
card_class += link_path ? " hover:border-indigo-300 hover:shadow-md group cursor-pointer" : " hover:bg-slate-50"
|
|
831
870
|
|
|
832
871
|
card_content = capture do
|
|
833
872
|
concat(content_tag(:div, class: "flex items-start justify-between gap-2 mb-2") do
|
|
834
873
|
title = item_display_title(item)
|
|
835
|
-
title_class = link_path ? "font-medium text-slate-900
|
|
874
|
+
title_class = link_path ? "font-medium text-slate-900 group-hover:text-indigo-600" : "font-medium text-slate-900"
|
|
836
875
|
concat(content_tag(:span, title.truncate(35), class: title_class))
|
|
837
876
|
concat(render_status_badge(item.status, size: :sm)) if item.respond_to?(:status) && item.status.present?
|
|
838
877
|
end)
|
|
839
|
-
concat(content_tag(:div, class: "flex items-center justify-between text-xs text-slate-400 pt-2 border-t border-slate-100
|
|
878
|
+
concat(content_tag(:div, class: "flex items-center justify-between text-xs text-slate-400 pt-2 border-t border-slate-100") do
|
|
840
879
|
concat(content_tag(:span, time_ago_in_words(item.created_at) + " ago")) if item.respond_to?(:created_at) && item.created_at
|
|
841
|
-
concat('<svg class="w-4 h-4 text-slate-300
|
|
880
|
+
concat('<svg class="w-4 h-4 text-slate-300 group-hover:text-indigo-500 group-hover:translate-x-0.5 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>'.html_safe) if link_path
|
|
842
881
|
end)
|
|
843
882
|
end
|
|
844
883
|
|
|
@@ -894,15 +933,15 @@ module AdminSuite
|
|
|
894
933
|
status_str = status.to_s.downcase
|
|
895
934
|
colors = case status_str
|
|
896
935
|
when "active", "open", "success", "approved", "completed", "enabled"
|
|
897
|
-
"bg-green-100
|
|
936
|
+
"bg-green-100 text-green-700"
|
|
898
937
|
when "pending", "proposed", "queued", "waiting"
|
|
899
|
-
"bg-amber-100
|
|
938
|
+
"bg-amber-100 text-amber-700"
|
|
900
939
|
when "running", "processing", "in_progress"
|
|
901
|
-
"bg-blue-100
|
|
940
|
+
"bg-blue-100 text-blue-700"
|
|
902
941
|
when "error", "failed", "rejected", "cancelled"
|
|
903
|
-
"bg-red-100
|
|
942
|
+
"bg-red-100 text-red-700"
|
|
904
943
|
else
|
|
905
|
-
"bg-slate-100
|
|
944
|
+
"bg-slate-100 text-slate-600"
|
|
906
945
|
end
|
|
907
946
|
|
|
908
947
|
padding = size == :sm ? "px-1.5 py-0.5 text-xs" : "px-2 py-1 text-xs"
|
|
@@ -927,25 +966,25 @@ module AdminSuite
|
|
|
927
966
|
def label_badge_colors(color)
|
|
928
967
|
case color.to_s.downcase
|
|
929
968
|
when "green"
|
|
930
|
-
"bg-green-100
|
|
969
|
+
"bg-green-100 text-green-700"
|
|
931
970
|
when "amber", "yellow", "orange"
|
|
932
|
-
"bg-amber-100
|
|
971
|
+
"bg-amber-100 text-amber-700"
|
|
933
972
|
when "blue"
|
|
934
|
-
"bg-blue-100
|
|
973
|
+
"bg-blue-100 text-blue-700"
|
|
935
974
|
when "red"
|
|
936
|
-
"bg-red-100
|
|
975
|
+
"bg-red-100 text-red-700"
|
|
937
976
|
when "indigo"
|
|
938
|
-
"bg-indigo-100
|
|
977
|
+
"bg-indigo-100 text-indigo-700"
|
|
939
978
|
when "purple"
|
|
940
|
-
"bg-purple-100
|
|
979
|
+
"bg-purple-100 text-purple-700"
|
|
941
980
|
when "violet"
|
|
942
|
-
"bg-violet-100
|
|
981
|
+
"bg-violet-100 text-violet-700"
|
|
943
982
|
when "emerald"
|
|
944
|
-
"bg-emerald-100
|
|
983
|
+
"bg-emerald-100 text-emerald-700"
|
|
945
984
|
when "cyan"
|
|
946
|
-
"bg-cyan-100
|
|
985
|
+
"bg-cyan-100 text-cyan-700"
|
|
947
986
|
else
|
|
948
|
-
"bg-slate-100
|
|
987
|
+
"bg-slate-100 text-slate-600"
|
|
949
988
|
end
|
|
950
989
|
end
|
|
951
990
|
|
|
@@ -979,7 +1018,7 @@ module AdminSuite
|
|
|
979
1018
|
when :searchable_select then render_searchable_select(f, field, resource)
|
|
980
1019
|
when :multi_select, :tags then render_multi_select(f, field, resource)
|
|
981
1020
|
when :image, :attachment then render_file_upload(f, field, resource)
|
|
982
|
-
when :trix, :rich_text then f.rich_text_area(field.name, class: "prose
|
|
1021
|
+
when :trix, :rich_text then f.rich_text_area(field.name, class: "prose max-w-none")
|
|
983
1022
|
when :markdown
|
|
984
1023
|
f.text_area(field.name, class: "#{field_class} font-mono", rows: field.rows || 12, data: { controller: "admin-suite--markdown-editor" }, placeholder: field.placeholder)
|
|
985
1024
|
when :file then f.file_field(field.name, class: "form-input-file", accept: field.accept)
|
|
@@ -995,8 +1034,8 @@ module AdminSuite
|
|
|
995
1034
|
|
|
996
1035
|
concat(field_html)
|
|
997
1036
|
|
|
998
|
-
concat(content_tag(:p, field.help, class: "mt-1 text-sm text-slate-500
|
|
999
|
-
concat(content_tag(:p, resource.errors[field.name].first, class: "mt-1 text-sm text-red-600
|
|
1037
|
+
concat(content_tag(:p, field.help, class: "mt-1 text-sm text-slate-500")) if field.help.present?
|
|
1038
|
+
concat(content_tag(:p, resource.errors[field.name].first, class: "mt-1 text-sm text-red-600")) if resource.errors[field.name].any?
|
|
1000
1039
|
end)
|
|
1001
1040
|
end
|
|
1002
1041
|
end
|
|
@@ -1062,7 +1101,7 @@ module AdminSuite
|
|
|
1062
1101
|
action: "input->admin-suite--searchable-select#search focus->admin-suite--searchable-select#open keydown->admin-suite--searchable-select#keydown"
|
|
1063
1102
|
}))
|
|
1064
1103
|
concat(content_tag(:div, "",
|
|
1065
|
-
class: "absolute z-
|
|
1104
|
+
class: "absolute z-40 w-full mt-1 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg shadow-lg hidden max-h-60 overflow-y-auto",
|
|
1066
1105
|
data: { "admin-suite--searchable-select-target": "dropdown" }))
|
|
1067
1106
|
end
|
|
1068
1107
|
end
|
|
@@ -1100,11 +1139,11 @@ module AdminSuite
|
|
|
1100
1139
|
concat(hidden_field_tag(full_field_name, "", id: nil, data: { "admin-suite--tag-select-target": "placeholder" }))
|
|
1101
1140
|
|
|
1102
1141
|
concat(content_tag(:div,
|
|
1103
|
-
class: "flex flex-wrap gap-2 min-h-[2.5rem] p-2 bg-white
|
|
1142
|
+
class: "flex flex-wrap gap-2 min-h-[2.5rem] p-2 bg-white border border-slate-200 rounded-lg",
|
|
1104
1143
|
data: { "admin-suite--tag-select-target": "tags" }) do
|
|
1105
1144
|
current_values.each do |val|
|
|
1106
1145
|
concat(content_tag(:span,
|
|
1107
|
-
class: "inline-flex items-center gap-1 px-2 py-1 bg-indigo-100
|
|
1146
|
+
class: "inline-flex items-center gap-1 px-2 py-1 bg-indigo-100 text-indigo-700 rounded text-sm") do
|
|
1108
1147
|
concat(val.to_s)
|
|
1109
1148
|
concat(hidden_field_tag(full_field_name, val, id: nil))
|
|
1110
1149
|
concat(button_tag("×", type: "button", class: "text-indigo-500 hover:text-indigo-700 font-bold", data: { action: "admin-suite--tag-select#remove" }))
|
|
@@ -1119,13 +1158,13 @@ module AdminSuite
|
|
|
1119
1158
|
|
|
1120
1159
|
if options.any?
|
|
1121
1160
|
concat(content_tag(:div,
|
|
1122
|
-
class: "hidden border border-slate-200
|
|
1161
|
+
class: "hidden border border-slate-200 rounded-lg bg-white shadow-lg max-h-48 overflow-y-auto",
|
|
1123
1162
|
data: { "admin-suite--tag-select-target": "dropdown" }) do
|
|
1124
1163
|
options.each do |opt|
|
|
1125
1164
|
label, value = opt.is_a?(Array) ? [ opt[0], opt[1] ] : [ opt, opt ]
|
|
1126
1165
|
concat(content_tag(:button, label,
|
|
1127
1166
|
type: "button",
|
|
1128
|
-
class: "block w-full text-left px-3 py-2 text-sm hover:bg-slate-100
|
|
1167
|
+
class: "block w-full text-left px-3 py-2 text-sm hover:bg-slate-100",
|
|
1129
1168
|
data: { action: "admin-suite--tag-select#select", value: value }))
|
|
1130
1169
|
end
|
|
1131
1170
|
end)
|
|
@@ -1157,18 +1196,18 @@ module AdminSuite
|
|
|
1157
1196
|
class: "space-y-3") do
|
|
1158
1197
|
if has_attachment && is_image
|
|
1159
1198
|
concat(content_tag(:div, class: "relative inline-block") do
|
|
1160
|
-
concat(image_tag(existing_url, class: "max-w-[200px] max-h-[150px] rounded-lg border border-slate-200
|
|
1199
|
+
concat(image_tag(existing_url, class: "max-w-[200px] max-h-[150px] rounded-lg border border-slate-200 object-cover", data: { "admin-suite--file-upload-target": "imagePreview" }))
|
|
1161
1200
|
concat(button_tag("×", type: "button",
|
|
1162
1201
|
class: "absolute -top-2 -right-2 w-6 h-6 bg-red-500 hover:bg-red-600 text-white rounded-full flex items-center justify-center text-sm",
|
|
1163
1202
|
data: { "admin-suite--file-upload-target": "removeButton", action: "admin-suite--file-upload#remove" }))
|
|
1164
1203
|
end)
|
|
1165
1204
|
else
|
|
1166
|
-
concat(image_tag("", class: "hidden max-w-[200px] max-h-[150px] rounded-lg border border-slate-200
|
|
1205
|
+
concat(image_tag("", class: "hidden max-w-[200px] max-h-[150px] rounded-lg border border-slate-200 object-cover", data: { "admin-suite--file-upload-target": "imagePreview" }))
|
|
1167
1206
|
concat(content_tag(:div, "", class: "hidden", data: { "admin-suite--file-upload-target": "filename" }))
|
|
1168
1207
|
end
|
|
1169
1208
|
|
|
1170
1209
|
concat(content_tag(:div,
|
|
1171
|
-
class: "relative border-2 border-dashed border-slate-300
|
|
1210
|
+
class: "relative border-2 border-dashed border-slate-300 rounded-lg hover:border-indigo-400 transition-colors",
|
|
1172
1211
|
data: { "admin-suite--file-upload-target": "dropzone" }) do
|
|
1173
1212
|
concat(f.file_field(field.name,
|
|
1174
1213
|
class: "sr-only",
|
|
@@ -1177,9 +1216,9 @@ module AdminSuite
|
|
|
1177
1216
|
data: { "admin-suite--file-upload-target": "input", action: "change->admin-suite--file-upload#preview" }))
|
|
1178
1217
|
|
|
1179
1218
|
concat(content_tag(:label, for: "#{field.name}_input",
|
|
1180
|
-
class: "flex flex-col items-center justify-center w-full py-6 cursor-pointer hover:bg-slate-50
|
|
1219
|
+
class: "flex flex-col items-center justify-center w-full py-6 cursor-pointer hover:bg-slate-50 rounded-lg transition-colors") do
|
|
1181
1220
|
concat('<svg class="w-8 h-8 text-slate-400 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/></svg>'.html_safe)
|
|
1182
|
-
concat(content_tag(:span, "Click to upload or drag and drop", class: "text-sm text-slate-500
|
|
1221
|
+
concat(content_tag(:span, "Click to upload or drag and drop", class: "text-sm text-slate-500"))
|
|
1183
1222
|
concat(content_tag(:span, "PNG, JPG, WebP up to 10MB", class: "text-xs text-slate-400 mt-1")) if is_image
|
|
1184
1223
|
end)
|
|
1185
1224
|
end)
|