avo 3.0.0.pre12 → 3.0.0.pre14
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 +1 -1
- data/Gemfile.lock +2 -1
- data/app/assets/stylesheets/avo.base.css +1 -1
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +40 -16
- 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 +2 -2
- data/app/components/avo/field_wrapper_component.rb +1 -1
- data/app/components/avo/fields/area_field/edit_component.html.erb +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 -4
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -0
- 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 +1 -0
- data/app/components/avo/fields/common/heading_component.html.erb +1 -1
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/file_field/index_component.rb +2 -2
- data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -0
- data/app/components/avo/fields/index_component.rb +1 -0
- data/app/components/avo/fields/location_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +4 -3
- 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 -0
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -1
- 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/grid_item_component.html.erb +9 -35
- data/app/components/avo/index/grid_item_component.rb +36 -10
- data/app/components/avo/index/resource_controls_component.rb +6 -6
- data/app/components/avo/item_switcher_component.html.erb +9 -4
- data/app/components/avo/item_switcher_component.rb +2 -1
- data/app/components/avo/panel_component.html.erb +1 -1
- data/app/components/avo/profile_item_component.html.erb +17 -2
- data/app/components/avo/profile_item_component.rb +13 -1
- data/app/components/avo/resource_component.rb +6 -3
- data/app/components/avo/resource_sidebar_component.rb +1 -1
- data/app/components/avo/row_component.html.erb +3 -0
- data/app/components/avo/row_component.rb +12 -0
- data/app/components/avo/sidebar/link_component.html.erb +2 -0
- data/app/components/avo/sidebar/link_component.rb +5 -3
- 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.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +1 -1
- data/app/components/avo/views/resource_index_component.rb +8 -8
- data/app/controllers/avo/actions_controller.rb +22 -8
- data/app/controllers/avo/application_controller.rb +71 -66
- data/app/controllers/avo/associations_controller.rb +4 -6
- data/app/controllers/avo/attachments_controller.rb +1 -1
- data/app/controllers/avo/base_controller.rb +36 -17
- data/app/controllers/avo/home_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +18 -20
- data/app/controllers/concerns/avo/initializes_avo.rb +2 -5
- data/app/javascript/js/controllers/fields/{simple_mde_controller.js → easy_mde_controller.js} +4 -3
- data/app/javascript/js/controllers/search_controller.js +3 -1
- data/app/javascript/js/controllers.js +2 -2
- data/app/views/avo/actions/show.html.erb +2 -1
- data/app/views/avo/associations/new.html.erb +1 -1
- data/app/views/avo/debug/status.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/_profile_menu_extra.html.erb +2 -0
- data/app/views/layouts/avo/application.html.erb +2 -2
- data/avo.gemspec +1 -0
- data/config/initializers/pagy.rb +12 -10
- data/config/routes.rb +3 -3
- data/db/factories.rb +2 -1
- data/lib/avo/base_action.rb +12 -2
- data/lib/avo/base_resource.rb +178 -178
- data/lib/avo/concerns/filters_session_handler.rb +0 -1
- data/lib/avo/concerns/has_item_type.rb +4 -0
- data/lib/avo/concerns/has_items.rb +28 -23
- data/lib/avo/concerns/model_class_constantized.rb +0 -2
- data/lib/avo/configuration.rb +6 -2
- data/lib/avo/current.rb +22 -1
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/dynamic_router.rb +12 -1
- data/lib/avo/engine.rb +8 -6
- data/lib/avo/fields/base_field.rb +25 -7
- data/lib/avo/fields/belongs_to_field.rb +20 -13
- data/lib/avo/fields/concerns/is_searchable.rb +1 -1
- data/lib/avo/fields/concerns/use_resource.rb +1 -1
- data/lib/avo/fields/field_manager.rb +13 -3
- data/lib/avo/fields/has_base_field.rb +5 -5
- data/lib/avo/fields/has_one_field.rb +1 -1
- data/lib/avo/fields/location_field.rb +18 -1
- data/lib/avo/licensing/h_q.rb +11 -6
- data/lib/avo/licensing/license.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/licensing/{null_license.rb → nil_license.rb} +1 -1
- data/lib/avo/loaders/fields_loader.rb +7 -1
- data/lib/avo/plugin_manager.rb +2 -4
- data/lib/avo/reloader.rb +1 -1
- data/lib/avo/resources/controls/actions_list.rb +2 -1
- data/lib/avo/resources/items/holder.rb +5 -1
- data/lib/avo/resources/items/item_group.rb +1 -0
- data/lib/avo/resources/items/row.rb +54 -0
- data/lib/avo/resources/resource_manager.rb +4 -7
- data/lib/avo/services/debug_service.rb +6 -6
- data/lib/avo/services/telemetry_service.rb +3 -3
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +107 -25
- data/lib/generators/avo/action_generator.rb +8 -8
- data/lib/generators/avo/card_generator.rb +27 -0
- data/lib/generators/avo/eject_generator.rb +1 -0
- data/lib/generators/avo/filter_generator.rb +8 -8
- data/lib/generators/avo/install_generator.rb +0 -1
- data/lib/generators/avo/resource_generator.rb +4 -1
- data/lib/generators/avo/templates/action.tt +3 -3
- 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 +1 -1
- data/lib/generators/avo/templates/resource/resource.tt +3 -4
- data/lib/generators/avo/templates/scope.tt +1 -1
- data/lib/tasks/avo_tasks.rake +1 -1
- data/public/avo-assets/avo.base.css +295 -165
- data/public/avo-assets/avo.base.js +307 -278
- data/public/avo-assets/avo.base.js.map +3 -3
- metadata +23 -10
- data/lib/avo/app.rb +0 -170
- data/lib/avo/grid_collector.rb +0 -40
- data/lib/generators/avo/card/chartkick_generator.rb +0 -18
- data/lib/generators/avo/card/metric_generator.rb +0 -18
- data/lib/generators/avo/card/partial_generator.rb +0 -19
- data/lib/generators/avo/templates/standalone_action.tt +0 -15
@@ -7,10 +7,10 @@ module Avo
|
|
7
7
|
end
|
8
8
|
|
9
9
|
include Avo::InitializesAvo
|
10
|
-
include Pagy::Backend
|
11
10
|
include Avo::ApplicationHelper
|
12
11
|
include Avo::UrlHelpers
|
13
12
|
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,6 +61,49 @@ 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
|
+
|
64
107
|
def set_resource_name
|
65
108
|
@resource_name = resource_name
|
66
109
|
end
|
@@ -72,23 +115,18 @@ module Avo
|
|
72
115
|
def set_resource
|
73
116
|
raise ActionController::RoutingError.new "No route matches" if resource.nil?
|
74
117
|
|
75
|
-
@resource = resource.
|
118
|
+
@resource = resource.new(view: action_name.to_sym, user: _current_user, params: params)
|
119
|
+
|
120
|
+
set_authorization
|
76
121
|
end
|
77
122
|
|
78
123
|
def set_related_resource
|
79
|
-
@related_resource = related_resource.
|
124
|
+
@related_resource = related_resource.new(params: params, view: action_name.to_sym, user: _current_user, record: @related_record)
|
80
125
|
end
|
81
126
|
|
82
127
|
def set_record
|
83
128
|
@record = @resource.find_record(params[:id], query: model_find_scope, params: params)
|
84
|
-
|
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
|
129
|
+
@resource.hydrate(record: @record)
|
92
130
|
end
|
93
131
|
|
94
132
|
def set_related_record
|
@@ -98,6 +136,16 @@ module Avo
|
|
98
136
|
else
|
99
137
|
@related_resource.find_record params[:related_id], query: eager_load_files(@related_resource, @record.send(association_name)), params: params
|
100
138
|
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
|
101
149
|
end
|
102
150
|
|
103
151
|
def set_view
|
@@ -110,6 +158,7 @@ module Avo
|
|
110
158
|
|
111
159
|
# If resource.record is nil, most likely the user is creating a new record.
|
112
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
|
113
162
|
@resource.hydrate(record: @record_to_fill) if @resource.record.nil?
|
114
163
|
end
|
115
164
|
|
@@ -136,14 +185,6 @@ module Avo
|
|
136
185
|
end
|
137
186
|
end
|
138
187
|
|
139
|
-
def hydrate_resource
|
140
|
-
@resource.hydrate(view: action_name.to_sym, user: _current_user, record: @record)
|
141
|
-
end
|
142
|
-
|
143
|
-
def hydrate_related_resource
|
144
|
-
@related_resource.hydrate(view: action_name.to_sym, user: _current_user, record: @related_record)
|
145
|
-
end
|
146
|
-
|
147
188
|
def authorize_base_action
|
148
189
|
class_to_authorize = @record || @resource.model_class
|
149
190
|
|
@@ -157,52 +198,16 @@ module Avo
|
|
157
198
|
@authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
|
158
199
|
end
|
159
200
|
|
160
|
-
# Get the pluralized resource name for this request
|
161
|
-
# Ex: projects, teams, users
|
162
|
-
def resource_name
|
163
|
-
return params[:resource_name] if params[:resource_name].present?
|
164
|
-
|
165
|
-
return controller_name if controller_name.present?
|
166
|
-
|
167
|
-
begin
|
168
|
-
request.path
|
169
|
-
.match(/\/?#{Avo::App.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
|
170
|
-
.captures
|
171
|
-
.first
|
172
|
-
rescue
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
def related_resource_name
|
177
|
-
params[:related_name]
|
178
|
-
end
|
179
|
-
|
180
|
-
# Gets the Avo resource for this request based on the request from the `resource_name` "param"
|
181
|
-
# Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
|
182
|
-
def resource
|
183
|
-
resource = Avo::App.resources.get_resource @resource_name.to_s.camelize.singularize
|
184
|
-
|
185
|
-
return resource if resource.present?
|
186
|
-
|
187
|
-
Avo::App.resources.get_resource_by_controller_name @resource_name
|
188
|
-
end
|
189
|
-
|
190
|
-
def related_resource
|
191
|
-
# Find the field from the parent resource
|
192
|
-
field = @resource.get_field params[:related_name]
|
193
|
-
|
194
|
-
return field.use_resource if field&.use_resource.present?
|
195
|
-
|
196
|
-
reflection = @record._reflections[params[:related_name]]
|
197
|
-
|
198
|
-
reflected_model = reflection.klass
|
199
|
-
|
200
|
-
Avo::App.resources.get_resource_by_model_class reflected_model
|
201
|
-
end
|
202
|
-
|
203
201
|
def eager_load_files(resource, query)
|
204
|
-
|
205
|
-
|
202
|
+
# Get the non-computed file fields and try to eager load them
|
203
|
+
attachment_fields = resource
|
204
|
+
.attachment_fields
|
205
|
+
.reject do |field|
|
206
|
+
field.computed
|
207
|
+
end
|
208
|
+
|
209
|
+
if attachment_fields.present?
|
210
|
+
attachment_fields.map do |field|
|
206
211
|
attachment = case field.class.to_s
|
207
212
|
when "Avo::Fields::FileField"
|
208
213
|
"attachment"
|
@@ -238,8 +243,8 @@ module Avo
|
|
238
243
|
def set_authorization
|
239
244
|
# We need to set @resource_name for the #resource method to work properly
|
240
245
|
set_resource_name
|
241
|
-
@authorization = if resource
|
242
|
-
resource.authorization(user: _current_user)
|
246
|
+
@authorization = if @resource
|
247
|
+
@resource.authorization(user: _current_user)
|
243
248
|
else
|
244
249
|
Services::AuthorizationService.new _current_user
|
245
250
|
end
|
@@ -3,13 +3,11 @@ 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]
|
7
6
|
before_action :set_related_resource_name
|
8
7
|
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy]
|
9
8
|
before_action :set_related_authorization
|
10
9
|
before_action :set_reflection_field
|
11
10
|
before_action :set_related_record, only: [:show]
|
12
|
-
before_action :hydrate_related_resource, only: [:show, :index, :create, :destroy]
|
13
11
|
before_action :set_reflection
|
14
12
|
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy]
|
15
13
|
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy]
|
@@ -54,7 +52,7 @@ module Avo
|
|
54
52
|
end
|
55
53
|
|
56
54
|
@options = query.all.map do |record|
|
57
|
-
[
|
55
|
+
[@attachment_resource.new(record: record).record_title, record.id]
|
58
56
|
end
|
59
57
|
end
|
60
58
|
end
|
@@ -102,7 +100,7 @@ module Avo
|
|
102
100
|
end
|
103
101
|
|
104
102
|
def set_attachment_resource
|
105
|
-
@attachment_resource = @field.use_resource || (Avo
|
103
|
+
@attachment_resource = @field.use_resource || (Avo.resource_manager.get_resource_by_model_class @attachment_class)
|
106
104
|
end
|
107
105
|
|
108
106
|
def set_attachment_record
|
@@ -151,8 +149,8 @@ module Avo
|
|
151
149
|
private
|
152
150
|
|
153
151
|
def set_related_authorization
|
154
|
-
@related_authorization = if related_resource
|
155
|
-
related_resource.authorization(user: _current_user)
|
152
|
+
@related_authorization = if @related_resource.present?
|
153
|
+
@related_resource.authorization(user: _current_user)
|
156
154
|
else
|
157
155
|
Services::AuthorizationService.new _current_user
|
158
156
|
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], filename: params[:filename]
|
10
|
+
blob = ActiveStorage::Blob.create_and_upload! io: params[:file].to_io, filename: params[:filename]
|
11
11
|
association_name = BaseResource.valid_attachment_name(@record, params[:attachment_key])
|
12
12
|
|
13
13
|
if association_name.blank?
|
@@ -6,7 +6,6 @@ module Avo
|
|
6
6
|
|
7
7
|
before_action :set_resource_name
|
8
8
|
before_action :set_resource
|
9
|
-
before_action :hydrate_resource
|
10
9
|
before_action :set_applied_filters, only: :index
|
11
10
|
before_action :set_record, only: [:show, :edit, :destroy, :update, :preview]
|
12
11
|
before_action :set_record_to_fill
|
@@ -69,9 +68,9 @@ module Avo
|
|
69
68
|
|
70
69
|
safe_call :set_and_apply_scopes
|
71
70
|
|
72
|
-
if Avo.avo_filters_installed? && params[
|
71
|
+
if Avo.avo_filters_installed? && params[Avo::DynamicFilters.configuration.param_key].present?
|
73
72
|
# Apply dynamic filters
|
74
|
-
query_builder =
|
73
|
+
query_builder = Avo::DynamicFilters::QueryBuilder.new(resource: @resource, params: params, query: @query)
|
75
74
|
@query = @query.ransack(**query_builder.ransack_query)
|
76
75
|
end
|
77
76
|
|
@@ -98,9 +97,9 @@ module Avo
|
|
98
97
|
|
99
98
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
100
99
|
if params[:via_resource_class].present? && params[:via_record_id].present?
|
101
|
-
via_resource = Avo
|
100
|
+
via_resource = Avo.resource_manager.get_resource(params[:via_resource_class])
|
102
101
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
103
|
-
via_resource.
|
102
|
+
via_resource = via_resource.new record: via_record
|
104
103
|
|
105
104
|
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
106
105
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -121,9 +120,9 @@ module Avo
|
|
121
120
|
@page_title = @resource.default_panel_name.to_s
|
122
121
|
|
123
122
|
if is_associated_record?
|
124
|
-
via_resource = Avo
|
123
|
+
via_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
125
124
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
126
|
-
via_resource.
|
125
|
+
via_resource = via_resource.new record: via_record
|
127
126
|
|
128
127
|
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
129
128
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -146,7 +145,7 @@ module Avo
|
|
146
145
|
# Fills in the required infor for belongs_to and has_many
|
147
146
|
# Get the foreign key and set it to the id we received in the params
|
148
147
|
if @reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) || @reflection.is_a?(ActiveRecord::Reflection::HasManyReflection)
|
149
|
-
related_resource = Avo
|
148
|
+
related_resource = Avo.resource_manager.get_resource_by_model_class params[:via_relation_class]
|
150
149
|
related_record = related_resource.find_record params[:via_record_id], params: params
|
151
150
|
|
152
151
|
@record.send("#{@reflection.foreign_key}=", related_record.id)
|
@@ -156,7 +155,7 @@ module Avo
|
|
156
155
|
# For when working with has_one, has_one_through, has_many_through, has_and_belongs_to_many, polymorphic
|
157
156
|
if @reflection.is_a? ActiveRecord::Reflection::ThroughReflection
|
158
157
|
# find the record
|
159
|
-
via_resource =
|
158
|
+
via_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
160
159
|
@related_record = via_resource.find_record params[:via_record_id], params: params
|
161
160
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
162
161
|
|
@@ -215,16 +214,24 @@ module Avo
|
|
215
214
|
|
216
215
|
def save_record
|
217
216
|
perform_action_and_record_errors do
|
218
|
-
|
217
|
+
save_record_action
|
219
218
|
end
|
220
219
|
end
|
221
220
|
|
221
|
+
def save_record_action
|
222
|
+
@record.save!
|
223
|
+
end
|
224
|
+
|
222
225
|
def destroy_model
|
223
226
|
perform_action_and_record_errors do
|
224
|
-
|
227
|
+
destroy_record_action
|
225
228
|
end
|
226
229
|
end
|
227
230
|
|
231
|
+
def destroy_record_action
|
232
|
+
@record.destroy!
|
233
|
+
end
|
234
|
+
|
228
235
|
def perform_action_and_record_errors(&block)
|
229
236
|
begin
|
230
237
|
succeeded = block.call
|
@@ -253,7 +260,7 @@ module Avo
|
|
253
260
|
end
|
254
261
|
|
255
262
|
def permitted_params
|
256
|
-
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param).concat
|
263
|
+
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param).concat(extra_params).uniq
|
257
264
|
end
|
258
265
|
|
259
266
|
def extra_params
|
@@ -313,8 +320,20 @@ module Avo
|
|
313
320
|
@index_params[:sort_direction] = params[:sort_direction] || :desc
|
314
321
|
|
315
322
|
# View types
|
316
|
-
|
317
|
-
@index_params[:available_view_types] =
|
323
|
+
available_view_types = @resource.available_view_types
|
324
|
+
@index_params[:available_view_types] = available_view_types
|
325
|
+
|
326
|
+
@index_params[:view_type] = if params[:view_type].present?
|
327
|
+
params[:view_type]
|
328
|
+
elsif available_view_types.size == 1
|
329
|
+
available_view_types.first
|
330
|
+
else
|
331
|
+
@resource.default_view_type || Avo.configuration.default_view_type
|
332
|
+
end
|
333
|
+
|
334
|
+
if available_view_types.exclude? @index_params[:view_type].to_sym
|
335
|
+
raise "View type '#{@index_params[:view_type]}' is unavailable for #{@resource.class}."
|
336
|
+
end
|
318
337
|
end
|
319
338
|
|
320
339
|
def set_filters
|
@@ -392,9 +411,9 @@ module Avo
|
|
392
411
|
last_crumb_args = {}
|
393
412
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
394
413
|
if params[:via_resource_class].present? && params[:via_record_id].present?
|
395
|
-
via_resource = Avo
|
414
|
+
via_resource = Avo.resource_manager.get_resource(params[:via_resource_class])
|
396
415
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
397
|
-
via_resource.
|
416
|
+
via_resource = via_resource.new record: via_record
|
398
417
|
|
399
418
|
add_breadcrumb via_resource.plural_name, resources_path(resource: @resource)
|
400
419
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -435,7 +454,7 @@ module Avo
|
|
435
454
|
def after_create_path
|
436
455
|
# If this is an associated record return to the association show page
|
437
456
|
if is_associated_record?
|
438
|
-
parent_resource =
|
457
|
+
parent_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
439
458
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
440
459
|
|
441
460
|
return resource_view_path(
|
@@ -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.resource_manager.all.min_by { |resource| resource.model_key }
|
18
18
|
redirect_to resources_path(resource: resource)
|
19
19
|
end
|
20
20
|
end
|
@@ -37,11 +37,11 @@ module Avo
|
|
37
37
|
query = Avo::ExecutionContext.new(
|
38
38
|
target: resource.search_query,
|
39
39
|
params: params,
|
40
|
-
query: resource.
|
40
|
+
query: resource.query_scope
|
41
41
|
).handle
|
42
42
|
|
43
43
|
# Get the count
|
44
|
-
results_count = query.reselect(
|
44
|
+
results_count = query.reselect(resource.model_class.primary_key).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.fetch_search(:help) || "",
|
62
62
|
results: results,
|
63
63
|
count: results.count
|
64
64
|
}
|
@@ -101,37 +101,36 @@ 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
|
+
|
105
|
+
# Get association records
|
104
106
|
query = parent.send(association_name)
|
105
107
|
|
106
|
-
|
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
|
107
112
|
end
|
108
113
|
|
109
114
|
def apply_search_metadata(records, avo_resource)
|
110
115
|
records.map do |record|
|
111
|
-
|
112
|
-
# resource = avo_resource.dup.hydrate(record: record).hydrate_fields
|
113
|
-
resource = avo_resource.dup.hydrate(record: record)
|
116
|
+
resource = avo_resource.new(record: record)
|
114
117
|
|
115
|
-
fetch_result_information record, resource
|
118
|
+
fetch_result_information record, resource, resource.class.fetch_search(:item, record: record)
|
116
119
|
end
|
117
120
|
end
|
118
121
|
|
119
122
|
private
|
120
123
|
|
121
|
-
def fetch_result_information(record, resource)
|
124
|
+
def fetch_result_information(record, resource, item)
|
122
125
|
{
|
123
126
|
_id: record.id,
|
124
|
-
_label: resource.
|
125
|
-
_url:
|
126
|
-
target: resource.search_result_path || resource.record_path,
|
127
|
-
resource: resource,
|
128
|
-
record: record
|
129
|
-
).handle,
|
127
|
+
_label: item&.dig(:title) || resource.record_title,
|
128
|
+
_url: resource.class.fetch_search(:result_path, record: resource.record) || resource.record_path
|
130
129
|
}
|
131
130
|
end
|
132
131
|
|
133
132
|
def should_apply_has_many_scope?
|
134
|
-
params[:via_association] == "has_many" && @resource.search_query.present?
|
133
|
+
params[:via_association] == "has_many" && @resource.class.search_query.present?
|
135
134
|
end
|
136
135
|
|
137
136
|
def should_apply_attach_scope?
|
@@ -155,16 +154,15 @@ module Avo
|
|
155
154
|
end
|
156
155
|
|
157
156
|
def fetch_field
|
158
|
-
fields =
|
157
|
+
fields = Avo.resource_manager.get_resource_by_model_class(params[:via_reflection_class]).new.get_field_definitions
|
159
158
|
fields.find { |f| f.id.to_s == params[:via_association_id] }
|
160
159
|
end
|
161
160
|
|
162
161
|
def fetch_parent
|
163
162
|
return unless params[:via_reflection_id].present?
|
164
163
|
|
165
|
-
|
166
|
-
|
167
|
-
parent_class.find params[:via_reflection_id]
|
164
|
+
parent_resource = Avo.resource_manager.get_resource_by_model_class params[:via_reflection_class]
|
165
|
+
parent_resource.find_record params[:via_reflection_id], params: params
|
168
166
|
end
|
169
167
|
end
|
170
168
|
end
|
@@ -1,16 +1,13 @@
|
|
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::NilLicense.new
|
5
5
|
Avo::Current.context = context
|
6
6
|
Avo::Current.current_user = _current_user
|
7
7
|
Avo::Current.view_context = view_context
|
8
|
-
Avo
|
9
|
-
Avo::Current.app.init
|
8
|
+
Avo.init
|
10
9
|
Avo::Current.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
|
11
10
|
Avo.plugin_manager.init_plugins
|
12
|
-
|
13
|
-
@license = Avo::App.license
|
14
11
|
end
|
15
12
|
|
16
13
|
def _current_user
|
data/app/javascript/js/controllers/fields/{simple_mde_controller.js → easy_mde_controller.js}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
|
-
import
|
2
|
+
import EasyMDE from 'easymde'
|
3
3
|
|
4
4
|
export default class extends Controller {
|
5
5
|
static targets = ['element']
|
@@ -20,6 +20,7 @@ export default class extends Controller {
|
|
20
20
|
const options = {
|
21
21
|
element: this.elementTarget,
|
22
22
|
spellChecker: this.componentOptions.spell_checker,
|
23
|
+
autoRefresh: { delay: 500},
|
23
24
|
}
|
24
25
|
|
25
26
|
if (this.view === 'show') {
|
@@ -27,9 +28,9 @@ export default class extends Controller {
|
|
27
28
|
options.status = false
|
28
29
|
}
|
29
30
|
|
30
|
-
const
|
31
|
+
const easyMde = new EasyMDE(options)
|
31
32
|
if (this.view === 'show') {
|
32
|
-
|
33
|
+
easyMde.codemirror.options.readOnly = true
|
33
34
|
}
|
34
35
|
}
|
35
36
|
}
|
@@ -211,7 +211,9 @@ export default class extends Controller {
|
|
211
211
|
searchUrl(query) {
|
212
212
|
const url = URI()
|
213
213
|
|
214
|
-
return url.segment([window.Avo.configuration.root_path, ...this.searchSegments()])
|
214
|
+
return url.segment([window.Avo.configuration.root_path, ...this.searchSegments()])
|
215
|
+
.search(this.searchParams(encodeURIComponent(query)))
|
216
|
+
.readable().toString()
|
215
217
|
}
|
216
218
|
|
217
219
|
searchSegments() {
|
@@ -10,6 +10,7 @@ import CodeFieldController from './controllers/fields/code_field_controller'
|
|
10
10
|
import CopyToClipboardController from './controllers/copy_to_clipboard_controller'
|
11
11
|
import DashboardCardController from './controllers/dashboard_card_controller'
|
12
12
|
import DateFieldController from './controllers/fields/date_field_controller'
|
13
|
+
import EasyMdeController from './controllers/fields/easy_mde_controller'
|
13
14
|
import FilterController from './controllers/filter_controller'
|
14
15
|
import HiddenInputController from './controllers/hidden_input_controller'
|
15
16
|
import InputAutofocusController from './controllers/input_autofocus_controller'
|
@@ -31,7 +32,6 @@ import SelectController from './controllers/select_controller'
|
|
31
32
|
import SelectFilterController from './controllers/select_filter_controller'
|
32
33
|
import SelfDestroyController from './controllers/self_destroy_controller'
|
33
34
|
import SidebarController from './controllers/sidebar_controller'
|
34
|
-
import SimpleMdeController from './controllers/fields/simple_mde_controller'
|
35
35
|
import TabsController from './controllers/tabs_controller'
|
36
36
|
import TextFilterController from './controllers/text_filter_controller'
|
37
37
|
import TippyController from './controllers/tippy_controller'
|
@@ -73,9 +73,9 @@ application.register('toggle', ToggleController)
|
|
73
73
|
application.register('belongs-to-field', BelongsToFieldController)
|
74
74
|
application.register('code-field', CodeFieldController)
|
75
75
|
application.register('date-field', DateFieldController)
|
76
|
+
application.register('easy-mde', EasyMdeController)
|
76
77
|
application.register('key-value', KeyValueController)
|
77
78
|
application.register('progress-bar-field', ProgressBarFieldController)
|
78
|
-
application.register('simple-mde', SimpleMdeController)
|
79
79
|
application.register('trix-field', TrixFieldController)
|
80
80
|
|
81
81
|
// Custom controllers
|
@@ -9,7 +9,7 @@
|
|
9
9
|
>
|
10
10
|
<%= form_with model: @record,
|
11
11
|
scope: 'fields',
|
12
|
-
url:
|
12
|
+
url: Avo::Services::URIService.parse(@resource.records_path).append_paths("actions").to_s,
|
13
13
|
local: true,
|
14
14
|
data: @action.class.form_data_attributes do |form|
|
15
15
|
%>
|
@@ -23,6 +23,7 @@
|
|
23
23
|
<%= hidden_field_tag :action_id, @action.param_id %>
|
24
24
|
<%= form.hidden_field :avo_resource_ids, value: params[:id] || params[:resource_ids], 'data-action-target': 'resourceIds' %>
|
25
25
|
<%= form.hidden_field :avo_selected_query, 'data-action-target': 'selectedAllQuery' %>
|
26
|
+
<%= form.hidden_field :arguments, value: params[:arguments] %>
|
26
27
|
<% if @action.get_fields.present? %>
|
27
28
|
<div class="my-4 -mx-6">
|
28
29
|
<% @action.get_fields.each_with_index do |field, index| %>
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
<div class="flex-1 flex items-center justify-center px-0 lg:px-8 text-lg mt-8 mb-12">
|
19
19
|
<% if @field.is_searchable? %>
|
20
|
-
<%= render
|
20
|
+
<%= render Avo::Pro::SearchableAssociations::AutocompleteComponent.new form: form,
|
21
21
|
classes: input_classes("w-full"),
|
22
22
|
field: @field,
|
23
23
|
model_key: @field.target_resource&.model_key,
|
@@ -5,8 +5,8 @@
|
|
5
5
|
</a>
|
6
6
|
</div>
|
7
7
|
<% end %>
|
8
|
-
<% if Avo
|
9
|
-
<% Avo
|
8
|
+
<% if Avo.error_manager.has_errors?.present? %>
|
9
|
+
<% Avo.error_manager.all.each do |error| %>
|
10
10
|
<% if error.is_a? Hash %>
|
11
11
|
<%
|
12
12
|
url, message, target = error.values_at :url, :message, :target
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<div class="text-center text-sm text-gray-700 <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>">
|
2
|
-
<a href="https://avohq.io/" target="_blank">Avo</a> · © <%= Date.today.year %> AvoHQ · <span title="<%= Avo
|
2
|
+
<a href="https://avohq.io/" target="_blank">Avo</a> · © <%= Date.today.year %> AvoHQ · <span title="<%= Avo.license.valid ? 'valid' : 'invalid'%> <%= Avo.license.id %> license">v<%= Avo::VERSION %></span>
|
3
3
|
</div>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
Avo.configuration.cookies_key = '<%= Avo::COOKIES_KEY %>'
|
7
7
|
<% if Avo.avo_filters_installed? %>
|
8
8
|
Avo.configuration.avo_filters = {
|
9
|
-
param_key: '<%=
|
9
|
+
param_key: '<%= Avo::DynamicFilters.configuration.param_key %>'
|
10
10
|
}
|
11
11
|
<% end %>
|
12
12
|
<% end %>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<%= render partial: "avo/partials/logo" %>
|
11
11
|
</div>
|
12
12
|
<div class="flex-1 flex items-center justify-between lg:justify-start space-x-2 sm:space-x-8 lg:px-2">
|
13
|
-
<%= render
|
13
|
+
<%= render Avo::Pro::GlobalSearchComponent.new rescue nil %>
|
14
14
|
<div class="m-0">
|
15
15
|
<%= render partial: "avo/partials/header" %>
|
16
16
|
</div>
|