avo 3.0.0.beta1 → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +5 -5
- data/Gemfile.lock +81 -92
- data/{public/avo-assets/avo.css → app/assets/builds/avo.base.css} +686 -728
- data/app/assets/builds/avo.base.js +93804 -0
- data/app/assets/builds/avo.base.js.map +7 -0
- data/app/assets/stylesheets/avo.base.css +2 -1
- data/app/assets/svgs/failed_to_load.svg +1 -0
- data/app/assets/svgs/grid-empty-state.svg +1 -0
- data/app/assets/svgs/table-empty-state.svg +1 -0
- data/app/assets/svgs/triangle-up.svg +1 -1
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +16 -42
- data/app/components/avo/alert_component.html.erb +1 -1
- data/app/components/avo/base_component.rb +7 -7
- data/app/components/avo/field_wrapper_component.html.erb +4 -4
- data/app/components/avo/field_wrapper_component.rb +1 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +5 -5
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +4 -8
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/code_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/common/files_list_viewer_component.html.erb +5 -0
- data/app/components/avo/fields/common/files_list_viewer_component.rb +8 -0
- data/app/components/avo/fields/common/heading_component.html.erb +1 -1
- data/app/components/avo/fields/common/single_file_viewer_component.html.erb +56 -0
- data/app/components/avo/fields/common/single_file_viewer_component.rb +55 -0
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/file_field/edit_component.html.erb +2 -4
- data/app/components/avo/fields/file_field/edit_component.rb +0 -1
- data/app/components/avo/fields/file_field/index_component.rb +2 -2
- data/app/components/avo/fields/file_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +2 -4
- data/app/components/avo/fields/files_field/edit_component.rb +0 -1
- data/app/components/avo/fields/files_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_many_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.html.erb +4 -5
- data/app/components/avo/fields/has_one_field/show_component.rb +2 -6
- data/app/components/avo/fields/index_component.rb +0 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +3 -4
- data/app/components/avo/fields/markdown_field/show_component.html.erb +3 -3
- data/app/components/avo/fields/number_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/select_field/edit_component.html.erb +1 -2
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +2 -3
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -2
- data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.rb +12 -0
- data/app/components/avo/index/grid_item_component.html.erb +35 -9
- data/app/components/avo/index/grid_item_component.rb +10 -36
- data/app/components/avo/index/resource_controls_component.rb +11 -8
- data/app/components/avo/index/resource_table_component.rb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +5 -10
- data/app/components/avo/item_switcher_component.rb +1 -2
- data/app/components/avo/modal_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +1 -6
- data/app/components/avo/panel_component.rb +0 -1
- data/app/components/avo/profile_item_component.html.erb +2 -17
- data/app/components/avo/profile_item_component.rb +1 -13
- data/app/components/avo/referrer_params_component.html.erb +0 -2
- data/app/components/avo/resource_component.rb +6 -69
- data/app/components/avo/resource_sidebar_component.rb +1 -1
- data/app/components/avo/sidebar/link_component.html.erb +0 -2
- data/app/components/avo/sidebar/link_component.rb +3 -5
- data/app/components/avo/sidebar_component.html.erb +3 -3
- data/app/components/avo/sidebar_component.rb +4 -4
- data/app/components/avo/sidebar_profile_component.html.erb +27 -27
- data/app/components/avo/views/resource_edit_component.html.erb +5 -5
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +10 -19
- data/app/components/avo/views/resource_index_component.rb +16 -22
- data/app/components/avo/views/resource_show_component.html.erb +4 -4
- data/app/controllers/avo/actions_controller.rb +20 -20
- data/app/controllers/avo/application_controller.rb +67 -90
- data/app/controllers/avo/associations_controller.rb +7 -5
- data/app/controllers/avo/attachments_controller.rb +7 -22
- data/app/controllers/avo/base_controller.rb +35 -47
- data/app/controllers/avo/home_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +16 -20
- data/app/controllers/concerns/avo/initializes_avo.rb +8 -3
- data/app/helpers/avo/application_helper.rb +6 -13
- data/app/javascript/js/application.js +0 -2
- data/app/javascript/js/controllers/fields/{easy_mde_controller.js → simple_mde_controller.js} +3 -4
- data/app/javascript/js/controllers/search_controller.js +1 -3
- data/app/javascript/js/controllers.js +2 -2
- data/app/views/avo/actions/show.html.erb +3 -5
- data/app/views/avo/associations/new.html.erb +3 -3
- data/app/views/avo/debug/status.html.erb +5 -6
- data/app/views/avo/home/index.html.erb +1 -1
- data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
- data/app/views/avo/partials/_footer.html.erb +1 -1
- data/app/views/avo/partials/_javascript.html.erb +1 -1
- data/app/views/avo/partials/_navbar.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +8 -0
- data/app/views/avo/partials/_view_toggle_button.html.erb +0 -9
- data/app/views/avo/private/design.html.erb +2 -2
- data/app/views/layouts/avo/application.html.erb +3 -2
- data/avo.gemspec +1 -2
- data/config/initializers/pagy.rb +10 -12
- data/config/routes.rb +5 -5
- data/db/factories.rb +0 -17
- data/lib/avo/app.rb +165 -0
- data/lib/avo/base_action.rb +18 -31
- data/lib/avo/base_resource.rb +213 -238
- data/lib/avo/concerns/breadcrumbs.rb +2 -2
- data/lib/avo/concerns/can_replace_items.rb +7 -3
- data/lib/avo/concerns/filters_session_handler.rb +4 -5
- data/lib/avo/concerns/has_item_type.rb +0 -4
- data/lib/avo/concerns/has_items.rb +115 -93
- data/lib/avo/concerns/is_visible.rb +1 -1
- data/lib/avo/concerns/model_class_constantized.rb +2 -0
- data/lib/avo/configuration.rb +8 -9
- data/lib/avo/current.rb +1 -35
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/dynamic_router.rb +2 -13
- data/lib/avo/engine.rb +13 -11
- data/lib/avo/execution_context.rb +2 -4
- data/lib/avo/fields/base_field.rb +14 -51
- data/lib/avo/fields/belongs_to_field.rb +13 -20
- data/lib/avo/fields/concerns/is_searchable.rb +1 -1
- data/lib/avo/fields/concerns/use_resource.rb +1 -1
- data/lib/avo/fields/date_field.rb +3 -16
- data/lib/avo/fields/field_manager.rb +3 -13
- data/lib/avo/fields/file_field.rb +0 -2
- data/lib/avo/fields/files_field.rb +0 -6
- data/lib/avo/fields/has_base_field.rb +5 -5
- data/lib/avo/fields/has_one_field.rb +1 -2
- data/lib/avo/fields/id_field.rb +1 -2
- data/lib/avo/filters/base_filter.rb +0 -9
- data/lib/avo/grid_collector.rb +40 -0
- data/lib/avo/html/builder.rb +1 -3
- data/lib/avo/licensing/h_q.rb +6 -11
- data/lib/avo/licensing/license.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/licensing/{nil_license.rb → null_license.rb} +1 -1
- data/lib/avo/loaders/fields_loader.rb +1 -7
- data/lib/avo/plugin.rb +0 -10
- data/lib/avo/plugin_manager.rb +4 -2
- data/lib/avo/reloader.rb +1 -1
- data/lib/avo/resources/controls/actions_list.rb +1 -2
- data/lib/avo/resources/controls/create_button.rb +1 -1
- data/lib/avo/resources/controls/delete_button.rb +1 -1
- data/lib/avo/resources/controls/detach_button.rb +1 -1
- data/lib/avo/resources/controls/edit_button.rb +1 -1
- data/lib/avo/resources/controls/show_button.rb +1 -1
- data/lib/avo/resources/items/holder.rb +5 -13
- data/lib/avo/resources/items/item_group.rb +0 -1
- data/lib/avo/resources/resource_manager.rb +18 -11
- data/lib/avo/services/debug_service.rb +5 -6
- data/lib/avo/services/telemetry_service.rb +2 -3
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +25 -109
- data/lib/generators/avo/action_generator.rb +8 -8
- data/lib/generators/avo/card/chartkick_generator.rb +18 -0
- data/lib/generators/avo/card/metric_generator.rb +18 -0
- data/lib/generators/avo/card/partial_generator.rb +19 -0
- data/lib/generators/avo/eject_generator.rb +0 -1
- data/lib/generators/avo/filter_generator.rb +8 -8
- data/lib/generators/avo/install_generator.rb +1 -11
- data/lib/generators/avo/resource_generator.rb +4 -22
- data/lib/generators/avo/tailwindcss/install_generator.rb +1 -4
- data/lib/generators/avo/templates/action.tt +5 -7
- data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
- data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
- data/lib/generators/avo/templates/dashboards/dashboard.tt +3 -5
- data/lib/generators/avo/templates/initializer/avo.tt +2 -4
- data/lib/generators/avo/templates/resource/resource.tt +6 -6
- data/lib/generators/avo/templates/scope.tt +1 -1
- data/lib/generators/avo/templates/standalone_action.tt +8 -0
- data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
- data/lib/tasks/avo_tasks.rake +0 -5
- metadata +19 -56
- data/app/assets/svgs/map-empty-state.svg +0 -35
- data/app/assets/svgs/map-view-type.svg +0 -3
- data/app/components/avo/fields/area_field/edit_component.html.erb +0 -7
- data/app/components/avo/fields/area_field/edit_component.rb +0 -4
- data/app/components/avo/fields/area_field/show_component.html.erb +0 -8
- data/app/components/avo/fields/area_field/show_component.rb +0 -4
- data/app/components/avo/fields/common/files/controls_component.html.erb +0 -29
- data/app/components/avo/fields/common/files/controls_component.rb +0 -19
- data/app/components/avo/fields/common/files/list_viewer_component.html.erb +0 -20
- data/app/components/avo/fields/common/files/list_viewer_component.rb +0 -41
- data/app/components/avo/fields/common/files/view_type/grid_component.html.erb +0 -27
- data/app/components/avo/fields/common/files/view_type/grid_component.rb +0 -51
- data/app/components/avo/fields/common/files/view_type/list_component.html.erb +0 -22
- data/app/components/avo/fields/common/files/view_type/list_component.rb +0 -15
- data/app/components/avo/fields/location_field/edit_component.html.erb +0 -22
- data/app/components/avo/fields/location_field/edit_component.rb +0 -4
- data/app/components/avo/fields/location_field/show_component.html.erb +0 -7
- data/app/components/avo/fields/location_field/show_component.rb +0 -4
- data/app/components/avo/index/resource_map_component.html.erb +0 -16
- data/app/components/avo/index/resource_map_component.rb +0 -109
- data/app/components/avo/row_component.html.erb +0 -3
- data/app/components/avo/row_component.rb +0 -12
- data/app/views/avo/attachments/destroy.turbo_stream.erb +0 -7
- data/app/views/avo/partials/_profile_menu_extra.html.erb +0 -2
- data/lib/avo/concerns/has_description.rb +0 -23
- data/lib/avo/fields/area_field.rb +0 -39
- data/lib/avo/fields/concerns/file_authorization.rb +0 -31
- data/lib/avo/fields/location_field.rb +0 -86
- data/lib/avo/resources/items/row.rb +0 -54
- data/lib/generators/avo/card_generator.rb +0 -27
- data/public/avo-assets/avo.base.css +0 -10542
- data/public/avo-assets/avo.base.js +0 -949
- data/public/avo-assets/avo.base.js.map +0 -7
- data/public/avo-assets/avo.js +0 -513
- data/public/avo-assets/avo.js.map +0 -7
@@ -7,10 +7,10 @@ module Avo
|
|
7
7
|
end
|
8
8
|
|
9
9
|
include Avo::InitializesAvo
|
10
|
+
include Pagy::Backend
|
10
11
|
include Avo::ApplicationHelper
|
11
12
|
include Avo::UrlHelpers
|
12
13
|
include Avo::Concerns::Breadcrumbs
|
13
|
-
include Pagy::Backend
|
14
14
|
|
15
15
|
protect_from_forgery with: :exception
|
16
16
|
around_action :set_avo_locale
|
@@ -61,49 +61,6 @@ module Avo
|
|
61
61
|
|
62
62
|
private
|
63
63
|
|
64
|
-
# Get the pluralized resource name for this request
|
65
|
-
# Ex: projects, teams, users
|
66
|
-
def resource_name
|
67
|
-
return params[:resource_name] if params[:resource_name].present?
|
68
|
-
|
69
|
-
return controller_name if controller_name.present?
|
70
|
-
|
71
|
-
begin
|
72
|
-
request.path
|
73
|
-
.match(/\/?#{Avo.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
|
74
|
-
.captures
|
75
|
-
.first
|
76
|
-
rescue
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def related_resource_name
|
81
|
-
params[:related_name]
|
82
|
-
end
|
83
|
-
|
84
|
-
# Gets the Avo resource for this request based on the request from the `resource_name` "param"
|
85
|
-
# Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
|
86
|
-
def resource
|
87
|
-
resource = Avo.resource_manager.get_resource @resource_name.to_s.camelize.singularize
|
88
|
-
|
89
|
-
return resource if resource.present?
|
90
|
-
|
91
|
-
Avo.resource_manager.get_resource_by_controller_name @resource_name
|
92
|
-
end
|
93
|
-
|
94
|
-
def related_resource
|
95
|
-
# Find the field from the parent resource
|
96
|
-
field = @resource.get_field params[:related_name]
|
97
|
-
|
98
|
-
return field.use_resource if field&.use_resource.present?
|
99
|
-
|
100
|
-
reflection = @record._reflections[params[:related_name]]
|
101
|
-
|
102
|
-
reflected_model = reflection.klass
|
103
|
-
|
104
|
-
Avo.resource_manager.get_resource_by_model_class reflected_model
|
105
|
-
end
|
106
|
-
|
107
64
|
def set_resource_name
|
108
65
|
@resource_name = resource_name
|
109
66
|
end
|
@@ -115,18 +72,23 @@ module Avo
|
|
115
72
|
def set_resource
|
116
73
|
raise ActionController::RoutingError.new "No route matches" if resource.nil?
|
117
74
|
|
118
|
-
@resource = resource.
|
119
|
-
|
120
|
-
set_authorization
|
75
|
+
@resource = resource.hydrate(params: params)
|
121
76
|
end
|
122
77
|
|
123
78
|
def set_related_resource
|
124
|
-
@related_resource = related_resource.
|
79
|
+
@related_resource = related_resource.hydrate(params: params)
|
125
80
|
end
|
126
81
|
|
127
82
|
def set_record
|
128
83
|
@record = @resource.find_record(params[:id], query: model_find_scope, params: params)
|
129
|
-
|
84
|
+
end
|
85
|
+
|
86
|
+
def model_find_scope
|
87
|
+
eager_load_files(@resource, model_scope)
|
88
|
+
end
|
89
|
+
|
90
|
+
def model_scope
|
91
|
+
@resource.class.find_scope
|
130
92
|
end
|
131
93
|
|
132
94
|
def set_related_record
|
@@ -136,16 +98,6 @@ module Avo
|
|
136
98
|
else
|
137
99
|
@related_resource.find_record params[:related_id], query: eager_load_files(@related_resource, @record.send(association_name)), params: params
|
138
100
|
end
|
139
|
-
@related_resource.hydrate(record: @related_record)
|
140
|
-
end
|
141
|
-
|
142
|
-
def model_find_scope
|
143
|
-
eager_load_files(@resource, model_scope)
|
144
|
-
end
|
145
|
-
|
146
|
-
def model_scope
|
147
|
-
# abort @resource.inspect
|
148
|
-
@resource.class.find_scope
|
149
101
|
end
|
150
102
|
|
151
103
|
def set_view
|
@@ -155,34 +107,23 @@ module Avo
|
|
155
107
|
def set_record_to_fill
|
156
108
|
@record_to_fill = @resource.model_class.new if @view == :create
|
157
109
|
@record_to_fill = @record if @view == :update
|
158
|
-
|
159
|
-
# If resource.record is nil, most likely the user is creating a new record.
|
160
|
-
# In that case, to access resource.record in visible and readonly blocks we hydrate the resource with a new record.
|
161
|
-
# TODO: commented this
|
162
|
-
@resource.hydrate(record: @record_to_fill) if @resource.record.nil?
|
163
110
|
end
|
164
111
|
|
165
112
|
def fill_record
|
166
113
|
# We have to skip filling the the record if this is an attach action
|
167
|
-
|
114
|
+
is_attach_action = params[model_param_key].blank? && params[:related_name].present? && params[:fields].present?
|
168
115
|
|
169
|
-
|
170
|
-
|
116
|
+
unless is_attach_action
|
117
|
+
@record = @resource.fill_record(@record_to_fill, cast_nullable(model_params), extra_params: extra_params)
|
118
|
+
end
|
171
119
|
end
|
172
120
|
|
173
|
-
def
|
174
|
-
|
121
|
+
def hydrate_resource
|
122
|
+
@resource.hydrate(view: action_name.to_sym, user: _current_user, record: @record)
|
175
123
|
end
|
176
124
|
|
177
|
-
def
|
178
|
-
@
|
179
|
-
field.is_disabled? && field.visible? && !field.computed
|
180
|
-
end.each do |field|
|
181
|
-
# Get the default value from the field default definition
|
182
|
-
# If there is no default value specified on the resource, get the value from the record (DB, Callbacks, etc.)
|
183
|
-
default_value = field.default || @record.send(field.id)
|
184
|
-
field.fill_field @record, field.id, default_value, params
|
185
|
-
end
|
125
|
+
def hydrate_related_resource
|
126
|
+
@related_resource.hydrate(view: action_name.to_sym, user: _current_user, record: @related_record)
|
186
127
|
end
|
187
128
|
|
188
129
|
def authorize_base_action
|
@@ -198,16 +139,52 @@ module Avo
|
|
198
139
|
@authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
|
199
140
|
end
|
200
141
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
142
|
+
# Get the pluralized resource name for this request
|
143
|
+
# Ex: projects, teams, users
|
144
|
+
def resource_name
|
145
|
+
return params[:resource_name] if params[:resource_name].present?
|
146
|
+
|
147
|
+
return controller_name if controller_name.present?
|
148
|
+
|
149
|
+
begin
|
150
|
+
request.path
|
151
|
+
.match(/\/?#{Avo::App.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
|
152
|
+
.captures
|
153
|
+
.first
|
154
|
+
rescue
|
155
|
+
end
|
156
|
+
end
|
208
157
|
|
209
|
-
|
210
|
-
|
158
|
+
def related_resource_name
|
159
|
+
params[:related_name]
|
160
|
+
end
|
161
|
+
|
162
|
+
# Gets the Avo resource for this request based on the request from the `resource_name` "param"
|
163
|
+
# Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
|
164
|
+
def resource
|
165
|
+
resource = Avo::App.resources.get_resource @resource_name.to_s.camelize.singularize
|
166
|
+
|
167
|
+
return resource if resource.present?
|
168
|
+
|
169
|
+
Avo::App.resources.get_resource_by_controller_name @resource_name
|
170
|
+
end
|
171
|
+
|
172
|
+
def related_resource
|
173
|
+
# Find the field from the parent resource
|
174
|
+
field = @resource.get_field params[:related_name]
|
175
|
+
|
176
|
+
return field.use_resource if field&.use_resource.present?
|
177
|
+
|
178
|
+
reflection = @record._reflections[params[:related_name]]
|
179
|
+
|
180
|
+
reflected_model = reflection.klass
|
181
|
+
|
182
|
+
Avo::App.resources.get_resource_by_model_class reflected_model
|
183
|
+
end
|
184
|
+
|
185
|
+
def eager_load_files(resource, query)
|
186
|
+
if resource.attached_file_fields.present?
|
187
|
+
resource.attached_file_fields.map do |field|
|
211
188
|
attachment = case field.class.to_s
|
212
189
|
when "Avo::Fields::FileField"
|
213
190
|
"attachment"
|
@@ -243,8 +220,8 @@ module Avo
|
|
243
220
|
def set_authorization
|
244
221
|
# We need to set @resource_name for the #resource method to work properly
|
245
222
|
set_resource_name
|
246
|
-
@authorization = if
|
247
|
-
|
223
|
+
@authorization = if resource
|
224
|
+
resource.authorization(user: _current_user)
|
248
225
|
else
|
249
226
|
Services::AuthorizationService.new _current_user
|
250
227
|
end
|
@@ -308,7 +285,7 @@ module Avo
|
|
308
285
|
if Rails::VERSION::MAJOR === 6
|
309
286
|
ActiveStorage::Current.host = request.base_url
|
310
287
|
elsif Rails::VERSION::MAJOR === 7
|
311
|
-
ActiveStorage::Current.url_options =
|
288
|
+
ActiveStorage::Current.url_options = request.base_url
|
312
289
|
end
|
313
290
|
end
|
314
291
|
rescue => exception
|
@@ -3,11 +3,13 @@ require_dependency "avo/base_controller"
|
|
3
3
|
module Avo
|
4
4
|
class AssociationsController < BaseController
|
5
5
|
before_action :set_record, only: [:show, :index, :new, :create, :destroy]
|
6
|
+
before_action :hydrate_resource, only: [:show, :index, :new, :create, :destroy]
|
6
7
|
before_action :set_related_resource_name
|
7
8
|
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy]
|
8
9
|
before_action :set_related_authorization
|
9
10
|
before_action :set_reflection_field
|
10
11
|
before_action :set_related_record, only: [:show]
|
12
|
+
before_action :hydrate_related_resource, only: [:show, :index, :create, :destroy]
|
11
13
|
before_action :set_reflection
|
12
14
|
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy]
|
13
15
|
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy]
|
@@ -52,7 +54,7 @@ module Avo
|
|
52
54
|
end
|
53
55
|
|
54
56
|
@options = query.all.map do |record|
|
55
|
-
[@attachment_resource.
|
57
|
+
[record.send(@attachment_resource.class.title), record.id]
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
@@ -79,7 +81,7 @@ module Avo
|
|
79
81
|
association_name = BaseResource.valid_association_name(@record, params[:related_name])
|
80
82
|
|
81
83
|
if reflection_class == "HasManyReflection"
|
82
|
-
@record.send(association_name).
|
84
|
+
@record.send(association_name).delete @attachment_record
|
83
85
|
else
|
84
86
|
@record.send("#{association_name}=", nil)
|
85
87
|
end
|
@@ -100,7 +102,7 @@ module Avo
|
|
100
102
|
end
|
101
103
|
|
102
104
|
def set_attachment_resource
|
103
|
-
@attachment_resource = @field.use_resource || (Avo.
|
105
|
+
@attachment_resource = @field.use_resource || (Avo::App.resources.get_resource_by_model_class @attachment_class)
|
104
106
|
end
|
105
107
|
|
106
108
|
def set_attachment_record
|
@@ -149,8 +151,8 @@ module Avo
|
|
149
151
|
private
|
150
152
|
|
151
153
|
def set_related_authorization
|
152
|
-
@related_authorization = if
|
153
|
-
|
154
|
+
@related_authorization = if related_resource
|
155
|
+
related_resource.authorization(user: _current_user)
|
154
156
|
else
|
155
157
|
Services::AuthorizationService.new _current_user
|
156
158
|
end
|
@@ -7,7 +7,7 @@ module Avo
|
|
7
7
|
before_action :set_record, only: [:destroy, :create]
|
8
8
|
|
9
9
|
def create
|
10
|
-
blob = ActiveStorage::Blob.create_and_upload! io: params[:file]
|
10
|
+
blob = ActiveStorage::Blob.create_and_upload! io: params[:file], filename: params[:filename]
|
11
11
|
association_name = BaseResource.valid_attachment_name(@record, params[:attachment_key])
|
12
12
|
|
13
13
|
if association_name.blank?
|
@@ -23,31 +23,16 @@ module Avo
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def destroy
|
26
|
-
|
27
|
-
|
26
|
+
attachment = ActiveStorage::Attachment.find(params[:attachment_id])
|
27
|
+
path = resource_path(record: @record, resource: @resource)
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
if attachment.present?
|
30
|
+
attachment.destroy
|
31
31
|
|
32
|
-
|
33
|
-
else
|
34
|
-
t("avo.failed_to_find_attachment")
|
35
|
-
end
|
32
|
+
redirect_to params[:referrer] || path, notice: t("avo.attachment_destroyed")
|
36
33
|
else
|
37
|
-
|
34
|
+
redirect_back fallback_location: path, notice: t("avo.failed_to_find_attachment")
|
38
35
|
end
|
39
|
-
|
40
|
-
respond_to do |format|
|
41
|
-
format.turbo_stream do
|
42
|
-
render "destroy"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def authorized_to(action)
|
50
|
-
@resource.authorization.authorize_action("#{action}_#{params[:attachment_name]}?", record: @record, raise_exception: false)
|
51
36
|
end
|
52
37
|
end
|
53
38
|
end
|
@@ -6,6 +6,7 @@ module Avo
|
|
6
6
|
|
7
7
|
before_action :set_resource_name
|
8
8
|
before_action :set_resource
|
9
|
+
before_action :hydrate_resource
|
9
10
|
before_action :set_applied_filters, only: :index
|
10
11
|
before_action :set_record, only: [:show, :edit, :destroy, :update, :preview]
|
11
12
|
before_action :set_record_to_fill
|
@@ -28,6 +29,11 @@ module Avo
|
|
28
29
|
@query = @resource.class.query_scope
|
29
30
|
end
|
30
31
|
|
32
|
+
# Remove default_scope for index view if no parent_resource present
|
33
|
+
if @resource.unscoped_queries_on_index && @parent_resource.blank?
|
34
|
+
@query = @query.unscoped
|
35
|
+
end
|
36
|
+
|
31
37
|
# Eager load the associations
|
32
38
|
if @resource.includes.present?
|
33
39
|
@query = @query.includes(*@resource.includes)
|
@@ -46,7 +52,7 @@ module Avo
|
|
46
52
|
field_id = @index_params[:sort_by].to_sym
|
47
53
|
field = @resource.get_field_definitions.find { |field| field.id == field_id }
|
48
54
|
@query = if field&.sortable.is_a?(Proc)
|
49
|
-
|
55
|
+
field.sortable.call(@query, @index_params[:sort_direction])
|
50
56
|
else
|
51
57
|
@query.order("#{@resource.model_class.table_name}.#{@index_params[:sort_by]} #{@index_params[:sort_direction]}")
|
52
58
|
end
|
@@ -67,7 +73,18 @@ module Avo
|
|
67
73
|
end
|
68
74
|
|
69
75
|
safe_call :set_and_apply_scopes
|
70
|
-
|
76
|
+
|
77
|
+
if Avo.avo_filters_installed? && params[AvoFilters.configuration.param_key].present?
|
78
|
+
# Apply dynamic filters
|
79
|
+
query_builder = AvoFilters::QueryBuilder.new(resource: @resource, params: params, query: @query)
|
80
|
+
@query = @query.ransack(**query_builder.ransack_query)
|
81
|
+
end
|
82
|
+
|
83
|
+
pagy_query = if @query.instance_of?(Ransack::Search)
|
84
|
+
@query.result(distinct: false)
|
85
|
+
else
|
86
|
+
@query
|
87
|
+
end
|
71
88
|
|
72
89
|
@pagy, @records = pagy(pagy_query, items: @index_params[:per_page], link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"", size: [1, 2, 2, 1], params: extra_pagy_params)
|
73
90
|
|
@@ -78,7 +95,7 @@ module Avo
|
|
78
95
|
end
|
79
96
|
|
80
97
|
def show
|
81
|
-
@resource.hydrate(record: @record, view: :show, user: _current_user, params: params)
|
98
|
+
@resource.hydrate(record: @record, view: :show, user: _current_user, params: params)
|
82
99
|
|
83
100
|
set_actions
|
84
101
|
|
@@ -86,9 +103,9 @@ module Avo
|
|
86
103
|
|
87
104
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
88
105
|
if params[:via_resource_class].present? && params[:via_record_id].present?
|
89
|
-
via_resource = Avo.
|
106
|
+
via_resource = Avo::App.resources.get_resource(params[:via_resource_class]).dup
|
90
107
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
91
|
-
via_resource
|
108
|
+
via_resource.hydrate record: via_record
|
92
109
|
|
93
110
|
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
94
111
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -109,9 +126,9 @@ module Avo
|
|
109
126
|
@page_title = @resource.default_panel_name.to_s
|
110
127
|
|
111
128
|
if is_associated_record?
|
112
|
-
via_resource = Avo.
|
129
|
+
via_resource = Avo::App.resources.get_resource_by_model_class(params[:via_relation_class]).dup
|
113
130
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
114
|
-
via_resource
|
131
|
+
via_resource.hydrate record: via_record
|
115
132
|
|
116
133
|
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
117
134
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -134,7 +151,7 @@ module Avo
|
|
134
151
|
# Fills in the required infor for belongs_to and has_many
|
135
152
|
# Get the foreign key and set it to the id we received in the params
|
136
153
|
if @reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) || @reflection.is_a?(ActiveRecord::Reflection::HasManyReflection)
|
137
|
-
related_resource = Avo.
|
154
|
+
related_resource = Avo::App.resources.get_resource_by_model_class params[:via_relation_class]
|
138
155
|
related_record = related_resource.find_record params[:via_record_id], params: params
|
139
156
|
|
140
157
|
@record.send("#{@reflection.foreign_key}=", related_record.id)
|
@@ -144,16 +161,11 @@ module Avo
|
|
144
161
|
# For when working with has_one, has_one_through, has_many_through, has_and_belongs_to_many, polymorphic
|
145
162
|
if @reflection.is_a? ActiveRecord::Reflection::ThroughReflection
|
146
163
|
# find the record
|
147
|
-
via_resource = Avo.
|
164
|
+
via_resource = ::Avo::App.resources.get_resource_by_model_class(params[:via_relation_class]).dup
|
148
165
|
@related_record = via_resource.find_record params[:via_record_id], params: params
|
149
166
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
150
167
|
|
151
|
-
|
152
|
-
# On has_one scenarios we should switch the @record and @related_record
|
153
|
-
@related_record.send("#{@reflection.parent_reflection.inverse_of.name}=", @record)
|
154
|
-
else
|
155
|
-
@record.send(association_name) << @related_record
|
156
|
-
end
|
168
|
+
@record.send(association_name) << @related_record
|
157
169
|
end
|
158
170
|
end
|
159
171
|
|
@@ -203,24 +215,16 @@ module Avo
|
|
203
215
|
|
204
216
|
def save_record
|
205
217
|
perform_action_and_record_errors do
|
206
|
-
|
218
|
+
@record.save!
|
207
219
|
end
|
208
220
|
end
|
209
221
|
|
210
|
-
def save_record_action
|
211
|
-
@record.save!
|
212
|
-
end
|
213
|
-
|
214
222
|
def destroy_model
|
215
223
|
perform_action_and_record_errors do
|
216
|
-
|
224
|
+
@record.destroy!
|
217
225
|
end
|
218
226
|
end
|
219
227
|
|
220
|
-
def destroy_record_action
|
221
|
-
@record.destroy!
|
222
|
-
end
|
223
|
-
|
224
228
|
def perform_action_and_record_errors(&block)
|
225
229
|
begin
|
226
230
|
succeeded = block.call
|
@@ -249,7 +253,7 @@ module Avo
|
|
249
253
|
end
|
250
254
|
|
251
255
|
def permitted_params
|
252
|
-
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param).concat
|
256
|
+
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param).concat extra_params
|
253
257
|
end
|
254
258
|
|
255
259
|
def extra_params
|
@@ -309,20 +313,8 @@ module Avo
|
|
309
313
|
@index_params[:sort_direction] = params[:sort_direction] || :desc
|
310
314
|
|
311
315
|
# View types
|
312
|
-
|
313
|
-
@index_params[:available_view_types] = available_view_types
|
314
|
-
|
315
|
-
@index_params[:view_type] = if params[:view_type].present?
|
316
|
-
params[:view_type]
|
317
|
-
elsif available_view_types.size == 1
|
318
|
-
available_view_types.first
|
319
|
-
else
|
320
|
-
@resource.default_view_type || Avo.configuration.default_view_type
|
321
|
-
end
|
322
|
-
|
323
|
-
if available_view_types.exclude? @index_params[:view_type].to_sym
|
324
|
-
raise "View type '#{@index_params[:view_type]}' is unavailable for #{@resource.class}."
|
325
|
-
end
|
316
|
+
@index_params[:view_type] = params[:view_type] || @resource.default_view_type || Avo.configuration.default_view_type
|
317
|
+
@index_params[:available_view_types] = @resource.available_view_types
|
326
318
|
end
|
327
319
|
|
328
320
|
def set_filters
|
@@ -400,9 +392,9 @@ module Avo
|
|
400
392
|
last_crumb_args = {}
|
401
393
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
402
394
|
if params[:via_resource_class].present? && params[:via_record_id].present?
|
403
|
-
via_resource = Avo.
|
395
|
+
via_resource = Avo::App.resources.get_resource(params[:via_resource_class]).dup
|
404
396
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
405
|
-
via_resource
|
397
|
+
via_resource.hydrate record: via_record
|
406
398
|
|
407
399
|
add_breadcrumb via_resource.plural_name, resources_path(resource: @resource)
|
408
400
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -443,7 +435,7 @@ module Avo
|
|
443
435
|
def after_create_path
|
444
436
|
# If this is an associated record return to the association show page
|
445
437
|
if is_associated_record?
|
446
|
-
parent_resource = Avo.
|
438
|
+
parent_resource = ::Avo::App.resources.get_resource_by_model_class(params[:via_relation_class]).dup
|
447
439
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
448
440
|
|
449
441
|
return resource_view_path(
|
@@ -536,9 +528,5 @@ module Avo
|
|
536
528
|
def safe_call(method)
|
537
529
|
send(method) if respond_to?(method, true)
|
538
530
|
end
|
539
|
-
|
540
|
-
def pagy_query
|
541
|
-
@query
|
542
|
-
end
|
543
531
|
end
|
544
532
|
end
|
@@ -14,7 +14,7 @@ module Avo
|
|
14
14
|
redirect_to computed_path
|
15
15
|
elsif !Rails.env.development?
|
16
16
|
@page_title = "Get started"
|
17
|
-
resource = Avo.
|
17
|
+
resource = Avo::App.resources.min_by { |resource| resource.model_key }
|
18
18
|
redirect_to resources_path(resource: resource)
|
19
19
|
end
|
20
20
|
end
|
@@ -17,7 +17,7 @@ module Avo
|
|
17
17
|
resources
|
18
18
|
.map do |resource|
|
19
19
|
# Apply authorization
|
20
|
-
next unless @authorization.set_record(resource.model_class).authorize_action(:
|
20
|
+
next unless @authorization.set_record(resource.model_class).authorize_action(:index, raise_exception: false)
|
21
21
|
# Filter out the models without a search_query
|
22
22
|
next if resource.search_query.nil?
|
23
23
|
|
@@ -37,11 +37,11 @@ module Avo
|
|
37
37
|
query = Avo::ExecutionContext.new(
|
38
38
|
target: resource.search_query,
|
39
39
|
params: params,
|
40
|
-
|
40
|
+
scope: resource.class.scope
|
41
41
|
).handle
|
42
42
|
|
43
43
|
# Get the count
|
44
|
-
results_count = query.reselect(
|
44
|
+
results_count = query.reselect(:id).count
|
45
45
|
|
46
46
|
# Get the results
|
47
47
|
query = query.limit(8)
|
@@ -58,7 +58,7 @@ module Avo
|
|
58
58
|
|
59
59
|
result_object = {
|
60
60
|
header: header,
|
61
|
-
help: resource.
|
61
|
+
help: resource.class.search_query_help,
|
62
62
|
results: results,
|
63
63
|
count: results.count
|
64
64
|
}
|
@@ -101,36 +101,31 @@ module Avo
|
|
101
101
|
# This scope is applied if the search is being performed on a has_many association
|
102
102
|
def apply_has_many_scope
|
103
103
|
association_name = BaseResource.valid_association_name(parent, params[:via_association_id])
|
104
|
+
scope = parent.send(association_name)
|
104
105
|
|
105
|
-
|
106
|
-
query = parent.send(association_name)
|
107
|
-
|
108
|
-
# Apply policy scope if authorization is present
|
109
|
-
query = resource.authorization&.apply_policy query
|
110
|
-
|
111
|
-
Avo::ExecutionContext.new(target: @resource.class.search_query, params: params, query: query).handle
|
106
|
+
Avo::ExecutionContext.new(target: @resource.search_query, params: params, scope: scope).handle
|
112
107
|
end
|
113
108
|
|
114
109
|
def apply_search_metadata(records, avo_resource)
|
115
110
|
records.map do |record|
|
116
|
-
resource = avo_resource.
|
111
|
+
resource = avo_resource.dup.hydrate(record: record).hydrate_fields
|
117
112
|
|
118
|
-
fetch_result_information record, resource
|
113
|
+
fetch_result_information record, resource
|
119
114
|
end
|
120
115
|
end
|
121
116
|
|
122
117
|
private
|
123
118
|
|
124
|
-
def fetch_result_information(record, resource
|
119
|
+
def fetch_result_information(record, resource)
|
125
120
|
{
|
126
121
|
_id: record.id,
|
127
|
-
_label:
|
128
|
-
_url: resource.
|
122
|
+
_label: resource.label,
|
123
|
+
_url: resource.record_path,
|
129
124
|
}
|
130
125
|
end
|
131
126
|
|
132
127
|
def should_apply_has_many_scope?
|
133
|
-
params[:via_association] == "has_many" && @resource.
|
128
|
+
params[:via_association] == "has_many" && @resource.search_query.present?
|
134
129
|
end
|
135
130
|
|
136
131
|
def should_apply_attach_scope?
|
@@ -154,15 +149,16 @@ module Avo
|
|
154
149
|
end
|
155
150
|
|
156
151
|
def fetch_field
|
157
|
-
fields = Avo.
|
152
|
+
fields = ::Avo::App.resources.get_resource_by_model_class(params[:via_reflection_class]).get_field_definitions
|
158
153
|
fields.find { |f| f.id.to_s == params[:via_association_id] }
|
159
154
|
end
|
160
155
|
|
161
156
|
def fetch_parent
|
162
157
|
return unless params[:via_reflection_id].present?
|
163
158
|
|
164
|
-
|
165
|
-
|
159
|
+
parent_class = BaseResource.get_model_by_name params[:via_reflection_class]
|
160
|
+
|
161
|
+
parent_class.find params[:via_reflection_id]
|
166
162
|
end
|
167
163
|
end
|
168
164
|
end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
module Avo
|
2
2
|
module InitializesAvo
|
3
3
|
def init_app
|
4
|
-
Avo::Current.license = Avo::Licensing::
|
4
|
+
Avo::Current.license = Avo::Licensing::NullLicense.new
|
5
|
+
Avo::Current.params = request.params
|
6
|
+
Avo::Current.request = request
|
5
7
|
Avo::Current.context = context
|
6
|
-
Avo::Current.
|
8
|
+
Avo::Current.current_user = _current_user
|
7
9
|
Avo::Current.view_context = view_context
|
8
|
-
Avo.
|
10
|
+
Avo::Current.app = Avo::App.build request: request, context: context, current_user: _current_user, view_context: view_context
|
11
|
+
Avo::Current.app.init
|
9
12
|
Avo::Current.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
|
10
13
|
Avo.plugin_manager.init_plugins
|
14
|
+
|
15
|
+
@license = Avo::App.license
|
11
16
|
end
|
12
17
|
|
13
18
|
def _current_user
|