avo 2.18.1 → 2.19.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 +4 -5
- data/Gemfile.lock +75 -76
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +4 -4
- data/app/components/avo/base_component.rb +17 -0
- data/app/components/avo/field_wrapper_component.rb +7 -1
- data/app/components/avo/fields/has_one_field/show_component.rb +1 -2
- data/app/components/avo/fields/index_component.rb +4 -3
- data/app/components/avo/filters_component.html.erb +1 -1
- data/app/components/avo/filters_component.rb +2 -2
- data/app/components/avo/index/grid_item_component.rb +2 -2
- data/app/components/avo/index/resource_controls_component.rb +2 -2
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +1 -1
- data/app/components/avo/resource_component.rb +1 -1
- data/app/components/avo/resource_sidebar_component.rb +1 -6
- data/app/components/avo/sidebar_profile_component.rb +3 -1
- data/app/components/avo/tab_group_component.rb +1 -1
- data/app/components/avo/views/resource_show_component.html.erb +1 -1
- data/app/controllers/avo/application_controller.rb +6 -0
- data/app/controllers/avo/base_controller.rb +14 -7
- data/app/controllers/avo/dashboards/cards_controller.rb +37 -0
- data/app/helpers/avo/application_helper.rb +5 -1
- data/app/javascript/js/controllers/search_controller.js +11 -2
- data/app/views/avo/{cards → dashboards/cards}/_chartkick_card.html.erb +0 -0
- data/app/views/avo/{cards → dashboards/cards}/_metric_card.html.erb +0 -0
- data/app/views/avo/{cards → dashboards/cards}/chartkick_missing.html.erb +0 -0
- data/app/views/avo/{cards → dashboards/cards}/show.html.erb +0 -0
- data/app/views/avo/partials/_branding.html.erb +1 -0
- data/avo.gemspec +1 -1
- data/bin/init +11 -1
- data/bin/test +1 -0
- data/config/routes.rb +2 -2
- data/db/factories.rb +10 -0
- data/lib/avo/app.rb +11 -1
- data/lib/avo/base_action.rb +19 -9
- data/lib/avo/base_resource.rb +3 -6
- data/lib/avo/concerns/filters_session_handler.rb +43 -0
- data/lib/avo/concerns/has_fields.rb +2 -0
- data/lib/avo/concerns/visible_items.rb +44 -0
- data/lib/avo/configuration/branding.rb +10 -2
- data/lib/avo/configuration.rb +3 -0
- data/lib/avo/dynamic_router.rb +16 -15
- data/lib/avo/engine.rb +6 -9
- data/lib/avo/fields/base_field.rb +21 -12
- data/lib/avo/fields/concerns/has_default.rb +17 -0
- data/lib/avo/fields/concerns/is_readonly.rb +1 -1
- data/lib/avo/fields/concerns/is_required.rb +2 -2
- data/lib/avo/fields/has_base_field.rb +2 -0
- data/lib/avo/fields/key_value_field.rb +1 -1
- data/lib/avo/filters/base_filter.rb +17 -2
- data/lib/avo/hosts/resource_view_record_host.rb +7 -0
- data/lib/avo/hosts/visibility_host.rb +11 -0
- data/lib/avo/panel.rb +4 -1
- data/lib/avo/resources/controls/action.rb +1 -3
- data/lib/avo/sidebar.rb +1 -31
- data/lib/avo/tab.rb +5 -22
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +9 -0
- data/lib/generators/avo/resource_generator.rb +281 -0
- data/lib/generators/avo/templates/action.tt +3 -0
- data/lib/generators/avo/templates/filters/boolean_filter.tt +3 -0
- data/lib/generators/avo/templates/filters/multiple_select_filter.tt +3 -0
- data/lib/generators/avo/templates/filters/select_filter.tt +3 -0
- data/lib/generators/avo/templates/filters/text_filter.tt +3 -0
- data/lib/generators/avo/templates/initializer/avo.tt +4 -0
- data/lib/generators/avo/templates/resource/controller.tt +1 -1
- data/lib/generators/avo/templates/resource/resource.tt +2 -2
- data/lib/generators/model_generator.rb +10 -0
- data/lib/generators/rails/avo_resource_generator.rb +11 -0
- data/public/avo-assets/avo.base.css +10 -10
- data/public/avo-assets/avo.base.js +1 -1
- data/public/avo-assets/avo.base.js.map +2 -2
- data/public/avo-assets/favicon.ico +0 -0
- data/{app/assets/svgs → public/avo-assets}/placeholder.svg +0 -0
- metadata +18 -11
- data/app/controllers/avo/cards_controller.rb +0 -35
- data/config/master.key +0 -1
@@ -6,7 +6,7 @@ module Avo
|
|
6
6
|
|
7
7
|
def is_required?
|
8
8
|
if required.respond_to? :call
|
9
|
-
Avo::Hosts::
|
9
|
+
Avo::Hosts::ResourceViewRecordHost.new(block: required, record: model, view: view, resource: resource).handle
|
10
10
|
else
|
11
11
|
required.nil? ? required_from_validators : required
|
12
12
|
end
|
@@ -18,7 +18,7 @@ module Avo
|
|
18
18
|
return false if model.nil?
|
19
19
|
|
20
20
|
validators.any? do |validator|
|
21
|
-
validator.
|
21
|
+
validator.is_a? ActiveModel::Validations::PresenceValidator
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -7,6 +7,7 @@ module Avo
|
|
7
7
|
attr_accessor :description
|
8
8
|
attr_accessor :discreet_pagination
|
9
9
|
attr_accessor :hide_search_input
|
10
|
+
attr_reader :link_to_child_resource
|
10
11
|
|
11
12
|
def initialize(id, **args, &block)
|
12
13
|
super(id, **args, &block)
|
@@ -19,6 +20,7 @@ module Avo
|
|
19
20
|
@description = args[:description]
|
20
21
|
@use_resource = args[:use_resource] || nil
|
21
22
|
@discreet_pagination = args[:discreet_pagination] || false
|
23
|
+
@link_to_child_resource = args[:link_to_child_resource] || false
|
22
24
|
end
|
23
25
|
|
24
26
|
def searchable
|
@@ -3,11 +3,12 @@ module Avo
|
|
3
3
|
class BaseFilter
|
4
4
|
PARAM_KEY = :filters unless const_defined?(:PARAM_KEY)
|
5
5
|
|
6
|
-
class_attribute :name, default: "Filter"
|
7
6
|
class_attribute :component, default: "boolean-filter"
|
8
7
|
class_attribute :default, default: nil
|
9
|
-
class_attribute :template, default: "avo/base/select_filter"
|
10
8
|
class_attribute :empty_message
|
9
|
+
class_attribute :name, default: "Filter"
|
10
|
+
class_attribute :template, default: "avo/base/select_filter"
|
11
|
+
class_attribute :visible
|
11
12
|
|
12
13
|
delegate :params, to: Avo::App
|
13
14
|
|
@@ -52,6 +53,20 @@ module Avo
|
|
52
53
|
def applied_filters
|
53
54
|
self.class.decode_filters params[PARAM_KEY]
|
54
55
|
end
|
56
|
+
|
57
|
+
def visible_in_view(resource: nil, parent_model: nil, parent_resource: nil)
|
58
|
+
return true if visible.blank?
|
59
|
+
|
60
|
+
# Run the visible block if available
|
61
|
+
Avo::Hosts::VisibilityHost.new(
|
62
|
+
block: visible,
|
63
|
+
params: params,
|
64
|
+
parent_model: parent_model,
|
65
|
+
parent_resource: parent_resource,
|
66
|
+
resource: resource
|
67
|
+
).handle
|
68
|
+
|
69
|
+
end
|
55
70
|
end
|
56
71
|
end
|
57
72
|
end
|
data/lib/avo/panel.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
class Avo::Panel
|
2
2
|
include Avo::Concerns::IsResourceItem
|
3
|
+
include Avo::Concerns::VisibleItems
|
3
4
|
|
4
5
|
class_attribute :item_type, default: :panel
|
5
6
|
|
6
7
|
attr_reader :name
|
8
|
+
attr_reader :view
|
7
9
|
attr_reader :description
|
8
10
|
attr_accessor :items_holder
|
9
11
|
|
10
12
|
delegate :items, :add_item, to: :items_holder
|
11
13
|
|
12
|
-
def initialize(name: nil, description: nil)
|
14
|
+
def initialize(name: nil, description: nil, view: nil)
|
13
15
|
@name = name
|
16
|
+
@view = view
|
14
17
|
@description = description
|
15
18
|
@items_holder = Avo::ItemsHolder.new
|
16
19
|
end
|
data/lib/avo/sidebar.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class Avo::Sidebar
|
2
2
|
include Avo::Concerns::IsResourceItem
|
3
|
+
include Avo::Concerns::VisibleItems
|
3
4
|
include Avo::Fields::FieldExtensions::VisibleInDifferentViews
|
4
5
|
|
5
6
|
class_attribute :item_type, default: :sidebar
|
@@ -23,38 +24,7 @@ class Avo::Sidebar
|
|
23
24
|
except_on args[:except_on] if args[:except_on].present?
|
24
25
|
end
|
25
26
|
|
26
|
-
def hydrate(view: nil)
|
27
|
-
@view = view
|
28
|
-
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
27
|
def empty?
|
33
28
|
visible_items.blank?
|
34
29
|
end
|
35
|
-
|
36
|
-
def items
|
37
|
-
if self.items_holder.present?
|
38
|
-
self.items_holder.items
|
39
|
-
else
|
40
|
-
[]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def visible_items
|
45
|
-
items.map do |item|
|
46
|
-
# Remove the fields that shouldn't be visible in this view
|
47
|
-
# eg: has_many fields on edit
|
48
|
-
if not_visible_field(item)
|
49
|
-
nil
|
50
|
-
else
|
51
|
-
item
|
52
|
-
end
|
53
|
-
end
|
54
|
-
.compact
|
55
|
-
end
|
56
|
-
|
57
|
-
def not_visible_field(item)
|
58
|
-
item.is_field? && !item.visible_on?(view)
|
59
|
-
end
|
60
30
|
end
|
data/lib/avo/tab.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class Avo::Tab
|
2
2
|
include Avo::Concerns::IsResourceItem
|
3
|
+
include Avo::Concerns::VisibleItems
|
3
4
|
include Avo::Fields::FieldExtensions::VisibleInDifferentViews
|
4
5
|
|
5
6
|
class_attribute :item_type, default: :tab
|
@@ -30,6 +31,10 @@ class Avo::Tab
|
|
30
31
|
def hydrate(view: nil)
|
31
32
|
@view = view
|
32
33
|
|
34
|
+
items_holder.items.grep(Avo::Panel).each do |panel|
|
35
|
+
panel.hydrate(view: view)
|
36
|
+
end
|
37
|
+
|
33
38
|
self
|
34
39
|
end
|
35
40
|
|
@@ -53,26 +58,4 @@ class Avo::Tab
|
|
53
58
|
super(view)
|
54
59
|
end
|
55
60
|
end
|
56
|
-
|
57
|
-
def items
|
58
|
-
if self.items_holder.present?
|
59
|
-
self.items_holder.items
|
60
|
-
else
|
61
|
-
[]
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def visible_items
|
66
|
-
items.map do |item|
|
67
|
-
if item.is_field?
|
68
|
-
visible = item.visible_on?(view)
|
69
|
-
# Remove the fields that shouldn't be visible in this view
|
70
|
-
# eg: has_many fields on edit
|
71
|
-
item = nil unless visible
|
72
|
-
end
|
73
|
-
|
74
|
-
item
|
75
|
-
end
|
76
|
-
.compact
|
77
|
-
end
|
78
61
|
end
|
data/lib/avo/version.rb
CHANGED
data/lib/avo.rb
CHANGED
@@ -40,6 +40,15 @@ module Avo
|
|
40
40
|
IN_DEVELOPMENT = ENV["AVO_IN_DEVELOPMENT"] == "1"
|
41
41
|
PACKED = !IN_DEVELOPMENT
|
42
42
|
COOKIES_KEY = "avo"
|
43
|
+
ENTITIES = {
|
44
|
+
cards: ["app", "avo", "cards"],
|
45
|
+
fields: ["app", "avo", "fields"],
|
46
|
+
filters: ["app", "avo", "filters"],
|
47
|
+
actions: ["app", "avo", "actions"],
|
48
|
+
resources: ["app", "avo", "resources"],
|
49
|
+
dashboards: ["app", "avo", "dashboards"],
|
50
|
+
resource_tools: ["app", "avo", "resource_tools"]
|
51
|
+
}
|
43
52
|
|
44
53
|
class LicenseVerificationTemperedError < StandardError; end
|
45
54
|
|
@@ -7,6 +7,11 @@ module Generators
|
|
7
7
|
|
8
8
|
namespace "avo:resource"
|
9
9
|
|
10
|
+
class_option "model-class",
|
11
|
+
type: :string,
|
12
|
+
required: false,
|
13
|
+
desc: "The name of the model."
|
14
|
+
|
10
15
|
def create
|
11
16
|
template "resource/resource.tt", "app/avo/resources/#{resource_name}.rb"
|
12
17
|
template "resource/controller.tt", "app/controllers/avo/#{controller_name}.rb"
|
@@ -33,6 +38,282 @@ module Generators
|
|
33
38
|
model.capitalize.singularize.camelize
|
34
39
|
end
|
35
40
|
end
|
41
|
+
|
42
|
+
def class_from_args
|
43
|
+
@class_from_args ||= options["model-class"]&.capitalize
|
44
|
+
end
|
45
|
+
|
46
|
+
def model_class_from_args
|
47
|
+
"\n self.model_class = ::#{class_from_args}" if class_from_args.present?
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def model_class
|
53
|
+
@model_class ||= class_from_args || singular_name
|
54
|
+
end
|
55
|
+
|
56
|
+
def model
|
57
|
+
@model ||= model_class.classify.safe_constantize
|
58
|
+
end
|
59
|
+
|
60
|
+
def model_db_columns
|
61
|
+
@model_db_columns ||= model.columns_hash.reject { |name, _| db_columns_to_ignore.include? name }
|
62
|
+
end
|
63
|
+
|
64
|
+
def db_columns_to_ignore
|
65
|
+
%w[id encrypted_password reset_password_token reset_password_sent_at remember_created_at created_at updated_at]
|
66
|
+
end
|
67
|
+
|
68
|
+
def reflections
|
69
|
+
@reflections ||= model.reflections.reject do |name, _|
|
70
|
+
reflections_sufixes_to_ignore.include?(name.split("_").pop) || reflections_to_ignore.include?(name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def reflections_sufixes_to_ignore
|
75
|
+
%w[blob blobs tags]
|
76
|
+
end
|
77
|
+
|
78
|
+
def reflections_to_ignore
|
79
|
+
%w[taggings]
|
80
|
+
end
|
81
|
+
|
82
|
+
def attachments
|
83
|
+
@attachments ||= reflections.select do |_, reflection|
|
84
|
+
reflection.options[:class_name] == "ActiveStorage::Attachment"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def tags
|
89
|
+
@tags ||= reflections.select { |_, reflection| reflection.options[:as] == :taggable }
|
90
|
+
end
|
91
|
+
|
92
|
+
def associations
|
93
|
+
@associations ||= reflections.reject { |key| attachments.key?(key) || tags.key?(key) }
|
94
|
+
end
|
95
|
+
|
96
|
+
def fields
|
97
|
+
@fields ||= {}
|
98
|
+
end
|
99
|
+
|
100
|
+
def invoked_by_model_generator?
|
101
|
+
@options.dig("from_model_generator")
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_fields
|
105
|
+
return generate_fields_from_args if invoked_by_model_generator?
|
106
|
+
|
107
|
+
if model.blank?
|
108
|
+
puts "Can't generate fields from model. '#{model_class}.rb' not found!"
|
109
|
+
return
|
110
|
+
end
|
111
|
+
|
112
|
+
fields_from_model_db_columns
|
113
|
+
fields_from_model_enums
|
114
|
+
fields_from_model_attachements
|
115
|
+
fields_from_model_associations
|
116
|
+
fields_from_model_tags
|
117
|
+
|
118
|
+
generated_fields_template
|
119
|
+
end
|
120
|
+
|
121
|
+
def generated_fields_template
|
122
|
+
return if fields.blank?
|
123
|
+
|
124
|
+
fields_string = "\n # Fields generated from the model"
|
125
|
+
|
126
|
+
fields.each do |field_name, field_options|
|
127
|
+
options = ""
|
128
|
+
field_options[:options].each { |k, v| options += ", #{k}: #{v}" } if field_options[:options].present?
|
129
|
+
|
130
|
+
fields_string += "\n #{field_string field_name, field_options[:field], options}"
|
131
|
+
end
|
132
|
+
|
133
|
+
fields_string
|
134
|
+
end
|
135
|
+
|
136
|
+
def field_string(name, type, options)
|
137
|
+
"field :#{name}, as: :#{type}#{options}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def generate_fields_from_args
|
141
|
+
@args.each do |arg|
|
142
|
+
name, type = arg.split(":")
|
143
|
+
type = "string" if type.blank?
|
144
|
+
fields[name] = field(name, type.to_sym)
|
145
|
+
end
|
146
|
+
|
147
|
+
generated_fields_template
|
148
|
+
end
|
149
|
+
|
150
|
+
def fields_from_model_tags
|
151
|
+
tags.each do |name, _|
|
152
|
+
fields[(remove_last_word_from name).pluralize] = {field: "tags"}
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def fields_from_model_associations
|
157
|
+
associations.each do |name, association|
|
158
|
+
fields[name] = associations_mapping[association.class]
|
159
|
+
|
160
|
+
if association.is_a? ActiveRecord::Reflection::ThroughReflection
|
161
|
+
fields[name][:options][:through] = ":#{association.options[:through]}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def fields_from_model_attachements
|
167
|
+
attachments.each do |name, attachment|
|
168
|
+
fields[remove_last_word_from name] = attachments_mapping[attachment.class]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# "hello_world_hehe".split('_') => ['hello', 'world', 'hehe']
|
173
|
+
# ['hello', 'world', 'hehe'].pop => ['hello', 'world']
|
174
|
+
# ['hello', 'world'].join('_') => "hello_world"
|
175
|
+
def remove_last_word_from(snake_case_string)
|
176
|
+
snake_case_string = snake_case_string.split("_")
|
177
|
+
snake_case_string.pop
|
178
|
+
snake_case_string.join("_")
|
179
|
+
end
|
180
|
+
|
181
|
+
def fields_from_model_enums
|
182
|
+
model.defined_enums.each_key do |enum|
|
183
|
+
fields[enum] = {
|
184
|
+
field: "select",
|
185
|
+
options: {
|
186
|
+
enum: "::#{model_class.capitalize}.#{enum.pluralize}"
|
187
|
+
}
|
188
|
+
}
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def fields_from_model_db_columns
|
193
|
+
model_db_columns.each do |name, data|
|
194
|
+
fields[name] = field(name, data.type)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def field(name, type)
|
199
|
+
names_mapping[name.to_sym] || fields_mapping[type.to_sym] || {field: "text"}
|
200
|
+
end
|
201
|
+
|
202
|
+
def associations_mapping
|
203
|
+
{
|
204
|
+
ActiveRecord::Reflection::BelongsToReflection => {
|
205
|
+
field: "belongs_to"
|
206
|
+
},
|
207
|
+
ActiveRecord::Reflection::HasOneReflection => {
|
208
|
+
field: "has_one"
|
209
|
+
},
|
210
|
+
ActiveRecord::Reflection::HasManyReflection => {
|
211
|
+
field: "has_many"
|
212
|
+
},
|
213
|
+
ActiveRecord::Reflection::ThroughReflection => {
|
214
|
+
field: "has_many",
|
215
|
+
options: {
|
216
|
+
through: ":..."
|
217
|
+
}
|
218
|
+
},
|
219
|
+
ActiveRecord::Reflection::HasAndBelongsToManyReflection => {
|
220
|
+
field: "has_and_belongs_to_many"
|
221
|
+
}
|
222
|
+
}
|
223
|
+
end
|
224
|
+
|
225
|
+
def attachments_mapping
|
226
|
+
{
|
227
|
+
ActiveRecord::Reflection::HasOneReflection => {
|
228
|
+
field: "file"
|
229
|
+
},
|
230
|
+
ActiveRecord::Reflection::HasManyReflection => {
|
231
|
+
field: "files"
|
232
|
+
}
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
def names_mapping
|
237
|
+
{
|
238
|
+
id: {
|
239
|
+
field: "id"
|
240
|
+
},
|
241
|
+
description: {
|
242
|
+
field: "textarea"
|
243
|
+
},
|
244
|
+
gravatar: {
|
245
|
+
field: "gravatar"
|
246
|
+
},
|
247
|
+
email: {
|
248
|
+
field: "text"
|
249
|
+
},
|
250
|
+
password: {
|
251
|
+
field: "password"
|
252
|
+
},
|
253
|
+
password_confirmation: {
|
254
|
+
field: "password"
|
255
|
+
},
|
256
|
+
stage: {
|
257
|
+
field: "select"
|
258
|
+
},
|
259
|
+
budget: {
|
260
|
+
field: "currency"
|
261
|
+
},
|
262
|
+
money: {
|
263
|
+
field: "currency"
|
264
|
+
},
|
265
|
+
country: {
|
266
|
+
field: "country"
|
267
|
+
}
|
268
|
+
}
|
269
|
+
end
|
270
|
+
|
271
|
+
def fields_mapping
|
272
|
+
{
|
273
|
+
primary_key: {
|
274
|
+
field: "id"
|
275
|
+
},
|
276
|
+
string: {
|
277
|
+
field: "text"
|
278
|
+
},
|
279
|
+
text: {
|
280
|
+
field: "textarea"
|
281
|
+
},
|
282
|
+
integer: {
|
283
|
+
field: "number"
|
284
|
+
},
|
285
|
+
float: {
|
286
|
+
field: "number"
|
287
|
+
},
|
288
|
+
decimal: {
|
289
|
+
field: "number"
|
290
|
+
},
|
291
|
+
datetime: {
|
292
|
+
field: "datetime"
|
293
|
+
},
|
294
|
+
timestamp: {
|
295
|
+
field: "datetime"
|
296
|
+
},
|
297
|
+
time: {
|
298
|
+
field: "datetime"
|
299
|
+
},
|
300
|
+
date: {
|
301
|
+
field: "date"
|
302
|
+
},
|
303
|
+
binary: {
|
304
|
+
field: "number"
|
305
|
+
},
|
306
|
+
boolean: {
|
307
|
+
field: "boolean"
|
308
|
+
},
|
309
|
+
references: {
|
310
|
+
field: "belongs_to"
|
311
|
+
},
|
312
|
+
json: {
|
313
|
+
field: "code"
|
314
|
+
}
|
315
|
+
}
|
316
|
+
end
|
36
317
|
end
|
37
318
|
end
|
38
319
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
class <%= class_name.camelize %> < Avo::Filters::TextFilter
|
2
2
|
self.name = "<%= name.underscore.humanize %>"
|
3
3
|
self.button_label = 'Filter by <%= class_name.underscore.humanize.downcase.gsub(' filter', '') %>'
|
4
|
+
# self.visible = -> do
|
5
|
+
# true
|
6
|
+
# end
|
4
7
|
|
5
8
|
def apply(request, query, value)
|
6
9
|
query
|
@@ -44,6 +44,10 @@ Avo.configure do |config|
|
|
44
44
|
# config.via_per_page = 8
|
45
45
|
# config.id_links_to_resource = false
|
46
46
|
# config.cache_resources_on_index_view = true
|
47
|
+
## permanent enable or disable cache_resource_filters, default value is false
|
48
|
+
# config.cache_resource_filters = false
|
49
|
+
## provide a lambda to enable or disable cache_resource_filters per user/resource.
|
50
|
+
# config.cache_resource_filters = ->(current_user:, resource:) { current_user.cache_resource_filters?}
|
47
51
|
|
48
52
|
## == Customization ==
|
49
53
|
# config.app_name = 'Avocadelicious'
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class <%= resource_class %> < Avo::BaseResource
|
2
2
|
self.title = :id
|
3
|
-
self.includes = []
|
3
|
+
self.includes = []<%= model_class_from_args %>
|
4
4
|
# self.search_query = -> do
|
5
5
|
# scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
|
6
6
|
# end
|
7
7
|
|
8
|
-
field :id, as: :id
|
8
|
+
field :id, as: :id<%= generate_fields %>
|
9
9
|
# add fields here
|
10
10
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/rails/model/model_generator'
|
3
|
+
|
4
|
+
module Rails
|
5
|
+
module Generators
|
6
|
+
class ModelGenerator
|
7
|
+
hook_for :avo_resource, type: :boolean, default: true unless ARGV.include?("--skip-avo-resource")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rails/generators/active_record/model/model_generator'
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
module Generators
|
5
|
+
class AvoResourceGenerator < ::Rails::Generators::Base
|
6
|
+
def invoke_avo_command
|
7
|
+
invoke "avo:resource", @args, {from_model_generator: true}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -7783,16 +7783,6 @@ trix-toolbar .trix-button-group:not(:first-child){
|
|
7783
7783
|
line-height:1.5rem
|
7784
7784
|
}
|
7785
7785
|
|
7786
|
-
.text-3xl{
|
7787
|
-
font-size:1.875rem;
|
7788
|
-
line-height:2.25rem
|
7789
|
-
}
|
7790
|
-
|
7791
|
-
.text-5xl{
|
7792
|
-
font-size:3rem;
|
7793
|
-
line-height:1
|
7794
|
-
}
|
7795
|
-
|
7796
7786
|
.text-xl{
|
7797
7787
|
font-size:1.25rem;
|
7798
7788
|
line-height:1.75rem
|
@@ -7803,6 +7793,16 @@ trix-toolbar .trix-button-group:not(:first-child){
|
|
7803
7793
|
line-height:1rem
|
7804
7794
|
}
|
7805
7795
|
|
7796
|
+
.text-3xl{
|
7797
|
+
font-size:1.875rem;
|
7798
|
+
line-height:2.25rem
|
7799
|
+
}
|
7800
|
+
|
7801
|
+
.text-5xl{
|
7802
|
+
font-size:3rem;
|
7803
|
+
line-height:1
|
7804
|
+
}
|
7805
|
+
|
7806
7806
|
.text-2xl{
|
7807
7807
|
font-size:1.5rem;
|
7808
7808
|
line-height:2rem
|