rails_admin_next 1.0.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/Gemfile +46 -0
- data/LICENSE.md +21 -0
- data/README.md +317 -0
- data/Rakefile +25 -0
- data/app/assets/javascripts/rails_admin/custom/ui.js +1 -0
- data/app/assets/stylesheets/rails_admin/framework.css +2375 -0
- data/app/assets/stylesheets/rails_admin/skin.css +472 -0
- data/app/assets/stylesheets/rails_admin/tokens.css +281 -0
- data/app/assets/stylesheets/rails_admin.css +47 -0
- data/app/controllers/rails_admin_next/application_controller.rb +98 -0
- data/app/controllers/rails_admin_next/main_controller.rb +185 -0
- data/app/helpers/rails_admin_next/application_helper.rb +254 -0
- data/app/helpers/rails_admin_next/form_builder.rb +173 -0
- data/app/helpers/rails_admin_next/main_helper.rb +63 -0
- data/app/views/layouts/rails_admin_next/_head.html.erb +29 -0
- data/app/views/layouts/rails_admin_next/_navigation.html.erb +18 -0
- data/app/views/layouts/rails_admin_next/_secondary_navigation.html.erb +27 -0
- data/app/views/layouts/rails_admin_next/_sidebar_navigation.html.erb +6 -0
- data/app/views/layouts/rails_admin_next/application.html.erb +42 -0
- data/app/views/layouts/rails_admin_next/content.html.erb +22 -0
- data/app/views/layouts/rails_admin_next/modal.js.erb +7 -0
- data/app/views/rails_admin_next/main/_dashboard_history.html.erb +46 -0
- data/app/views/rails_admin_next/main/_delete_notice.html.erb +36 -0
- data/app/views/rails_admin_next/main/_form_action_text.html.erb +2 -0
- data/app/views/rails_admin_next/main/_form_boolean.html.erb +15 -0
- data/app/views/rails_admin_next/main/_form_colorpicker.html.erb +6 -0
- data/app/views/rails_admin_next/main/_form_datetime.html.erb +14 -0
- data/app/views/rails_admin_next/main/_form_enumeration.html.erb +26 -0
- data/app/views/rails_admin_next/main/_form_field.html.erb +2 -0
- data/app/views/rails_admin_next/main/_form_file_upload.html.erb +18 -0
- data/app/views/rails_admin_next/main/_form_filtering_multiselect.html.erb +20 -0
- data/app/views/rails_admin_next/main/_form_filtering_select.html.erb +22 -0
- data/app/views/rails_admin_next/main/_form_multiple_file_upload.html.erb +21 -0
- data/app/views/rails_admin_next/main/_form_nested_many.html.erb +20 -0
- data/app/views/rails_admin_next/main/_form_nested_one.html.erb +19 -0
- data/app/views/rails_admin_next/main/_form_polymorphic_association.html.erb +24 -0
- data/app/views/rails_admin_next/main/_form_text.html.erb +2 -0
- data/app/views/rails_admin_next/main/_pagination.html.erb +54 -0
- data/app/views/rails_admin_next/main/_submit_buttons.html.erb +26 -0
- data/app/views/rails_admin_next/main/bulk_delete.html.erb +19 -0
- data/app/views/rails_admin_next/main/dashboard.html.erb +64 -0
- data/app/views/rails_admin_next/main/delete.html.erb +21 -0
- data/app/views/rails_admin_next/main/edit.html.erb +3 -0
- data/app/views/rails_admin_next/main/export.html.erb +149 -0
- data/app/views/rails_admin_next/main/history.html.erb +80 -0
- data/app/views/rails_admin_next/main/index.html.erb +186 -0
- data/app/views/rails_admin_next/main/new.html.erb +3 -0
- data/app/views/rails_admin_next/main/show.html.erb +30 -0
- data/config/brakeman.ignore +145 -0
- data/config/importmap.rails_admin.rb +29 -0
- data/config/initializers/active_record_extensions.rb +21 -0
- data/config/locales/rails_admin_next.en.yml +158 -0
- data/config/routes.rb +14 -0
- data/lib/generators/rails_admin_next/install_generator.rb +39 -0
- data/lib/generators/rails_admin_next/templates/initializer.erb +40 -0
- data/lib/generators/rails_admin_next/utils.rb +21 -0
- data/lib/rails_admin_next/abstract_model.rb +266 -0
- data/lib/rails_admin_next/adapters/active_record/association.rb +130 -0
- data/lib/rails_admin_next/adapters/active_record/object_extension.rb +13 -0
- data/lib/rails_admin_next/adapters/active_record/property.rb +58 -0
- data/lib/rails_admin_next/adapters/active_record.rb +371 -0
- data/lib/rails_admin_next/config/actions/base.rb +160 -0
- data/lib/rails_admin_next/config/actions/bulk_delete.rb +67 -0
- data/lib/rails_admin_next/config/actions/dashboard.rb +62 -0
- data/lib/rails_admin_next/config/actions/delete.rb +58 -0
- data/lib/rails_admin_next/config/actions/edit.rb +56 -0
- data/lib/rails_admin_next/config/actions/export.rb +47 -0
- data/lib/rails_admin_next/config/actions/history_index.rb +40 -0
- data/lib/rails_admin_next/config/actions/history_show.rb +40 -0
- data/lib/rails_admin_next/config/actions/index.rb +108 -0
- data/lib/rails_admin_next/config/actions/new.rb +69 -0
- data/lib/rails_admin_next/config/actions/show.rb +36 -0
- data/lib/rails_admin_next/config/actions/show_in_app.rb +37 -0
- data/lib/rails_admin_next/config/actions.rb +122 -0
- data/lib/rails_admin_next/config/configurable.rb +107 -0
- data/lib/rails_admin_next/config/const_load_suppressor.rb +78 -0
- data/lib/rails_admin_next/config/fields/association.rb +169 -0
- data/lib/rails_admin_next/config/fields/base.rb +391 -0
- data/lib/rails_admin_next/config/fields/collection_association.rb +90 -0
- data/lib/rails_admin_next/config/fields/factories/action_text.rb +14 -0
- data/lib/rails_admin_next/config/fields/factories/active_storage.rb +34 -0
- data/lib/rails_admin_next/config/fields/factories/association.rb +32 -0
- data/lib/rails_admin_next/config/fields/factories/encrypted_password.rb +28 -0
- data/lib/rails_admin_next/config/fields/factories/enum.rb +23 -0
- data/lib/rails_admin_next/config/fields/factories/password.rb +19 -0
- data/lib/rails_admin_next/config/fields/group.rb +77 -0
- data/lib/rails_admin_next/config/fields/singular_association.rb +62 -0
- data/lib/rails_admin_next/config/fields/types/action_text.rb +20 -0
- data/lib/rails_admin_next/config/fields/types/active_record_enum.rb +62 -0
- data/lib/rails_admin_next/config/fields/types/active_storage.rb +70 -0
- data/lib/rails_admin_next/config/fields/types/all.rb +32 -0
- data/lib/rails_admin_next/config/fields/types/belongs_to_association.rb +48 -0
- data/lib/rails_admin_next/config/fields/types/boolean.rb +70 -0
- data/lib/rails_admin_next/config/fields/types/citext.rb +15 -0
- data/lib/rails_admin_next/config/fields/types/color.rb +43 -0
- data/lib/rails_admin_next/config/fields/types/date.rb +38 -0
- data/lib/rails_admin_next/config/fields/types/datetime.rb +79 -0
- data/lib/rails_admin_next/config/fields/types/decimal.rb +23 -0
- data/lib/rails_admin_next/config/fields/types/enum.rb +52 -0
- data/lib/rails_admin_next/config/fields/types/file_upload.rb +87 -0
- data/lib/rails_admin_next/config/fields/types/float.rb +23 -0
- data/lib/rails_admin_next/config/fields/types/has_and_belongs_to_many_association.rb +16 -0
- data/lib/rails_admin_next/config/fields/types/has_many_association.rb +16 -0
- data/lib/rails_admin_next/config/fields/types/has_one_association.rb +35 -0
- data/lib/rails_admin_next/config/fields/types/hidden.rb +31 -0
- data/lib/rails_admin_next/config/fields/types/inet.rb +15 -0
- data/lib/rails_admin_next/config/fields/types/integer.rb +20 -0
- data/lib/rails_admin_next/config/fields/types/json.rb +37 -0
- data/lib/rails_admin_next/config/fields/types/multiple_active_storage.rb +82 -0
- data/lib/rails_admin_next/config/fields/types/multiple_file_upload.rb +134 -0
- data/lib/rails_admin_next/config/fields/types/numeric.rb +24 -0
- data/lib/rails_admin_next/config/fields/types/password.rb +45 -0
- data/lib/rails_admin_next/config/fields/types/polymorphic_association.rb +118 -0
- data/lib/rails_admin_next/config/fields/types/serialized.rb +28 -0
- data/lib/rails_admin_next/config/fields/types/string.rb +50 -0
- data/lib/rails_admin_next/config/fields/types/string_like.rb +25 -0
- data/lib/rails_admin_next/config/fields/types/text.rb +28 -0
- data/lib/rails_admin_next/config/fields/types/time.rb +39 -0
- data/lib/rails_admin_next/config/fields/types/timestamp.rb +16 -0
- data/lib/rails_admin_next/config/fields/types/uuid.rb +15 -0
- data/lib/rails_admin_next/config/fields/types.rb +29 -0
- data/lib/rails_admin_next/config/fields.rb +88 -0
- data/lib/rails_admin_next/config/groupable.rb +20 -0
- data/lib/rails_admin_next/config/has_description.rb +14 -0
- data/lib/rails_admin_next/config/has_fields.rb +144 -0
- data/lib/rails_admin_next/config/has_groups.rb +27 -0
- data/lib/rails_admin_next/config/hideable.rb +30 -0
- data/lib/rails_admin_next/config/inspectable.rb +39 -0
- data/lib/rails_admin_next/config/lazy_model.rb +74 -0
- data/lib/rails_admin_next/config/model.rb +126 -0
- data/lib/rails_admin_next/config/proxyable/proxy.rb +42 -0
- data/lib/rails_admin_next/config/proxyable.rb +26 -0
- data/lib/rails_admin_next/config/sections/base.rb +36 -0
- data/lib/rails_admin_next/config/sections/create.rb +13 -0
- data/lib/rails_admin_next/config/sections/edit.rb +13 -0
- data/lib/rails_admin_next/config/sections/export.rb +13 -0
- data/lib/rails_admin_next/config/sections/list.rb +63 -0
- data/lib/rails_admin_next/config/sections/modal.rb +12 -0
- data/lib/rails_admin_next/config/sections/nested.rb +12 -0
- data/lib/rails_admin_next/config/sections/show.rb +12 -0
- data/lib/rails_admin_next/config/sections/update.rb +12 -0
- data/lib/rails_admin_next/config/sections.rb +39 -0
- data/lib/rails_admin_next/config.rb +436 -0
- data/lib/rails_admin_next/engine.rb +91 -0
- data/lib/rails_admin_next/extension.rb +35 -0
- data/lib/rails_admin_next/extensions/cancancan/authorization_adapter.rb +90 -0
- data/lib/rails_admin_next/extensions/cancancan.rb +5 -0
- data/lib/rails_admin_next/extensions/controller_extension.rb +8 -0
- data/lib/rails_admin_next/extensions/paper_trail/auditing_adapter.rb +192 -0
- data/lib/rails_admin_next/extensions/paper_trail.rb +5 -0
- data/lib/rails_admin_next/extensions/pundit/authorization_adapter.rb +72 -0
- data/lib/rails_admin_next/extensions/pundit.rb +5 -0
- data/lib/rails_admin_next/extensions/url_for_extension.rb +15 -0
- data/lib/rails_admin_next/icons.rb +143 -0
- data/lib/rails_admin_next/support/composite_keys_serializer.rb +15 -0
- data/lib/rails_admin_next/support/csv_converter.rb +100 -0
- data/lib/rails_admin_next/support/hash_helper.rb +31 -0
- data/lib/rails_admin_next/support/paginated_collection.rb +79 -0
- data/lib/rails_admin_next/version.rb +17 -0
- data/lib/rails_admin_next.rb +72 -0
- data/lib/tasks/rails_admin.rake +40 -0
- data/src/rails_admin/application.js +15 -0
- data/src/rails_admin/base.js +12 -0
- data/src/rails_admin/controllers/alert_controller.js +28 -0
- data/src/rails_admin/controllers/collapse_controller.js +16 -0
- data/src/rails_admin/controllers/dropdown_controller.js +110 -0
- data/src/rails_admin/controllers/feedback_controller.js +73 -0
- data/src/rails_admin/controllers/filter_box_controller.js +346 -0
- data/src/rails_admin/controllers/filtering_multiselect_controller.js +386 -0
- data/src/rails_admin/controllers/filtering_select_controller.js +509 -0
- data/src/rails_admin/controllers/index.js +31 -0
- data/src/rails_admin/controllers/modal_controller.js +142 -0
- data/src/rails_admin/controllers/nested_form_controller.js +117 -0
- data/src/rails_admin/controllers/polymorphic_controller.js +26 -0
- data/src/rails_admin/controllers/remote_form_controller.js +173 -0
- data/src/rails_admin/controllers/sidescroll_controller.js +23 -0
- data/src/rails_admin/dom-ready.js +20 -0
- data/src/rails_admin/dom.js +19 -0
- data/src/rails_admin/i18n.js +20 -0
- data/src/rails_admin/icons.js +64 -0
- data/src/rails_admin/interactions.js +221 -0
- data/src/rails_admin/select_query.js +65 -0
- metadata +346 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
en:
|
|
2
|
+
admin:
|
|
3
|
+
js:
|
|
4
|
+
true: "True"
|
|
5
|
+
false: "False"
|
|
6
|
+
is_present: Is present
|
|
7
|
+
is_blank: Is blank
|
|
8
|
+
date: Date ...
|
|
9
|
+
between_and_: Between ... and ...
|
|
10
|
+
today: Today
|
|
11
|
+
yesterday: Yesterday
|
|
12
|
+
this_week: This week
|
|
13
|
+
last_week: Last week
|
|
14
|
+
time: Time ...
|
|
15
|
+
number: Number ...
|
|
16
|
+
contains: Contains
|
|
17
|
+
does_not_contain: Does not contain
|
|
18
|
+
is_exactly: Is exactly
|
|
19
|
+
starts_with: Starts with
|
|
20
|
+
ends_with: Ends with
|
|
21
|
+
too_many_objects: "Too many objects, use search box above"
|
|
22
|
+
no_objects: "No objects found"
|
|
23
|
+
clear: Clear
|
|
24
|
+
loading: "Loading..."
|
|
25
|
+
toggle_navigation: Toggle navigation
|
|
26
|
+
home:
|
|
27
|
+
name: "Home"
|
|
28
|
+
pagination:
|
|
29
|
+
previous: "« Prev"
|
|
30
|
+
next: "Next »"
|
|
31
|
+
truncate: "…"
|
|
32
|
+
misc:
|
|
33
|
+
search: "Search"
|
|
34
|
+
filter: "Filter"
|
|
35
|
+
reset_filters: "Reset filters"
|
|
36
|
+
refresh: "Refresh"
|
|
37
|
+
show_all: "Show all"
|
|
38
|
+
add_filter: "Add filter"
|
|
39
|
+
bulk_menu_title: "Selected items"
|
|
40
|
+
remove: "Remove"
|
|
41
|
+
add_new: "Add new"
|
|
42
|
+
chose_all: "Choose all"
|
|
43
|
+
clear_all: "Clear all"
|
|
44
|
+
up: "Up"
|
|
45
|
+
down: "Down"
|
|
46
|
+
navigation: "Navigation"
|
|
47
|
+
root_navigation: "Actions"
|
|
48
|
+
navigation_static_label: "Links"
|
|
49
|
+
log_out: "Log out"
|
|
50
|
+
time_ago: "%{time} ago"
|
|
51
|
+
ago: "ago"
|
|
52
|
+
more: "Plus %{count} more %{models_name}"
|
|
53
|
+
flash:
|
|
54
|
+
successful: "%{name} successfully %{action}"
|
|
55
|
+
error: "%{name} failed to be %{action}"
|
|
56
|
+
noaction: "No actions were taken"
|
|
57
|
+
model_not_found: "Model '%{model}' could not be found"
|
|
58
|
+
object_not_found: "%{model} with id '%{id}' could not be found"
|
|
59
|
+
table_headers:
|
|
60
|
+
model_name: "Model name"
|
|
61
|
+
last_created: "Last created"
|
|
62
|
+
records: "Records"
|
|
63
|
+
username: "User"
|
|
64
|
+
changes: "Changes"
|
|
65
|
+
created_at: "Date/Time"
|
|
66
|
+
item: "Item"
|
|
67
|
+
message: "Message"
|
|
68
|
+
actions:
|
|
69
|
+
dashboard:
|
|
70
|
+
title: "Site Administration"
|
|
71
|
+
menu: "Dashboard"
|
|
72
|
+
breadcrumb: "Dashboard"
|
|
73
|
+
index:
|
|
74
|
+
title: "List of %{model_label_plural}"
|
|
75
|
+
menu: "List"
|
|
76
|
+
breadcrumb: "%{model_label_plural}"
|
|
77
|
+
no_records: "No records found"
|
|
78
|
+
show:
|
|
79
|
+
title: "Details for %{model_label} '%{object_label}'"
|
|
80
|
+
menu: "Show"
|
|
81
|
+
breadcrumb: "%{object_label}"
|
|
82
|
+
show_in_app:
|
|
83
|
+
menu: "Show in app"
|
|
84
|
+
new:
|
|
85
|
+
title: "New %{model_label}"
|
|
86
|
+
menu: "Add new"
|
|
87
|
+
breadcrumb: "New"
|
|
88
|
+
link: "Add a new %{model_label}"
|
|
89
|
+
done: "created"
|
|
90
|
+
edit:
|
|
91
|
+
title: "Edit %{model_label} '%{object_label}'"
|
|
92
|
+
menu: "Edit"
|
|
93
|
+
breadcrumb: "Edit"
|
|
94
|
+
link: "Edit this %{model_label}"
|
|
95
|
+
done: "updated"
|
|
96
|
+
delete:
|
|
97
|
+
title: "Delete %{model_label} '%{object_label}'"
|
|
98
|
+
menu: "Delete"
|
|
99
|
+
breadcrumb: "Delete"
|
|
100
|
+
link: "Delete '%{object_label}'"
|
|
101
|
+
done: "deleted"
|
|
102
|
+
bulk_delete:
|
|
103
|
+
title: "Delete %{model_label_plural}"
|
|
104
|
+
menu: "Multiple delete"
|
|
105
|
+
breadcrumb: "Multiple delete"
|
|
106
|
+
bulk_link: "Delete selected %{model_label_plural}"
|
|
107
|
+
export:
|
|
108
|
+
title: "Export %{model_label_plural}"
|
|
109
|
+
menu: "Export"
|
|
110
|
+
breadcrumb: "Export"
|
|
111
|
+
link: "Export found %{model_label_plural}"
|
|
112
|
+
bulk_link: "Export selected %{model_label_plural}"
|
|
113
|
+
done: "exported"
|
|
114
|
+
history_index:
|
|
115
|
+
title: "History for %{model_label_plural}"
|
|
116
|
+
menu: "History"
|
|
117
|
+
breadcrumb: "History"
|
|
118
|
+
history_show:
|
|
119
|
+
title: "History for %{model_label} '%{object_label}'"
|
|
120
|
+
menu: "History"
|
|
121
|
+
breadcrumb: "History"
|
|
122
|
+
form:
|
|
123
|
+
cancel: "Cancel"
|
|
124
|
+
basic_info: "Basic info"
|
|
125
|
+
required: "Required"
|
|
126
|
+
optional: "Optional"
|
|
127
|
+
one_char: "character"
|
|
128
|
+
char_length_up_to: "length up to"
|
|
129
|
+
char_length_of: "length of"
|
|
130
|
+
save: "Save"
|
|
131
|
+
save_and_add_another: "Save and add another"
|
|
132
|
+
save_and_edit: "Save and edit"
|
|
133
|
+
delete_file: "Delete '%{field_label}' #%{number}"
|
|
134
|
+
all_of_the_following_related_items_will_be_deleted: "? The following related items may be deleted or orphaned:"
|
|
135
|
+
are_you_sure_you_want_to_delete_the_object: "Are you sure you want to delete this %{model_name}"
|
|
136
|
+
confirmation: "Yes, I'm sure"
|
|
137
|
+
bulk_delete: "The following objects will be deleted, which may delete or orphan some of their related dependencies:"
|
|
138
|
+
new_model: "%{name} (new)"
|
|
139
|
+
export:
|
|
140
|
+
confirmation: "Export to %{name}"
|
|
141
|
+
select: "Select fields to export"
|
|
142
|
+
select_all_fields: "Select All Fields"
|
|
143
|
+
fields_from: "Fields from %{name}"
|
|
144
|
+
fields_from_associated: "Fields from associated %{name}"
|
|
145
|
+
display: "Display %{name}: %{type}"
|
|
146
|
+
options_for: "Options for %{name}"
|
|
147
|
+
empty_value_for_associated_objects: "<empty>"
|
|
148
|
+
click_to_reverse_selection: "Click to reverse selection"
|
|
149
|
+
csv:
|
|
150
|
+
header_for_root_methods: "%{name}" # 'model' is available
|
|
151
|
+
header_for_association_methods: "%{name} [%{association}]"
|
|
152
|
+
encoding_to: "Encode to"
|
|
153
|
+
encoding_to_help: "Choose output encoding. Leave empty to let current input encoding untouched: (%{name})"
|
|
154
|
+
skip_header: "No header"
|
|
155
|
+
skip_header_help: "Do not output a header (no fields description)"
|
|
156
|
+
default_col_sep: ","
|
|
157
|
+
col_sep: "Column separator"
|
|
158
|
+
col_sep_help: "Leave blank for default ('%{value}')" # value is default_col_sep
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RailsAdminNext::Engine.routes.draw do
|
|
4
|
+
controller "main" do
|
|
5
|
+
RailsAdminNext::Config::Actions.all(:root).each { |action| match "/#{action.route_fragment}", action: action.action_name, as: action.action_name, via: action.http_methods }
|
|
6
|
+
scope ":model_name" do
|
|
7
|
+
RailsAdminNext::Config::Actions.all(:collection).each { |action| match "/#{action.route_fragment}", action: action.action_name, as: action.action_name, via: action.http_methods }
|
|
8
|
+
post "/bulk_action", action: :bulk_action, as: "bulk_action"
|
|
9
|
+
scope ":id" do
|
|
10
|
+
RailsAdminNext::Config::Actions.all(:member).each { |action| match "/#{action.route_fragment}", action: action.action_name, as: action.action_name, via: action.http_methods }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails_admin_next/version"
|
|
5
|
+
require File.expand_path("utils", __dir__)
|
|
6
|
+
|
|
7
|
+
module RailsAdminNext
|
|
8
|
+
class InstallGenerator < Rails::Generators::Base
|
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
|
10
|
+
include Generators::Utils::InstanceMethods
|
|
11
|
+
|
|
12
|
+
argument :_namespace, type: :string, required: false, desc: "RailsAdminNext url namespace"
|
|
13
|
+
desc "RailsAdminNext installation generator"
|
|
14
|
+
|
|
15
|
+
# RailsAdminNext ships a single zero-build asset path: browser-native ESM + CSS served by Propshaft and
|
|
16
|
+
# pinned with an engine-owned importmap. The engine is self-contained, so installation is just the
|
|
17
|
+
# mount point and an initializer — no bundler detection, yarn add, CSS build, or generated pins.
|
|
18
|
+
def install
|
|
19
|
+
if File.read(File.join(destination_root, "config/routes.rb")).include?("mount RailsAdminNext::Engine")
|
|
20
|
+
display "Skipped route addition, since it's already there"
|
|
21
|
+
else
|
|
22
|
+
namespace = ask_for("Where do you want to mount RailsAdminNext?", "admin", _namespace)
|
|
23
|
+
route("mount RailsAdminNext::Engine => '/#{namespace}', as: 'rails_admin_next'")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if File.exist? File.join(destination_root, "config/initializers/rails_admin_next.rb")
|
|
27
|
+
display "Skipped initializer creation, since config/initializers/rails_admin_next.rb already exists"
|
|
28
|
+
else
|
|
29
|
+
template "initializer.erb", "config/initializers/rails_admin_next.rb"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
display <<~MSG
|
|
33
|
+
RailsAdminNext uses a zero-build asset pipeline: browser-native ESM and CSS served by Propshaft and
|
|
34
|
+
pinned through an engine-owned importmap. There is no yarn/build step. Make sure your app uses
|
|
35
|
+
Propshaft and importmap-rails (both are bundled automatically as RailsAdminNext dependencies).
|
|
36
|
+
MSG
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
RailsAdminNext.config do |config|
|
|
2
|
+
### Popular gems integration
|
|
3
|
+
|
|
4
|
+
## == Devise ==
|
|
5
|
+
# config.authenticate_with do
|
|
6
|
+
# warden.authenticate! scope: :user
|
|
7
|
+
# end
|
|
8
|
+
# config.current_user_method(&:current_user)
|
|
9
|
+
|
|
10
|
+
## == CancanCan ==
|
|
11
|
+
# config.authorize_with :cancancan
|
|
12
|
+
|
|
13
|
+
## == Pundit ==
|
|
14
|
+
# config.authorize_with :pundit
|
|
15
|
+
|
|
16
|
+
## == PaperTrail ==
|
|
17
|
+
# config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0
|
|
18
|
+
|
|
19
|
+
### More at https://github.com/railsadminteam/rails_admin/wiki/Base-configuration
|
|
20
|
+
|
|
21
|
+
## == Gravatar integration ==
|
|
22
|
+
## To disable Gravatar integration in Navigation Bar set to false
|
|
23
|
+
# config.show_gravatar = true
|
|
24
|
+
|
|
25
|
+
config.actions do
|
|
26
|
+
dashboard # mandatory
|
|
27
|
+
index # mandatory
|
|
28
|
+
new
|
|
29
|
+
export
|
|
30
|
+
bulk_delete
|
|
31
|
+
show
|
|
32
|
+
edit
|
|
33
|
+
delete
|
|
34
|
+
show_in_app
|
|
35
|
+
|
|
36
|
+
## With an audit adapter, you can add:
|
|
37
|
+
# history_index
|
|
38
|
+
# history_show
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAdminNext
|
|
4
|
+
module Generators
|
|
5
|
+
module Utils
|
|
6
|
+
module InstanceMethods
|
|
7
|
+
def display(output, color = :green)
|
|
8
|
+
say(" - #{output}", color)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def ask_for(wording, default_value = nil, override_if_present_value = nil)
|
|
12
|
+
if override_if_present_value.present?
|
|
13
|
+
display("Using [#{override_if_present_value}] for question '#{wording}'") && override_if_present_value
|
|
14
|
+
else
|
|
15
|
+
ask(" ? #{wording} Press <enter> for [#{default_value}] >", :yellow).presence || default_value
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAdminNext
|
|
4
|
+
class AbstractModel
|
|
5
|
+
cattr_accessor :all
|
|
6
|
+
attr_reader :adapter, :model_name
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def reset
|
|
10
|
+
@@all = nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def all(adapter = nil)
|
|
14
|
+
@@all ||= Config.models_pool.collect { |m| new(m) }.compact
|
|
15
|
+
adapter ? @@all.select { |m| m.adapter == adapter } : @@all
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias_method :old_new, :new
|
|
19
|
+
def new(m)
|
|
20
|
+
m = m.constantize unless m.is_a?(Class)
|
|
21
|
+
((am = old_new(m)).model && am.adapter) ? am : nil
|
|
22
|
+
rescue *([LoadError, NameError] + (defined?(ActiveRecord) ? ["ActiveRecord::NoDatabaseError".constantize, "ActiveRecord::ConnectionNotEstablished".constantize] : []))
|
|
23
|
+
puts "[RailsAdminNext] Could not load model #{m}, assuming model is non existing. (#{$ERROR_INFO})" unless Rails.env.test?
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@@polymorphic_parents = {}
|
|
28
|
+
|
|
29
|
+
def polymorphic_parents(adapter, model_name, name)
|
|
30
|
+
@@polymorphic_parents[adapter.to_sym] ||= {}.tap do |hash|
|
|
31
|
+
all(adapter).each do |am|
|
|
32
|
+
am.associations.select(&:as).each do |association|
|
|
33
|
+
(hash[[association.klass.to_s.underscore, association.as].join("_").to_sym] ||= []) << am.model
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
@@polymorphic_parents[adapter.to_sym][[model_name.to_s.underscore, name].join("_").to_sym]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# For testing
|
|
41
|
+
def reset_polymorphic_parents
|
|
42
|
+
@@polymorphic_parents = {}
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize(model_or_model_name)
|
|
47
|
+
@model_name = model_or_model_name.to_s
|
|
48
|
+
ancestors = model.ancestors.collect(&:to_s)
|
|
49
|
+
return unless ancestors.include?("ActiveRecord::Base") && !model.abstract_class? && model.table_exists?
|
|
50
|
+
|
|
51
|
+
initialize_active_record
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Re-resolve via constantize on every call instead of caching @model: Rails reloads
|
|
55
|
+
# classes in development, and a cached Class object would go stale after a reload.
|
|
56
|
+
def model
|
|
57
|
+
@model_name.constantize
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def quoted_table_name
|
|
61
|
+
table_name
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def quote_column_name(name)
|
|
65
|
+
name
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_s
|
|
69
|
+
model.to_s
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def config
|
|
73
|
+
Config.model self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def to_param
|
|
77
|
+
@model_name.split("::").collect(&:underscore).join("~")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def param_key
|
|
81
|
+
@model_name.split("::").collect(&:underscore).join("_")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def pretty_name
|
|
85
|
+
model.model_name.human
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def where(conditions)
|
|
89
|
+
model.where(conditions)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def each_associated_children(object)
|
|
93
|
+
associations.each do |association|
|
|
94
|
+
case association.type
|
|
95
|
+
when :has_one
|
|
96
|
+
child = object.send(association.name)
|
|
97
|
+
yield(association, [child]) if child
|
|
98
|
+
when :has_many
|
|
99
|
+
children = object.send(association.name)
|
|
100
|
+
yield(association, Array.new(children))
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def format_id(id)
|
|
106
|
+
id
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def parse_id(id)
|
|
110
|
+
id
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
|
|
115
|
+
def initialize_active_record
|
|
116
|
+
@adapter = :active_record
|
|
117
|
+
require "rails_admin_next/adapters/active_record"
|
|
118
|
+
extend Adapters::ActiveRecord
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def parse_field_value(field, value)
|
|
122
|
+
value.is_a?(Array) ? value.map { |v| field.parse_value(v) } : field.parse_value(value)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
class StatementBuilder
|
|
126
|
+
def initialize(column, type, value, operator)
|
|
127
|
+
@column = column
|
|
128
|
+
@type = type
|
|
129
|
+
@value = value
|
|
130
|
+
@operator = operator
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def to_statement
|
|
134
|
+
return if [@operator, @value].any? { |v| v == "_discard" }
|
|
135
|
+
|
|
136
|
+
unary_operators[@operator] || unary_operators[@value] ||
|
|
137
|
+
build_statement_for_type_generic
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
protected
|
|
141
|
+
|
|
142
|
+
def get_filtering_duration
|
|
143
|
+
FilteringDuration.new(@operator, @value).get_duration
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def build_statement_for_type_generic
|
|
147
|
+
build_statement_for_type || begin
|
|
148
|
+
case @type
|
|
149
|
+
when :date
|
|
150
|
+
build_statement_for_date
|
|
151
|
+
when :datetime, :timestamp, :time
|
|
152
|
+
build_statement_for_datetime_or_timestamp
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def build_statement_for_type
|
|
158
|
+
raise "You must override build_statement_for_type in your StatementBuilder"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def build_statement_for_integer_decimal_or_float
|
|
162
|
+
case @value
|
|
163
|
+
when Array
|
|
164
|
+
val, range_begin, range_end = *@value.collect do |v|
|
|
165
|
+
next unless v.to_i.to_s == v || v.to_f.to_s == v
|
|
166
|
+
|
|
167
|
+
(@type == :integer) ? v.to_i : v.to_f
|
|
168
|
+
end
|
|
169
|
+
case @operator
|
|
170
|
+
when "between"
|
|
171
|
+
range_filter(range_begin, range_end)
|
|
172
|
+
else
|
|
173
|
+
column_for_value(val) if val
|
|
174
|
+
end
|
|
175
|
+
else
|
|
176
|
+
if @value.to_i.to_s == @value || @value.to_f.to_s == @value
|
|
177
|
+
(@type == :integer) ? column_for_value(@value.to_i) : column_for_value(@value.to_f)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def build_statement_for_date
|
|
183
|
+
start_date, end_date = get_filtering_duration
|
|
184
|
+
if start_date
|
|
185
|
+
start_date = begin
|
|
186
|
+
start_date.to_date
|
|
187
|
+
rescue
|
|
188
|
+
nil
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
if end_date
|
|
192
|
+
end_date = begin
|
|
193
|
+
end_date.to_date
|
|
194
|
+
rescue
|
|
195
|
+
nil
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
range_filter(start_date, end_date)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def build_statement_for_datetime_or_timestamp
|
|
202
|
+
start_date, end_date = get_filtering_duration
|
|
203
|
+
start_date = start_date.beginning_of_day if start_date.is_a?(Date)
|
|
204
|
+
end_date = end_date.end_of_day if end_date.is_a?(Date)
|
|
205
|
+
range_filter(start_date, end_date)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def unary_operators
|
|
209
|
+
raise "You must override unary_operators in your StatementBuilder"
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def range_filter(_min, _max)
|
|
213
|
+
raise "You must override range_filter in your StatementBuilder"
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
class FilteringDuration
|
|
217
|
+
def initialize(operator, value)
|
|
218
|
+
@value = value
|
|
219
|
+
@operator = operator
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def get_duration
|
|
223
|
+
case @operator
|
|
224
|
+
when "between" then between
|
|
225
|
+
when "today" then today
|
|
226
|
+
when "yesterday" then yesterday
|
|
227
|
+
when "this_week" then this_week
|
|
228
|
+
when "last_week" then last_week
|
|
229
|
+
else default
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def today
|
|
234
|
+
[Date.today, Date.today]
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def yesterday
|
|
238
|
+
[Date.yesterday, Date.yesterday]
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def this_week
|
|
242
|
+
[Date.today.beginning_of_week, Date.today.end_of_week]
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def last_week
|
|
246
|
+
[1.week.ago.to_date.beginning_of_week,
|
|
247
|
+
1.week.ago.to_date.end_of_week]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def between
|
|
251
|
+
[@value[1], @value[2]]
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def default
|
|
255
|
+
[default_date, default_date]
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
private
|
|
259
|
+
|
|
260
|
+
def default_date
|
|
261
|
+
Array.wrap(@value).first
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAdminNext
|
|
4
|
+
module Adapters
|
|
5
|
+
module ActiveRecord
|
|
6
|
+
class Association
|
|
7
|
+
attr_reader :association, :model
|
|
8
|
+
|
|
9
|
+
def initialize(association, model)
|
|
10
|
+
@association = association
|
|
11
|
+
@model = model
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def name
|
|
15
|
+
association.name.to_sym
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def pretty_name
|
|
19
|
+
name.to_s.tr("_", " ").capitalize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def type
|
|
23
|
+
association.macro
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def field_type
|
|
27
|
+
if polymorphic?
|
|
28
|
+
:polymorphic_association
|
|
29
|
+
else
|
|
30
|
+
:"#{association.macro}_association"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def klass
|
|
35
|
+
if options[:polymorphic]
|
|
36
|
+
polymorphic_parents(:active_record, association.active_record.name.to_s, name) || []
|
|
37
|
+
else
|
|
38
|
+
association.klass
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def primary_key
|
|
43
|
+
return nil if polymorphic?
|
|
44
|
+
|
|
45
|
+
value =
|
|
46
|
+
case type
|
|
47
|
+
when :has_one
|
|
48
|
+
association.klass.primary_key
|
|
49
|
+
else
|
|
50
|
+
association.association_primary_key
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if value.is_a? Array
|
|
54
|
+
:id
|
|
55
|
+
else
|
|
56
|
+
value.to_sym
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def foreign_key
|
|
61
|
+
if association.options[:query_constraints].present?
|
|
62
|
+
association.options[:query_constraints].map(&:to_sym)
|
|
63
|
+
elsif association.foreign_key.is_a?(Array)
|
|
64
|
+
association.foreign_key.map(&:to_sym)
|
|
65
|
+
else
|
|
66
|
+
association.foreign_key.to_sym
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def foreign_key_nullable?
|
|
71
|
+
return true if foreign_key.nil? || type != :has_many
|
|
72
|
+
|
|
73
|
+
(column = klass.columns_hash[foreign_key.to_s]).nil? || column.null
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def foreign_type
|
|
77
|
+
options[:foreign_type].try(:to_sym) || :"#{name}_type" if options[:polymorphic]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def foreign_inverse_of
|
|
81
|
+
nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def key_accessor
|
|
85
|
+
case type
|
|
86
|
+
when :has_many, :has_and_belongs_to_many
|
|
87
|
+
:"#{name.to_s.singularize}_ids"
|
|
88
|
+
when :has_one
|
|
89
|
+
:"#{name}_id"
|
|
90
|
+
else
|
|
91
|
+
if foreign_key.is_a?(Array)
|
|
92
|
+
:"#{name}_id"
|
|
93
|
+
else
|
|
94
|
+
foreign_key
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def as
|
|
100
|
+
options[:as].try :to_sym
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def polymorphic?
|
|
104
|
+
options[:polymorphic] || false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def inverse_of
|
|
108
|
+
options[:inverse_of].try :to_sym
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def read_only?
|
|
112
|
+
(klass.all.instance_exec(&scope).readonly_value if scope.is_a?(Proc) && scope.arity == 0) ||
|
|
113
|
+
association.nested? ||
|
|
114
|
+
false
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def nested_options
|
|
118
|
+
model.nested_attributes_options.try { |o| o[name.to_sym] }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def association?
|
|
122
|
+
true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
delegate :options, :scope, to: :association, prefix: false
|
|
126
|
+
delegate :polymorphic_parents, to: RailsAdminNext::AbstractModel
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|