avo 2.12.1.pre.1 → 2.13.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.lock +1 -3
- data/README.md +2 -1
- data/app/components/avo/actions_component.html.erb +3 -3
- data/app/components/avo/actions_component.rb +12 -3
- data/app/components/avo/button_component.rb +1 -3
- data/app/components/avo/fields/common/gravatar_viewer_component.html.erb +1 -1
- data/app/components/avo/fields/date_field/edit_component.html.erb +0 -3
- data/app/components/avo/fields/date_time_field/edit_component.html.erb +0 -2
- data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/show_component.rb +0 -2
- data/app/components/avo/item_switcher_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +1 -1
- data/app/components/avo/panel_component.rb +3 -4
- data/app/components/avo/resource_component.rb +6 -4
- data/app/components/avo/sidebar_component.html.erb +1 -1
- data/app/components/avo/tab_group_component.html.erb +1 -1
- data/app/components/avo/tab_switcher_component.rb +2 -2
- data/app/components/avo/views/resource_edit_component.html.erb +1 -1
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +3 -3
- data/app/components/avo/views/resource_index_component.rb +18 -1
- data/app/components/avo/views/resource_show_component.html.erb +139 -48
- data/app/components/avo/views/resource_show_component.rb +1 -0
- data/app/controllers/avo/base_controller.rb +8 -11
- data/app/controllers/avo/search_controller.rb +57 -20
- data/app/javascript/js/controllers/menu_controller.js +2 -2
- data/app/javascript/js/controllers/search_controller.js +42 -15
- data/app/views/avo/associations/new.html.erb +1 -0
- data/app/views/avo/dashboards/show.html.erb +1 -1
- data/app/views/avo/debug/index.html.erb +1 -1
- data/app/views/avo/debug/report.html.erb +1 -0
- data/app/views/avo/home/index.html.erb +1 -1
- data/app/views/avo/partials/_resource_search.html.erb +6 -0
- data/app/views/avo/private/design.html.erb +2 -2
- data/app/views/layouts/avo/application.html.erb +1 -1
- data/lib/avo/base_resource.rb +5 -1
- data/lib/avo/concerns/has_editable_controls.rb +34 -0
- data/lib/avo/fields/base_field.rb +1 -1
- data/lib/avo/fields/date_field.rb +1 -3
- data/lib/avo/fields/field_extensions/has_include_blank.rb +1 -1
- data/lib/avo/fields/has_base_field.rb +2 -0
- data/lib/avo/fields/key_value_field.rb +6 -6
- data/lib/avo/hosts/search_scope_host.rb +7 -0
- data/lib/avo/licensing/h_q.rb +12 -4
- data/lib/avo/licensing/pro_license.rb +1 -0
- data/lib/avo/menu/builder.rb +2 -0
- data/lib/avo/resources/controls/action.rb +32 -0
- data/lib/avo/resources/controls/actions_list.rb +19 -0
- data/lib/avo/resources/controls/back_button.rb +13 -0
- data/lib/avo/resources/controls/base_control.rb +59 -0
- data/lib/avo/resources/controls/delete_button.rb +13 -0
- data/lib/avo/resources/controls/detach_button.rb +13 -0
- data/lib/avo/resources/controls/edit_button.rb +13 -0
- data/lib/avo/resources/controls/execution_context.rb +58 -0
- data/lib/avo/resources/controls/items_holder.rb +19 -0
- data/lib/avo/resources/controls/link_to.rb +27 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/action.tt +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +1 -0
- data/lib/generators/avo/templates/resource/resource.tt +1 -1
- data/lib/generators/avo/templates/resource_tools/partial.tt +1 -1
- data/lib/generators/avo/templates/standalone_action.tt +1 -1
- data/public/avo-assets/avo.css +564 -44
- data/public/avo-assets/avo.js +47 -47
- data/public/avo-assets/avo.js.map +2 -2
- metadata +16 -5
- data/lib/avo/concerns/has_model.rb +0 -11
@@ -44,10 +44,13 @@ module Avo
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def search_resource(resource)
|
47
|
-
query =
|
47
|
+
query = Avo::Hosts::SearchScopeHost.new(
|
48
|
+
block: resource.search_query,
|
49
|
+
params: params,
|
50
|
+
scope: resource.class.scope
|
51
|
+
).handle
|
48
52
|
|
49
|
-
|
50
|
-
query = apply_attach_scope query
|
53
|
+
query = apply_scope(query) if should_apply_any_scope?
|
51
54
|
|
52
55
|
results = apply_search_metadata(query, resource)
|
53
56
|
|
@@ -67,22 +70,19 @@ module Avo
|
|
67
70
|
[resource.name.pluralize.downcase, result_object]
|
68
71
|
end
|
69
72
|
|
70
|
-
#
|
71
|
-
#
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
# No need to modify the query if there's no attach_scope present.
|
79
|
-
return query if field.attach_scope.blank?
|
80
|
-
|
81
|
-
# Try to fetch the parent.
|
82
|
-
if params[:via_reflection_id].present?
|
83
|
-
parent = params[:via_reflection_class].safe_constantize.find params[:via_reflection_id]
|
73
|
+
# When searching in a `has_many` association and will scope out the records against the parent record.
|
74
|
+
# This is also used when looking for `belongs_to` associations, and this method applies the parents `attach_scope` if present.
|
75
|
+
def apply_scope(query)
|
76
|
+
if should_apply_has_many_scope?
|
77
|
+
apply_has_many_scope
|
78
|
+
elsif should_apply_attach_scope?
|
79
|
+
apply_attach_scope(query, parent)
|
84
80
|
end
|
81
|
+
end
|
85
82
|
|
83
|
+
# Parent passed as argument to be used as a variable instead of the method "def parent"
|
84
|
+
# Otherwise parent = params...safe_constantize... will try to call method "def parent="
|
85
|
+
def apply_attach_scope(query, parent)
|
86
86
|
# If the parent is nil it probably means that someone's creating the record so it's not attached yet.
|
87
87
|
# In these scenarios, try to find the grandparent for the new views where the parent is nil
|
88
88
|
# and initialize the parent record with the grandparent attached so the user has the required information
|
@@ -94,8 +94,13 @@ module Avo
|
|
94
94
|
)
|
95
95
|
end
|
96
96
|
|
97
|
-
|
98
|
-
|
97
|
+
Avo::Hosts::AssociationScopeHost.new(block: attach_scope, query: query, parent: parent).handle
|
98
|
+
end
|
99
|
+
|
100
|
+
def apply_has_many_scope
|
101
|
+
scope = parent.send(params[:via_association_id])
|
102
|
+
|
103
|
+
Avo::Hosts::SearchScopeHost.new(block: @resource.search_query, params: params, scope: scope).handle
|
99
104
|
end
|
100
105
|
|
101
106
|
def apply_search_metadata(models, avo_resource)
|
@@ -118,9 +123,41 @@ module Avo
|
|
118
123
|
end
|
119
124
|
end
|
120
125
|
|
121
|
-
|
126
|
+
private
|
127
|
+
|
128
|
+
def should_apply_has_many_scope?
|
129
|
+
params[:via_association] == "has_many" && @resource.search_query.present?
|
130
|
+
end
|
131
|
+
|
132
|
+
def should_apply_attach_scope?
|
133
|
+
params[:via_association] == "belongs_to" && attach_scope.present?
|
134
|
+
end
|
135
|
+
|
136
|
+
def should_apply_any_scope?
|
137
|
+
should_apply_has_many_scope? || should_apply_attach_scope?
|
138
|
+
end
|
139
|
+
|
140
|
+
def attach_scope
|
141
|
+
@attach_scope ||= field&.attach_scope
|
142
|
+
end
|
143
|
+
|
144
|
+
def field
|
145
|
+
@field ||= fetch_field
|
146
|
+
end
|
147
|
+
|
148
|
+
def parent
|
149
|
+
@parent ||= fetch_parent
|
150
|
+
end
|
151
|
+
|
152
|
+
def fetch_field
|
122
153
|
fields = ::Avo::App.get_resource_by_model_name(params[:via_reflection_class]).get_field_definitions
|
123
154
|
fields.find { |f| f.id.to_s == params[:via_association_id] }
|
124
155
|
end
|
156
|
+
|
157
|
+
def fetch_parent
|
158
|
+
return unless params[:via_reflection_id].present?
|
159
|
+
|
160
|
+
params[:via_reflection_class].safe_constantize.find params[:via_reflection_id]
|
161
|
+
end
|
125
162
|
end
|
126
163
|
end
|
@@ -22,8 +22,8 @@ export default class extends Controller {
|
|
22
22
|
}
|
23
23
|
|
24
24
|
get initiallyCollapsed() {
|
25
|
-
if (this.
|
26
|
-
return this.
|
25
|
+
if (!this.userState) {
|
26
|
+
return this.defaultState === 'collapsed'
|
27
27
|
}
|
28
28
|
|
29
29
|
return this.userState === 'collapsed'
|
@@ -48,6 +48,10 @@ export default class extends Controller {
|
|
48
48
|
return this.dataset.viaAssociation === 'belongs_to'
|
49
49
|
}
|
50
50
|
|
51
|
+
get isHasManySearch() {
|
52
|
+
return this.dataset.viaAssociation === 'has_many'
|
53
|
+
}
|
54
|
+
|
51
55
|
get isGlobalSearch() {
|
52
56
|
return this.dataset.searchResource === 'global'
|
53
57
|
}
|
@@ -83,27 +87,50 @@ export default class extends Controller {
|
|
83
87
|
params.global = true
|
84
88
|
}
|
85
89
|
|
86
|
-
if (this.isBelongsToSearch) {
|
87
|
-
params =
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
via_relation: this.dataset.viaRelation,
|
90
|
+
if (this.isBelongsToSearch || this.isHasManySearch) {
|
91
|
+
params = this.addAssociationParams(params)
|
92
|
+
params = this.addReflectionParams(params)
|
93
|
+
|
94
|
+
if (this.isBelongsToSearch) {
|
95
|
+
params = {
|
96
|
+
...params,
|
97
|
+
// eslint-disable-next-line camelcase
|
98
|
+
via_parent_resource_id: this.dataset.viaParentResourceId,
|
99
|
+
// eslint-disable-next-line camelcase
|
100
|
+
via_parent_resource_class: this.dataset.viaParentResourceClass,
|
101
|
+
// eslint-disable-next-line camelcase
|
102
|
+
via_relation: this.dataset.viaRelation,
|
103
|
+
}
|
101
104
|
}
|
102
105
|
}
|
103
106
|
|
104
107
|
return params
|
105
108
|
}
|
106
109
|
|
110
|
+
addAssociationParams(params) {
|
111
|
+
params = {
|
112
|
+
...params,
|
113
|
+
// eslint-disable-next-line camelcase
|
114
|
+
via_association: this.dataset.viaAssociation,
|
115
|
+
// eslint-disable-next-line camelcase
|
116
|
+
via_association_id: this.dataset.viaAssociationId,
|
117
|
+
}
|
118
|
+
|
119
|
+
return params
|
120
|
+
}
|
121
|
+
|
122
|
+
addReflectionParams(params) {
|
123
|
+
params = {
|
124
|
+
...params,
|
125
|
+
// eslint-disable-next-line camelcase
|
126
|
+
via_reflection_class: this.dataset.viaReflectionClass,
|
127
|
+
// eslint-disable-next-line camelcase
|
128
|
+
via_reflection_id: this.dataset.viaReflectionId,
|
129
|
+
}
|
130
|
+
|
131
|
+
return params
|
132
|
+
}
|
133
|
+
|
107
134
|
handleOnSelect({ item }) {
|
108
135
|
if (this.isBelongsToSearch) {
|
109
136
|
this.updateFieldAttribute(this.hiddenIdTarget, 'value', item._id)
|
@@ -13,6 +13,7 @@
|
|
13
13
|
<div class="flex-1 flex items-center justify-center px-0 lg:px-8 text-lg mt-8 mb-12">
|
14
14
|
<% if @field.searchable %>
|
15
15
|
<%= render Avo::Fields::BelongsToField::AutocompleteComponent.new form: form,
|
16
|
+
classes: input_classes("w-full"),
|
16
17
|
field: @field,
|
17
18
|
model_key: @field.target_resource&.model_key,
|
18
19
|
foreign_key: 'related_id',
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= render Avo::PanelComponent.new(
|
1
|
+
<%= render Avo::PanelComponent.new(name: @dashboard.name, description: @dashboard.description) do |c| %>
|
2
2
|
<% c.bare_content do %>
|
3
3
|
<% if @dashboard.items.present? %>
|
4
4
|
<div class="min-h-24">
|
@@ -14,7 +14,7 @@
|
|
14
14
|
hq_payload = Avo::Licensing::HQ.new(request).payload
|
15
15
|
%>
|
16
16
|
<div class="flex flex-col">
|
17
|
-
<%= render Avo::PanelComponent.new(
|
17
|
+
<%= render Avo::PanelComponent.new(name: 'Debug Avo', description: 'Use this page to debug the Avo license.') do |c| %>
|
18
18
|
<% c.tools do %>
|
19
19
|
<% end %>
|
20
20
|
<% c.bare_content do %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="flex flex-col">
|
2
|
-
<%= render Avo::PanelComponent.new(
|
2
|
+
<%= render Avo::PanelComponent.new(name: 'Welcome to Avo', description: 'This page is visible only in development. It will be hidden in other environments.') do |c| %>
|
3
3
|
<% c.body do %>
|
4
4
|
<div class="flex flex-col justify-between py-6 min-h-24">
|
5
5
|
<div class="px-6 space-y-4">
|
@@ -3,6 +3,12 @@
|
|
3
3
|
data-search-target="autocomplete"
|
4
4
|
data-search-resource="<%= resource %>"
|
5
5
|
data-translation-keys='{"no_item_found": "<%= I18n.translate 'avo.no_item_found' %>"}'
|
6
|
+
<% if via_reflection.present? %>
|
7
|
+
data-via-association="<%= via_reflection[:association] %>"
|
8
|
+
data-via-association-id="<%= via_reflection[:association_id] %>"
|
9
|
+
data-via-reflection-class="<%= via_reflection[:class] %>"
|
10
|
+
data-via-reflection-id="<%= via_reflection[:id] %>"
|
11
|
+
<% end %>
|
6
12
|
>
|
7
13
|
</div>
|
8
14
|
<div class="hidden relative inline-flex text-gray-400 text-sm border border-gray-300 rounded cursor-pointer" data-search-target="button"></div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="flex flex-col">
|
2
|
-
<%= render Avo::PanelComponent.new(
|
2
|
+
<%= render Avo::PanelComponent.new(name: 'Welcome to Avo', description: 'This page is visible only in development. It will be hidden in other environments.') do |c| %>
|
3
3
|
<% c.tools do %>
|
4
|
-
<%= a_link('/admin', icon: 'arrow-left', style: :primary, is_link: true) do %>
|
4
|
+
<%= a_link('/admin', icon: 'arrow-left', color: :green, style: :primary, is_link: true) do %>
|
5
5
|
Primary
|
6
6
|
<% end %>
|
7
7
|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<% end %>
|
19
19
|
<% end %>
|
20
20
|
</head>
|
21
|
-
<body class="bg-
|
21
|
+
<body class="bg-application os-mac">
|
22
22
|
<div class="relative flex flex-1 w-full min-h-full" data-controller="sidebar" data-sidebar-open-value="<%= @sidebar_open %>">
|
23
23
|
<div class="flex-1 flex flex-col max-w-full">
|
24
24
|
<%= render partial: "avo/partials/navbar" %>
|
data/lib/avo/base_resource.rb
CHANGED
@@ -3,8 +3,8 @@ module Avo
|
|
3
3
|
extend ActiveSupport::DescendantsTracker
|
4
4
|
|
5
5
|
include ActionView::Helpers::UrlHelper
|
6
|
-
include Avo::Concerns::HasModel
|
7
6
|
include Avo::Concerns::HasFields
|
7
|
+
include Avo::Concerns::HasEditableControls
|
8
8
|
include Avo::Concerns::HasStimulusControllers
|
9
9
|
include Avo::Concerns::ModelClassConstantized
|
10
10
|
|
@@ -439,5 +439,9 @@ module Avo
|
|
439
439
|
def ordering_host(**args)
|
440
440
|
Avo::Hosts::Ordering.new resource: self, options: self.class.ordering, **args
|
441
441
|
end
|
442
|
+
|
443
|
+
def has_model_id?
|
444
|
+
model.present? && model.id.present?
|
445
|
+
end
|
442
446
|
end
|
443
447
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Avo
|
2
|
+
module Concerns
|
3
|
+
module HasEditableControls
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :show_controls
|
8
|
+
class_attribute :show_controls_holder
|
9
|
+
class_attribute :show_controls_holder_called, default: false
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_show_controls?
|
13
|
+
return false if ::Avo::App.license.lacks_with_trial(:resource_show_controls)
|
14
|
+
|
15
|
+
self.class.show_controls.present?
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_show_controls
|
19
|
+
return [] if ::Avo::App.license.lacks_with_trial(:resource_show_controls)
|
20
|
+
|
21
|
+
if show_controls.present?
|
22
|
+
Avo::Resources::Controls::ExecutionContext.new(
|
23
|
+
block: show_controls,
|
24
|
+
resource: self,
|
25
|
+
record: model,
|
26
|
+
view: view
|
27
|
+
).handle&.items || []
|
28
|
+
else
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -160,7 +160,7 @@ module Avo
|
|
160
160
|
final_value = @model.send(property) if (model_or_class(@model) == "model") && @model.respond_to?(property)
|
161
161
|
|
162
162
|
# On new views and actions modals we need to prefill the fields
|
163
|
-
if
|
163
|
+
if @view.in?([:new, :create]) || @action.present?
|
164
164
|
if default.present?
|
165
165
|
final_value = if default.respond_to?(:call)
|
166
166
|
default.call
|
@@ -5,15 +5,13 @@ module Avo
|
|
5
5
|
attr_reader :picker_format
|
6
6
|
attr_reader :disable_mobile
|
7
7
|
attr_reader :format
|
8
|
-
attr_reader :relative
|
9
8
|
|
10
9
|
def initialize(id, **args, &block)
|
11
10
|
super(id, **args, &block)
|
12
11
|
|
13
|
-
add_string_prop args, :first_day_of_week,
|
12
|
+
add_string_prop args, :first_day_of_week, 1
|
14
13
|
add_string_prop args, :picker_format, "Y-m-d"
|
15
14
|
add_string_prop args, :format, "yyyy-LL-dd"
|
16
|
-
add_boolean_prop args, :relative
|
17
15
|
add_boolean_prop args, :disable_mobile
|
18
16
|
end
|
19
17
|
|
@@ -6,6 +6,7 @@ module Avo
|
|
6
6
|
attr_accessor :attach_scope
|
7
7
|
attr_accessor :description
|
8
8
|
attr_accessor :discreet_pagination
|
9
|
+
attr_accessor :hide_search_input
|
9
10
|
|
10
11
|
def initialize(id, **args, &block)
|
11
12
|
super(id, **args, &block)
|
@@ -14,6 +15,7 @@ module Avo
|
|
14
15
|
@attach_scope = args[:attach_scope].present? ? args[:attach_scope] : nil
|
15
16
|
@display = args[:display].present? ? args[:display] : :show
|
16
17
|
@searchable = args[:searchable] == true
|
18
|
+
@hide_search_input = args[:hide_search_input] || false
|
17
19
|
@description = args[:description]
|
18
20
|
@use_resource = args[:use_resource] || nil
|
19
21
|
@discreet_pagination = args[:discreet_pagination] || false
|
@@ -12,8 +12,8 @@ module Avo
|
|
12
12
|
hide_on :index
|
13
13
|
|
14
14
|
@key_label = args[:key_label] if args[:key_label].present?
|
15
|
-
@value_label = args[:value_label]if args[:value_label].present?
|
16
|
-
@action_text = args[:action_text] if args[:action_text].present?
|
15
|
+
@value_label = args[:value_label] if args[:value_label].present?
|
16
|
+
@action_text = args[:action_text] if args[:action_text].present? # This should be add_row_label
|
17
17
|
@delete_text = args[:delete_text] if args[:delete_text].present?
|
18
18
|
|
19
19
|
@disable_editing_keys = args[:disable_editing_keys].present? ? args[:disable_editing_keys] : false
|
@@ -31,25 +31,25 @@ module Avo
|
|
31
31
|
def key_label
|
32
32
|
return @key_label if @key_label.present?
|
33
33
|
|
34
|
-
I18n.translate(
|
34
|
+
I18n.translate("avo.key_value_field.key")
|
35
35
|
end
|
36
36
|
|
37
37
|
def value_label
|
38
38
|
return @value_label if @value_label.present?
|
39
39
|
|
40
|
-
I18n.translate(
|
40
|
+
I18n.translate("avo.key_value_field.value")
|
41
41
|
end
|
42
42
|
|
43
43
|
def action_text
|
44
44
|
return @action_text if @action_text.present?
|
45
45
|
|
46
|
-
I18n.translate(
|
46
|
+
I18n.translate("avo.key_value_field.add_row")
|
47
47
|
end
|
48
48
|
|
49
49
|
def delete_text
|
50
50
|
return @delete_text if @delete_text.present?
|
51
51
|
|
52
|
-
I18n.translate(
|
52
|
+
I18n.translate("avo.key_value_field.delete_row")
|
53
53
|
end
|
54
54
|
|
55
55
|
def to_permitted_param
|
data/lib/avo/licensing/h_q.rb
CHANGED
@@ -22,16 +22,24 @@ module Avo
|
|
22
22
|
def response
|
23
23
|
expire_cache_if_overdue
|
24
24
|
|
25
|
+
# ------------------------------------------------------------------
|
26
|
+
# You could set this to true to become a pro user for free.
|
27
|
+
# I'd rather you didn't. Avo takes time & love to build,
|
28
|
+
# and I can't do that if it doesn't pay my bills!
|
29
|
+
#
|
30
|
+
# If you want Pro, help pay for its development.
|
31
|
+
# Can't afford it? Get in touch: adrian@avohq.io
|
32
|
+
# ------------------------------------------------------------------
|
25
33
|
make_request
|
26
34
|
end
|
27
35
|
|
28
36
|
# Some cache stores don't auto-expire their keys and payloads so we need to do it for them
|
29
37
|
def expire_cache_if_overdue
|
30
38
|
return unless cached_response.present?
|
31
|
-
return unless cached_response[
|
39
|
+
return unless cached_response["fetched_at"].present?
|
32
40
|
|
33
41
|
allowed_time = 1.hour
|
34
|
-
parsed_time = Time.parse(cached_response[
|
42
|
+
parsed_time = Time.parse(cached_response["fetched_at"].to_s)
|
35
43
|
time_has_passed = parsed_time < Time.now - allowed_time
|
36
44
|
|
37
45
|
clear_response if time_has_passed
|
@@ -159,7 +167,7 @@ module Avo
|
|
159
167
|
def perform_request
|
160
168
|
::Rails.logger.debug "[Avo] Performing request to avohq.io API to check license availability." if Rails.env.development?
|
161
169
|
|
162
|
-
HTTParty.post ENDPOINT, body: payload.to_json, headers: {
|
170
|
+
HTTParty.post ENDPOINT, body: payload.to_json, headers: {"Content-type": "application/json"}, timeout: REQUEST_TIMEOUT
|
163
171
|
end
|
164
172
|
|
165
173
|
def app_name
|
@@ -177,7 +185,7 @@ module Avo
|
|
177
185
|
|
178
186
|
{
|
179
187
|
"#{type}_count": type_count,
|
180
|
-
"#{type}_per_resource": type_per_resource
|
188
|
+
"#{type}_per_resource": type_per_resource
|
181
189
|
}
|
182
190
|
end
|
183
191
|
|
data/lib/avo/menu/builder.rb
CHANGED
@@ -11,6 +11,8 @@ class Avo::Menu::Builder
|
|
11
11
|
delegate :request, to: ::Avo::App
|
12
12
|
delegate :root_path, to: ::Avo::App
|
13
13
|
delegate :view_context, to: ::Avo::App
|
14
|
+
delegate :main_app, to: :view_context
|
15
|
+
delegate :avo, to: :view_context
|
14
16
|
|
15
17
|
def initialize(name: nil, items: [])
|
16
18
|
@menu = Avo::Menu::Menu.new
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Avo
|
2
|
+
module Resources
|
3
|
+
module Controls
|
4
|
+
class Action < BaseControl
|
5
|
+
attr_reader :klass
|
6
|
+
|
7
|
+
def initialize(klass, model: nil, resource: nil, view: nil, **args)
|
8
|
+
super(**args)
|
9
|
+
|
10
|
+
@klass = klass
|
11
|
+
@resource = resource
|
12
|
+
@model = model
|
13
|
+
@view = view
|
14
|
+
end
|
15
|
+
|
16
|
+
def action
|
17
|
+
return @instance if @instance.present?
|
18
|
+
|
19
|
+
@instance = @klass.new(model: @model, resource: @resource, view: @view)
|
20
|
+
end
|
21
|
+
|
22
|
+
def path
|
23
|
+
Avo::Services::URIService.parse(@resource.record_path).append_paths("actions", action.param_id).to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def label
|
27
|
+
@args[:label] || action.action_name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Avo
|
2
|
+
module Resources
|
3
|
+
module Controls
|
4
|
+
class ActionsList < BaseControl
|
5
|
+
def exclude
|
6
|
+
Array.wrap(@args[:exclude]) || []
|
7
|
+
end
|
8
|
+
|
9
|
+
def color
|
10
|
+
@args[:color] || :primary
|
11
|
+
end
|
12
|
+
|
13
|
+
def style
|
14
|
+
@args[:style] || :outline
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Avo
|
2
|
+
module Resources
|
3
|
+
module Controls
|
4
|
+
class BaseControl
|
5
|
+
def initialize(**args)
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def label
|
10
|
+
@args[:label] || @label
|
11
|
+
end
|
12
|
+
|
13
|
+
def title
|
14
|
+
@args[:title]
|
15
|
+
end
|
16
|
+
|
17
|
+
def color
|
18
|
+
@args[:color] || :gray
|
19
|
+
end
|
20
|
+
|
21
|
+
def style
|
22
|
+
@args[:style] || :text
|
23
|
+
end
|
24
|
+
|
25
|
+
def icon
|
26
|
+
@args[:icon] || nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def back_button?
|
30
|
+
is_a? Avo::Resources::Controls::BackButton
|
31
|
+
end
|
32
|
+
|
33
|
+
def edit_button?
|
34
|
+
is_a? Avo::Resources::Controls::EditButton
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_button?
|
38
|
+
is_a? Avo::Resources::Controls::DeleteButton
|
39
|
+
end
|
40
|
+
|
41
|
+
def actions_list?
|
42
|
+
is_a? Avo::Resources::Controls::ActionsList
|
43
|
+
end
|
44
|
+
|
45
|
+
def link_to?
|
46
|
+
is_a? Avo::Resources::Controls::LinkTo
|
47
|
+
end
|
48
|
+
|
49
|
+
def detach_button?
|
50
|
+
is_a? Avo::Resources::Controls::DetachButton
|
51
|
+
end
|
52
|
+
|
53
|
+
def action?
|
54
|
+
is_a? Avo::Resources::Controls::Action
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|