avo 1.0.2 → 1.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 +7 -4
- data/Gemfile.lock +19 -4
- data/README.md +3 -1
- data/app/components/avo/edit/fields/belongs_to_field_component.html.erb +0 -1
- data/app/components/avo/edit/fields/belongs_to_field_component.rb +7 -0
- data/app/components/avo/index/grid_cover_empty_state_component.html.erb +3 -0
- data/app/components/avo/index/grid_cover_empty_state_component.rb +4 -0
- data/app/components/avo/index/grid_item_component.html.erb +4 -4
- data/app/components/avo/modal_component.rb +2 -1
- data/app/components/avo/panel_component.html.erb +7 -2
- data/app/components/avo/panel_component.rb +4 -1
- data/app/components/avo/show/fields/has_one_field_component.html.erb +3 -3
- data/app/components/avo/views/resource_edit_component.html.erb +3 -3
- data/app/components/avo/views/resource_index_component.html.erb +6 -6
- data/app/components/avo/views/resource_new_component.html.erb +3 -3
- data/app/components/avo/views/resource_show_component.html.erb +2 -2
- data/app/controllers/avo/application_controller.rb +12 -8
- data/app/controllers/avo/base_controller.rb +16 -0
- data/app/controllers/avo/home_controller.rb +2 -0
- data/app/helpers/avo/application_helper.rb +0 -30
- data/app/packs/entrypoints/application.css +1 -0
- data/app/packs/stylesheets/breadcrumbs.css +12 -0
- data/app/packs/svgs/chevron-right.svg +3 -0
- data/app/views/avo/actions/show.html.erb +2 -2
- data/app/views/avo/home/index.html.erb +3 -3
- data/{lib/generators/avo/templates → app/views/avo}/partials/_scripts.html.erb +0 -0
- data/app/views/avo/relations/new.html.erb +2 -2
- data/app/views/avo/sidebar/_sidebar.html.erb +11 -2
- data/app/views/layouts/avo/application.html.erb +5 -4
- data/avo.gemspec +2 -0
- data/lib/avo/app.rb +28 -9
- data/lib/avo/base_resource.rb +12 -12
- data/lib/avo/configuration.rb +11 -1
- data/lib/avo/fields/belongs_to_field.rb +0 -2
- data/lib/avo/grid_collector.rb +1 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/eject_generator.rb +55 -0
- data/lib/generators/avo/templates/tool/controller.tt +2 -0
- data/lib/generators/avo/templates/tool/sidebar_item.tt +1 -0
- data/lib/generators/avo/templates/tool/view.tt +27 -0
- data/lib/generators/avo/tool_generator.rb +62 -0
- data/public/avo-packs/css/{application-9d115b7e.css → application-13cc02fb.css} +41 -7
- data/public/avo-packs/css/application-13cc02fb.css.br +0 -0
- data/public/avo-packs/css/application-13cc02fb.css.gz +0 -0
- data/public/avo-packs/css/application-13cc02fb.css.map +1 -0
- data/public/avo-packs/css/application-13cc02fb.css.map.br +0 -0
- data/public/avo-packs/css/application-13cc02fb.css.map.gz +0 -0
- data/public/avo-packs/js/application-e351ef988a3cb9687542.js.map +1 -1
- data/public/avo-packs/js/application-e351ef988a3cb9687542.js.map.br +0 -0
- data/public/avo-packs/js/application-e351ef988a3cb9687542.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +7 -7
- metadata +46 -13
- data/lib/generators/avo/partials_generator.rb +0 -14
- data/lib/generators/avo/templates/partials/_footer.html.erb +0 -3
- data/lib/generators/avo/templates/partials/_header.html.erb +0 -1
- data/lib/generators/avo/templates/partials/_logo.html.erb +0 -1
- data/public/avo-packs/css/application-9d115b7e.css.br +0 -0
- data/public/avo-packs/css/application-9d115b7e.css.gz +0 -0
- data/public/avo-packs/css/application-9d115b7e.css.map +0 -1
- data/public/avo-packs/css/application-9d115b7e.css.map.br +0 -0
- data/public/avo-packs/css/application-9d115b7e.css.map.gz +0 -0
@@ -3,6 +3,8 @@ require_dependency "avo/application_controller"
|
|
3
3
|
module Avo
|
4
4
|
class HomeController < ApplicationController
|
5
5
|
def index
|
6
|
+
@page_title = "Get started"
|
7
|
+
|
6
8
|
unless Rails.env.development?
|
7
9
|
redirect_to resources_path Avo::App.get_resources.min_by { |resource| resource.route_key }.model_class
|
8
10
|
end
|
@@ -7,30 +7,6 @@ module Avo
|
|
7
7
|
Avo.webpacker
|
8
8
|
end
|
9
9
|
|
10
|
-
def render_logo
|
11
|
-
render partial: "vendor/avo/partials/logo"
|
12
|
-
rescue
|
13
|
-
render partial: "avo/partials/logo"
|
14
|
-
end
|
15
|
-
|
16
|
-
def render_header
|
17
|
-
render partial: "vendor/avo/partials/header"
|
18
|
-
rescue
|
19
|
-
render partial: "avo/partials/header"
|
20
|
-
end
|
21
|
-
|
22
|
-
def render_footer
|
23
|
-
render partial: "vendor/avo/partials/footer"
|
24
|
-
rescue
|
25
|
-
render partial: "avo/partials/footer"
|
26
|
-
end
|
27
|
-
|
28
|
-
def render_scripts
|
29
|
-
render partial: "vendor/avo/partials/scripts"
|
30
|
-
rescue
|
31
|
-
""
|
32
|
-
end
|
33
|
-
|
34
10
|
def render_license_warnings
|
35
11
|
render partial: "avo/sidebar/license_warnings", locals: {
|
36
12
|
license: Avo::App.license.properties
|
@@ -45,12 +21,6 @@ module Avo
|
|
45
21
|
}
|
46
22
|
end
|
47
23
|
|
48
|
-
def panel(**args, &block)
|
49
|
-
render(Avo::PanelComponent.new(**args)) do |component|
|
50
|
-
capture(component, &block)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
24
|
def empty_state(resource_name)
|
55
25
|
render partial: "avo/partials/empty_state", locals: {resource_name: resource_name}
|
56
26
|
end
|
@@ -14,6 +14,7 @@
|
|
14
14
|
@import './../stylesheets/alerts.css';
|
15
15
|
@import './../stylesheets/loader.css';
|
16
16
|
@import './../stylesheets/pagination.css';
|
17
|
+
@import './../stylesheets/breadcrumbs.css';
|
17
18
|
|
18
19
|
@import './../stylesheets/components/status.css';
|
19
20
|
@import './../stylesheets/components/code.css';
|
@@ -9,7 +9,7 @@
|
|
9
9
|
>
|
10
10
|
<%= form_with model: @model, scope: 'fields', url: "/avo/resources/#{@resource.model_class.model_name.route_key}/actions/#{@action.param_id}", data: {'turbo-frame': '_top', 'action-target': 'form'} do |form| %>
|
11
11
|
<%= render Avo::ModalComponent.new do |c| %>
|
12
|
-
<% c.
|
12
|
+
<% c.heading do %>
|
13
13
|
<%= @action.name %>
|
14
14
|
<% end %>
|
15
15
|
|
@@ -25,7 +25,7 @@
|
|
25
25
|
<% end %>
|
26
26
|
<% end %>
|
27
27
|
|
28
|
-
<% c.
|
28
|
+
<% c.controls do %>
|
29
29
|
<%= a_button @action.cancel_button_label, 'data-action': 'click->modal#close', size: :sm %>
|
30
30
|
<%= a_button @action.confirm_button_label, type: :submit, color: :green, size: :sm %>
|
31
31
|
<% end %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<div class="flex flex-col">
|
2
|
-
<%=
|
3
|
-
<% c.
|
2
|
+
<%= render Avo::PanelComponent.new title: 'Welcome to Avo' do |c| %>
|
3
|
+
<% c.tools do %>
|
4
4
|
<div class="text-sm italic">This page is visible only in development. It will be hidden in other environments.</div>
|
5
5
|
<% end %>
|
6
6
|
|
7
|
-
<% c.
|
7
|
+
<% c.body do %>
|
8
8
|
<div class="flex flex-col justify-between py-6 min-h-24">
|
9
9
|
<div class="px-6 space-y-4">
|
10
10
|
<h3>About</h3>
|
File without changes
|
@@ -5,7 +5,7 @@
|
|
5
5
|
'turbo-frame': '_top'
|
6
6
|
} do |form| %>
|
7
7
|
<%= render Avo::ModalComponent.new do |c| %>
|
8
|
-
<% c.
|
8
|
+
<% c.heading do %>
|
9
9
|
<%= t 'avo.choose_item', item: params[:related_name].downcase %>
|
10
10
|
<% end %>
|
11
11
|
|
@@ -24,7 +24,7 @@
|
|
24
24
|
|
25
25
|
<%#= form.hidden_field :resource_ids, value: params[:resource_ids], 'data-action-target': 'resourceIds' %>
|
26
26
|
|
27
|
-
<% c.
|
27
|
+
<% c.controls do %>
|
28
28
|
<%= a_button t('avo.cancel'), 'data-action': 'click->modal#close', size: :sm %>
|
29
29
|
<%= a_button t('avo.attach'), type: :submit, color: :green, size: :sm %>
|
30
30
|
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="application-sidebar flex h-full bg-white text-white w-56 z-50 border-r border-gray-300">
|
2
2
|
<div class="flex flex-col w-full">
|
3
3
|
<%= link_to root_path, class: 'logo-placeholder h-16 bg-white p-2 flex justify-center' do %>
|
4
|
-
<%=
|
4
|
+
<%= render partial: "avo/partials/logo" %>
|
5
5
|
<% end %>
|
6
6
|
|
7
7
|
<div class="flex-1 flex flex-col justify-between">
|
@@ -10,9 +10,18 @@
|
|
10
10
|
<%= render Avo::NavigationHeadingComponent.new label: t('avo.resources') %>
|
11
11
|
|
12
12
|
<div class="w-full">
|
13
|
-
<% Avo::App.
|
13
|
+
<% Avo::App.resources_navigation(_current_user).each do |resource| %>
|
14
14
|
<%= render Avo::NavigationLinkComponent.new label: resource.name.pluralize.humanize, path: resources_path(resource.model_class) %>
|
15
15
|
<% end %>
|
16
|
+
|
17
|
+
<% sidebar_partials = Avo::App.get_sidebar_partials %>
|
18
|
+
<% if sidebar_partials.present? %>
|
19
|
+
<%= render Avo::NavigationHeadingComponent.new label: t('avo.tools') %>
|
20
|
+
|
21
|
+
<% sidebar_partials.each do |partial| %>
|
22
|
+
<%= render partial: "/avo/sidebar/items/#{partial}" %>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
16
25
|
</div>
|
17
26
|
|
18
27
|
</div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
|
4
|
+
<%= display_meta_tags site: Avo.configuration.app_name, reverse: true, separator: "—" %>
|
5
5
|
|
6
6
|
<%= csrf_meta_tags %>
|
7
7
|
<%= csp_meta_tag %>
|
@@ -20,7 +20,7 @@
|
|
20
20
|
<div class="flex-1 flex flex-col h-full overflow-auto">
|
21
21
|
<div class="relative bg-white p-2 shadow-md h-16 w-full flex flex-shrink-0 items-center z-50" v-if="layout !== 'blank'">
|
22
22
|
<div class="ml-6">
|
23
|
-
<%=
|
23
|
+
<%= render partial: "avo/partials/header" %>
|
24
24
|
</div>
|
25
25
|
<div class="flex-1 flex justify-center">
|
26
26
|
<div class="w-64">
|
@@ -31,7 +31,7 @@
|
|
31
31
|
|
32
32
|
<div class="content p-8 flex-1 flex flex-col justify-between items-stretch <%= @container_classes %>">
|
33
33
|
<%= yield %>
|
34
|
-
<%=
|
34
|
+
<%= render partial: "avo/partials/footer" %>
|
35
35
|
</div>
|
36
36
|
</div>
|
37
37
|
</div>
|
@@ -44,6 +44,7 @@
|
|
44
44
|
<% end %>
|
45
45
|
</div>
|
46
46
|
|
47
|
-
<%=
|
47
|
+
<%= render partial: "avo/partials/scripts" %>
|
48
|
+
<!-- Avo version: <%= Avo::VERSION %> -->
|
48
49
|
</body>
|
49
50
|
</html>
|
data/avo.gemspec
CHANGED
data/lib/avo/app.rb
CHANGED
@@ -129,10 +129,28 @@ module Avo
|
|
129
129
|
.sort_by { |r| r.name }
|
130
130
|
end
|
131
131
|
|
132
|
-
def
|
132
|
+
def resources_navigation(user = nil)
|
133
133
|
get_available_resources(user).select do |resource|
|
134
134
|
resource.model_class.present?
|
135
135
|
end
|
136
|
+
.select do |resource|
|
137
|
+
resource.visible_on_sidebar
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Insert any partials that we find in app/views/avo/sidebar/items.
|
142
|
+
def get_sidebar_partials
|
143
|
+
Dir.glob(Rails.root.join("app", "views", "avo", "sidebar", "items", "*.html.erb"))
|
144
|
+
.map do |path|
|
145
|
+
File.basename path
|
146
|
+
end
|
147
|
+
.map do |filename|
|
148
|
+
# remove the leading underscore (_)
|
149
|
+
filename[0] = ""
|
150
|
+
# remove the extension
|
151
|
+
filename.gsub!('.html.erb', '')
|
152
|
+
filename
|
153
|
+
end
|
136
154
|
end
|
137
155
|
|
138
156
|
def draw_routes
|
@@ -144,16 +162,17 @@ module Avo
|
|
144
162
|
.select do |resource|
|
145
163
|
resource != :BaseResource
|
146
164
|
end
|
165
|
+
.select do |resource|
|
166
|
+
resource.is_a? Class
|
167
|
+
end
|
147
168
|
.map do |resource|
|
148
|
-
if resource.
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
resource.to_s.underscore.gsub("_resource", "").downcase.pluralize.to_sym
|
153
|
-
end
|
154
|
-
|
155
|
-
resources route_key
|
169
|
+
route_key = if resource.model_class.present?
|
170
|
+
resource.model_class.model_name.route_key
|
171
|
+
else
|
172
|
+
resource.to_s.underscore.gsub("_resource", "").downcase.pluralize.to_sym
|
156
173
|
end
|
174
|
+
|
175
|
+
resources route_key
|
157
176
|
end
|
158
177
|
end
|
159
178
|
end
|
data/lib/avo/base_resource.rb
CHANGED
@@ -21,6 +21,7 @@ module Avo
|
|
21
21
|
class_attribute :filters_loader
|
22
22
|
class_attribute :fields
|
23
23
|
class_attribute :grid_loader
|
24
|
+
class_attribute :visible_on_sidebar, default: true
|
24
25
|
|
25
26
|
class << self
|
26
27
|
def grid(&block)
|
@@ -260,28 +261,27 @@ module Avo
|
|
260
261
|
end
|
261
262
|
end
|
262
263
|
|
263
|
-
# For :new views we're hydrating the model with the values from the resource's default attribute.
|
264
264
|
# We will not overwrite any attributes that come pre-filled in the model.
|
265
265
|
def hydrate_model_with_default_values
|
266
266
|
default_values = get_fields.select do |field|
|
267
267
|
!field.computed
|
268
268
|
end
|
269
269
|
.map do |field|
|
270
|
-
|
271
|
-
|
270
|
+
id = field.id
|
271
|
+
value = field.value
|
272
272
|
|
273
|
-
|
274
|
-
|
273
|
+
if field.respond_to? :foreign_key
|
274
|
+
id = field.foreign_key.to_sym
|
275
275
|
|
276
|
-
|
276
|
+
reflection = @model._reflections[@params[:via_relation]]
|
277
277
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
278
|
+
if reflection.present? && reflection.foreign_key.present? && field.id.to_s == @params[:via_relation].to_s
|
279
|
+
value = @params[:via_resource_id]
|
280
|
+
end
|
281
|
+
end
|
282
282
|
|
283
|
-
|
284
|
-
|
283
|
+
[id, value]
|
284
|
+
end
|
285
285
|
.to_h
|
286
286
|
.select do |id, value|
|
287
287
|
value.present?
|
data/lib/avo/configuration.rb
CHANGED
@@ -19,10 +19,12 @@ module Avo
|
|
19
19
|
attr_accessor :full_width_index_view
|
20
20
|
attr_accessor :cache_resources_on_index_view
|
21
21
|
attr_accessor :context
|
22
|
+
attr_accessor :display_breadcrumbs
|
23
|
+
attr_accessor :initial_breadcrumbs
|
22
24
|
|
23
25
|
def initialize
|
24
26
|
@root_path = "/avo"
|
25
|
-
@app_name = Rails.application.class.to_s.split("::").first.underscore.humanize(keep_id_suffix: true)
|
27
|
+
@app_name = ::Rails.application.class.to_s.split("::").first.underscore.humanize(keep_id_suffix: true)
|
26
28
|
@timezone = "UTC"
|
27
29
|
@per_page = 24
|
28
30
|
@per_page_steps = [12, 24, 48, 72]
|
@@ -48,6 +50,10 @@ module Avo
|
|
48
50
|
@full_width_index_view = false
|
49
51
|
@cache_resources_on_index_view = Avo::PACKED
|
50
52
|
@context = proc {}
|
53
|
+
@initial_breadcrumbs = proc {
|
54
|
+
add_breadcrumb I18n.t("avo.home").humanize, avo.root_path
|
55
|
+
}
|
56
|
+
@display_breadcrumbs = true
|
51
57
|
end
|
52
58
|
|
53
59
|
def locale_tag
|
@@ -71,6 +77,10 @@ module Avo
|
|
71
77
|
def set_context(&block)
|
72
78
|
@context = block if block.present?
|
73
79
|
end
|
80
|
+
|
81
|
+
def set_initial_breadcrumbs(&block)
|
82
|
+
@initial_breadcrumbs = block if block.present?
|
83
|
+
end
|
74
84
|
end
|
75
85
|
|
76
86
|
def self.configuration
|
data/lib/avo/grid_collector.rb
CHANGED
@@ -27,7 +27,7 @@ module Avo
|
|
27
27
|
def hydrate(model:, view:, resource:)
|
28
28
|
cover_field.hydrate(model: model, view: view, resource: resource) if cover_field.present?
|
29
29
|
title_field.hydrate(model: model, view: view, resource: resource) if title_field.present?
|
30
|
-
body_field.hydrate(model: model, view: view, resource: resource) if
|
30
|
+
body_field.hydrate(model: model, view: view, resource: resource) if body_field.present?
|
31
31
|
|
32
32
|
self
|
33
33
|
end
|
data/lib/avo/version.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require "fileutils"
|
3
|
+
|
4
|
+
module Generators
|
5
|
+
module Avo
|
6
|
+
class EjectGenerator < ::Rails::Generators::Base
|
7
|
+
argument :filename, type: :string, required: true
|
8
|
+
|
9
|
+
source_root ::Avo::Engine.root
|
10
|
+
|
11
|
+
namespace "avo:eject"
|
12
|
+
|
13
|
+
TEMPLATES = {
|
14
|
+
sidebar: "app/views/avo/sidebar/_sidebar.html.erb",
|
15
|
+
logo: "app/views/avo/partials/logo.html.erb",
|
16
|
+
header: "app/views/avo/partials/header.html.erb",
|
17
|
+
footer: "app/views/avo/partials/footer.html.erb",
|
18
|
+
scripts: "app/views/avo/partials/scripts.html.erb"
|
19
|
+
}
|
20
|
+
|
21
|
+
def handle
|
22
|
+
if @filename.starts_with?(":")
|
23
|
+
template_id = path_to_sym @filename
|
24
|
+
template_path = TEMPLATES[template_id]
|
25
|
+
|
26
|
+
if path_exists? template_path
|
27
|
+
eject template_path
|
28
|
+
else
|
29
|
+
say("Failed to find the `#{template_id.to_sym}` template.", :yellow)
|
30
|
+
end
|
31
|
+
elsif path_exists? @filename
|
32
|
+
eject @filename
|
33
|
+
else
|
34
|
+
say("Failed to find the `#{@filename}` template.", :yellow)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
no_tasks do
|
39
|
+
def path_to_sym(filename)
|
40
|
+
template_id = filename.dup
|
41
|
+
template_id[0] = ""
|
42
|
+
template_id.to_sym
|
43
|
+
end
|
44
|
+
|
45
|
+
def path_exists?(path)
|
46
|
+
path.present? && File.file?(::Avo::Engine.root.join(path))
|
47
|
+
end
|
48
|
+
|
49
|
+
def eject(path)
|
50
|
+
copy_file ::Avo::Engine.root.join(path), ::Rails.root.join(path)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%%= render Avo::NavigationLinkComponent.new label: '<%= human_name %>', path: '/avo/<%= file_name %>' %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div class="flex flex-col">
|
2
|
+
<%%= render Avo::PanelComponent.new title: '<%= human_name %>' do |c| %>
|
3
|
+
<%% c.tools do %>
|
4
|
+
<div class="text-sm italic">This is the panels tools section.</div>
|
5
|
+
<%% end %>
|
6
|
+
|
7
|
+
<%% c.body do %>
|
8
|
+
<div class="flex flex-col justify-between py-6 min-h-24">
|
9
|
+
<div class="px-6 space-y-4">
|
10
|
+
<h3>What a nice new tool 👋</h3>
|
11
|
+
|
12
|
+
<p>
|
13
|
+
You can edit this file here <%= in_code "app/views/avo/tools/#{file_name}.html.erb" %>.
|
14
|
+
</p>
|
15
|
+
|
16
|
+
<p>
|
17
|
+
For this tool we created the <%= in_code file_name %> method in the <%= in_code "Avo::ToolsController" %>. You may delete it or move it to your own controller.
|
18
|
+
</p>
|
19
|
+
|
20
|
+
<p>
|
21
|
+
A new <%= in_code human_name %> item should have been added to the sidebar. Edit it in <%= in_code "app/views/avo/sidebar/items/_#{file_name}.html.erb" %>
|
22
|
+
</p>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
<%% end %>
|
26
|
+
<%% end %>
|
27
|
+
</div>
|