avo 2.1.2.pre2 → 2.2.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 +4 -2
- data/Gemfile.lock +11 -5
- data/app/assets/svgs/{dashboards-icon.svg → dashboards.svg} +1 -1
- data/app/assets/svgs/{resources-icon.svg → resources.svg} +0 -0
- data/app/assets/svgs/{tools-icon.svg → tools.svg} +0 -0
- data/app/components/avo/button_component.rb +6 -2
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +1 -0
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +5 -2
- data/app/components/avo/index/field_wrapper_component.rb +13 -0
- data/app/components/avo/index/grid_item_component.html.erb +3 -1
- data/app/components/avo/index/table_row_component.html.erb +7 -5
- data/app/components/avo/panel_component.html.erb +4 -4
- data/app/components/avo/profile_item_component.html.erb +2 -2
- data/app/components/avo/profile_item_component.rb +6 -0
- data/app/components/avo/sidebar/base_item_component.rb +31 -0
- data/app/components/avo/sidebar/group_component.html.erb +28 -0
- data/app/components/avo/sidebar/group_component.rb +4 -0
- data/app/components/avo/sidebar/heading_component.html.erb +14 -0
- data/app/components/avo/sidebar/heading_component.rb +15 -0
- data/app/components/avo/sidebar/item_switcher_component.html.erb +16 -0
- data/app/components/avo/sidebar/item_switcher_component.rb +15 -0
- data/app/components/avo/sidebar/link_component.html.erb +12 -0
- data/app/components/avo/sidebar/link_component.rb +28 -0
- data/app/components/avo/sidebar/section_component.html.erb +15 -0
- data/app/components/avo/sidebar/section_component.rb +9 -0
- data/app/components/avo/sidebar_component.html.erb +33 -24
- data/app/components/avo/sidebar_component.rb +3 -9
- data/app/components/avo/sidebar_profile_component.html.erb +10 -1
- data/app/components/avo/views/resource_edit_component.html.erb +2 -2
- data/app/components/avo/views/resource_new_component.html.erb +2 -2
- data/app/components/avo/views/resource_show_component.html.erb +2 -2
- data/app/controllers/avo/application_controller.rb +1 -2
- data/app/controllers/avo/base_controller.rb +1 -1
- data/app/helpers/avo/application_helper.rb +2 -0
- data/app/javascript/js/controllers/loading_button_controller.js +47 -10
- data/app/javascript/js/controllers/menu_controller.js +60 -0
- data/app/javascript/js/controllers/search_controller.js +28 -10
- data/app/javascript/js/controllers.js +2 -0
- data/app/views/avo/base/_boolean_filter.html.erb +1 -1
- data/app/views/avo/base/_multiple_select_filter.html.erb +7 -4
- data/app/views/avo/base/_select_filter.html.erb +1 -1
- data/app/views/avo/base/_text_filter.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +12 -13
- data/app/views/layouts/avo/application.html.erb +3 -0
- data/avo.gemspec +1 -0
- data/bin/helpers.rb +7 -1
- data/bin/init +2 -2
- data/lib/avo/app.rb +8 -86
- data/lib/avo/base_resource.rb +1 -3
- data/lib/avo/concerns/fetches_things.rb +127 -0
- data/lib/avo/configuration.rb +4 -0
- data/lib/avo/dynamic_router.rb +1 -1
- data/lib/avo/engine.rb +0 -1
- data/lib/avo/fields/base_field.rb +2 -0
- data/lib/avo/fields/belongs_to_field.rb +2 -0
- data/lib/avo/hosts/base_host.rb +20 -0
- data/lib/avo/licensing/pro_license.rb +2 -1
- data/lib/avo/menu/base_item.rb +20 -0
- data/lib/avo/menu/builder.rb +77 -0
- data/lib/avo/menu/dashboard.rb +17 -0
- data/lib/avo/menu/group.rb +2 -0
- data/lib/avo/menu/link.rb +4 -0
- data/lib/avo/menu/menu.rb +2 -0
- data/lib/avo/menu/resource.rb +9 -0
- data/lib/avo/menu/section.rb +2 -0
- data/lib/avo/reloader.rb +15 -7
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/filter_generator.rb +2 -0
- data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
- data/lib/generators/avo/templates/filters/multiple_select_filter.tt +11 -0
- data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
- data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
- data/lib/generators/avo/templates/tool/sidebar_item.tt +1 -1
- data/public/avo-assets/avo.css +23 -6
- data/public/avo-assets/avo.js +63 -63
- data/public/avo-assets/avo.js.map +3 -3
- metadata +44 -14
- data/app/assets/builds/avo.css +0 -8810
- data/app/assets/builds/avo.js +0 -423
- data/app/assets/builds/avo.js.map +0 -7
- data/app/components/avo/sidebar_heading_component.html.erb +0 -3
- data/app/components/avo/sidebar_heading_component.rb +0 -11
- data/app/components/avo/sidebar_item_component.html.erb +0 -3
- data/app/components/avo/sidebar_item_component.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35ab86df7a30aa58a644902eea79236c3b46f3f77eb86fc791e100dbdfc4c278
|
4
|
+
data.tar.gz: a1c038e4cfd7101b35361638152c60f1ec06d456364909860cb9296ffa1aa99a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9976990e8b22f579579f2e983e1990a058fe8f91e27e40972b8ee745a879d3200eb134a9583fb7c7c7f8991e6e44dd18ba5d832914025b8faa881336a5da2168
|
7
|
+
data.tar.gz: 7f16c6e613a17e130a7c2352ac343da1c29b95be680f697dc51f8f95ffbb779751b7fd73ece5f905d020ca2a275cce4c61c07ebdda97a95321efb87f08a0979e
|
data/Gemfile
CHANGED
@@ -34,7 +34,7 @@ gem "puma", "~> 5.6.4"
|
|
34
34
|
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
35
35
|
# gem "jbuilder", "~> 2.7"
|
36
36
|
# Use Redis adapter to run Action Cable in production
|
37
|
-
|
37
|
+
gem 'redis', '~> 4.0'
|
38
38
|
# Use Active Model has_secure_password
|
39
39
|
# gem 'bcrypt', '~> 3.1.7'
|
40
40
|
|
@@ -79,10 +79,12 @@ group :development do
|
|
79
79
|
# gem 'pry-rails'
|
80
80
|
|
81
81
|
gem 'htmlbeautifier'
|
82
|
+
|
83
|
+
gem "hotwire-livereload", "~> 1.1"
|
82
84
|
end
|
83
85
|
|
84
86
|
group :development, :test do
|
85
|
-
gem
|
87
|
+
gem "awesome_print"
|
86
88
|
gem "faker", require: false
|
87
89
|
end
|
88
90
|
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (2.
|
4
|
+
avo (2.2.2)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
8
8
|
chartkick
|
9
9
|
countries
|
10
|
+
docile
|
10
11
|
dry-initializer
|
11
12
|
hotwire-rails
|
12
13
|
httparty
|
@@ -89,13 +90,12 @@ GEM
|
|
89
90
|
activerecord (>= 4.2)
|
90
91
|
addressable (2.8.0)
|
91
92
|
public_suffix (>= 2.0.2, < 5.0)
|
92
|
-
ap (0.1.1)
|
93
|
-
httparty (>= 0.7.7)
|
94
93
|
appraisal (2.4.1)
|
95
94
|
bundler
|
96
95
|
rake
|
97
96
|
thor (>= 0.14.0)
|
98
97
|
ast (2.4.2)
|
98
|
+
awesome_print (1.9.2)
|
99
99
|
aws-eventstream (1.2.0)
|
100
100
|
aws-partitions (1.551.0)
|
101
101
|
aws-sdk-core (3.125.5)
|
@@ -183,6 +183,9 @@ GEM
|
|
183
183
|
hashdiff (1.0.1)
|
184
184
|
hightop (0.3.0)
|
185
185
|
activesupport (>= 5.2)
|
186
|
+
hotwire-livereload (1.1.0)
|
187
|
+
listen (>= 3.0.0)
|
188
|
+
rails (>= 6.0.0)
|
186
189
|
hotwire-rails (0.1.3)
|
187
190
|
rails (>= 6.0.0)
|
188
191
|
stimulus-rails
|
@@ -239,7 +242,7 @@ GEM
|
|
239
242
|
net-protocol
|
240
243
|
timeout
|
241
244
|
nio4r (2.5.8)
|
242
|
-
nokogiri (1.13.
|
245
|
+
nokogiri (1.13.4)
|
243
246
|
mini_portile2 (~> 2.8.0)
|
244
247
|
racc (~> 1.4)
|
245
248
|
orm_adapter (0.5.0)
|
@@ -297,6 +300,7 @@ GEM
|
|
297
300
|
rb-fsevent (0.11.0)
|
298
301
|
rb-inotify (0.10.1)
|
299
302
|
ffi (~> 1.0)
|
303
|
+
redis (4.6.0)
|
300
304
|
regexp_parser (2.2.0)
|
301
305
|
responders (3.0.1)
|
302
306
|
actionpack (>= 5.0)
|
@@ -414,9 +418,9 @@ DEPENDENCIES
|
|
414
418
|
active_median
|
415
419
|
acts_as_list
|
416
420
|
addressable
|
417
|
-
ap
|
418
421
|
appraisal
|
419
422
|
avo!
|
423
|
+
awesome_print
|
420
424
|
aws-sdk-s3
|
421
425
|
bootsnap (>= 1.4.2)
|
422
426
|
breadcrumbs_on_rails
|
@@ -435,6 +439,7 @@ DEPENDENCIES
|
|
435
439
|
gem-release
|
436
440
|
groupdate
|
437
441
|
hightop
|
442
|
+
hotwire-livereload (~> 1.1)
|
438
443
|
hotwire-rails
|
439
444
|
htmlbeautifier
|
440
445
|
httparty
|
@@ -452,6 +457,7 @@ DEPENDENCIES
|
|
452
457
|
rails (~> 6.1.0)
|
453
458
|
rails-controller-testing
|
454
459
|
ransack
|
460
|
+
redis (~> 4.0)
|
455
461
|
rspec-rails (~> 4.0.0)
|
456
462
|
rubocop
|
457
463
|
rubocop-shopify
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<svg
|
1
|
+
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
2
|
<path d="M8.4 2H2V8.4H8.4V2Z" stroke="#757D8A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
3
3
|
<path d="M18 2H11.6V8.4H18V2Z" stroke="#757D8A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
4
4
|
<path d="M8.4 11.6001H2V18.0001H8.4V11.6001Z" stroke="#757D8A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
File without changes
|
File without changes
|
@@ -24,8 +24,12 @@ class Avo::ButtonComponent < ViewComponent::Base
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def args
|
27
|
-
if @args[:
|
27
|
+
if @args[:loading]
|
28
28
|
@args[:"data-controller"] = "loading-button"
|
29
|
+
|
30
|
+
if @args[:confirm]
|
31
|
+
@args[:"data-avo-confirm"] = @args.delete(:confirm)
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
@args[:class] = button_classes
|
@@ -34,7 +38,7 @@ class Avo::ButtonComponent < ViewComponent::Base
|
|
34
38
|
end
|
35
39
|
|
36
40
|
def button_classes
|
37
|
-
classes = "button-component inline-flex flex-grow-0 items-center text-sm font-semibold leading-6 fill-current whitespace-nowrap transition duration-100 transform transition duration-100 cursor-pointer disabled:cursor-not-allowed disabled:opacity-
|
41
|
+
classes = "button-component inline-flex flex-grow-0 items-center text-sm font-semibold leading-6 fill-current whitespace-nowrap transition duration-100 transform transition duration-100 cursor-pointer disabled:cursor-not-allowed disabled:opacity-70 border justify-center active:outline active:outline-1 #{@class}"
|
38
42
|
|
39
43
|
classes += " rounded" if @rounded.present?
|
40
44
|
|
@@ -7,6 +7,7 @@
|
|
7
7
|
></div>
|
8
8
|
<div class="relative w-full" autocomplete="off">
|
9
9
|
<%= @form.text_field @foreign_key,
|
10
|
+
type: :text,
|
10
11
|
value: field_label,
|
11
12
|
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
12
13
|
placeholder: @field.placeholder,
|
@@ -9,8 +9,11 @@ class Avo::Fields::BelongsToField::EditComponent < Avo::Fields::EditComponent
|
|
9
9
|
|
10
10
|
def disabled
|
11
11
|
return true if @field.readonly
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
# When visiting the record through it's association we keep the field disabled by default
|
14
|
+
# We make an exception when the user deliberately instructs Avo to allow detaching in this scenario
|
15
|
+
return !@field.allow_via_detaching if @field.target_resource.present? && @field.target_resource.model_class.name == params[:via_resource_class]
|
16
|
+
return !@field.allow_via_detaching if @field.id.to_s == params[:via_relation].to_s
|
14
17
|
|
15
18
|
false
|
16
19
|
end
|
@@ -17,6 +17,19 @@ class Avo::Index::FieldWrapperComponent < ViewComponent::Base
|
|
17
17
|
result += " py-3"
|
18
18
|
end
|
19
19
|
|
20
|
+
result += " #{text_align_classes}"
|
21
|
+
|
20
22
|
result
|
21
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def text_align_classes
|
28
|
+
case @field.index_text_align.to_sym
|
29
|
+
when :right
|
30
|
+
'text-right'
|
31
|
+
when :center
|
32
|
+
'text-center'
|
33
|
+
end
|
34
|
+
end
|
22
35
|
end
|
@@ -3,7 +3,9 @@
|
|
3
3
|
<%== item_selector_init @resource %>
|
4
4
|
>
|
5
5
|
<div class="relative w-full pb-3/4 rounded-t overflow-hidden">
|
6
|
-
|
6
|
+
<% if @resource.record_selector %>
|
7
|
+
<%== item_selector_input floating: true, size: :lg %>
|
8
|
+
<% end %>
|
7
9
|
<% if cover.blank? %>
|
8
10
|
<%= link_to cover.link_to_resource do %>
|
9
11
|
<%= render Avo::Index::GridCoverEmptyStateComponent.new %>
|
@@ -2,11 +2,13 @@
|
|
2
2
|
class="bg-white hover:bg-blue-50 hover:shadow-row hover:z-[21] relative z-20 border-b"
|
3
3
|
<%== item_selector_init @resource %>
|
4
4
|
>
|
5
|
-
|
6
|
-
<
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
<% if @resource.record_selector %>
|
6
|
+
<td class="w-10">
|
7
|
+
<div class="flex justify-center h-full">
|
8
|
+
<%== item_selector_input floating: false %>
|
9
|
+
</div>
|
10
|
+
</td>
|
11
|
+
<% end %>
|
10
12
|
<% @resource.get_fields(reflection: @reflection).each_with_index do |field, index| %>
|
11
13
|
<%= render field.component_for_view(:index).new(field: field, resource: @resource, index: index, parent_model: @parent_model) %>
|
12
14
|
<% end %>
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<div <%== data_attributes %>>
|
2
2
|
<% if render_header? %>
|
3
3
|
<div class="<%= white_panel_classes %> p-4 flex-1 flex flex-col xl:flex-row justify-between mb-6">
|
4
|
-
<div class="overflow-hidden mr-4">
|
4
|
+
<div class="overflow-hidden mr-4 flex flex-col">
|
5
5
|
<% if display_breadcrumbs? %>
|
6
6
|
<div class="breadcrumbs truncate mb-2">
|
7
7
|
<%= helpers.render_breadcrumbs(separator: helpers.svg('chevron-right', class: 'inline-block h-3 stroke-current relative top-[-1px] ml-1' )) if Avo.configuration.display_breadcrumbs %>
|
8
8
|
</div>
|
9
9
|
<% end %>
|
10
10
|
|
11
|
-
<div class="text-2xl tracking-normal font-semibold text-gray-800 truncate" data-target="title">
|
12
|
-
|
11
|
+
<div class="text-2xl tracking-normal font-semibold text-gray-800 truncate items-center flex flex-1" data-target="title">
|
12
|
+
<span><%= @title %></span>
|
13
13
|
</div>
|
14
14
|
|
15
15
|
<% if description.present? %>
|
16
|
-
<div class="text-base tracking-normal font-medium text-gray-600
|
16
|
+
<div class="text-base tracking-normal font-medium text-gray-600" data-target="description">
|
17
17
|
<%== description %>
|
18
18
|
</div>
|
19
19
|
<% end %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= link_to
|
2
|
-
<%=
|
1
|
+
<%= link_to path, class: "flex-1 flex items-center justify-center bg-white text-left cursor-pointer text-gray-800 font-semibold hover:bg-blue-100 block px-4 py-1 w-full py-3 text-center rounded w-full", target: target do %>
|
2
|
+
<%= helpers.svg(icon, class: 'h-4 mr-1') if icon.present? %> <%= label %>
|
3
3
|
<% end %>
|
@@ -1,6 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::ProfileItemComponent < ViewComponent::Base
|
4
|
+
attr_reader :label
|
5
|
+
attr_reader :icon
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :active
|
8
|
+
attr_reader :target
|
9
|
+
|
4
10
|
def initialize(label: nil, icon: nil, path: nil, active: :inclusive, target: nil)
|
5
11
|
@label = label
|
6
12
|
@icon = icon
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Sidebar::BaseItemComponent < ViewComponent::Base
|
4
|
+
attr_reader :item
|
5
|
+
|
6
|
+
def initialize(item: nil)
|
7
|
+
@item = item
|
8
|
+
end
|
9
|
+
|
10
|
+
def items
|
11
|
+
item.items
|
12
|
+
end
|
13
|
+
|
14
|
+
def key
|
15
|
+
result = "avo.#{request.host}.main_menu.#{item.name.underscore}"
|
16
|
+
|
17
|
+
if item.icon.present?
|
18
|
+
result += ".#{item.icon.parameterize.underscore}"
|
19
|
+
end
|
20
|
+
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def collapsable
|
25
|
+
item.collapsable
|
26
|
+
end
|
27
|
+
|
28
|
+
def collapsed
|
29
|
+
item.collapsed
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div class="pb-2 space-y-1"
|
2
|
+
<% if collapsable %>
|
3
|
+
data-controller="menu"
|
4
|
+
data-menu-target="self"
|
5
|
+
data-menu-key-param="<%= key %>"
|
6
|
+
data-menu-collapsed-param="<%= collapsed ? 'collapsed' : 'expanded' %>"
|
7
|
+
<% end %>
|
8
|
+
>
|
9
|
+
<div class="flex justify-between px-10 pt-2 pb-0 text-gray-600 ">
|
10
|
+
<div class="flex items-center text-xs uppercase font-semibold leading-none">
|
11
|
+
<%= item.name %>
|
12
|
+
</div>
|
13
|
+
<% if collapsable %>
|
14
|
+
<div class="cursor-pointer"
|
15
|
+
data-action="click->menu#triggerCollapse"
|
16
|
+
data-menu-target="svg"
|
17
|
+
data-menu-key-param="<%= key %>"
|
18
|
+
>
|
19
|
+
<%= helpers.svg 'heroicons/outline/chevron-down', class: 'h-4'%>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
<div class="w-full space-y-1" data-menu-target="items">
|
24
|
+
<% items.each do |item| %>
|
25
|
+
<%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="flex justify-between p-4 py-2 text-gray-500">
|
2
|
+
<div class="flex items-center text-sm uppercase font-semibold leading-none space-x-1">
|
3
|
+
<span class="min-w-[20px]"><%= icon %></span> <span><%= label %></span>
|
4
|
+
</div>
|
5
|
+
<% if collapsable %>
|
6
|
+
<div class="cursor-pointer"
|
7
|
+
data-action="click->menu#triggerCollapse"
|
8
|
+
data-menu-key-param="<%= key %>"
|
9
|
+
data-menu-target="svg"
|
10
|
+
>
|
11
|
+
<%= helpers.svg 'heroicons/outline/chevron-down', class: 'h-5'%>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Sidebar::HeadingComponent < ViewComponent::Base
|
4
|
+
attr_reader :collapsable
|
5
|
+
attr_reader :icon
|
6
|
+
attr_reader :key
|
7
|
+
attr_reader :label
|
8
|
+
|
9
|
+
def initialize(label: nil, icon: nil, collapsable: false, key: nil)
|
10
|
+
@collapsable = collapsable
|
11
|
+
@icon = icon
|
12
|
+
@key = key
|
13
|
+
@label = label
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% if item.is_a? Avo::Menu::Link %>
|
2
|
+
<%= render Avo::Sidebar::LinkComponent.new label: item.name, path: item.path, target: item.target %>
|
3
|
+
<% end %>
|
4
|
+
<% if item.is_a? Avo::Menu::Resource %>
|
5
|
+
<%= render Avo::Sidebar::LinkComponent.new label: resource.navigation_label, path: helpers.resources_path(resource: resource) %>
|
6
|
+
<% end %>
|
7
|
+
<% if item.is_a? Avo::Menu::Dashboard %>
|
8
|
+
<%= render Avo::Sidebar::LinkComponent.new label: dashboard.navigation_label, path: dashboard.navigation_path %>
|
9
|
+
<% end %>
|
10
|
+
<% if item.is_a? Avo::Menu::Section %>
|
11
|
+
<%= render Avo::Sidebar::SectionComponent.new item: item %>
|
12
|
+
<% end %>
|
13
|
+
<% if item.is_a? Avo::Menu::Group %>
|
14
|
+
<%= render Avo::Sidebar::GroupComponent.new item: item %>
|
15
|
+
<% end %>
|
16
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Sidebar::ItemSwitcherComponent < Avo::Sidebar::BaseItemComponent
|
4
|
+
def resource
|
5
|
+
item.parsed_resource
|
6
|
+
end
|
7
|
+
|
8
|
+
def dashboard
|
9
|
+
item.parsed_dashboard
|
10
|
+
end
|
11
|
+
|
12
|
+
def render?
|
13
|
+
item.visible?
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% if path.present? %>
|
2
|
+
<%= send link_method, path, class: classes, active: active, target: target do %>
|
3
|
+
<%= label %>
|
4
|
+
<% if target == :_blank %>
|
5
|
+
<%= helpers.svg('heroicons/outline/external-link', class: 'self-center ml-auto h-3') %>
|
6
|
+
<% end %>
|
7
|
+
<% end %>
|
8
|
+
<% else %>
|
9
|
+
<%= content_tag :div, class: classes, active: active, target: target do %>
|
10
|
+
<%= label %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Sidebar::LinkComponent < ViewComponent::Base
|
4
|
+
attr_reader :active
|
5
|
+
attr_reader :target
|
6
|
+
attr_reader :label
|
7
|
+
attr_reader :path
|
8
|
+
|
9
|
+
def initialize(label: nil, path: nil, active: :inclusive, target: nil)
|
10
|
+
@label = label
|
11
|
+
@path = path
|
12
|
+
@active = active
|
13
|
+
@target = target
|
14
|
+
end
|
15
|
+
|
16
|
+
def is_external?
|
17
|
+
URI(path).scheme.present?
|
18
|
+
end
|
19
|
+
|
20
|
+
# For external links active_link_to marks them all as active.
|
21
|
+
def link_method
|
22
|
+
is_external? ? :link_to : :active_link_to
|
23
|
+
end
|
24
|
+
|
25
|
+
def classes
|
26
|
+
"px-4 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-150"
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<div class="space-y-1"
|
2
|
+
<% if collapsable %>
|
3
|
+
data-controller="menu"
|
4
|
+
data-menu-target="self"
|
5
|
+
data-menu-key-param="<%= key %>"
|
6
|
+
data-menu-collapsed-param="<%= collapsed ? 'collapsed' : 'expanded' %>"
|
7
|
+
<% end %>
|
8
|
+
>
|
9
|
+
<%= render Avo::Sidebar::HeadingComponent.new label: item.name, icon: helpers.svg(icon, class: 'h-5'), collapsable: item.collapsable, key: key %>
|
10
|
+
<div class="w-full space-y-1" data-menu-target="items">
|
11
|
+
<% items.each do |item| %>
|
12
|
+
<%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
15
|
+
</div>
|
@@ -7,41 +7,50 @@
|
|
7
7
|
</div>
|
8
8
|
</div>
|
9
9
|
<div class="flex-1 flex flex-col justify-between overflow-auto mt-3">
|
10
|
-
<div class="space-y-6">
|
11
|
-
<%= render Avo::
|
10
|
+
<div class="space-y-6 mb-4">
|
11
|
+
<%= render Avo::Sidebar::LinkComponent.new label: 'Get started', path: helpers.avo.root_path, active: :exclusive if Rails.env.development? && Avo.configuration.home_path.nil? %>
|
12
12
|
|
13
|
-
<% if
|
14
|
-
<div>
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
<% dashboards.sort_by { |r| r.navigation_label }.each do |dashboard| %>
|
19
|
-
<%= render Avo::SidebarItemComponent.new label: dashboard.navigation_label, path: dashboard.navigation_path %>
|
20
|
-
<% end %>
|
21
|
-
</div>
|
13
|
+
<% if Avo::App.license.has_with_trial(:menu_editor) && Avo.configuration.main_menu.present? %>
|
14
|
+
<div class="text-black space-y-4">
|
15
|
+
<% Avo::App.main_menu.items.each do |item| %>
|
16
|
+
<%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
|
17
|
+
<% end %>
|
22
18
|
</div>
|
23
|
-
<%
|
19
|
+
<% else %>
|
24
20
|
|
25
|
-
|
26
|
-
|
21
|
+
<% if dashboards.present? %>
|
22
|
+
<div>
|
23
|
+
<%= render Avo::Sidebar::HeadingComponent.new label: t('avo.dashboards'), icon: helpers.svg('dashboards', class: 'h-4') %>
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
<div class="w-full space-y-1">
|
26
|
+
<% dashboards.sort_by { |r| r.navigation_label }.each do |dashboard| %>
|
27
|
+
<%= render Avo::Sidebar::LinkComponent.new label: dashboard.navigation_label, path: dashboard.navigation_path %>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
34
32
|
|
35
|
-
<% if tools.present? %>
|
36
33
|
<div>
|
37
|
-
<%= render Avo::
|
34
|
+
<%= render Avo::Sidebar::HeadingComponent.new label: t('avo.resources'), icon: helpers.svg('resources', class: 'h-4') %>
|
38
35
|
|
39
36
|
<div class="w-full space-y-1">
|
40
|
-
<%
|
41
|
-
<%= render
|
37
|
+
<% resources.sort_by { |r| r.navigation_label }.each do |resource| %>
|
38
|
+
<%= render Avo::Sidebar::LinkComponent.new label: resource.navigation_label, path: helpers.resources_path(resource: resource) %>
|
42
39
|
<% end %>
|
43
40
|
</div>
|
44
41
|
</div>
|
42
|
+
|
43
|
+
<% if tools.present? %>
|
44
|
+
<div>
|
45
|
+
<%= render Avo::Sidebar::HeadingComponent.new label: t('avo.tools'), icon: helpers.svg('tools', class: 'h-4') %>
|
46
|
+
|
47
|
+
<div class="w-full space-y-1">
|
48
|
+
<% tools.each do |partial| %>
|
49
|
+
<%= render partial: "/avo/sidebar/items/#{partial}" %>
|
50
|
+
<% end %>
|
51
|
+
</div>
|
52
|
+
</div>
|
53
|
+
<% end %>
|
45
54
|
<% end %>
|
46
55
|
|
47
56
|
<%= render partial: "/avo/partials/sidebar_extra" %>
|
@@ -2,20 +2,14 @@
|
|
2
2
|
|
3
3
|
class Avo::SidebarComponent < ViewComponent::Base
|
4
4
|
def dashboards
|
5
|
-
|
6
|
-
|
7
|
-
Avo::App.get_dashboards(helpers._current_user).select do |dashboard|
|
8
|
-
dashboard.is_visible?
|
9
|
-
end
|
5
|
+
Avo::App.dashboards_for_navigation
|
10
6
|
end
|
11
7
|
|
12
8
|
def resources
|
13
|
-
Avo::App.
|
9
|
+
Avo::App.resources_for_navigation
|
14
10
|
end
|
15
11
|
|
16
12
|
def tools
|
17
|
-
|
18
|
-
|
19
|
-
Avo::App.get_sidebar_partials
|
13
|
+
Avo::App.tools_for_navigation
|
20
14
|
end
|
21
15
|
end
|
@@ -25,8 +25,17 @@
|
|
25
25
|
class="hidden absolute flex flex-col inset-auto right-0 -mt-12 bg-white rounded min-w-[200px] shadow-context -translate-y-full"
|
26
26
|
data-toggle-panel-target="panel"
|
27
27
|
>
|
28
|
+
<% if Avo::App.license.has_with_trial(:menu_editor) && Avo.configuration.profile_menu.present? %>
|
29
|
+
<div class="text-black space-y-4">
|
30
|
+
<% Avo::App.profile_menu.items.each do |item| %>
|
31
|
+
<% if item.is_a? Avo::Menu::Link %>
|
32
|
+
<%= render Avo::ProfileItemComponent.new label: item.name, path: item.path, icon: item.icon %>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
36
|
+
<% end %>
|
28
37
|
<%# Example link below %>
|
29
|
-
<%#= render Avo::ProfileItemComponent.new label: 'Profile', path: '/profile', icon:
|
38
|
+
<%#= render Avo::ProfileItemComponent.new label: 'Profile', path: '/profile', icon: 'user-circle' %>
|
30
39
|
<%= button_to helpers.main_app.send(destroy_user_session_path),
|
31
40
|
method: :delete,
|
32
41
|
form: { "data-turbo" => "false" },
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<%= t('avo.cancel').capitalize %>
|
14
14
|
<% end %>
|
15
15
|
<% if can_see_the_save_button? %>
|
16
|
-
<%= a_button color: :green,
|
16
|
+
<%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
|
17
17
|
<%= t('avo.save').capitalize %>
|
18
18
|
<% end %>
|
19
19
|
<% end %>
|
@@ -24,7 +24,7 @@
|
|
24
24
|
<%= t('avo.cancel').capitalize %>
|
25
25
|
<% end %>
|
26
26
|
<% if can_see_the_save_button? %>
|
27
|
-
<%= a_button color: :green,
|
27
|
+
<%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
|
28
28
|
<%= t('avo.save').capitalize %>
|
29
29
|
<% end %>
|
30
30
|
<% end %>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<%= t('avo.cancel').capitalize %>
|
19
19
|
<% end %>
|
20
20
|
<% if can_see_the_save_button? %>
|
21
|
-
<%= a_button color: 'green',
|
21
|
+
<%= a_button color: 'green', loading: true, type: :submit, icon: 'save' do %>
|
22
22
|
<%= t('avo.save').capitalize %>
|
23
23
|
<% end %>
|
24
24
|
<% end %>
|
@@ -30,7 +30,7 @@
|
|
30
30
|
<%= t('avo.cancel').capitalize %>
|
31
31
|
<% end %>
|
32
32
|
<% if can_see_the_save_button? %>
|
33
|
-
<%= a_button color: :green,
|
33
|
+
<%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
|
34
34
|
<%= t('avo.save').capitalize %>
|
35
35
|
<% end %>
|
36
36
|
<% end %>
|