avo 2.12.1.pre.1 → 2.13.2.pre.1
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 -1
- data/README.md +2 -1
- data/app/assets/stylesheets/avo.css +1 -1
- data/app/assets/stylesheets/css/fields/progress.css +3 -3
- data/app/assets/stylesheets/css/pagination.css +0 -4
- data/app/assets/stylesheets/css/search.css +1 -1
- data/app/assets/stylesheets/css/sidebar.css +1 -1
- data/app/assets/stylesheets/css/tags.css +7 -0
- data/app/assets/svgs/failed_to_load.svg +4 -5
- data/app/assets/svgs/grid-empty-state.svg +10 -11
- data/app/assets/svgs/table-empty-state.svg +11 -12
- data/app/components/avo/actions_component.html.erb +5 -5
- data/app/components/avo/actions_component.rb +12 -3
- data/app/components/avo/button_component.rb +3 -5
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -1
- 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/progress_bar_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/progress_bar_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/edit_component.html.erb +1 -1
- 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/profile_item_component.html.erb +1 -1
- data/app/components/avo/resource_component.rb +6 -4
- data/app/components/avo/sidebar_component.html.erb +1 -1
- data/app/components/avo/views/resource_edit_component.html.erb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +1 -1
- data/app/components/avo/views/resource_index_component.rb +1 -1
- data/app/components/avo/views/resource_show_component.html.erb +138 -48
- data/app/components/avo/views/resource_show_component.rb +1 -0
- data/app/helpers/avo/resources_helper.rb +2 -2
- data/app/javascript/avo.js +0 -1
- data/app/javascript/js/controllers/fields/trix_field_controller.js +4 -3
- data/app/javascript/js/controllers/item_selector_controller.js +1 -1
- data/app/views/avo/associations/new.html.erb +2 -2
- data/app/views/avo/base/_multiple_select_filter.html.erb +1 -1
- data/app/views/avo/base/_text_filter.html.erb +1 -1
- 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/_branding.html.erb +5 -0
- data/app/views/avo/partials/_header.html.erb +1 -1
- data/app/views/avo/partials/_logo.html.erb +2 -2
- data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
- data/app/views/avo/private/design.html.erb +5 -5
- data/app/views/layouts/avo/application.html.erb +2 -1
- data/lib/avo/base_resource.rb +5 -1
- data/lib/avo/concerns/has_editable_controls.rb +34 -0
- data/lib/avo/configuration/branding.rb +57 -0
- data/lib/avo/configuration.rb +5 -0
- 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/key_value_field.rb +6 -6
- data/lib/avo/licensing/h_q.rb +12 -4
- data/lib/avo/licensing/pro_license.rb +2 -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 +14 -0
- 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 +760 -202
- data/public/avo-assets/avo.js +2 -2
- data/public/avo-assets/avo.js.map +2 -2
- metadata +15 -11
- data/app/components/avo/button_component.html.erb +0 -1
- data/app/helpers/avo/actions_helper.rb +0 -4
- data/app/helpers/avo/attachments_helper.rb +0 -4
- data/app/views/kaminari/_first_page.html.erb +0 -3
- data/app/views/kaminari/_last_page.html.erb +0 -3
- data/app/views/kaminari/_next_page.html.erb +0 -9
- data/app/views/kaminari/_page.html.erb +0 -12
- data/app/views/kaminari/_prev_page.html.erb +0 -9
- data/lib/avo/concerns/has_model.rb +0 -11
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
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "dry-initializer"
|
2
|
+
|
3
|
+
# This object holds some data tha is usually needed to compute blocks around the app.
|
4
|
+
module Avo
|
5
|
+
module Resources
|
6
|
+
module Controls
|
7
|
+
class ExecutionContext
|
8
|
+
extend Dry::Initializer
|
9
|
+
|
10
|
+
option :context, default: proc { Avo::App.context }
|
11
|
+
option :params, default: proc { Avo::App.params }
|
12
|
+
option :view_context, default: proc { Avo::App.view_context }
|
13
|
+
option :current_user, default: proc { Avo::App.current_user }
|
14
|
+
option :items_holder, default: proc { Avo::Resources::Controls::ItemsHolder.new }
|
15
|
+
option :resource, optional: true
|
16
|
+
option :record, optional: true
|
17
|
+
option :view, optional: true
|
18
|
+
option :block, optional: true
|
19
|
+
|
20
|
+
delegate :authorize, to: Avo::Services::AuthorizationService
|
21
|
+
|
22
|
+
def handle
|
23
|
+
instance_exec(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def back_button(**args)
|
29
|
+
items_holder.add_item Avo::Resources::Controls::BackButton.new(**args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete_button(**args)
|
33
|
+
items_holder.add_item Avo::Resources::Controls::DeleteButton.new(**args)
|
34
|
+
end
|
35
|
+
|
36
|
+
def detach_button(**args)
|
37
|
+
items_holder.add_item Avo::Resources::Controls::DetachButton.new(**args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def edit_button(**args)
|
41
|
+
items_holder.add_item Avo::Resources::Controls::EditButton.new(**args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def link_to(label, path, **args)
|
45
|
+
items_holder.add_item Avo::Resources::Controls::LinkTo.new(label: label, path: path, **args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def actions_list(**args)
|
49
|
+
items_holder.add_item Avo::Resources::Controls::ActionsList.new(**args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def action(klass, **args)
|
53
|
+
items_holder.add_item Avo::Resources::Controls::Action.new(klass, record: record, resource: resource, view: view, **args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Avo
|
2
|
+
module Resources
|
3
|
+
module Controls
|
4
|
+
class LinkTo < BaseControl
|
5
|
+
def initialize(**args)
|
6
|
+
super(**args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def path
|
10
|
+
@args[:path]
|
11
|
+
end
|
12
|
+
|
13
|
+
def target
|
14
|
+
@args[:target] || nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def data
|
18
|
+
@args[:data] || {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def class
|
22
|
+
@args[:class] || nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/avo/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class <%= class_name.camelize %> < Avo::BaseAction
|
2
|
-
self.name =
|
2
|
+
self.name = "<%= name.underscore.humanize %>"
|
3
3
|
|
4
4
|
def handle(**args)
|
5
5
|
models, fields, current_user, resource = args.values_at(:models, :fields, :current_user, :resource)
|
@@ -51,6 +51,20 @@ Avo.configure do |config|
|
|
51
51
|
# config.view_component_path = "app/components"
|
52
52
|
# config.display_license_request_timeout_error = true
|
53
53
|
# config.disabled_features = []
|
54
|
+
# config.resource_controls = :right
|
55
|
+
# config.buttons_on_form_footers = true
|
56
|
+
|
57
|
+
## == Branding ==
|
58
|
+
# config.branding = {
|
59
|
+
# colors: {
|
60
|
+
# 100 => "#CEE7F8",
|
61
|
+
# 400 => "#399EE5",
|
62
|
+
# 500 => "#0886DE",
|
63
|
+
# 600 => "#066BB2",
|
64
|
+
# },
|
65
|
+
# logo: "/avo-assets/logo.png"
|
66
|
+
# logomark: "/avo-assets/logomark.png",
|
67
|
+
# }
|
54
68
|
|
55
69
|
|
56
70
|
## == Breadcrumbs ==
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="flex flex-col">
|
2
2
|
<%%= render Avo::PanelComponent.new(name: "<%= human_name %>") do |c| %>
|
3
3
|
<%% c.tools do %>
|
4
|
-
<%%= a_link('/avo', icon: 'heroicons/solid/academic-cap', style: :primary) do %>
|
4
|
+
<%%= a_link('/avo', icon: 'heroicons/solid/academic-cap', color: :primary, style: :primary) do %>
|
5
5
|
Dummy link
|
6
6
|
<%% end %>
|
7
7
|
<%% end %>
|