avo 1.24.0 → 1.25.0
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 +6 -4
- data/app/components/avo/base_component.rb +28 -0
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +10 -2
- data/app/components/avo/index/ordering/base_component.rb +1 -1
- data/app/components/avo/index/ordering/button_component.html.erb +1 -0
- data/app/components/avo/index/ordering/button_component.rb +11 -5
- data/app/components/avo/index/ordering/buttons_component.html.erb +14 -12
- data/app/components/avo/index/ordering/buttons_component.rb +30 -4
- data/app/components/avo/index/resource_controls_component.html.erb +1 -3
- data/app/components/avo/index/resource_controls_component.rb +0 -4
- data/app/components/avo/resource_component.rb +0 -21
- data/app/controllers/avo/base_controller.rb +5 -3
- data/app/controllers/avo/relations_controller.rb +29 -12
- data/app/views/avo/relations/new.html.erb +15 -12
- data/avo.gemspec +1 -0
- data/config/routes.rb +1 -0
- data/lib/avo/base_resource.rb +10 -5
- data/lib/avo/fields/base_field.rb +1 -1
- data/lib/avo/fields/belongs_to_field.rb +1 -1
- data/lib/avo/fields/has_base_field.rb +24 -1
- data/lib/avo/hosts/ordering.rb +22 -0
- data/lib/avo/licensing/pro_license.rb +2 -2
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +6 -0
- data/public/avo-assets/avo.js +7 -5
- data/public/avo-assets/avo.js.map +2 -2
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 371a5db5091d8aad3fd0109c8640a06b10ee5cb61d9b16c5a98d25e566b54787
|
4
|
+
data.tar.gz: 8c15d927349aed0e15ccda76f656883e51ca8c3d33ba703c2646ff7a59695a1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab631914363eb8bd77a5f1053d9c568d6e36f2cdd8c05a84845e4726e3d069394afc1be9778dcc3ad051a91839cb1ef050b12711e165cf8140014cb844096c8c
|
7
|
+
data.tar.gz: 8cbbe3db1bd3e0b77b548706eb696f0ee0bb455cdb2d5ccab6047e4747a0eeae9eff167456bd214ab392825b6c356d061be07c15c7732ef213bc4fa64753c3df
|
data/Gemfile
CHANGED
@@ -39,7 +39,7 @@ gem "puma", "~> 5.6.2"
|
|
39
39
|
# gem 'bcrypt', '~> 3.1.7'
|
40
40
|
|
41
41
|
# Use Active Storage variant
|
42
|
-
gem "image_processing", "~> 1.
|
42
|
+
gem "image_processing", "~> 1.12"
|
43
43
|
|
44
44
|
# Reduces boot times through caching; required in config/boot.rb
|
45
45
|
gem "bootsnap", ">= 1.4.2", require: false
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (1.
|
4
|
+
avo (1.25.0)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
8
8
|
countries
|
9
|
+
dry-initializer
|
9
10
|
hotwire-rails
|
10
11
|
httparty
|
11
12
|
image_processing
|
@@ -155,6 +156,7 @@ GEM
|
|
155
156
|
dotenv-rails (2.7.6)
|
156
157
|
dotenv (= 2.7.6)
|
157
158
|
railties (>= 3.2)
|
159
|
+
dry-initializer (3.1.1)
|
158
160
|
erubi (1.10.0)
|
159
161
|
factory_bot (6.2.0)
|
160
162
|
activesupport (>= 5.0.0)
|
@@ -185,7 +187,7 @@ GEM
|
|
185
187
|
concurrent-ruby (~> 1.0)
|
186
188
|
i18n_data (0.15.0)
|
187
189
|
simple_po_parser (~> 1.1)
|
188
|
-
image_processing (1.12.
|
190
|
+
image_processing (1.12.2)
|
189
191
|
mini_magick (>= 4.9.5, < 5)
|
190
192
|
ruby-vips (>= 2.0.17, < 3)
|
191
193
|
io-wait (0.2.1)
|
@@ -368,7 +370,7 @@ GEM
|
|
368
370
|
tzinfo (2.0.4)
|
369
371
|
concurrent-ruby (~> 1.0)
|
370
372
|
unicode-display_width (2.1.0)
|
371
|
-
view_component (2.
|
373
|
+
view_component (2.49.1)
|
372
374
|
activesupport (>= 5.0.0, < 8.0)
|
373
375
|
method_source (~> 1.0)
|
374
376
|
warden (1.2.9)
|
@@ -423,7 +425,7 @@ DEPENDENCIES
|
|
423
425
|
hotwire-rails
|
424
426
|
htmlbeautifier
|
425
427
|
httparty
|
426
|
-
image_processing (~> 1.
|
428
|
+
image_processing (~> 1.12)
|
427
429
|
iso
|
428
430
|
jsbundling-rails
|
429
431
|
launchy
|
@@ -4,4 +4,32 @@ class Avo::BaseComponent < ViewComponent::Base
|
|
4
4
|
def has_with_trial(ability)
|
5
5
|
::Avo::App.license.has_with_trial(ability)
|
6
6
|
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Figure out what is the corresponding field for this @reflection
|
11
|
+
def field
|
12
|
+
fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
|
13
|
+
fields.find { |f| f.id == @reflection.name }
|
14
|
+
rescue
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def relation_resource
|
19
|
+
::Avo::App.get_resource_by_model_name params[:via_resource_class].safe_constantize
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the resource for the resource using the klass attribute so we get the namespace too
|
23
|
+
def reflection_resource
|
24
|
+
::Avo::App.get_resource_by_model_name(@reflection.klass.to_s)
|
25
|
+
rescue
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get the resource for the resource using the klass attribute so we get the namespace too
|
30
|
+
def reflection_parent_resource
|
31
|
+
::Avo::App.get_resource_by_model_name(@reflection.active_record.to_s)
|
32
|
+
rescue
|
33
|
+
nil
|
34
|
+
end
|
7
35
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
data-via-association="belongs_to"
|
7
7
|
></div>
|
8
8
|
<div class="relative w-full" autocomplete="off">
|
9
|
-
<%= @form.text_field @
|
9
|
+
<%= @form.text_field @foreign_key,
|
10
10
|
value: field_label,
|
11
11
|
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
12
12
|
placeholder: @field.placeholder,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::Fields::BelongsToField::AutocompleteComponent < ViewComponent::Base
|
4
|
-
def initialize(form:, field:, model_key:, foreign_key:, disabled
|
4
|
+
def initialize(form:, field:, model_key:, foreign_key:, disabled: false, type: nil, resource: nil, polymorphic_record: nil)
|
5
5
|
@form = form
|
6
6
|
@field = field
|
7
7
|
@type = type
|
@@ -37,7 +37,15 @@ class Avo::Fields::BelongsToField::AutocompleteComponent < ViewComponent::Base
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def should_prefill?
|
40
|
-
|
40
|
+
# default this conditional to true
|
41
|
+
is_polymorphic = true
|
42
|
+
|
43
|
+
# if this is a field that can be polymorphic (belongs_to)
|
44
|
+
if @field.respond_to? :is_polymorphic?
|
45
|
+
is_polymorphic = @field.is_polymorphic?
|
46
|
+
end
|
47
|
+
|
48
|
+
is_polymorphic && searchable? && !(new_record? && has_polymorphic_association?)
|
41
49
|
end
|
42
50
|
|
43
51
|
def searchable?
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::Index::Ordering::ButtonComponent < Avo::Index::Ordering::BaseComponent
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
attr_accessor :resource
|
5
|
+
attr_accessor :reflection
|
6
|
+
attr_accessor :direction
|
7
|
+
attr_accessor :svg
|
7
8
|
|
8
|
-
def initialize(resource
|
9
|
+
def initialize(resource:, direction:, svg: nil, reflection: nil)
|
9
10
|
@resource = resource
|
11
|
+
@reflection = reflection
|
10
12
|
@direction = direction
|
11
13
|
@svg = svg
|
12
14
|
end
|
@@ -16,7 +18,11 @@ class Avo::Index::Ordering::ButtonComponent < Avo::Index::Ordering::BaseComponen
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def order_path(args)
|
19
|
-
|
21
|
+
if reflection.present?
|
22
|
+
path = "#{::Avo::App.root_path}/resources/#{reflection_parent_resource.route_key}/#{params[:id]}/#{field.id}/#{resource.model.id}/order"
|
23
|
+
else
|
24
|
+
path = "#{::Avo::App.root_path}/resources/#{resource.route_key}/#{resource.model.id}/order"
|
25
|
+
end
|
20
26
|
|
21
27
|
if args.present?
|
22
28
|
string_args = args.map do |key, value|
|
@@ -1,5 +1,12 @@
|
|
1
1
|
<div class="flex items-center justify-center">
|
2
|
-
<%
|
2
|
+
<% if display_inline? %>
|
3
|
+
<div class="flex max-w-xs rounded">
|
4
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :higher, svg: 'arrow-up' %>
|
5
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :lower, svg: 'arrow-down' %>
|
6
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :to_top, svg: 'download-solid-reversed' %>
|
7
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :to_bottom, svg: 'download-solid' %>
|
8
|
+
</div>
|
9
|
+
<% else %>
|
3
10
|
<div class="popover inline-block"
|
4
11
|
data-controller="popover"
|
5
12
|
data-popover-translate-x="-100%"
|
@@ -15,16 +22,11 @@
|
|
15
22
|
%>
|
16
23
|
<%= helpers.svg('switch-vertical', class: 'text-gray-400 h-6 hover:text-gray-600') %>
|
17
24
|
<% end %>
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
<% end %>
|
24
|
-
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, direction: :higher, svg: 'arrow-up' %>
|
25
|
-
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, direction: :lower, svg: 'arrow-down' %>
|
26
|
-
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, direction: :to_top, svg: 'download-solid-reversed' %>
|
27
|
-
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, direction: :to_bottom, svg: 'download-solid' %>
|
25
|
+
<div class="flex hidden absolute max-w-xs bg-white rounded p-2 z-40" data-popover-target="content">
|
26
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :higher, svg: 'arrow-up' %>
|
27
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :lower, svg: 'arrow-down' %>
|
28
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :to_top, svg: 'download-solid-reversed' %>
|
29
|
+
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :to_bottom, svg: 'download-solid' %>
|
28
30
|
</div>
|
29
|
-
|
31
|
+
<% end %>
|
30
32
|
</div>
|
@@ -1,19 +1,45 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::Index::Ordering::ButtonsComponent < Avo::Index::Ordering::BaseComponent
|
4
|
-
def initialize(resource: nil)
|
4
|
+
def initialize(resource: nil, reflection: nil, view_type: nil)
|
5
5
|
@resource = resource
|
6
|
+
@reflection = reflection
|
7
|
+
@view_type = view_type
|
6
8
|
end
|
7
9
|
|
8
10
|
def render?
|
9
|
-
can_order_any?
|
11
|
+
has_with_trial(:resource_ordering) && can_order_any? && view_type_is_table? && enabled_in_view?
|
10
12
|
end
|
11
13
|
|
14
|
+
private
|
15
|
+
|
12
16
|
def can_order_any?
|
13
17
|
order_actions.present?
|
14
18
|
end
|
15
19
|
|
16
|
-
def
|
17
|
-
@
|
20
|
+
def view_type_is_table?
|
21
|
+
@view_type.to_sym == :table
|
22
|
+
end
|
23
|
+
|
24
|
+
def display_inline?
|
25
|
+
ordering[:display_inline]
|
26
|
+
end
|
27
|
+
|
28
|
+
def enabled_in_view?
|
29
|
+
in_association = @reflection.present?
|
30
|
+
|
31
|
+
if in_association
|
32
|
+
visible_on_option.include? :association
|
33
|
+
else
|
34
|
+
visible_on_option.include? :index
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def visible_on_option
|
39
|
+
[ordering[:visible_on]].flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
def ordering
|
43
|
+
@resource.class.ordering
|
18
44
|
end
|
19
45
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
<div class="space-x-2 flex flex-row justify-around items-center w-full">
|
2
|
-
|
3
|
-
<%= render Avo::Index::Ordering::ButtonsComponent.new resource: @resource %>
|
4
|
-
<% end %>
|
2
|
+
<%= render Avo::Index::Ordering::ButtonsComponent.new resource: @resource, reflection: @reflection, view_type: @view_type %>
|
5
3
|
|
6
4
|
<% if can_view? %>
|
7
5
|
<%= link_to helpers.svg('eye', class: 'text-gray-400 h-6 hover:text-gray-600'),
|
@@ -70,8 +70,4 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
70
70
|
def is_has_many_association
|
71
71
|
@reflection.is_a?(::ActiveRecord::Reflection::HasManyReflection) || @reflection.is_a?(::ActiveRecord::Reflection::ThroughReflection)
|
72
72
|
end
|
73
|
-
|
74
|
-
def view_is_table?
|
75
|
-
@view_type == :table
|
76
|
-
end
|
77
73
|
end
|
@@ -30,25 +30,4 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
30
30
|
|
31
31
|
association_policy
|
32
32
|
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
# Figure out what is the corresponding field for this @reflection
|
37
|
-
def field
|
38
|
-
fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
|
39
|
-
fields.find { |f| f.id == @reflection.name }
|
40
|
-
rescue
|
41
|
-
nil
|
42
|
-
end
|
43
|
-
|
44
|
-
def relation_resource
|
45
|
-
::Avo::App.get_resource_by_model_name params[:via_resource_class].safe_constantize
|
46
|
-
end
|
47
|
-
|
48
|
-
# Get the resource for the resource using the klass attribute so we get the namespace too
|
49
|
-
def reflection_resource
|
50
|
-
::Avo::App.get_resource_by_model_name(@reflection.klass.to_s)
|
51
|
-
rescue
|
52
|
-
nil
|
53
|
-
end
|
54
33
|
end
|
@@ -192,10 +192,12 @@ module Avo
|
|
192
192
|
|
193
193
|
def order
|
194
194
|
direction = params[:direction].to_sym
|
195
|
-
order_actions = @resource.class.order_actions
|
196
195
|
|
197
|
-
if direction.present?
|
198
|
-
|
196
|
+
if direction.present?
|
197
|
+
@resource
|
198
|
+
.hydrate(model: @model, params: params)
|
199
|
+
.ordering_host
|
200
|
+
.order direction
|
199
201
|
end
|
200
202
|
|
201
203
|
respond_to do |format|
|
@@ -2,15 +2,15 @@ require_dependency "avo/base_controller"
|
|
2
2
|
|
3
3
|
module Avo
|
4
4
|
class RelationsController < BaseController
|
5
|
-
before_action :set_model, only: [:show, :index, :new, :create, :destroy]
|
5
|
+
before_action :set_model, only: [:show, :index, :new, :create, :destroy, :order]
|
6
6
|
before_action :set_related_resource_name
|
7
|
-
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy]
|
8
|
-
before_action :hydrate_related_resource, only: [:show, :index, :new, :create, :destroy]
|
9
|
-
before_action :set_related_model, only: [:show]
|
10
|
-
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy]
|
11
|
-
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy]
|
12
|
-
before_action :set_attachment_model, only: [:create, :destroy]
|
13
|
-
before_action :set_reflection, only: [:index, :show]
|
7
|
+
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy, :order]
|
8
|
+
before_action :hydrate_related_resource, only: [:show, :index, :new, :create, :destroy, :order]
|
9
|
+
before_action :set_related_model, only: [:show, :order]
|
10
|
+
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy, :order]
|
11
|
+
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy, :order]
|
12
|
+
before_action :set_attachment_model, only: [:create, :destroy, :order]
|
13
|
+
before_action :set_reflection, only: [:index, :show, :order]
|
14
14
|
|
15
15
|
def index
|
16
16
|
@parent_resource = @resource.dup
|
@@ -34,10 +34,20 @@ module Avo
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def new
|
37
|
-
|
37
|
+
@resource.hydrate(model: @model)
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
begin
|
40
|
+
@field = @resource.get_field_definitions.find { |f| f.id == @related_resource_name.to_sym }
|
41
|
+
@field.hydrate(resource: @resource, model: @model, view: :new)
|
42
|
+
rescue
|
43
|
+
end
|
44
|
+
|
45
|
+
if @field.present? && !@field.searchable
|
46
|
+
query = @authorization.apply_policy @attachment_class
|
47
|
+
|
48
|
+
@options = query.all.map do |model|
|
49
|
+
[model.send(@attachment_resource.class.title), model.id]
|
50
|
+
end
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
@@ -50,7 +60,7 @@ module Avo
|
|
50
60
|
|
51
61
|
respond_to do |format|
|
52
62
|
if @model.save
|
53
|
-
format.html { redirect_to resource_path(model: @model, resource: @resource), notice: t("avo.attachment_class_attached", attachment_class: @
|
63
|
+
format.html { redirect_to resource_path(model: @model, resource: @resource), notice: t("avo.attachment_class_attached", attachment_class: @related_resource.name) }
|
54
64
|
format.json { render :show, status: :created, location: resource_path(model: @model, resource: @resource) }
|
55
65
|
else
|
56
66
|
format.html { render :new }
|
@@ -71,6 +81,13 @@ module Avo
|
|
71
81
|
end
|
72
82
|
end
|
73
83
|
|
84
|
+
def order
|
85
|
+
@parent_resource = @resource.dup
|
86
|
+
@resource, @model = @related_resource, @related_model
|
87
|
+
|
88
|
+
super
|
89
|
+
end
|
90
|
+
|
74
91
|
private
|
75
92
|
|
76
93
|
def set_attachment_class
|
@@ -6,22 +6,25 @@
|
|
6
6
|
} do |form| %>
|
7
7
|
<%= render Avo::ModalComponent.new do |c| %>
|
8
8
|
<% c.heading do %>
|
9
|
-
<%= t 'avo.choose_item', item:
|
9
|
+
<%= t 'avo.choose_item', item: @related_resource.name.downcase %>
|
10
10
|
<% end %>
|
11
|
-
|
12
11
|
<div class="flex-1 flex items-center justify-center px-8 text-lg mt-8 mb-12">
|
13
|
-
|
14
|
-
<%=
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
class: input_classes('w-full'),
|
20
|
-
}
|
12
|
+
<% if @field.searchable %>
|
13
|
+
<%= render Avo::Fields::BelongsToField::AutocompleteComponent.new form: form,
|
14
|
+
field: @field,
|
15
|
+
model_key: @field.target_resource&.model_key,
|
16
|
+
foreign_key: 'related_id',
|
17
|
+
resource: @resource
|
21
18
|
%>
|
22
|
-
|
19
|
+
<% else %>
|
20
|
+
<div class="flex-1 flex flex-col items-center justify-center px-24 text-base">
|
21
|
+
<%= form.select :related_id, options_for_select(@options, nil),
|
22
|
+
{ include_blank: t('avo.choose_an_option') },
|
23
|
+
{ class: input_classes('w-full') }
|
24
|
+
%>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
23
27
|
</div>
|
24
|
-
|
25
28
|
<% c.controls do %>
|
26
29
|
<%= a_button t('avo.cancel'), 'data-action': 'click->modal#close', size: :sm %>
|
27
30
|
<%= a_button t('avo.attach'), type: :submit, color: :green, size: :sm %>
|
data/avo.gemspec
CHANGED
data/config/routes.rb
CHANGED
@@ -19,6 +19,7 @@ Avo::Engine.routes.draw do
|
|
19
19
|
|
20
20
|
# Ordering
|
21
21
|
patch "/:resource_name/:id/order", to: "resources#order"
|
22
|
+
patch "/:resource_name/:id/:related_name/:related_id/order", to: "relations#order", as: "associations_order"
|
22
23
|
|
23
24
|
# Actions
|
24
25
|
get "/:resource_name(/:id)/actions/:action_id", to: "actions#show"
|
data/lib/avo/base_resource.rb
CHANGED
@@ -14,6 +14,7 @@ module Avo
|
|
14
14
|
|
15
15
|
attr_accessor :view
|
16
16
|
attr_accessor :model
|
17
|
+
attr_accessor :reflection
|
17
18
|
attr_accessor :user
|
18
19
|
attr_accessor :params
|
19
20
|
|
@@ -142,16 +143,16 @@ module Avo
|
|
142
143
|
# we're matching the reflection inverse_of foriegn key with the field's foreign_key
|
143
144
|
if field.is_a?(Avo::Fields::BelongsToField)
|
144
145
|
if field.respond_to?(:foreign_key) &&
|
145
|
-
|
146
|
-
|
146
|
+
reflection.inverse_of.present? &&
|
147
|
+
reflection.inverse_of.foreign_key == field.foreign_key
|
147
148
|
is_valid = false
|
148
149
|
end
|
149
150
|
|
150
151
|
# polymorphic association
|
151
152
|
if field.respond_to?(:foreign_key) &&
|
152
|
-
|
153
|
-
|
154
|
-
|
153
|
+
field.is_polymorphic? &&
|
154
|
+
reflection.respond_to?(:polymorphic?) &&
|
155
|
+
reflection.inverse_of.foreign_key == field.reflection.foreign_key
|
155
156
|
is_valid = false
|
156
157
|
end
|
157
158
|
end
|
@@ -477,5 +478,9 @@ module Avo
|
|
477
478
|
def form_scope
|
478
479
|
model_class.base_class.to_s.underscore.downcase
|
479
480
|
end
|
481
|
+
|
482
|
+
def ordering_host(**args)
|
483
|
+
Avo::Hosts::Ordering.new resource: self, options: self.class.ordering, **args
|
484
|
+
end
|
480
485
|
end
|
481
486
|
end
|
@@ -7,7 +7,7 @@ module Avo
|
|
7
7
|
include ActionView::Helpers::UrlHelper
|
8
8
|
include Avo::Fields::FieldExtensions::VisibleInDifferentViews
|
9
9
|
|
10
|
-
delegate :view_context, to:
|
10
|
+
delegate :view_context, to: "Avo::App"
|
11
11
|
delegate :main_app, to: :view_context
|
12
12
|
delegate :avo, to: :view_context
|
13
13
|
|
@@ -7,8 +7,13 @@ module Avo
|
|
7
7
|
def initialize(id, **args, &block)
|
8
8
|
super(id, **args, &block)
|
9
9
|
|
10
|
-
@display = args[:display].present? ? args[:display] : :show
|
11
10
|
@scope = args[:scope].present? ? args[:scope] : nil
|
11
|
+
@display = args[:display].present? ? args[:display] : :show
|
12
|
+
@searchable = args[:searchable] == true
|
13
|
+
end
|
14
|
+
|
15
|
+
def searchable
|
16
|
+
@searchable && ::Avo::App.license.has_with_trial(:searchable_associations)
|
12
17
|
end
|
13
18
|
|
14
19
|
def resource
|
@@ -23,6 +28,20 @@ module Avo
|
|
23
28
|
"#{@resource.record_path}/#{id}?turbo_frame=#{turbo_frame}"
|
24
29
|
end
|
25
30
|
|
31
|
+
# The value
|
32
|
+
def field_value
|
33
|
+
value.send(database_value)
|
34
|
+
rescue
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# What the user sees in the text field
|
39
|
+
def field_label
|
40
|
+
value.send(target_resource.class.title)
|
41
|
+
rescue
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
26
45
|
def target_resource
|
27
46
|
if @model._reflections[id.to_s].klass.present?
|
28
47
|
Avo::App.get_resource_by_model_name @model._reflections[id.to_s].klass.to_s
|
@@ -32,6 +51,10 @@ module Avo
|
|
32
51
|
Avo::App.get_resource_by_name id.to_s
|
33
52
|
end
|
34
53
|
end
|
54
|
+
|
55
|
+
def placeholder
|
56
|
+
@placeholder || I18n.t("avo.choose_an_option")
|
57
|
+
end
|
35
58
|
end
|
36
59
|
end
|
37
60
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'dry-initializer'
|
2
|
+
|
3
|
+
module Avo
|
4
|
+
module Hosts
|
5
|
+
class Ordering
|
6
|
+
extend Dry::Initializer
|
7
|
+
|
8
|
+
option :options, default: proc { {} }
|
9
|
+
option :resource
|
10
|
+
option :record, default: proc { resource.model }
|
11
|
+
option :params, default: proc { resource.params }
|
12
|
+
|
13
|
+
def order(direction)
|
14
|
+
action = options.dig(:actions, direction.to_sym)
|
15
|
+
|
16
|
+
if action.present?
|
17
|
+
instance_exec(&action)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/avo/version.rb
CHANGED
@@ -95,3 +95,9 @@ en:
|
|
95
95
|
was_successfully_updated: 'was successfully updated'
|
96
96
|
clear_value: "Clear value"
|
97
97
|
tools: Tools
|
98
|
+
order:
|
99
|
+
reorder_record: Reorder record
|
100
|
+
higher: Move record higher
|
101
|
+
lower: Move record lower
|
102
|
+
to_top: Move record to top
|
103
|
+
to_bottom: Move record to bottom
|