avo 2.9.1.pre7 → 2.10.2
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 +8 -10
- data/README.md +4 -0
- data/app/assets/stylesheets/css/buttons.css +4 -1
- data/app/components/avo/base_component.rb +2 -0
- data/app/components/avo/button_component.rb +3 -1
- data/app/components/avo/fields/edit_component.rb +5 -0
- data/app/components/avo/fields/show_component.rb +1 -1
- data/app/components/avo/index/ordering/button_component.rb +3 -5
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +19 -0
- data/app/components/avo/item_switcher_component.rb +45 -0
- data/app/components/avo/panel_component.html.erb +23 -24
- data/app/components/avo/panel_component.rb +8 -5
- data/app/components/avo/tab_group_component.html.erb +53 -0
- data/app/components/avo/tab_group_component.rb +51 -0
- data/app/components/avo/tab_switcher_component.html.erb +21 -0
- data/app/components/avo/tab_switcher_component.rb +86 -0
- data/app/components/avo/views/resource_edit_component.html.erb +34 -56
- data/app/components/avo/views/resource_edit_component.rb +10 -0
- 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 +58 -89
- data/app/components/avo/views/resource_show_component.rb +2 -2
- data/app/controllers/avo/actions_controller.rb +1 -1
- data/app/controllers/avo/application_controller.rb +11 -15
- data/app/helpers/avo/application_helper.rb +0 -6
- data/app/helpers/avo/url_helpers.rb +1 -1
- data/app/javascript/js/controllers/loading_button_controller.js +25 -21
- data/app/javascript/js/controllers/tabs_controller.js +9 -3
- data/app/javascript/js/controllers.js +2 -0
- data/app/views/avo/base/index.html.erb +1 -1
- data/app/views/avo/base/show.html.erb +1 -1
- data/app/views/avo/cards/show.html.erb +1 -1
- data/app/views/avo/debug/index.html.erb +1 -1
- data/app/views/avo/home/_actions.html.erb +1 -1
- data/app/views/avo/home/_dashboards.html.erb +19 -0
- data/app/views/avo/home/_filters.html.erb +1 -1
- data/app/views/avo/home/_resources.html.erb +1 -1
- data/app/views/avo/home/failed_to_load.html.erb +1 -1
- data/app/views/avo/home/index.html.erb +14 -2
- data/app/views/avo/partials/_tabs_toggle.html.erb +20 -0
- data/app/views/avo/private/design.html.erb +1 -1
- data/lib/avo/base_action.rb +2 -19
- data/lib/avo/base_resource.rb +0 -94
- data/lib/avo/base_resource_tool.rb +3 -1
- data/lib/avo/concerns/has_fields.rb +247 -50
- data/lib/avo/concerns/has_html_attributes.rb +1 -1
- data/lib/avo/concerns/is_resource_item.rb +36 -0
- data/lib/avo/dsl/field_parser.rb +83 -0
- data/lib/avo/fields/base_field.rb +19 -2
- data/lib/avo/fields/field_extensions/visible_in_different_views.rb +18 -1
- data/lib/avo/fields/has_base_field.rb +18 -1
- data/lib/avo/fields/key_value_field.rb +4 -4
- data/lib/avo/grid_collector.rb +6 -3
- data/lib/avo/items_holder.rb +68 -0
- data/lib/avo/licensing/h_q.rb +10 -0
- data/lib/avo/main_panel.rb +3 -0
- data/lib/avo/menu/builder.rb +6 -6
- data/lib/avo/panel.rb +25 -0
- data/lib/avo/panel_builder.rb +23 -0
- data/lib/avo/tab.rb +78 -0
- data/lib/avo/tab_builder.rb +25 -0
- data/lib/avo/tab_group.rb +40 -0
- data/lib/avo/tab_group_builder.rb +43 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/resource/controller.tt +2 -0
- data/lib/generators/avo/templates/resource_tools/partial.tt +1 -1
- data/lib/generators/avo/templates/tool/view.tt +1 -1
- data/public/avo-assets/avo.css +27 -3
- data/public/avo-assets/avo.js +73 -73
- data/public/avo-assets/avo.js.map +3 -3
- metadata +22 -5
- data/lib/avo/concerns/has_tools.rb +0 -47
@@ -1,77 +1,55 @@
|
|
1
1
|
<%= content_tag :div,
|
2
|
-
class: "space-y-12",
|
3
2
|
data: {
|
4
3
|
'model-id': @resource.model.id,
|
5
4
|
selected_resources_name: @resource.model_key,
|
6
5
|
selected_resources: [@resource.model.id],
|
7
6
|
**@resource.stimulus_data_attributes
|
8
7
|
} do %>
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
8
|
+
<%= form_with model: @resource.model,
|
9
|
+
scope: @resource.form_scope,
|
10
|
+
url: form_url,
|
11
|
+
method: form_method,
|
12
|
+
local: true,
|
13
|
+
html: {
|
14
|
+
novalidate: true
|
15
|
+
},
|
16
|
+
multipart: true do |form| %>
|
17
|
+
<%= render Avo::ReferrerParamsComponent.new back_path: back_path %>
|
18
|
+
<%= render Avo::PanelComponent.new(title: title, description: @resource.resource_description, display_breadcrumbs: @reflection.blank?, index: 0, data: { panel_id: "main" }) do |c| %>
|
19
|
+
<% c.tools do %>
|
20
|
+
<%= a_link back_path,
|
21
|
+
style: :text,
|
22
|
+
icon: 'arrow-left' do %>
|
23
|
+
<%= t('avo.cancel').capitalize %>
|
24
|
+
<% end %>
|
25
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
26
|
+
<% if can_see_the_save_button? %>
|
27
|
+
<%= a_button color: :primary,
|
26
28
|
style: :primary,
|
27
29
|
loading: true,
|
28
30
|
type: :submit,
|
29
31
|
icon: 'save' do %>
|
30
|
-
|
31
|
-
<% end %>
|
32
|
+
<%= t('avo.save').capitalize %>
|
32
33
|
<% end %>
|
33
34
|
<% end %>
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
<% if can_see_the_save_button? %>
|
40
|
-
<%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
|
41
|
-
<%= t('avo.save').capitalize %>
|
42
|
-
<% end %>
|
43
|
-
<% end %>
|
35
|
+
<% end %>
|
36
|
+
<% if Avo.configuration.buttons_on_form_footers %>
|
37
|
+
<% c.footer_tools do %>
|
38
|
+
<%= a_link back_path, icon: 'arrow-left' do %>
|
39
|
+
<%= t('avo.cancel').capitalize %>
|
44
40
|
<% end %>
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
<% @resource.get_fields.each_with_index do |field, index| %>
|
49
|
-
<%= render field.component_for_view(:edit).new(field: field, resource: @resource, index: index, form: form) unless field.computed %>
|
41
|
+
<% if can_see_the_save_button? %>
|
42
|
+
<%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
|
43
|
+
<%= t('avo.save').capitalize %>
|
50
44
|
<% end %>
|
51
|
-
|
45
|
+
<% end %>
|
52
46
|
<% end %>
|
53
47
|
<% end %>
|
54
48
|
<% end %>
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
60
|
-
<% end %>
|
61
|
-
<% end %>
|
62
|
-
<% if has_many_panels.present? %>
|
63
|
-
<% has_many_panels.each_with_index do |field, index| %>
|
64
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
65
|
-
<% end %>
|
66
|
-
<% end %>
|
67
|
-
<% if has_as_belongs_to_many_panels.present? %>
|
68
|
-
<% has_as_belongs_to_many_panels.each_with_index do |field, index| %>
|
69
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
70
|
-
<% end %>
|
71
|
-
<% end %>
|
72
|
-
<% if resource_tools.present? %>
|
73
|
-
<% resource_tools.each do |tool, index| %>
|
74
|
-
<%= render tool.partial, tool: tool %>
|
49
|
+
<%= content_tag :div, class: 'space-y-12' do %>
|
50
|
+
<% @resource.get_items.each_with_index do |item, index| %>
|
51
|
+
<% next if item.nil? %>
|
52
|
+
<%= render Avo::ItemSwitcherComponent.new resource: @resource, item: item, index: index + 1, view: @view, form: form %>
|
75
53
|
<% end %>
|
76
54
|
<% end %>
|
77
55
|
<% end %>
|
@@ -15,6 +15,10 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
15
15
|
split_panel_fields
|
16
16
|
end
|
17
17
|
|
18
|
+
def title
|
19
|
+
@resource.default_panel_name
|
20
|
+
end
|
21
|
+
|
18
22
|
def back_path
|
19
23
|
if via_resource?
|
20
24
|
helpers.resource_path(model: params[:via_resource_class].safe_constantize, resource: relation_resource, resource_id: params[:via_resource_id])
|
@@ -45,6 +49,12 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
45
49
|
view == :edit
|
46
50
|
end
|
47
51
|
|
52
|
+
def form_method
|
53
|
+
return :put if is_edit?
|
54
|
+
|
55
|
+
:post
|
56
|
+
end
|
57
|
+
|
48
58
|
def form_url
|
49
59
|
if is_edit?
|
50
60
|
helpers.resource_path(
|
@@ -37,7 +37,7 @@
|
|
37
37
|
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.model_name.collection} %>
|
38
38
|
</div>
|
39
39
|
<% else %>
|
40
|
-
<%# Offset for the space-y-2 property when the
|
40
|
+
<%# Offset for the space-y-2 property when the search is missing %>
|
41
41
|
<div class="-mb-2"></div>
|
42
42
|
<% end %>
|
43
43
|
<% if @filters.present? || available_view_types.count > 1 %>
|
@@ -113,7 +113,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
helpers.new_resource_path(
|
116
|
+
helpers.new_resource_path(resource: @resource, **args)
|
117
117
|
end
|
118
118
|
|
119
119
|
def attach_path
|
@@ -1,105 +1,74 @@
|
|
1
1
|
<%= content_tag :div,
|
2
|
-
class: "space-y-12",
|
3
2
|
data: {
|
4
3
|
'model-id': @resource.model.id,
|
5
4
|
selected_resources_name: @resource.model_key,
|
6
5
|
selected_resources: [@resource.model.id],
|
7
6
|
**@resource.stimulus_data_attributes
|
8
7
|
} do %>
|
9
|
-
|
10
|
-
|
11
|
-
<%
|
12
|
-
<% if
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
} do %>
|
23
|
-
<%= t('avo.detach_item', item: title).capitalize %>
|
24
|
-
<% end %>
|
25
|
-
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
26
|
-
<% end %>
|
27
|
-
<% if can_see_the_edit_button? %>
|
28
|
-
<%= a_link edit_path,
|
29
|
-
color: :primary,
|
30
|
-
style: :primary,
|
31
|
-
icon: 'edit' do %>
|
32
|
-
<%= t('avo.edit').capitalize %>
|
33
|
-
<% end %>
|
34
|
-
<% end %>
|
35
|
-
<% else %>
|
36
|
-
<%= a_link back_path,
|
37
|
-
style: :text,
|
38
|
-
icon: 'arrow-left' do %>
|
39
|
-
<%= t('avo.go_back') %>
|
40
|
-
<% end %>
|
41
|
-
<% if can_see_the_destroy_button? %>
|
42
|
-
<%= a_button url: helpers.resource_path(model: @resource.model, resource: @resource),
|
43
|
-
method: :delete,
|
44
|
-
local: true,
|
45
|
-
style: :text,
|
46
|
-
title: t('avo.delete_item', item: @resource.model.model_name.name.downcase).capitalize,
|
47
|
-
loading: true,
|
48
|
-
confirm: t('avo.are_you_sure', item: @resource.model.model_name.name.downcase),
|
49
|
-
color: :red,
|
50
|
-
icon: 'trash',
|
51
|
-
form_class: 'flex flex-col sm:flex-row sm:inline-flex',
|
52
|
-
data: {
|
53
|
-
control: :destroy,
|
54
|
-
'resource-id': @resource.model.id,
|
55
|
-
'tippy': 'tooltip',
|
56
|
-
} do %>
|
57
|
-
<%= t('avo.delete').capitalize %>
|
58
|
-
<% end %>
|
59
|
-
<% end %>
|
60
|
-
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
61
|
-
<% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
|
62
|
-
<%= a_link edit_path,
|
63
|
-
color: :primary,
|
64
|
-
style: :primary,
|
65
|
-
icon: 'edit' do %>
|
66
|
-
<%= t('avo.edit').capitalize %>
|
67
|
-
<% end %>
|
68
|
-
<% end %>
|
8
|
+
<%= render Avo::PanelComponent.new(title: title, description: @resource.resource_description, display_breadcrumbs: @reflection.blank?, index: 0, data: { panel_id: "main" }) do |c| %>
|
9
|
+
<% c.tools do %>
|
10
|
+
<% if @reflection.present? && @resource.model.present? %>
|
11
|
+
<% if can_detach? %>
|
12
|
+
<%= a_button url: detach_path,
|
13
|
+
icon: 'detach',
|
14
|
+
method: :delete,
|
15
|
+
form_class: 'flex flex-col sm:flex-row sm:inline-flex',
|
16
|
+
style: :text,
|
17
|
+
data: {
|
18
|
+
confirm: "Are you sure you want to detach this #{title}."
|
19
|
+
} do %>
|
20
|
+
<%= t('avo.detach_item', item: title).capitalize %>
|
69
21
|
<% end %>
|
22
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
70
23
|
<% end %>
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
24
|
+
<% if can_see_the_edit_button? %>
|
25
|
+
<%= a_link edit_path,
|
26
|
+
color: :primary,
|
27
|
+
style: :primary,
|
28
|
+
icon: 'edit' do %>
|
29
|
+
<%= t('avo.edit').capitalize %>
|
30
|
+
<% end %>
|
31
|
+
<% end %>
|
32
|
+
<% else %>
|
33
|
+
<%= a_link back_path,
|
34
|
+
style: :text,
|
35
|
+
icon: 'arrow-left' do %>
|
36
|
+
<%= t('avo.go_back') %>
|
37
|
+
<% end %>
|
38
|
+
<% if can_see_the_destroy_button? %>
|
39
|
+
<%= a_button url: helpers.resource_path(model: @resource.model, resource: @resource),
|
40
|
+
method: :delete,
|
41
|
+
local: true,
|
42
|
+
style: :text,
|
43
|
+
loading: true,
|
44
|
+
confirm: t('avo.are_you_sure', item: @resource.model.model_name.name.downcase),
|
45
|
+
color: :red,
|
46
|
+
icon: 'trash',
|
47
|
+
form_class: 'flex flex-col sm:flex-row sm:inline-flex',
|
48
|
+
data: {
|
49
|
+
control: :destroy,
|
50
|
+
'resource-id': @resource.model.id,
|
51
|
+
'tippy': 'tooltip',
|
52
|
+
} do %>
|
53
|
+
<%= t('avo.delete').capitalize %>
|
54
|
+
<% end %>
|
55
|
+
<% end %>
|
56
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
57
|
+
<% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
|
58
|
+
<%= a_link edit_path,
|
59
|
+
color: :primary,
|
60
|
+
style: :primary,
|
61
|
+
icon: 'edit' do %>
|
62
|
+
<%= t('avo.edit').capitalize %>
|
63
|
+
<% end %>
|
79
64
|
<% end %>
|
80
65
|
<% end %>
|
81
66
|
<% end %>
|
82
67
|
<% end %>
|
83
|
-
|
84
|
-
<%
|
85
|
-
<%
|
86
|
-
|
87
|
-
<% end %>
|
88
|
-
<% end %>
|
89
|
-
<% if has_many_panels.present? %>
|
90
|
-
<% has_many_panels.each_with_index do |field, index| %>
|
91
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
92
|
-
<% end %>
|
93
|
-
<% end %>
|
94
|
-
<% if has_as_belongs_to_many_panels.present? %>
|
95
|
-
<% has_as_belongs_to_many_panels.each_with_index do |field, index| %>
|
96
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
97
|
-
<% end %>
|
98
|
-
<% end %>
|
99
|
-
<% if resource_tools.present? %>
|
100
|
-
<% resource_tools.each do |tool, index| %>
|
101
|
-
<%= render tool.partial, tool: tool %>
|
102
|
-
<% end %>
|
68
|
+
<%= content_tag :div, class: 'space-y-12' do %>
|
69
|
+
<% @resource.get_items.each_with_index do |item, index| %>
|
70
|
+
<% next if item.nil? %>
|
71
|
+
<%= render Avo::ItemSwitcherComponent.new resource: @resource, reflection: @reflection, item: item, index: index + 1, view: @view %>
|
103
72
|
<% end %>
|
104
73
|
<% end %>
|
105
74
|
<% if should_display_invalid_fields_errors? %>
|
@@ -19,7 +19,7 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
19
19
|
return field.name if has_one_field?
|
20
20
|
reflection_resource.name
|
21
21
|
else
|
22
|
-
@resource.
|
22
|
+
@resource.default_panel_name
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -52,6 +52,6 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def has_one_field?
|
55
|
-
field.present? and field.
|
55
|
+
field.present? and field.instance_of? Avo::Fields::HasOneField
|
56
56
|
end
|
57
57
|
end
|
@@ -42,7 +42,7 @@ module Avo
|
|
42
42
|
model = @resource.class.find_scope.find params[:id]
|
43
43
|
end
|
44
44
|
|
45
|
-
@action = action_class.new(model: model, resource: resource, user: _current_user)
|
45
|
+
@action = action_class.new(model: model, resource: resource, user: _current_user, view: :edit)
|
46
46
|
end
|
47
47
|
|
48
48
|
def respond(response)
|
@@ -14,7 +14,7 @@ module Avo
|
|
14
14
|
before_action :init_app
|
15
15
|
before_action :check_avo_license
|
16
16
|
before_action :set_default_locale
|
17
|
-
around_action :set_force_locale
|
17
|
+
around_action :set_force_locale, if: -> { params[:force_locale].present? }
|
18
18
|
before_action :set_authorization
|
19
19
|
before_action :_authenticate!
|
20
20
|
before_action :set_container_classes
|
@@ -261,23 +261,23 @@ module Avo
|
|
261
261
|
end
|
262
262
|
|
263
263
|
def on_root_path
|
264
|
-
[Avo
|
264
|
+
[Avo.configuration.root_path, "#{Avo.configuration.root_path}/"].include?(request.original_fullpath)
|
265
265
|
end
|
266
266
|
|
267
267
|
def on_resources_path
|
268
|
-
request.original_url.match?(/.*#{Avo
|
268
|
+
request.original_url.match?(/.*#{Avo.configuration.root_path}\/resources\/.*/)
|
269
269
|
end
|
270
270
|
|
271
271
|
def on_api_path
|
272
|
-
request.original_url.match?(/.*#{Avo
|
272
|
+
request.original_url.match?(/.*#{Avo.configuration.root_path}\/avo_api\/.*/)
|
273
273
|
end
|
274
274
|
|
275
275
|
def on_dashboards_path
|
276
|
-
request.original_url.match?(/.*#{Avo
|
276
|
+
request.original_url.match?(/.*#{Avo.configuration.root_path}\/dashboards\/.*/)
|
277
277
|
end
|
278
278
|
|
279
279
|
def on_debug_path
|
280
|
-
request.original_url.match?(/.*#{Avo
|
280
|
+
request.original_url.match?(/.*#{Avo.configuration.root_path}\/avo_private\/debug.*/)
|
281
281
|
end
|
282
282
|
|
283
283
|
def on_custom_tool_page
|
@@ -294,16 +294,12 @@ module Avo
|
|
294
294
|
I18n.default_locale = I18n.locale
|
295
295
|
end
|
296
296
|
|
297
|
-
# Temporary set the locale
|
297
|
+
# Temporary set the locale and reverting at the end of the request.
|
298
298
|
def set_force_locale
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
I18n.locale = initial_locale
|
304
|
-
else
|
305
|
-
yield
|
306
|
-
end
|
299
|
+
initial_locale = I18n.locale.to_s.dup
|
300
|
+
I18n.locale = params[:force_locale]
|
301
|
+
yield
|
302
|
+
I18n.locale = initial_locale
|
307
303
|
end
|
308
304
|
|
309
305
|
def default_url_options
|
@@ -20,12 +20,6 @@ module Avo
|
|
20
20
|
render Avo::EmptyStateComponent.new **args
|
21
21
|
end
|
22
22
|
|
23
|
-
def turbo_frame_wrap(name, &block)
|
24
|
-
render Avo::TurboFrameWrapperComponent.new name do
|
25
|
-
capture(&block)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
23
|
def a_button(**args, &block)
|
30
24
|
render Avo::ButtonComponent.new(is_link: false, **args) do
|
31
25
|
capture(&block) if block_given?
|
@@ -35,7 +35,7 @@ module Avo
|
|
35
35
|
avo.send :"resources_#{resource.singular_route_key}_path", id, **args
|
36
36
|
end
|
37
37
|
|
38
|
-
def new_resource_path(
|
38
|
+
def new_resource_path(resource:, **args)
|
39
39
|
avo.send :"new_resources_#{resource.singular_route_key}_path", **args
|
40
40
|
end
|
41
41
|
|
@@ -7,33 +7,37 @@ export default class extends Controller {
|
|
7
7
|
<div class="double-bounce2"></div>
|
8
8
|
</div>`;
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
10
|
+
static values = {
|
11
|
+
confirmationMessage: String,
|
12
|
+
confirmed: Boolean,
|
13
|
+
}
|
14
|
+
|
15
|
+
attemptSubmit(e) {
|
16
|
+
// If the user has to confirm the action
|
17
|
+
if (this.confirmationMessageValue) {
|
18
|
+
this.confirmAndApply(e)
|
19
|
+
} else {
|
20
|
+
this.applyLoader()
|
21
|
+
}
|
22
|
+
|
23
|
+
return null
|
24
|
+
}
|
25
|
+
|
26
|
+
confirmAndApply(e) {
|
27
|
+
// Intervene only if not confirmed
|
28
|
+
if (!this.confirmedValue) {
|
29
|
+
e.preventDefault()
|
30
|
+
|
31
|
+
if (window.confirm(this.confirmationMessageValue)) {
|
24
32
|
this.applyLoader()
|
25
33
|
}
|
26
|
-
}
|
34
|
+
}
|
27
35
|
}
|
28
36
|
|
29
37
|
get button() {
|
30
38
|
return this.context.scope.element
|
31
39
|
}
|
32
40
|
|
33
|
-
get confirmationMessage() {
|
34
|
-
return this.context.scope.element.getAttribute('data-avo-confirm')
|
35
|
-
}
|
36
|
-
|
37
41
|
applyLoader() {
|
38
42
|
const { button } = this
|
39
43
|
|
@@ -50,10 +54,10 @@ export default class extends Controller {
|
|
50
54
|
}
|
51
55
|
|
52
56
|
markConfirmed() {
|
53
|
-
this.
|
57
|
+
this.confirmedValue = true
|
54
58
|
}
|
55
59
|
|
56
60
|
markUnconfirmed() {
|
57
|
-
this.
|
61
|
+
this.confirmedValue = false
|
58
62
|
}
|
59
63
|
}
|
@@ -6,6 +6,7 @@ export default class extends Controller {
|
|
6
6
|
static targets = ['tab'];
|
7
7
|
|
8
8
|
static values = {
|
9
|
+
view: String,
|
9
10
|
activeTab: String,
|
10
11
|
};
|
11
12
|
|
@@ -35,9 +36,15 @@ export default class extends Controller {
|
|
35
36
|
}
|
36
37
|
|
37
38
|
/**
|
38
|
-
|
39
|
-
|
39
|
+
* Sets the target container height to the previous panel height so we don't get jerky tab changes.
|
40
|
+
*/
|
40
41
|
setTheTargetPanelHeight(id) {
|
42
|
+
// Ignore this on edit.
|
43
|
+
// All tabs are loaded beforehand, they have their own height, and the page won't jiggle when the user toggles between them.
|
44
|
+
if (this.viewValue === 'edit' || this.viewValue === 'new') {
|
45
|
+
return
|
46
|
+
}
|
47
|
+
|
41
48
|
// We don't need to add a height to this panel because it was loaded before
|
42
49
|
if (castBoolean(this.targetTab(id).dataset.loaded)) {
|
43
50
|
return
|
@@ -71,7 +78,6 @@ export default class extends Controller {
|
|
71
78
|
element.classList.remove('hidden')
|
72
79
|
}
|
73
80
|
})
|
74
|
-
// this.tabTargets.map((element) => element.clasList.add('hidden'))
|
75
81
|
}
|
76
82
|
|
77
83
|
hideTabs() {
|
@@ -27,6 +27,7 @@ import SearchController from './controllers/search_controller'
|
|
27
27
|
import SelectController from './controllers/select_controller'
|
28
28
|
import SelectFilterController from './controllers/select_filter_controller'
|
29
29
|
import SimpleMdeController from './controllers/fields/simple_mde_controller'
|
30
|
+
import TabsController from './controllers/tabs_controller'
|
30
31
|
import TagsFieldController from './controllers/fields/tags_field_controller'
|
31
32
|
import TextFilterController from './controllers/text_filter_controller'
|
32
33
|
import TippyController from './controllers/tippy_controller'
|
@@ -55,6 +56,7 @@ application.register('resource-show', ResourceShowController)
|
|
55
56
|
application.register('search', SearchController)
|
56
57
|
application.register('select', SelectController)
|
57
58
|
application.register('select-filter', SelectFilterController)
|
59
|
+
application.register('tabs', TabsController)
|
58
60
|
application.register('tags-field', TagsFieldController)
|
59
61
|
application.register('text-filter', TextFilterController)
|
60
62
|
application.register('tippy', TippyController)
|
@@ -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(title: '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 %>
|
@@ -11,6 +11,6 @@
|
|
11
11
|
</div>
|
12
12
|
</div>
|
13
13
|
|
14
|
-
<a href="https://docs.avohq.io/
|
14
|
+
<a href="https://docs.avohq.io/2.0/actions.html" target="_blank" title="Avo Actions documentation" class="text-bold cursor-pointer block mt-2">Actions in the docs 👉</a>
|
15
15
|
</div>
|
16
16
|
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div>
|
2
|
+
<h3>Dashboards</h3>
|
3
|
+
|
4
|
+
<div>There comes the point in your app's life when you need to display the data in an aggregated form like a metric or chart. That's what Avo's Dashboards are all about.</div>
|
5
|
+
|
6
|
+
<div>Generate a dashboard using the command below 👇👇</div>
|
7
|
+
|
8
|
+
|
9
|
+
<div class="mt-2">
|
10
|
+
<div class="mt-1">
|
11
|
+
<code class="p-1 rounded bg-sky-500 text-white">bin/rails generate avo:dashboard dashy</code>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
<a href="https://docs.avohq.io/2.0/dashboards.html" target="_blank" title="Avo Dashboards documentation">Docs</a>
|
17
|
+
</p>
|
18
|
+
</div>
|
19
|
+
|
@@ -11,6 +11,6 @@
|
|
11
11
|
</div>
|
12
12
|
</div>
|
13
13
|
|
14
|
-
<a href="https://docs.avohq.io/
|
14
|
+
<a href="https://docs.avohq.io/2.0/filters.html" target="_blank" title="Avo Filters documentation" class="text-bold cursor-pointer block mt-2">Filters in the docs 👉</a>
|
15
15
|
</div>
|
16
16
|
</div>
|
@@ -35,7 +35,7 @@
|
|
35
35
|
<% end %>
|
36
36
|
|
37
37
|
<p>
|
38
|
-
<a href="https://docs.avohq.io/
|
38
|
+
<a href="https://docs.avohq.io/2.0/resources.html" target="_blank" title="Avo Resources documentation">Docs</a>
|
39
39
|
</p>
|
40
40
|
</div>
|
41
41
|
|