easy-admin-rails 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/builds/easy_admin.base.js +43505 -0
- data/app/assets/builds/easy_admin.base.js.map +7 -0
- data/app/assets/builds/easy_admin.css +6141 -0
- data/app/assets/config/easy_admin_manifest.js +1 -0
- data/app/assets/images/jsoneditor-icons.svg +749 -0
- data/app/assets/stylesheets/easy_admin/application.tailwind.css +390 -0
- data/app/components/easy_admin/base_component.rb +35 -0
- data/app/components/easy_admin/batch_action_bar_component.rb +125 -0
- data/app/components/easy_admin/batch_action_form_component.rb +124 -0
- data/app/components/easy_admin/combined_filters_component.rb +232 -0
- data/app/components/easy_admin/confirmation_modal_component.rb +61 -0
- data/app/components/easy_admin/context_menu_component.rb +161 -0
- data/app/components/easy_admin/dashboards/base_card_component.rb +152 -0
- data/app/components/easy_admin/dashboards/card_error_component.rb +23 -0
- data/app/components/easy_admin/dashboards/card_factory.rb +90 -0
- data/app/components/easy_admin/dashboards/card_stream_component.rb +22 -0
- data/app/components/easy_admin/dashboards/cards/base_card_component.rb +54 -0
- data/app/components/easy_admin/dashboards/cards/chart_card_component.rb +175 -0
- data/app/components/easy_admin/dashboards/cards/custom_card_component.rb +50 -0
- data/app/components/easy_admin/dashboards/cards/metric_card_component.rb +164 -0
- data/app/components/easy_admin/dashboards/cards/table_card_component.rb +148 -0
- data/app/components/easy_admin/dashboards/chart_card_component.rb +44 -0
- data/app/components/easy_admin/dashboards/metric_card_component.rb +56 -0
- data/app/components/easy_admin/dashboards/refresh_stream_component.rb +279 -0
- data/app/components/easy_admin/dashboards/show_component.rb +163 -0
- data/app/components/easy_admin/dashboards/table_card_component.rb +52 -0
- data/app/components/easy_admin/date_picker_component.rb +188 -0
- data/app/components/easy_admin/fields/base_component.rb +101 -0
- data/app/components/easy_admin/fields/belongs_to_edit_modal_component.rb +117 -0
- data/app/components/easy_admin/fields/form/belongs_to_component.rb +82 -0
- data/app/components/easy_admin/fields/form/boolean_component.rb +100 -0
- data/app/components/easy_admin/fields/form/date_component.rb +55 -0
- data/app/components/easy_admin/fields/form/datetime_component.rb +55 -0
- data/app/components/easy_admin/fields/form/email_component.rb +55 -0
- data/app/components/easy_admin/fields/form/file_component.rb +190 -0
- data/app/components/easy_admin/fields/form/has_many_component.rb +416 -0
- data/app/components/easy_admin/fields/form/json_component.rb +81 -0
- data/app/components/easy_admin/fields/form/number_component.rb +55 -0
- data/app/components/easy_admin/fields/form/select_component.rb +326 -0
- data/app/components/easy_admin/fields/form/text_component.rb +55 -0
- data/app/components/easy_admin/fields/form/textarea_component.rb +54 -0
- data/app/components/easy_admin/fields/index/belongs_to_component.rb +93 -0
- data/app/components/easy_admin/fields/index/boolean_component.rb +29 -0
- data/app/components/easy_admin/fields/index/date_component.rb +13 -0
- data/app/components/easy_admin/fields/index/datetime_component.rb +13 -0
- data/app/components/easy_admin/fields/index/email_component.rb +24 -0
- data/app/components/easy_admin/fields/index/filters/base_component.rb +48 -0
- data/app/components/easy_admin/fields/index/filters/boolean_component.rb +96 -0
- data/app/components/easy_admin/fields/index/filters/date_component.rb +182 -0
- data/app/components/easy_admin/fields/index/filters/number_component.rb +30 -0
- data/app/components/easy_admin/fields/index/filters/select_component.rb +101 -0
- data/app/components/easy_admin/fields/index/filters/string_component.rb +32 -0
- data/app/components/easy_admin/fields/index/json_component.rb +23 -0
- data/app/components/easy_admin/fields/index/number_component.rb +20 -0
- data/app/components/easy_admin/fields/index/select_component.rb +25 -0
- data/app/components/easy_admin/fields/index/text_component.rb +20 -0
- data/app/components/easy_admin/fields/inline_edit_modal_component.rb +135 -0
- data/app/components/easy_admin/fields/inline_edit_trigger_component.rb +144 -0
- data/app/components/easy_admin/fields/show/belongs_to_component.rb +93 -0
- data/app/components/easy_admin/fields/show/boolean_component.rb +21 -0
- data/app/components/easy_admin/fields/show/date_component.rb +13 -0
- data/app/components/easy_admin/fields/show/datetime_component.rb +13 -0
- data/app/components/easy_admin/fields/show/email_component.rb +19 -0
- data/app/components/easy_admin/fields/show/file_component.rb +304 -0
- data/app/components/easy_admin/fields/show/has_many_component.rb +192 -0
- data/app/components/easy_admin/fields/show/json_component.rb +45 -0
- data/app/components/easy_admin/fields/show/number_component.rb +20 -0
- data/app/components/easy_admin/fields/show/select_component.rb +25 -0
- data/app/components/easy_admin/fields/show/text_component.rb +17 -0
- data/app/components/easy_admin/fields/show/textarea_component.rb +26 -0
- data/app/components/easy_admin/filters_component.rb +120 -0
- data/app/components/easy_admin/form_tabs_component.rb +166 -0
- data/app/components/easy_admin/infinite_scroll_component.rb +82 -0
- data/app/components/easy_admin/lazy_chart_card_component.rb +128 -0
- data/app/components/easy_admin/lazy_metric_card_component.rb +76 -0
- data/app/components/easy_admin/modal_frame_component.rb +26 -0
- data/app/components/easy_admin/navbar_component.rb +226 -0
- data/app/components/easy_admin/notification_component.rb +83 -0
- data/app/components/easy_admin/pagination_component.rb +188 -0
- data/app/components/easy_admin/quick_filters_component.rb +65 -0
- data/app/components/easy_admin/resource_pagination_component.rb +14 -0
- data/app/components/easy_admin/resources/index_component.rb +211 -0
- data/app/components/easy_admin/resources/index_frame_component.rb +88 -0
- data/app/components/easy_admin/resources/show_page_actions_component.rb +324 -0
- data/app/components/easy_admin/resources/table_cell_component.rb +145 -0
- data/app/components/easy_admin/resources/table_component.rb +206 -0
- data/app/components/easy_admin/resources/table_row_component.rb +160 -0
- data/app/components/easy_admin/row_action_form_component.rb +127 -0
- data/app/components/easy_admin/scopes_component.rb +224 -0
- data/app/components/easy_admin/settings_sidebar_component.rb +140 -0
- data/app/components/easy_admin/show_layout_component.rb +600 -0
- data/app/components/easy_admin/sidebar_component.rb +174 -0
- data/app/components/easy_admin/turbo/response_component.rb +40 -0
- data/app/components/easy_admin/turbo/stream_component.rb +28 -0
- data/app/controllers/easy_admin/application_controller.rb +66 -0
- data/app/controllers/easy_admin/batch_actions_controller.rb +166 -0
- data/app/controllers/easy_admin/confirmation_modal_controller.rb +20 -0
- data/app/controllers/easy_admin/dashboard_controller.rb +6 -0
- data/app/controllers/easy_admin/dashboards_controller.rb +123 -0
- data/app/controllers/easy_admin/passwords_controller.rb +15 -0
- data/app/controllers/easy_admin/registrations_controller.rb +52 -0
- data/app/controllers/easy_admin/resources_controller.rb +907 -0
- data/app/controllers/easy_admin/row_actions_controller.rb +216 -0
- data/app/controllers/easy_admin/sessions_controller.rb +32 -0
- data/app/controllers/easy_admin/settings_controller.rb +94 -0
- data/app/helpers/easy_admin/application_helper.rb +4 -0
- data/app/helpers/easy_admin/dashboards_helper.rb +121 -0
- data/app/helpers/easy_admin/fields_helper.rb +27 -0
- data/app/helpers/easy_admin/pagy_helper.rb +30 -0
- data/app/helpers/easy_admin/resources_helper.rb +39 -0
- data/app/javascript/easy_admin/application.js +12 -0
- data/app/javascript/easy_admin/controllers/batch_modal_controller.js +66 -0
- data/app/javascript/easy_admin/controllers/batch_selection_controller.js +223 -0
- data/app/javascript/easy_admin/controllers/chart_controller.js +216 -0
- data/app/javascript/easy_admin/controllers/collapsible_filters_controller.js +118 -0
- data/app/javascript/easy_admin/controllers/confirmation_modal_controller.js +64 -0
- data/app/javascript/easy_admin/controllers/context_menu_controller.js +227 -0
- data/app/javascript/easy_admin/controllers/date_picker_controller.js +309 -0
- data/app/javascript/easy_admin/controllers/dropdown_controller.js +63 -0
- data/app/javascript/easy_admin/controllers/event_emitter_controller.js +19 -0
- data/app/javascript/easy_admin/controllers/file_controller.js +121 -0
- data/app/javascript/easy_admin/controllers/form_tabs_controller.js +100 -0
- data/app/javascript/easy_admin/controllers/has_many_search_controller.js +76 -0
- data/app/javascript/easy_admin/controllers/infinite_scroll_controller.js +174 -0
- data/app/javascript/easy_admin/controllers/ios_alert_controller.js +195 -0
- data/app/javascript/easy_admin/controllers/jsoneditor_controller.js +88 -0
- data/app/javascript/easy_admin/controllers/modal_controller.js +75 -0
- data/app/javascript/easy_admin/controllers/navbar_scroll_controller.js +76 -0
- data/app/javascript/easy_admin/controllers/notification_controller.js +48 -0
- data/app/javascript/easy_admin/controllers/row_action_controller.js +124 -0
- data/app/javascript/easy_admin/controllers/row_modal_controller.js +59 -0
- data/app/javascript/easy_admin/controllers/select_field_controller.js +618 -0
- data/app/javascript/easy_admin/controllers/settings_button_controller.js +8 -0
- data/app/javascript/easy_admin/controllers/settings_sidebar_controller.js +186 -0
- data/app/javascript/easy_admin/controllers/sidebar_controller.js +102 -0
- data/app/javascript/easy_admin/controllers/sidebar_mobile_controller.js +23 -0
- data/app/javascript/easy_admin/controllers/sidebar_nav_controller.js +96 -0
- data/app/javascript/easy_admin/controllers/table_controller.js +28 -0
- data/app/javascript/easy_admin/controllers/table_row_controller.js +16 -0
- data/app/javascript/easy_admin/controllers/toggle_switch_controller.js +22 -0
- data/app/javascript/easy_admin/controllers/turbo_stream_redirect.js +9 -0
- data/app/javascript/easy_admin/controllers.js +54 -0
- data/app/javascript/easy_admin.base.js +4 -0
- data/app/models/easy_admin/admin_user.rb +53 -0
- data/app/models/easy_admin/application_record.rb +5 -0
- data/app/views/easy_admin/dashboard/index.html.erb +3 -0
- data/app/views/easy_admin/dashboards/show.html.erb +7 -0
- data/app/views/easy_admin/passwords/edit.html.erb +42 -0
- data/app/views/easy_admin/passwords/new.html.erb +41 -0
- data/app/views/easy_admin/registrations/new.html.erb +65 -0
- data/app/views/easy_admin/resources/_redirect.turbo_stream.erb +3 -0
- data/app/views/easy_admin/resources/_table_rows.html.erb +46 -0
- data/app/views/easy_admin/resources/edit.html.erb +151 -0
- data/app/views/easy_admin/resources/index.html.erb +12 -0
- data/app/views/easy_admin/resources/index.turbo_stream.erb +139 -0
- data/app/views/easy_admin/resources/index_frame.html.erb +142 -0
- data/app/views/easy_admin/resources/new.html.erb +100 -0
- data/app/views/easy_admin/resources/show.html.erb +31 -0
- data/app/views/easy_admin/sessions/new.html.erb +55 -0
- data/app/views/easy_admin/settings/_form.html.erb +51 -0
- data/app/views/easy_admin/settings/index.html.erb +53 -0
- data/app/views/layouts/easy_admin/application.html.erb +48 -0
- data/app/views/layouts/easy_admin/auth.html.erb +34 -0
- data/config/initializers/easy_admin_card_factory.rb +27 -0
- data/config/initializers/pagy.rb +15 -0
- data/config/initializers/rack_mini_profiler.rb +67 -0
- data/config/routes.rb +70 -0
- data/db/migrate/20250101000001_create_easy_admin_admin_users.rb +45 -0
- data/lib/easy-admin.rb +32 -0
- data/lib/easy_admin/action.rb +159 -0
- data/lib/easy_admin/batch_action.rb +134 -0
- data/lib/easy_admin/configuration.rb +75 -0
- data/lib/easy_admin/dashboard.rb +110 -0
- data/lib/easy_admin/dashboard_registry.rb +30 -0
- data/lib/easy_admin/delete_action.rb +22 -0
- data/lib/easy_admin/engine.rb +54 -0
- data/lib/easy_admin/field.rb +118 -0
- data/lib/easy_admin/resource.rb +806 -0
- data/lib/easy_admin/resource_registry.rb +22 -0
- data/lib/easy_admin/types/json_type.rb +25 -0
- data/lib/easy_admin/version.rb +3 -0
- data/lib/generators/easy_admin/auth_generator.rb +69 -0
- data/lib/generators/easy_admin/card/card_generator.rb +94 -0
- data/lib/generators/easy_admin/card/templates/card_component.rb.erb +127 -0
- data/lib/generators/easy_admin/card/templates/card_component_spec.rb.erb +122 -0
- data/lib/generators/easy_admin/install/templates/easy_admin.rb +31 -0
- data/lib/generators/easy_admin/install_generator.rb +25 -0
- data/lib/generators/easy_admin/rbac/rbac_generator.rb +244 -0
- data/lib/generators/easy_admin/rbac/templates/add_rbac_to_admin_users.rb +23 -0
- data/lib/generators/easy_admin/rbac/templates/super_admin.rb +34 -0
- data/lib/generators/easy_admin/resource_generator.rb +43 -0
- data/lib/generators/easy_admin/templates/AUTH_README +35 -0
- data/lib/generators/easy_admin/templates/README +27 -0
- data/lib/generators/easy_admin/templates/create_easy_admin_admin_users.rb +45 -0
- data/lib/generators/easy_admin/templates/devise.rb +267 -0
- data/lib/generators/easy_admin/templates/easy_admin.rb +24 -0
- data/lib/generators/easy_admin/templates/resource.rb +29 -0
- data/lib/tasks/easy_admin_tasks.rake +4 -0
- metadata +445 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module EasyAdmin
|
2
|
+
module Fields
|
3
|
+
module Form
|
4
|
+
class DatetimeComponent < BaseComponent
|
5
|
+
def view_template
|
6
|
+
div(class: "mb-4") do
|
7
|
+
label(for: field_id, class: label_classes) do
|
8
|
+
plain field_label
|
9
|
+
if required?
|
10
|
+
span(class: "text-red-500 ml-1") { "*" }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
input(
|
14
|
+
type: "datetime-local",
|
15
|
+
name: form_field_name,
|
16
|
+
id: field_id,
|
17
|
+
value: current_value,
|
18
|
+
class: input_classes,
|
19
|
+
required: required?
|
20
|
+
)
|
21
|
+
if field[:help_text]
|
22
|
+
p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def label_classes
|
30
|
+
"block text-sm font-medium text-gray-700 mb-1"
|
31
|
+
end
|
32
|
+
|
33
|
+
def input_classes
|
34
|
+
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"
|
37
|
+
hover_classes = "hover:border-gray-400"
|
38
|
+
transition_classes = "transition-colors duration-200"
|
39
|
+
|
40
|
+
"#{base_classes} #{state_classes} #{focus_classes} #{hover_classes} #{transition_classes}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def form_field_name
|
44
|
+
model_name = form.object.class.name.underscore
|
45
|
+
"#{model_name}[#{field_name}]"
|
46
|
+
end
|
47
|
+
|
48
|
+
def current_value
|
49
|
+
value = form.object.public_send(field_name) if form.object.respond_to?(field_name)
|
50
|
+
value.respond_to?(:strftime) ? value.strftime("%Y-%m-%dT%H:%M") : value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module EasyAdmin
|
2
|
+
module Fields
|
3
|
+
module Form
|
4
|
+
class EmailComponent < BaseComponent
|
5
|
+
def view_template
|
6
|
+
div(class: "mb-4") do
|
7
|
+
label(for: field_id, class: label_classes) do
|
8
|
+
plain field_label
|
9
|
+
if required?
|
10
|
+
span(class: "text-red-500 ml-1") { "*" }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
input(
|
14
|
+
type: "email",
|
15
|
+
name: form_field_name,
|
16
|
+
id: field_id,
|
17
|
+
value: current_value,
|
18
|
+
class: input_classes,
|
19
|
+
required: required?,
|
20
|
+
placeholder: field[:placeholder] || "Enter #{field_label.downcase}"
|
21
|
+
)
|
22
|
+
if field[:help_text]
|
23
|
+
p(class: "mt-1 text-sm text-gray-500") { field[:help_text] }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def label_classes
|
31
|
+
"block text-sm font-medium text-gray-700 mb-1"
|
32
|
+
end
|
33
|
+
|
34
|
+
def input_classes
|
35
|
+
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"
|
38
|
+
hover_classes = "hover:border-gray-400"
|
39
|
+
transition_classes = "transition-colors duration-200"
|
40
|
+
|
41
|
+
"#{base_classes} #{state_classes} #{focus_classes} #{hover_classes} #{transition_classes}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def form_field_name
|
45
|
+
model_name = form.object.class.name.underscore
|
46
|
+
"#{model_name}[#{field_name}]"
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_value
|
50
|
+
form.object.public_send(field_name) if form.object.respond_to?(field_name)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
module EasyAdmin
|
2
|
+
module Fields
|
3
|
+
module Form
|
4
|
+
class FileComponent < BaseComponent
|
5
|
+
private
|
6
|
+
|
7
|
+
def view_template
|
8
|
+
div(class: "mb-6", data: { controller: "file" }) do
|
9
|
+
render_label if field_label
|
10
|
+
render_file_input
|
11
|
+
render_preview_area
|
12
|
+
render_help_text if field[:help_text]
|
13
|
+
render_current_file if current_file_exists?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_label
|
18
|
+
label(for: field_id, class: "block text-sm font-medium text-gray-700 mb-2") do
|
19
|
+
plain field_label
|
20
|
+
if required?
|
21
|
+
span(class: "text-red-500 ml-1") { "*" }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_file_input
|
27
|
+
input(
|
28
|
+
type: "file",
|
29
|
+
id: field_id,
|
30
|
+
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
|
+
data: { file_target: "input" },
|
33
|
+
**file_input_attributes
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_preview_area
|
38
|
+
div(data: { file_target: "preview" }, class: "mt-2")
|
39
|
+
end
|
40
|
+
|
41
|
+
def render_help_text
|
42
|
+
div(class: "mt-1 text-sm text-gray-500") do
|
43
|
+
plain field[:help_text]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_current_file
|
48
|
+
if current_file_url
|
49
|
+
div(class: "mt-4", data: { file_target: "currentFile" }) do
|
50
|
+
div(class: "flex items-center p-4 bg-gray-50 border border-gray-200 rounded-lg") do
|
51
|
+
div(class: "mr-4") do
|
52
|
+
if image_file?
|
53
|
+
img(src: current_file_url, alt: "Current file", class: "w-16 h-16 object-cover rounded-lg border border-gray-300")
|
54
|
+
else
|
55
|
+
div(class: "flex items-center justify-center w-16 h-16 bg-blue-100 text-blue-600 rounded-lg") do
|
56
|
+
unsafe_raw %(<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
57
|
+
<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"/>
|
58
|
+
</svg>)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
div(class: "flex-1") do
|
63
|
+
div(class: "text-sm font-medium text-gray-900") { plain current_file_name }
|
64
|
+
div(class: "text-xs text-gray-500") { plain file_size_text }
|
65
|
+
end
|
66
|
+
div(class: "flex items-center space-x-2") do
|
67
|
+
a(href: current_file_url, target: "_blank", class: "inline-flex items-center px-3 py-1.5 border border-blue-300 text-sm font-medium rounded-md text-blue-700 bg-blue-50 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500") do
|
68
|
+
unsafe_raw %(<svg class="w-4 h-4 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
69
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
70
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
|
71
|
+
</svg>)
|
72
|
+
plain "View"
|
73
|
+
end
|
74
|
+
if field[:allow_remove] != false
|
75
|
+
button(type: "button", class: "inline-flex items-center px-3 py-1.5 border border-red-300 text-sm font-medium rounded-md text-red-700 bg-red-50 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500",
|
76
|
+
data: { action: "click->file#removeFile" }) do
|
77
|
+
unsafe_raw %(<svg class="w-4 h-4 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
78
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
79
|
+
</svg>)
|
80
|
+
plain "Remove"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def file_input_attributes
|
90
|
+
attributes = {}
|
91
|
+
attributes[:accept] = field[:accept] if field[:accept]
|
92
|
+
attributes[:multiple] = true if field[:multiple]
|
93
|
+
attributes[:disabled] = true if readonly?
|
94
|
+
attributes[:required] = true if required?
|
95
|
+
attributes
|
96
|
+
end
|
97
|
+
|
98
|
+
def form_field_name
|
99
|
+
model_name = form.object.class.name.underscore
|
100
|
+
if field[:multiple]
|
101
|
+
"#{model_name}[#{field_name}][]"
|
102
|
+
else
|
103
|
+
"#{model_name}[#{field_name}]"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def size_class
|
108
|
+
case field[:size]
|
109
|
+
when :small then "text-xs py-1.5 px-3"
|
110
|
+
when :large then "text-base py-3 px-4"
|
111
|
+
else ""
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
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"
|
120
|
+
else
|
121
|
+
""
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def current_file_exists?
|
126
|
+
current_value = value || (form.object.respond_to?(field_name) ? form.object.public_send(field_name) : nil)
|
127
|
+
current_value.present? && (current_value.respond_to?(:attached?) ? current_value.attached? : true)
|
128
|
+
end
|
129
|
+
|
130
|
+
def current_file_url
|
131
|
+
return nil unless current_file_exists?
|
132
|
+
|
133
|
+
current_value = value || form.object.public_send(field_name)
|
134
|
+
if current_value.respond_to?(:url)
|
135
|
+
current_value.url
|
136
|
+
elsif current_value.respond_to?(:service_url)
|
137
|
+
current_value.service_url
|
138
|
+
elsif current_value.is_a?(String)
|
139
|
+
current_value
|
140
|
+
end
|
141
|
+
rescue
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
|
145
|
+
def current_file_name
|
146
|
+
return "Uploaded file" unless current_file_exists?
|
147
|
+
|
148
|
+
current_value = value || form.object.public_send(field_name)
|
149
|
+
if current_value.respond_to?(:filename)
|
150
|
+
current_value.filename.to_s
|
151
|
+
elsif current_value.respond_to?(:original_filename)
|
152
|
+
current_value.original_filename
|
153
|
+
elsif current_value.is_a?(String)
|
154
|
+
File.basename(current_value)
|
155
|
+
else
|
156
|
+
"Uploaded file"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def file_size_text
|
161
|
+
return "" unless current_file_exists?
|
162
|
+
|
163
|
+
current_value = value || form.object.public_send(field_name)
|
164
|
+
if current_value.respond_to?(:byte_size)
|
165
|
+
size = current_value.byte_size
|
166
|
+
elsif current_value.respond_to?(:size)
|
167
|
+
size = current_value.size
|
168
|
+
else
|
169
|
+
return ""
|
170
|
+
end
|
171
|
+
|
172
|
+
if size < 1024
|
173
|
+
"#{size} bytes"
|
174
|
+
elsif size < 1024 * 1024
|
175
|
+
"#{(size / 1024.0).round(1)} KB"
|
176
|
+
else
|
177
|
+
"#{(size / (1024.0 * 1024)).round(1)} MB"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def image_file?
|
182
|
+
return false unless current_file_exists?
|
183
|
+
|
184
|
+
filename = current_file_name.downcase
|
185
|
+
%w[.jpg .jpeg .png .gif .webp .svg].any? { |ext| filename.end_with?(ext) }
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|