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,100 @@
|
|
1
|
+
<% content_for :title, "New #{@resource_class.singular_title}" %>
|
2
|
+
|
3
|
+
<!-- Page Header -->
|
4
|
+
<div class="mb-6">
|
5
|
+
<div class="flex items-center justify-between">
|
6
|
+
<nav class="flex" aria-label="Breadcrumb">
|
7
|
+
<ol class="inline-flex items-center space-x-1 md:space-x-3">
|
8
|
+
<li>
|
9
|
+
<%= link_to easy_admin.resources_path(@resource_class.route_key),
|
10
|
+
class: "text-gray-500 hover:text-gray-700 text-sm font-medium" do %>
|
11
|
+
<%= @resource_class.title %>
|
12
|
+
<% end %>
|
13
|
+
</li>
|
14
|
+
<li>
|
15
|
+
<div class="flex items-center">
|
16
|
+
<svg class="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
17
|
+
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
|
18
|
+
</svg>
|
19
|
+
<span class="ml-1 text-sm font-medium text-gray-900">New</span>
|
20
|
+
</div>
|
21
|
+
</li>
|
22
|
+
</ol>
|
23
|
+
</nav>
|
24
|
+
|
25
|
+
<div>
|
26
|
+
<%= link_to easy_admin.resources_path(@resource_class.route_key),
|
27
|
+
class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" do %>
|
28
|
+
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
29
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m0 7h18"/>
|
30
|
+
</svg>
|
31
|
+
Back to <%= @resource_class.title %>
|
32
|
+
<% end %>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<!-- Form Container -->
|
38
|
+
<div class="max-w-4xl mx-auto">
|
39
|
+
<%= form_with model: [@resource_class.model_class.new], url: easy_admin.resources_path(@resource_class.route_key),
|
40
|
+
local: true, multipart: true, class: "space-y-6" do |form| %>
|
41
|
+
|
42
|
+
<!-- Error Messages -->
|
43
|
+
<% if @record && @record.errors.any? %>
|
44
|
+
<div class="bg-red-50 border border-red-200 rounded-md p-4">
|
45
|
+
<div class="flex">
|
46
|
+
<div class="flex-shrink-0">
|
47
|
+
<svg class="h-5 w-5 text-red-400" fill="currentColor" viewBox="0 0 20 20">
|
48
|
+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
|
49
|
+
</svg>
|
50
|
+
</div>
|
51
|
+
<div class="ml-3">
|
52
|
+
<h3 class="text-sm font-medium text-red-800">
|
53
|
+
<%= pluralize(@record.errors.count, "error") %> prohibited this <%= @resource_class.singular_title.downcase %> from being saved:
|
54
|
+
</h3>
|
55
|
+
<div class="mt-2 text-sm text-red-700">
|
56
|
+
<ul class="list-disc pl-5 space-y-1">
|
57
|
+
<% @record.errors.full_messages.each do |message| %>
|
58
|
+
<li><%= message %></li>
|
59
|
+
<% end %>
|
60
|
+
</ul>
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
</div>
|
64
|
+
</div>
|
65
|
+
<% end %>
|
66
|
+
|
67
|
+
<!-- Form Fields -->
|
68
|
+
<% if @resource_class.has_form_tabs? %>
|
69
|
+
<%= EasyAdmin::FormTabsComponent.new(resource_class: @resource_class, form: form).call.html_safe %>
|
70
|
+
<% else %>
|
71
|
+
<!-- Default Single Card Layout -->
|
72
|
+
<div class="bg-white shadow-sm rounded-lg border border-gray-200">
|
73
|
+
<div class="px-4 py-5 sm:p-6">
|
74
|
+
<h3 class="text-lg font-medium leading-6 text-gray-900 mb-6">
|
75
|
+
<%= @resource_class.singular_title %> Information
|
76
|
+
</h3>
|
77
|
+
|
78
|
+
<div class="grid grid-cols-1 gap-6">
|
79
|
+
<% @resource_class.form_fields.each do |field| %>
|
80
|
+
<div>
|
81
|
+
<%= render_field(field, action: :form, form: form) %>
|
82
|
+
</div>
|
83
|
+
<% end %>
|
84
|
+
</div>
|
85
|
+
</div>
|
86
|
+
</div>
|
87
|
+
<% end %>
|
88
|
+
|
89
|
+
<!-- Action Buttons -->
|
90
|
+
<div class="flex items-center justify-end space-x-3 pt-6">
|
91
|
+
<%= link_to easy_admin.resources_path(@resource_class.route_key),
|
92
|
+
class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" do %>
|
93
|
+
Cancel
|
94
|
+
<% end %>
|
95
|
+
|
96
|
+
<%= form.submit "Create #{@resource_class.singular_title}",
|
97
|
+
class: "inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" %>
|
98
|
+
</div>
|
99
|
+
<% end %>
|
100
|
+
</div>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% content_for :title, "#{@resource_class.singular_title} ##{@record.id}" %>
|
2
|
+
|
3
|
+
<!-- Page Header -->
|
4
|
+
<div class="mb-6">
|
5
|
+
<div class="sm:flex sm:items-center">
|
6
|
+
<div class="sm:flex-auto">
|
7
|
+
<div class="flex items-center space-x-3 mb-2">
|
8
|
+
<%= link_to easy_admin.resources_path(@resource_class.route_key),
|
9
|
+
class: "inline-flex items-center text-sm text-gray-500 hover:text-gray-700 transition-colors duration-150" do %>
|
10
|
+
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
11
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
12
|
+
</svg>
|
13
|
+
Back to <%= @resource_class.title %>
|
14
|
+
<% end %>
|
15
|
+
</div>
|
16
|
+
<h1 class="text-2xl font-bold leading-6 text-gray-900">
|
17
|
+
<%= @resource_class.singular_title %> #<%= @record.id %>
|
18
|
+
</h1>
|
19
|
+
</div>
|
20
|
+
<%== EasyAdmin::Resources::ShowPageActionsComponent.new(
|
21
|
+
record: @record,
|
22
|
+
resource_class: @resource_class,
|
23
|
+
current_user: current_admin_user
|
24
|
+
).call %>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<!-- Show Layout Content -->
|
29
|
+
<div class="show-content">
|
30
|
+
<%== EasyAdmin::ShowLayoutComponent.new(resource_class: @resource_class, record: @record).call %>
|
31
|
+
</div>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<!-- Form -->
|
2
|
+
<div class="p-10">
|
3
|
+
<%= form_for(resource, as: resource_name, url: session_path(resource_name), local: true, html: { class: "space-y-8" }) do |f| %>
|
4
|
+
|
5
|
+
<!-- Input Fields Container -->
|
6
|
+
<div class="space-y-4">
|
7
|
+
<!-- Email Field -->
|
8
|
+
<div class="relative">
|
9
|
+
<%= f.email_field :email, autofocus: true, autocomplete: "email",
|
10
|
+
class: "w-full px-6 py-5 bg-gray-50/80 border-0 text-gray-900 placeholder-gray-400 focus:bg-gray-100/80 focus:ring-0 focus:outline-none text-base rounded-2xl transition-colors duration-200 font-medium",
|
11
|
+
placeholder: "Email address" %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<!-- Password Field -->
|
15
|
+
<div class="relative">
|
16
|
+
<%= f.password_field :password, autocomplete: "current-password",
|
17
|
+
class: "w-full px-6 py-5 bg-gray-50/80 border-0 text-gray-900 placeholder-gray-400 focus:bg-gray-100/80 focus:ring-0 focus:outline-none text-base rounded-2xl transition-colors duration-200 font-medium",
|
18
|
+
placeholder: "Password" %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<!-- Remember Me -->
|
23
|
+
<% if devise_mapping.rememberable? %>
|
24
|
+
<div class="flex items-center justify-between">
|
25
|
+
<label class="flex items-center">
|
26
|
+
<%= f.check_box :remember_me, class: "h-5 w-5 text-blue-500 focus:ring-blue-500/30 focus:ring-4 border-gray-300 rounded-lg transition-all duration-200" %>
|
27
|
+
<span class="ml-3 text-base text-gray-700 font-medium">Remember me</span>
|
28
|
+
</label>
|
29
|
+
|
30
|
+
<% if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
31
|
+
<%= link_to "Forgot?", new_password_path(resource_name),
|
32
|
+
class: "text-base text-blue-500 hover:text-blue-600 font-semibold transition-colors duration-200" %>
|
33
|
+
<% end %>
|
34
|
+
</div>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<!-- Submit Button -->
|
38
|
+
<div class="pt-4">
|
39
|
+
<%= f.submit "Sign In",
|
40
|
+
class: "w-full bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white font-bold py-5 px-6 rounded-2xl transition-all duration-200 focus:outline-none focus:ring-4 focus:ring-blue-500/30 text-base shadow-xl shadow-blue-500/20 active:scale-[0.98]" %>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
<!-- Links -->
|
46
|
+
<div class="text-center pt-6">
|
47
|
+
<% if devise_mapping.registerable? && controller_name != 'registrations' %>
|
48
|
+
<div class="text-base text-gray-600">
|
49
|
+
New to EasyAdmin?
|
50
|
+
<%= link_to "Create account", new_registration_path(resource_name),
|
51
|
+
class: "text-blue-500 hover:text-blue-600 font-bold ml-2 transition-colors duration-200" %>
|
52
|
+
</div>
|
53
|
+
<% end %>
|
54
|
+
</div>
|
55
|
+
</div>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<%= form_with url: settings_path, method: :patch, class: "space-y-6" do |form| %>
|
2
|
+
<!-- Feature Toggles Section -->
|
3
|
+
<div>
|
4
|
+
<h3 class="text-md font-medium text-gray-900 mb-4">Feature Toggles</h3>
|
5
|
+
|
6
|
+
<div class="space-y-4">
|
7
|
+
<% @feature_toggles.each do |feature| %>
|
8
|
+
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg border border-gray-200">
|
9
|
+
<div class="flex-1">
|
10
|
+
<%= form.label "features_#{feature[:name]}", feature[:name].humanize,
|
11
|
+
class: "block text-sm font-medium text-gray-900 cursor-pointer" %>
|
12
|
+
|
13
|
+
<% if feature[:description].present? %>
|
14
|
+
<p class="text-xs text-gray-600 mt-1"><%= feature[:description] %></p>
|
15
|
+
<% end %>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<!-- Toggle switch -->
|
19
|
+
<div class="ml-4">
|
20
|
+
<%= form.hidden_field "features[#{feature[:name]}]", value: "0" %>
|
21
|
+
|
22
|
+
<%= form.check_box "features[#{feature[:name]}]",
|
23
|
+
{
|
24
|
+
checked: feature[:enabled],
|
25
|
+
class: "sr-only",
|
26
|
+
id: "features_#{feature[:name]}",
|
27
|
+
value: "1",
|
28
|
+
data: { action: "change->settings-sidebar#toggleFeature" }
|
29
|
+
} %>
|
30
|
+
|
31
|
+
<%= form.label "features_#{feature[:name]}",
|
32
|
+
class: "relative inline-flex items-center h-6 rounded-full w-11 cursor-pointer transition-colors ease-in-out duration-200 #{'bg-blue-600' if feature[:enabled]} #{'bg-gray-300' unless feature[:enabled]}" do %>
|
33
|
+
<span class="inline-block w-4 h-4 transform bg-white rounded-full transition ease-in-out duration-200 <%= 'translate-x-6' if feature[:enabled] %> <%= 'translate-x-1' unless feature[:enabled] %>"></span>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
<% end %>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<!-- Save button -->
|
42
|
+
<div class="pt-6 border-t border-gray-200">
|
43
|
+
<%= form.submit "Save Settings",
|
44
|
+
class: "w-full inline-flex items-center justify-center px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors" do %>
|
45
|
+
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
46
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
47
|
+
</svg>
|
48
|
+
<span>Save Settings</span>
|
49
|
+
<% end %>
|
50
|
+
</div>
|
51
|
+
<% end %>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<turbo-frame id="settings-form" class="space-y-6">
|
2
|
+
<%= form_with url: settings_path, method: :patch, class: "space-y-6" do |form| %>
|
3
|
+
<!-- Feature Toggles Section -->
|
4
|
+
<div>
|
5
|
+
<h3 class="text-md font-medium text-gray-900 mb-4">Feature Toggles</h3>
|
6
|
+
|
7
|
+
<div class="space-y-4">
|
8
|
+
<% @feature_toggles.each do |feature| %>
|
9
|
+
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg border border-gray-200">
|
10
|
+
<div class="flex-1">
|
11
|
+
<%= form.label "features_#{feature[:name]}", feature[:name].humanize,
|
12
|
+
class: "block text-sm font-medium text-gray-900 cursor-pointer" %>
|
13
|
+
|
14
|
+
<% if feature[:description].present? %>
|
15
|
+
<p class="text-xs text-gray-600 mt-1"><%= feature[:description] %></p>
|
16
|
+
<% end %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<!-- Toggle switch -->
|
20
|
+
<div class="ml-4">
|
21
|
+
<%= form.hidden_field "features[#{feature[:name]}]", value: "0" %>
|
22
|
+
|
23
|
+
<%= form.check_box "features[#{feature[:name]}]",
|
24
|
+
{
|
25
|
+
checked: feature[:enabled],
|
26
|
+
class: "sr-only",
|
27
|
+
id: "features_#{feature[:name]}",
|
28
|
+
value: "1",
|
29
|
+
data: { action: "change->settings-sidebar#toggleFeature" }
|
30
|
+
} %>
|
31
|
+
|
32
|
+
<%= form.label "features_#{feature[:name]}",
|
33
|
+
class: "relative inline-flex items-center h-6 rounded-full w-11 cursor-pointer transition-colors ease-in-out duration-200 #{'bg-blue-600' if feature[:enabled]} #{'bg-gray-300' unless feature[:enabled]}" do %>
|
34
|
+
<span class="inline-block w-4 h-4 transform bg-white rounded-full transition ease-in-out duration-200 <%= 'translate-x-6' if feature[:enabled] %> <%= 'translate-x-1' unless feature[:enabled] %>"></span>
|
35
|
+
<% end %>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<!-- Save button -->
|
43
|
+
<div class="pt-6 border-t border-gray-200">
|
44
|
+
<%= form.submit "Save Settings",
|
45
|
+
class: "w-full inline-flex items-center justify-center px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors" do %>
|
46
|
+
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
47
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
48
|
+
</svg>
|
49
|
+
<span>Save Settings</span>
|
50
|
+
<% end %>
|
51
|
+
</div>
|
52
|
+
<% end %>
|
53
|
+
</turbo-frame>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Easy admin</title>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<%= csp_meta_tag %>
|
8
|
+
|
9
|
+
<%= yield :head %>
|
10
|
+
|
11
|
+
<%= stylesheet_link_tag "easy_admin", media: "all" %>
|
12
|
+
<%= javascript_include_tag "easy_admin.base", "data-turbo-track": "reload", defer: true %>
|
13
|
+
</head>
|
14
|
+
<body class="bg-gray-50 font-sans text-gray-900 min-h-screen pt-20" data-controller="sidebar navbar-scroll settings-sidebar" data-navbar-scroll-target="body">
|
15
|
+
|
16
|
+
<!-- Mobile toggle button -->
|
17
|
+
<button class="lg:hidden fixed top-6 left-6 z-50 p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" data-action="click->sidebar#toggle" title="Toggle sidebar">
|
18
|
+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
19
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
20
|
+
</svg>
|
21
|
+
</button>
|
22
|
+
|
23
|
+
<%== EasyAdmin::SidebarComponent.new(current_path: request.path).call %>
|
24
|
+
|
25
|
+
<%== EasyAdmin::NavbarComponent.new(
|
26
|
+
page_title: content_for?(:page_title) ? yield(:page_title) : "Dashboard",
|
27
|
+
breadcrumbs: content_for?(:breadcrumbs) ? yield(:breadcrumbs) : nil
|
28
|
+
).call %>
|
29
|
+
|
30
|
+
<main class="flex-1 overflow-x-hidden overflow-y-auto bg-gray-50 lg:ml-64 transition-all duration-300" data-sidebar-target="content">
|
31
|
+
<div class="container mx-auto px-6 py-8">
|
32
|
+
<%= yield %>
|
33
|
+
</div>
|
34
|
+
</main>
|
35
|
+
|
36
|
+
<!-- Notifications Turbo Frame -->
|
37
|
+
<turbo-frame id="notifications"></turbo-frame>
|
38
|
+
|
39
|
+
<!-- Modal Container -->
|
40
|
+
<turbo-frame id="modal"></turbo-frame>
|
41
|
+
|
42
|
+
<!-- Settings Sidebar - only if global_settings enabled and Flipper available -->
|
43
|
+
<% if EasyAdmin.configuration.global_settings && defined?(Flipper) %>
|
44
|
+
<%== EasyAdmin::SettingsSidebarComponent.new(feature_toggles: @feature_toggles || []).call %>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
</body>
|
48
|
+
</html>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>EasyAdmin - Authentication</title>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<%= csp_meta_tag %>
|
8
|
+
|
9
|
+
<%= yield :head %>
|
10
|
+
|
11
|
+
<%= stylesheet_link_tag "easy_admin", media: "all" %>
|
12
|
+
<%= javascript_include_tag "easy_admin.base", "data-turbo-track": "reload", defer: true %>
|
13
|
+
</head>
|
14
|
+
<body class="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50 flex items-center justify-center p-4 font-sans antialiased">
|
15
|
+
|
16
|
+
<div class="w-full max-w-sm">
|
17
|
+
<!-- Auth Card -->
|
18
|
+
<div class="bg-white/90 backdrop-blur-2xl rounded-[28px] shadow-2xl shadow-black/5 border border-white/20 overflow-hidden">
|
19
|
+
<%= yield %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<!-- Footer -->
|
23
|
+
<div class="text-center mt-12">
|
24
|
+
<p class="text-gray-400 text-sm">
|
25
|
+
Powered by <span class="font-semibold text-gray-500">EasyAdmin</span>
|
26
|
+
</p>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<!-- Notifications Turbo Frame -->
|
31
|
+
<turbo-frame id="notifications"></turbo-frame>
|
32
|
+
|
33
|
+
</body>
|
34
|
+
</html>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# EasyAdmin Card Factory Configuration
|
2
|
+
#
|
3
|
+
# This file demonstrates how to extend the card factory with custom components.
|
4
|
+
# You can register custom card components or override existing ones.
|
5
|
+
|
6
|
+
# Example: Register a custom card component
|
7
|
+
# EasyAdmin::Dashboards::CardFactory.register(:kpi, MyApp::KpiCardComponent)
|
8
|
+
# EasyAdmin::Dashboards::CardFactory.register(:analytics, MyApp::AnalyticsCardComponent)
|
9
|
+
|
10
|
+
# Example: Register a third-party integration
|
11
|
+
# EasyAdmin::Dashboards::CardFactory.register(:stripe_metrics, StripeIntegration::MetricsCardComponent)
|
12
|
+
|
13
|
+
# The factory will automatically try to resolve components in this order:
|
14
|
+
# 1. Registered custom components (via CardFactory.register)
|
15
|
+
# 2. Component class specified in card configuration (component_class: "MyComponent")
|
16
|
+
# 3. Naming convention in gem namespace (EasyAdmin::Dashboards::Cards::TypeCardComponent)
|
17
|
+
# 4. Naming convention in app namespace (App::Dashboards::Cards::TypeCardComponent)
|
18
|
+
# 5. Fallback to CustomCardComponent
|
19
|
+
|
20
|
+
# Example card configuration using custom component class:
|
21
|
+
#
|
22
|
+
# dashboard "analytics" do
|
23
|
+
# card :special_metric,
|
24
|
+
# type: :custom,
|
25
|
+
# component_class: "MyApp::SpecialMetricCardComponent",
|
26
|
+
# title: "Special Metric"
|
27
|
+
# end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'pagy'
|
2
|
+
require 'pagy/extras/countless'
|
3
|
+
|
4
|
+
# Pagy configuration for EasyAdmin
|
5
|
+
Pagy::DEFAULT[:items] = 10 # items per page - changed from 20 to debug override issues
|
6
|
+
Pagy::DEFAULT[:size] = 7 # number of page links to show (was [1, 4, 4, 1] in older versions)
|
7
|
+
Pagy::DEFAULT[:page_param] = :page # page parameter name
|
8
|
+
|
9
|
+
# Performance optimization: Use countless pagination for large datasets
|
10
|
+
# This avoids expensive COUNT queries but shows "Page X" instead of "Page X of Y"
|
11
|
+
Pagy::DEFAULT[:countless_minimal] = false
|
12
|
+
|
13
|
+
# You can also configure other Pagy variables here if needed
|
14
|
+
# Pagy::DEFAULT[:max_pages] = 100 # max pages
|
15
|
+
# Pagy::DEFAULT[:overflow] = :empty_page # :last_page, :empty_page
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Rack Mini Profiler configuration for EasyAdmin
|
2
|
+
if defined?(Rack::MiniProfiler)
|
3
|
+
# Check if profiler is enabled in configuration
|
4
|
+
profiler_enabled = begin
|
5
|
+
EasyAdmin.configuration.enable_profiler
|
6
|
+
rescue => e
|
7
|
+
# Fallback if configuration not yet loaded
|
8
|
+
Rails.env.development?
|
9
|
+
end
|
10
|
+
|
11
|
+
if profiler_enabled
|
12
|
+
# Configure profiler settings
|
13
|
+
Rack::MiniProfiler.config.tap do |config|
|
14
|
+
# Position the profiler widget
|
15
|
+
config.position = 'bottom-left'
|
16
|
+
|
17
|
+
# Only show for admin users (if available)
|
18
|
+
config.authorization_mode = :allow_all
|
19
|
+
|
20
|
+
# Skip profiling for certain paths
|
21
|
+
config.skip_paths = [
|
22
|
+
'/assets/',
|
23
|
+
'/favicon.ico',
|
24
|
+
'/admin/assets/',
|
25
|
+
%r{^/admin.*\.(css|js|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$}
|
26
|
+
]
|
27
|
+
|
28
|
+
# Enable backtrace profiling for slow queries
|
29
|
+
config.backtrace_includes = [/easy_admin/, /app\//]
|
30
|
+
config.backtrace_ignores = []
|
31
|
+
|
32
|
+
# Show SQL queries by default
|
33
|
+
config.enable_advanced_debugging_tools = true
|
34
|
+
|
35
|
+
# Storage (use file storage in development)
|
36
|
+
config.storage = Rack::MiniProfiler::FileStore
|
37
|
+
config.storage_options = { path: Rails.root.join('tmp', 'miniprofiler') }
|
38
|
+
|
39
|
+
# Only profile requests that take longer than this (in milliseconds)
|
40
|
+
config.flamegraph_sample_rate = 0.5
|
41
|
+
|
42
|
+
# Custom colors for EasyAdmin
|
43
|
+
config.backtrace_threshold_ms = 0 # Show all backtraces
|
44
|
+
end
|
45
|
+
|
46
|
+
# Custom authorization for production-like environments
|
47
|
+
if Rails.env.staging?
|
48
|
+
Rack::MiniProfiler.config.authorization_mode = :whitelist
|
49
|
+
# You can customize this to check for admin users
|
50
|
+
# Rack::MiniProfiler.config.pre_authorize_cb = lambda { |env|
|
51
|
+
# # Check if current user is admin
|
52
|
+
# false # Disable by default in staging
|
53
|
+
# }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add custom timing for EasyAdmin components
|
57
|
+
if defined?(EasyAdmin)
|
58
|
+
# Hook into Rails to add custom profiling points
|
59
|
+
ActiveSupport::Notifications.subscribe("render_component.phlex") do |name, start, finish, id, payload|
|
60
|
+
if defined?(Rack::MiniProfiler) && Rack::MiniProfiler.current
|
61
|
+
duration_ms = (finish - start) * 1000
|
62
|
+
Rack::MiniProfiler.current.custom_timing("phlex", "#{payload[:component]}", duration_ms)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
EasyAdmin::Engine.routes.draw do
|
2
|
+
# Authentication routes
|
3
|
+
devise_for :admin_users,
|
4
|
+
class_name: 'EasyAdmin::AdminUser',
|
5
|
+
controllers: {
|
6
|
+
sessions: 'easy_admin/sessions',
|
7
|
+
registrations: 'easy_admin/registrations',
|
8
|
+
passwords: 'easy_admin/passwords'
|
9
|
+
},
|
10
|
+
path: '',
|
11
|
+
path_names: {
|
12
|
+
sign_in: 'sign_in',
|
13
|
+
sign_out: 'sign_out',
|
14
|
+
sign_up: 'sign_up'
|
15
|
+
}
|
16
|
+
|
17
|
+
root 'dashboard#index'
|
18
|
+
|
19
|
+
# Settings routes
|
20
|
+
get 'settings', to: 'settings#index'
|
21
|
+
patch 'settings', to: 'settings#update'
|
22
|
+
|
23
|
+
# Confirmation modal
|
24
|
+
get 'confirmation_modal', to: 'confirmation_modal#show'
|
25
|
+
|
26
|
+
# Dashboard routes
|
27
|
+
scope 'dashboards', as: 'dashboards' do
|
28
|
+
get ':dashboard_name', to: 'dashboards#show', as: 'dashboard'
|
29
|
+
get ':dashboard_name/cards/:card_name', to: 'dashboards#card', as: 'dashboard_card'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Generic resource routes - will be resolved dynamically in controller
|
33
|
+
scope ':resource_name', constraints: { resource_name: /[a-z_]+/ } do
|
34
|
+
get '/', to: 'resources#index', as: 'resources'
|
35
|
+
get '/new', to: 'resources#new', as: 'new_resource'
|
36
|
+
post '/', to: 'resources#create'
|
37
|
+
get '/:id', to: 'resources#show', as: 'resource'
|
38
|
+
get '/:id/edit', to: 'resources#edit', as: 'edit_resource'
|
39
|
+
patch '/:id', to: 'resources#update'
|
40
|
+
put '/:id', to: 'resources#update'
|
41
|
+
delete '/:id', to: 'resources#destroy'
|
42
|
+
|
43
|
+
# Inline field editing routes
|
44
|
+
get '/:id/fields/:field/edit', to: 'resources#edit_field', as: 'edit_field_resource'
|
45
|
+
patch '/:id/fields/:field', to: 'resources#update_field', as: 'update_field_resource'
|
46
|
+
|
47
|
+
# Suggest search route for dynamic option loading
|
48
|
+
get '/suggest/:field', to: 'resources#suggest', as: 'suggest_resource'
|
49
|
+
|
50
|
+
# Belongs_to field specific routes
|
51
|
+
get '/:id/fields/:field/reattach', to: 'resources#belongs_to_reattach', as: 'belongs_to_reattach_resource'
|
52
|
+
patch '/:id/fields/:field/reattach', to: 'resources#update_field'
|
53
|
+
get '/:id/fields/:field/edit_attached', to: 'resources#belongs_to_edit_attached', as: 'belongs_to_edit_attached_resource'
|
54
|
+
patch '/:id/fields/:field/attached/:attached_id', to: 'resources#update_belongs_to_attached', as: 'update_belongs_to_attached_resource'
|
55
|
+
|
56
|
+
# Batch action routes
|
57
|
+
post '/batch_action', to: 'batch_actions#execute', as: 'batch_action'
|
58
|
+
get '/batch_action/:action_class/form', to: 'batch_actions#form', as: 'batch_action_form'
|
59
|
+
|
60
|
+
# Row action routes (single record actions)
|
61
|
+
get '/:id/context_menu', to: 'row_actions#context_menu', as: 'context_menu'
|
62
|
+
post '/:id/actions/:action_class', to: 'row_actions#execute', as: 'row_action'
|
63
|
+
get '/:id/actions/:action_class/form', to: 'row_actions#form', as: 'row_action_form'
|
64
|
+
|
65
|
+
# Lazy loading routes for show page components
|
66
|
+
get '/:id/metrics/:metric_id', to: 'resources#metric', as: 'resource_metric'
|
67
|
+
get '/:id/charts/:chart_id', to: 'resources#chart', as: 'resource_chart'
|
68
|
+
get '/:id/tabs/:tab_name', to: 'resources#tab_content', as: 'resource_tab_content'
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class CreateEasyAdminAdminUsers < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :easy_admin_admin_users do |t|
|
4
|
+
## Database authenticatable
|
5
|
+
t.string :email, null: false, default: ""
|
6
|
+
t.string :encrypted_password, null: false, default: ""
|
7
|
+
|
8
|
+
## Personal information
|
9
|
+
t.string :first_name, null: false
|
10
|
+
t.string :last_name, null: false
|
11
|
+
|
12
|
+
## Recoverable
|
13
|
+
t.string :reset_password_token
|
14
|
+
t.datetime :reset_password_sent_at
|
15
|
+
|
16
|
+
## Rememberable
|
17
|
+
t.datetime :remember_created_at
|
18
|
+
|
19
|
+
## Trackable
|
20
|
+
t.integer :sign_in_count, default: 0, null: false
|
21
|
+
t.datetime :current_sign_in_at
|
22
|
+
t.datetime :last_sign_in_at
|
23
|
+
t.string :current_sign_in_ip
|
24
|
+
t.string :last_sign_in_ip
|
25
|
+
|
26
|
+
## Confirmable
|
27
|
+
t.string :confirmation_token
|
28
|
+
t.datetime :confirmed_at
|
29
|
+
t.datetime :confirmation_sent_at
|
30
|
+
t.string :unconfirmed_email # Only if using reconfirmable
|
31
|
+
|
32
|
+
## Lockable
|
33
|
+
t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
|
34
|
+
t.string :unlock_token # Only if unlock strategy is :email or :both
|
35
|
+
t.datetime :locked_at
|
36
|
+
|
37
|
+
t.timestamps null: false
|
38
|
+
end
|
39
|
+
|
40
|
+
add_index :easy_admin_admin_users, :email, unique: true
|
41
|
+
add_index :easy_admin_admin_users, :reset_password_token, unique: true
|
42
|
+
add_index :easy_admin_admin_users, :confirmation_token, unique: true
|
43
|
+
add_index :easy_admin_admin_users, :unlock_token, unique: true
|
44
|
+
end
|
45
|
+
end
|
data/lib/easy-admin.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "phlex"
|
2
|
+
require "dry-monads"
|
3
|
+
require "ransack"
|
4
|
+
require "easy_admin/version"
|
5
|
+
require "easy_admin/configuration"
|
6
|
+
require "easy_admin/resource_registry"
|
7
|
+
require "easy_admin/resource"
|
8
|
+
require "easy_admin/dashboard_registry"
|
9
|
+
require "easy_admin/dashboard"
|
10
|
+
require "easy_admin/field"
|
11
|
+
require "easy_admin/action"
|
12
|
+
require "easy_admin/delete_action"
|
13
|
+
require "easy_admin/batch_action"
|
14
|
+
require "easy_admin/engine"
|
15
|
+
|
16
|
+
module EasyAdmin
|
17
|
+
class << self
|
18
|
+
attr_writer :configuration
|
19
|
+
|
20
|
+
def configuration
|
21
|
+
@configuration ||= Configuration.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure
|
25
|
+
yield(configuration)
|
26
|
+
end
|
27
|
+
|
28
|
+
def reset_configuration!
|
29
|
+
@configuration = Configuration.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|