avo 1.7.1 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/Gemfile.lock +94 -70
- data/README.md +11 -0
- data/app/components/avo/fields/common/multiple_file_viewer_component.html.erb +1 -1
- data/app/components/avo/fields/common/single_file_viewer_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +3 -0
- data/app/components/avo/index/grid_item_component.html.erb +4 -6
- data/app/components/avo/views/resource_index_component.html.erb +48 -46
- data/app/components/avo/views/resource_index_component.rb +1 -1
- data/app/controllers/avo/actions_controller.rb +2 -2
- data/app/controllers/avo/application_controller.rb +11 -10
- data/app/controllers/avo/base_controller.rb +20 -4
- data/app/controllers/avo/relations_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +11 -8
- data/app/packs/js/controllers/fields/trix_field_controller.js +16 -0
- data/app/views/avo/actions/show.html.erb +1 -1
- data/app/views/avo/attachments/show.html.erb +1 -1
- data/app/views/avo/base/_actions.html.erb +2 -2
- data/app/views/avo/home/index.html.erb +2 -2
- data/app/views/avo/partials/_javascript.html.erb +1 -1
- data/app/views/avo/partials/_resource_search.html.erb +1 -1
- data/app/views/avo/relations/new.html.erb +1 -1
- data/app/views/avo/sidebar/_sidebar.html.erb +1 -1
- data/config/initializers/friendly_id.rb +107 -0
- data/db/migrate/20210525143134_add_slug_to_users.rb +6 -0
- data/lib/avo/app.rb +3 -1
- data/lib/avo/base_resource.rb +23 -3
- data/lib/avo/configuration.rb +7 -1
- data/lib/avo/fields/belongs_to_field.rb +1 -1
- data/lib/avo/fields/file_field.rb +0 -8
- data/lib/avo/fields/has_and_belongs_to_many_field.rb +4 -4
- data/lib/avo/fields/has_many_field.rb +4 -4
- data/lib/avo/fields/has_one_field.rb +4 -4
- data/lib/avo/fields/trix_field.rb +6 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/field_generator.rb +1 -1
- data/lib/generators/avo/install_generator.rb +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +1 -0
- data/lib/generators/avo/templates/tool/sidebar_item.tt +1 -1
- data/public/avo-packs/css/application-797341b7.css.map +1 -1
- data/public/avo-packs/css/application-797341b7.css.map.br +0 -0
- data/public/avo-packs/css/application-797341b7.css.map.gz +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js +26 -0
- data/public/avo-packs/js/{application-947ed727440d5b5d73ab.js.LICENSE.txt → application-651ed7b9bc727c83f673.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.br +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.gz +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.map +1 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.map.br +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +8 -8
- metadata +11 -9
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js +0 -26
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.br +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.gz +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.map +0 -1
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.map.br +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.map.gz +0 -0
| @@ -12,7 +12,7 @@ module Avo | |
| 12 12 |  | 
| 13 13 | 
             
                def handle
         | 
| 14 14 | 
             
                  resource_ids = action_params[:fields][:resource_ids].split(",").map(&:to_i)
         | 
| 15 | 
            -
                  models = @resource. | 
| 15 | 
            +
                  models = @resource.class.find_scope.find resource_ids
         | 
| 16 16 |  | 
| 17 17 | 
             
                  fields = action_params[:fields].select do |key, value|
         | 
| 18 18 | 
             
                    key != "resource_ids"
         | 
| @@ -33,7 +33,7 @@ module Avo | |
| 33 33 | 
             
                  action_class = params[:action_id].gsub("avo_actions_", "").classify.safe_constantize
         | 
| 34 34 |  | 
| 35 35 | 
             
                  if params[:id].present?
         | 
| 36 | 
            -
                    model = @resource. | 
| 36 | 
            +
                    model = @resource.class.find_scope.find params[:id]
         | 
| 37 37 | 
             
                  end
         | 
| 38 38 |  | 
| 39 39 | 
             
                  @action = action_class.new(model: model, resource: resource, user: _current_user)
         | 
| @@ -17,7 +17,7 @@ module Avo | |
| 17 17 | 
             
                add_flash_types :info, :warning, :success, :error
         | 
| 18 18 |  | 
| 19 19 | 
             
                def init_app
         | 
| 20 | 
            -
                  Avo::App.init request: request, context: context, current_user: _current_user
         | 
| 20 | 
            +
                  Avo::App.init request: request, context: context, root_path: avo.root_path.delete_suffix("/"), current_user: _current_user
         | 
| 21 21 |  | 
| 22 22 | 
             
                  @license = Avo::App.license
         | 
| 23 23 | 
             
                end
         | 
| @@ -78,6 +78,7 @@ module Avo | |
| 78 78 | 
             
                      existing_params = Addressable::URI.parse(request.fullpath).query_values.symbolize_keys
         | 
| 79 79 | 
             
                    end
         | 
| 80 80 | 
             
                  rescue; end
         | 
| 81 | 
            +
             | 
| 81 82 | 
             
                  avo.send :"resources_#{model.model_name.route_key}_path", **existing_params, **args
         | 
| 82 83 | 
             
                end
         | 
| 83 84 |  | 
| @@ -91,7 +92,7 @@ module Avo | |
| 91 92 | 
             
                      existing_params = Addressable::URI.parse(request.fullpath).query_values.symbolize_keys
         | 
| 92 93 | 
             
                    end
         | 
| 93 94 | 
             
                  rescue; end
         | 
| 94 | 
            -
                  Addressable::Template.new("#{Avo. | 
| 95 | 
            +
                  Addressable::Template.new("#{Avo::App.root_path}/resources/#{@parent_resource.model.model_name.route_key}/#{@parent_resource.model.id}/#{@resource.route_key}{?query*}")
         | 
| 95 96 | 
             
                    .expand({query: {**existing_params, **args}})
         | 
| 96 97 | 
             
                    .to_str
         | 
| 97 98 | 
             
                end
         | 
| @@ -103,7 +104,7 @@ module Avo | |
| 103 104 | 
             
                end
         | 
| 104 105 |  | 
| 105 106 | 
             
                def resource_attach_path(model_name, model_id, related_name, related_id = nil)
         | 
| 106 | 
            -
                  path = "#{Avo. | 
| 107 | 
            +
                  path = "#{Avo::App.root_path}/resources/#{model_name}/#{model_id}/#{related_name}/new"
         | 
| 107 108 |  | 
| 108 109 | 
             
                  path += "/#{related_id}" if related_id.present?
         | 
| 109 110 |  | 
| @@ -111,7 +112,7 @@ module Avo | |
| 111 112 | 
             
                end
         | 
| 112 113 |  | 
| 113 114 | 
             
                def resource_detach_path(model_name, model_id, related_name, related_id = nil)
         | 
| 114 | 
            -
                  path = "#{Avo. | 
| 115 | 
            +
                  path = "#{Avo::App.root_path}/resources/#{model_name}/#{model_id}/#{related_name}"
         | 
| 115 116 |  | 
| 116 117 | 
             
                  path += "/#{related_id}" if related_id.present?
         | 
| 117 118 |  | 
| @@ -147,11 +148,11 @@ module Avo | |
| 147 148 | 
             
                end
         | 
| 148 149 |  | 
| 149 150 | 
             
                def set_model
         | 
| 150 | 
            -
                  @model = eager_load_files(@resource, @resource. | 
| 151 | 
            +
                  @model = eager_load_files(@resource, @resource.class.find_scope).find params[:id]
         | 
| 151 152 | 
             
                end
         | 
| 152 153 |  | 
| 153 154 | 
             
                def set_related_model
         | 
| 154 | 
            -
                  @related_model = eager_load_files(@related_resource, @related_resource. | 
| 155 | 
            +
                  @related_model = eager_load_files(@related_resource, @related_resource.class.find_scope).find params[:related_id]
         | 
| 155 156 | 
             
                end
         | 
| 156 157 |  | 
| 157 158 | 
             
                def hydrate_resource
         | 
| @@ -179,7 +180,7 @@ module Avo | |
| 179 180 |  | 
| 180 181 | 
             
                  begin
         | 
| 181 182 | 
             
                    request.path
         | 
| 182 | 
            -
                      .match(/\/?#{Avo. | 
| 183 | 
            +
                      .match(/\/?#{Avo::App.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
         | 
| 183 184 | 
             
                      .captures
         | 
| 184 185 | 
             
                      .first
         | 
| 185 186 | 
             
                  rescue
         | 
| @@ -273,15 +274,15 @@ module Avo | |
| 273 274 | 
             
                end
         | 
| 274 275 |  | 
| 275 276 | 
             
                def on_root_path
         | 
| 276 | 
            -
                  [Avo. | 
| 277 | 
            +
                  [Avo::App.root_path, "#{Avo::App.root_path}/"].include?(request.original_fullpath)
         | 
| 277 278 | 
             
                end
         | 
| 278 279 |  | 
| 279 280 | 
             
                def on_resources_path
         | 
| 280 | 
            -
                  request.original_url.match?(/.*#{Avo. | 
| 281 | 
            +
                  request.original_url.match?(/.*#{Avo::App.root_path}\/resources\/.*/)
         | 
| 281 282 | 
             
                end
         | 
| 282 283 |  | 
| 283 284 | 
             
                def on_api_path
         | 
| 284 | 
            -
                  request.original_url.match?(/.*#{Avo. | 
| 285 | 
            +
                  request.original_url.match?(/.*#{Avo::App.root_path}\/avo_api\/.*/)
         | 
| 285 286 | 
             
                end
         | 
| 286 287 | 
             
              end
         | 
| 287 288 | 
             
            end
         | 
| @@ -7,6 +7,8 @@ module Avo | |
| 7 7 | 
             
                before_action :hydrate_resource
         | 
| 8 8 | 
             
                before_action :authorize_action
         | 
| 9 9 | 
             
                before_action :set_model, only: [:show, :edit, :destroy, :update]
         | 
| 10 | 
            +
                before_action :reset_pagination_if_filters_changed, only: :index
         | 
| 11 | 
            +
                before_action :cache_applied_filters, only: :index
         | 
| 10 12 |  | 
| 11 13 | 
             
                def index
         | 
| 12 14 | 
             
                  @page_title = resource_name.humanize
         | 
| @@ -18,7 +20,7 @@ module Avo | |
| 18 20 |  | 
| 19 21 | 
             
                  # If we don't get a query object predefined from a child controller like relations, just spin one up
         | 
| 20 22 | 
             
                  unless defined? @query
         | 
| 21 | 
            -
                    @query = @ | 
| 23 | 
            +
                    @query = @resource.class.query_scope
         | 
| 22 24 | 
             
                  end
         | 
| 23 25 |  | 
| 24 26 | 
             
                  # Remove default_scope for index view
         | 
| @@ -62,7 +64,7 @@ module Avo | |
| 62 64 | 
             
                  # If we're accessing this resource via another resource add the parent to the breadcrumbs.
         | 
| 63 65 | 
             
                  if params[:via_resource_class].present? && params[:via_resource_id].present?
         | 
| 64 66 | 
             
                    via_resource = Avo::App.get_resource_by_model_name params[:via_resource_class]
         | 
| 65 | 
            -
                    via_model = via_resource. | 
| 67 | 
            +
                    via_model = via_resource.class.find_scope.find params[:via_resource_id]
         | 
| 66 68 | 
             
                    via_resource.hydrate model: via_model
         | 
| 67 69 |  | 
| 68 70 | 
             
                    add_breadcrumb via_resource.plural_name, resources_path(via_resource.model_class)
         | 
| @@ -91,7 +93,7 @@ module Avo | |
| 91 93 | 
             
                  # If we're accessing this resource via another resource add the parent to the breadcrumbs.
         | 
| 92 94 | 
             
                  if params[:via_resource_class].present? && params[:via_resource_id].present?
         | 
| 93 95 | 
             
                    via_resource = Avo::App.get_resource_by_model_name params[:via_resource_class]
         | 
| 94 | 
            -
                    via_model = via_resource. | 
| 96 | 
            +
                    via_model = via_resource.class.find_scope.find params[:via_resource_id]
         | 
| 95 97 | 
             
                    via_resource.hydrate model: via_model
         | 
| 96 98 |  | 
| 97 99 | 
             
                    add_breadcrumb via_resource.plural_name, resources_path(via_resource.model_class)
         | 
| @@ -235,7 +237,7 @@ module Avo | |
| 235 237 |  | 
| 236 238 | 
             
                def set_actions
         | 
| 237 239 | 
             
                  if params[:resource_id].present?
         | 
| 238 | 
            -
                    model = @resource. | 
| 240 | 
            +
                    model = @resource.class.find_scope.find params[:resource_id]
         | 
| 239 241 | 
             
                  end
         | 
| 240 242 |  | 
| 241 243 | 
             
                  @actions = @resource.get_actions.map do |action|
         | 
| @@ -260,5 +262,19 @@ module Avo | |
| 260 262 |  | 
| 261 263 | 
             
                  filter_defaults
         | 
| 262 264 | 
             
                end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                def cache_applied_filters
         | 
| 267 | 
            +
                  ::Avo::App.cache_store.delete applied_filters_cache_key if params[:filters].nil?
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                  ::Avo::App.cache_store.write(applied_filters_cache_key, params[:filters], expires_in: 7.days)
         | 
| 270 | 
            +
                end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                def reset_pagination_if_filters_changed
         | 
| 273 | 
            +
                  params[:page] = 1 if params[:filters] != ::Avo::App.cache_store.read(applied_filters_cache_key)
         | 
| 274 | 
            +
                end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
                def applied_filters_cache_key
         | 
| 277 | 
            +
                  "avo.base_controller.#{@resource.route_key}.applied_filters"
         | 
| 278 | 
            +
                end
         | 
| 263 279 | 
             
              end
         | 
| 264 280 | 
             
            end
         | 
| @@ -15,7 +15,7 @@ module Avo | |
| 15 15 | 
             
                def index
         | 
| 16 16 | 
             
                  @parent_resource = @resource.dup
         | 
| 17 17 | 
             
                  @resource = @related_resource
         | 
| 18 | 
            -
                  @parent_model = @parent_resource. | 
| 18 | 
            +
                  @parent_model = @parent_resource.class.find_scope.find(params[:id])
         | 
| 19 19 | 
             
                  @parent_resource.hydrate(model: @parent_model)
         | 
| 20 20 | 
             
                  @query = @authorization.apply_policy @parent_model.public_send(params[:related_name])
         | 
| 21 21 |  | 
| @@ -2,6 +2,8 @@ require_dependency "avo/application_controller" | |
| 2 2 |  | 
| 3 3 | 
             
            module Avo
         | 
| 4 4 | 
             
              class SearchController < ApplicationController
         | 
| 5 | 
            +
                include Rails.application.routes.url_helpers
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
                before_action :set_resource_name, only: [:show]
         | 
| 6 8 | 
             
                before_action :set_resource, only: [:show]
         | 
| 7 9 |  | 
| @@ -18,14 +20,15 @@ module Avo | |
| 18 20 | 
             
                private
         | 
| 19 21 |  | 
| 20 22 | 
             
                def search_resources(resources)
         | 
| 21 | 
            -
                  resources | 
| 22 | 
            -
                     | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 23 | 
            +
                  resources
         | 
| 24 | 
            +
                    .map do |resource|
         | 
| 25 | 
            +
                      # Apply authorization
         | 
| 26 | 
            +
                      next unless @authorization.set_record(resource.model_class).authorize_action(:index, raise_exception: false)
         | 
| 27 | 
            +
                      # Filter out the models without a search_query
         | 
| 28 | 
            +
                      next if resource.search_query.nil?
         | 
| 26 29 |  | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 30 | 
            +
                      search_resource resource
         | 
| 31 | 
            +
                    end
         | 
| 29 32 | 
             
                    .select do |payload|
         | 
| 30 33 | 
             
                      payload.present?
         | 
| 31 34 | 
             
                    end
         | 
| @@ -61,7 +64,7 @@ module Avo | |
| 61 64 |  | 
| 62 65 | 
             
                    if App.license.has_with_trial(:enhanced_search_results)
         | 
| 63 66 | 
             
                      result[:_description] = resource.description
         | 
| 64 | 
            -
                      result[:_avatar] = resource.avatar
         | 
| 67 | 
            +
                      result[:_avatar] = resource.avatar.present? ? main_app.url_for(resource.avatar) : nil
         | 
| 65 68 | 
             
                      result[:_avatar_type] = resource.avatar_type
         | 
| 66 69 | 
             
                    end
         | 
| 67 70 |  | 
| @@ -21,6 +21,18 @@ export default class extends Controller { | |
| 21 21 | 
             
                return castBoolean(this.controllerTarget.dataset.attachmentsDisabled)
         | 
| 22 22 | 
             
              }
         | 
| 23 23 |  | 
| 24 | 
            +
              get hideAttachmentFilename() {
         | 
| 25 | 
            +
                return castBoolean(this.controllerTarget.dataset.hideAttachmentFilename)
         | 
| 26 | 
            +
              }
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              get hideAttachmentFilesize() {
         | 
| 29 | 
            +
                return castBoolean(this.controllerTarget.dataset.hideAttachmentFilesize)
         | 
| 30 | 
            +
              }
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              get hideAttachmentUrl() {
         | 
| 33 | 
            +
                return castBoolean(this.controllerTarget.dataset.hideAttachmentUrl)
         | 
| 34 | 
            +
              }
         | 
| 35 | 
            +
             | 
| 24 36 | 
             
              get uploadUrl() {
         | 
| 25 37 | 
             
                return `${window.location.origin}${window.Avo.configuration.root_path}/avo_api/resources/${this.resourceName}/${this.resourceId}/attachments`
         | 
| 26 38 | 
             
              }
         | 
| @@ -102,6 +114,10 @@ export default class extends Controller { | |
| 102 114 | 
             
                      href: response.href,
         | 
| 103 115 | 
             
                    }
         | 
| 104 116 |  | 
| 117 | 
            +
                    if (this.hideAttachmentFilename) attributes.filename = null
         | 
| 118 | 
            +
                    if (this.hideAttachmentFilesize) attributes.filesize = null
         | 
| 119 | 
            +
                    if (this.hideAttachmentUrl) attributes.href = null
         | 
| 120 | 
            +
             | 
| 105 121 | 
             
                    successCallback(attributes)
         | 
| 106 122 | 
             
                  }
         | 
| 107 123 | 
             
                })
         | 
| @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
                data-resource-id="<%= params[:id] %>"
         | 
| 8 8 | 
             
                class="hidden text-blue-gray-800"
         | 
| 9 9 | 
             
              >
         | 
| 10 | 
            -
                <%= form_with model: @model, scope: 'fields', url: "#{ | 
| 10 | 
            +
                <%= form_with model: @model, scope: 'fields', url: "#{avo.root_path}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 12 | 
             
                    <% c.heading do %>
         | 
| 13 13 | 
             
                      <%= @action.action_name %>
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            <%= turbo_frame_tag 'destroy_attachment_form' do %>
         | 
| 2 | 
            -
              <%= form_with url: "#{ | 
| 2 | 
            +
              <%= form_with url: "#{avo.root_path}resources/#{params[:resource_name]}/#{params[:id]
         | 
| 3 3 | 
             
                }/active_storage_attachments/#{params[:attachment_name]}/#{params[:signed_attachment_id]}",
         | 
| 4 4 | 
             
                method: :delete,
         | 
| 5 5 | 
             
                html: {
         | 
| @@ -15,8 +15,8 @@ | |
| 15 15 | 
             
                  <%
         | 
| 16 16 | 
             
                    @actions.each_with_index do |action, index|
         | 
| 17 17 | 
             
                      path = action_name == 'show' ?
         | 
| 18 | 
            -
                        "#{ | 
| 19 | 
            -
                        "#{ | 
| 18 | 
            +
                        "#{avo.root_path}resources/#{@resource.model_class.model_name.route_key}/#{@model.id}/actions/#{action.param_id}" :
         | 
| 19 | 
            +
                        "#{avo.root_path}resources/#{@resource.model_class.model_name.route_key}/actions/#{action.param_id}"
         | 
| 20 20 | 
             
                  %>
         | 
| 21 21 | 
             
                    <%= link_to path,
         | 
| 22 22 | 
             
                      'data-turbo-frame': 'actions_show',
         | 
| @@ -28,8 +28,8 @@ | |
| 28 28 | 
             
                          <li><span class="mr-2">👍</span> Authorization</li>
         | 
| 29 29 | 
             
                          <li><span class="mr-2">👍</span> Localization</li>
         | 
| 30 30 | 
             
                          <li><span class="mr-2">👍</span> Custom tools</li>
         | 
| 31 | 
            -
                          <li><span class="mr-2" | 
| 32 | 
            -
                          <li><span class="mr-2" | 
| 31 | 
            +
                          <li><span class="mr-2">👍</span> Custom fields</li>
         | 
| 32 | 
            +
                          <li><span class="mr-2">👍</span> Search</li>
         | 
| 33 33 | 
             
                          <li><span class="mr-2">🕐</span> Dashboards</li>
         | 
| 34 34 | 
             
                          <li><span class="mr-2">🕐</span> Themes</li>
         | 
| 35 35 | 
             
                        </ul>
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            <%= javascript_tag nonce: true do %>
         | 
| 2 2 | 
             
              window.Avo = window.Avo || { configuration: {} }
         | 
| 3 3 | 
             
              Avo.configuration.timezone = '<%= Avo.configuration.timezone %>'
         | 
| 4 | 
            -
              Avo.configuration.root_path = '<%= Avo. | 
| 4 | 
            +
              Avo.configuration.root_path = '<%= Avo::App.root_path %>'
         | 
| 5 5 | 
             
            <% end %>
         | 
| @@ -6,5 +6,5 @@ | |
| 6 6 | 
             
                data-debounce-timeout='<%= Avo.configuration.search_debounce %>'
         | 
| 7 7 | 
             
              >
         | 
| 8 8 | 
             
              </div>
         | 
| 9 | 
            -
              <div class="relative inline-flex text-gray-400 text-sm border border-gray-300 rounded-full cursor-pointer" data-search-target="button"></div>
         | 
| 9 | 
            +
              <div class="hidden relative inline-flex text-gray-400 text-sm border border-gray-300 rounded-full cursor-pointer" data-search-target="button"></div>
         | 
| 10 10 | 
             
            </div>
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            <%= turbo_frame_tag 'attach_modal' do %>
         | 
| 2 2 | 
             
              <%= form_with scope: 'fields',
         | 
| 3 | 
            -
                url: "#{ | 
| 3 | 
            +
                url: "#{avo.root_path}resources/#{params[:resource_name]}/#{params[:id]}/#{params[:related_name]}/",
         | 
| 4 4 | 
             
                data: {
         | 
| 5 5 | 
             
                  'turbo-frame': '_top'
         | 
| 6 6 | 
             
                } do |form| %>
         | 
| @@ -6,7 +6,7 @@ | |
| 6 6 |  | 
| 7 7 | 
             
                <div class="flex-1 flex flex-col justify-between">
         | 
| 8 8 | 
             
                  <div class="tools py-4">
         | 
| 9 | 
            -
                    <%= render Avo::NavigationLinkComponent.new label: 'Get started', path:  | 
| 9 | 
            +
                    <%= render Avo::NavigationLinkComponent.new label: 'Get started', path: avo.root_path, active: :exclusive if Rails.env.development? && Avo.configuration.home_path.nil?  %>
         | 
| 10 10 |  | 
| 11 11 | 
             
                    <%= render Avo::NavigationHeadingComponent.new label: t('avo.resources') %>
         | 
| 12 12 |  | 
| @@ -0,0 +1,107 @@ | |
| 1 | 
            +
            # # FriendlyId Global Configuration
         | 
| 2 | 
            +
            # #
         | 
| 3 | 
            +
            # # Use this to set up shared configuration options for your entire application.
         | 
| 4 | 
            +
            # # Any of the configuration options shown here can also be applied to single
         | 
| 5 | 
            +
            # # models by passing arguments to the `friendly_id` class method or defining
         | 
| 6 | 
            +
            # # methods in your model.
         | 
| 7 | 
            +
            # #
         | 
| 8 | 
            +
            # # To learn more, check out the guide:
         | 
| 9 | 
            +
            # #
         | 
| 10 | 
            +
            # # http://norman.github.io/friendly_id/file.Guide.html
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            # FriendlyId.defaults do |config|
         | 
| 13 | 
            +
            #   # ## Reserved Words
         | 
| 14 | 
            +
            #   #
         | 
| 15 | 
            +
            #   # Some words could conflict with Rails's routes when used as slugs, or are
         | 
| 16 | 
            +
            #   # undesirable to allow as slugs. Edit this list as needed for your app.
         | 
| 17 | 
            +
            #   config.use :reserved
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            #   config.reserved_words = %w(new edit index session login logout users admin
         | 
| 20 | 
            +
            #     stylesheets assets javascripts images)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            #   # This adds an option to treat reserved words as conflicts rather than exceptions.
         | 
| 23 | 
            +
            #   # When there is no good candidate, a UUID will be appended, matching the existing
         | 
| 24 | 
            +
            #   # conflict behavior.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            #   # config.treat_reserved_as_conflict = true
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            #   #  ## Friendly Finders
         | 
| 29 | 
            +
            #   #
         | 
| 30 | 
            +
            #   # Uncomment this to use friendly finders in all models. By default, if
         | 
| 31 | 
            +
            #   # you wish to find a record by its friendly id, you must do:
         | 
| 32 | 
            +
            #   #
         | 
| 33 | 
            +
            #   #    MyModel.friendly.find('foo')
         | 
| 34 | 
            +
            #   #
         | 
| 35 | 
            +
            #   # If you uncomment this, you can do:
         | 
| 36 | 
            +
            #   #
         | 
| 37 | 
            +
            #   #    MyModel.find('foo')
         | 
| 38 | 
            +
            #   #
         | 
| 39 | 
            +
            #   # This is significantly more convenient but may not be appropriate for
         | 
| 40 | 
            +
            #   # all applications, so you must explicity opt-in to this behavior. You can
         | 
| 41 | 
            +
            #   # always also configure it on a per-model basis if you prefer.
         | 
| 42 | 
            +
            #   #
         | 
| 43 | 
            +
            #   # Something else to consider is that using the :finders addon boosts
         | 
| 44 | 
            +
            #   # performance because it will avoid Rails-internal code that makes runtime
         | 
| 45 | 
            +
            #   # calls to `Module.extend`.
         | 
| 46 | 
            +
            #   #
         | 
| 47 | 
            +
            #   # config.use :finders
         | 
| 48 | 
            +
            #   #
         | 
| 49 | 
            +
            #   # ## Slugs
         | 
| 50 | 
            +
            #   #
         | 
| 51 | 
            +
            #   # Most applications will use the :slugged module everywhere. If you wish
         | 
| 52 | 
            +
            #   # to do so, uncomment the following line.
         | 
| 53 | 
            +
            #   #
         | 
| 54 | 
            +
            #   # config.use :slugged
         | 
| 55 | 
            +
            #   #
         | 
| 56 | 
            +
            #   # By default, FriendlyId's :slugged addon expects the slug column to be named
         | 
| 57 | 
            +
            #   # 'slug', but you can change it if you wish.
         | 
| 58 | 
            +
            #   #
         | 
| 59 | 
            +
            #   # config.slug_column = 'slug'
         | 
| 60 | 
            +
            #   #
         | 
| 61 | 
            +
            #   # By default, slug has no size limit, but you can change it if you wish.
         | 
| 62 | 
            +
            #   #
         | 
| 63 | 
            +
            #   # config.slug_limit = 255
         | 
| 64 | 
            +
            #   #
         | 
| 65 | 
            +
            #   # When FriendlyId can not generate a unique ID from your base method, it appends
         | 
| 66 | 
            +
            #   # a UUID, separated by a single dash. You can configure the character used as the
         | 
| 67 | 
            +
            #   # separator. If you're upgrading from FriendlyId 4, you may wish to replace this
         | 
| 68 | 
            +
            #   # with two dashes.
         | 
| 69 | 
            +
            #   #
         | 
| 70 | 
            +
            #   # config.sequence_separator = '-'
         | 
| 71 | 
            +
            #   #
         | 
| 72 | 
            +
            #   # Note that you must use the :slugged addon **prior** to the line which
         | 
| 73 | 
            +
            #   # configures the sequence separator, or else FriendlyId will raise an undefined
         | 
| 74 | 
            +
            #   # method error.
         | 
| 75 | 
            +
            #   #
         | 
| 76 | 
            +
            #   #  ## Tips and Tricks
         | 
| 77 | 
            +
            #   #
         | 
| 78 | 
            +
            #   #  ### Controlling when slugs are generated
         | 
| 79 | 
            +
            #   #
         | 
| 80 | 
            +
            #   # As of FriendlyId 5.0, new slugs are generated only when the slug field is
         | 
| 81 | 
            +
            #   # nil, but if you're using a column as your base method can change this
         | 
| 82 | 
            +
            #   # behavior by overriding the `should_generate_new_friendly_id?` method that
         | 
| 83 | 
            +
            #   # FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave
         | 
| 84 | 
            +
            #   # more like 4.0.
         | 
| 85 | 
            +
            #   # Note: Use(include) Slugged module in the config if using the anonymous module.
         | 
| 86 | 
            +
            #   # If you have `friendly_id :name, use: slugged` in the model, Slugged module
         | 
| 87 | 
            +
            #   # is included after the anonymous module defined in the initializer, so it
         | 
| 88 | 
            +
            #   # overrides the `should_generate_new_friendly_id?` method from the anonymous module.
         | 
| 89 | 
            +
            #   #
         | 
| 90 | 
            +
            #   # config.use :slugged
         | 
| 91 | 
            +
            #   # config.use Module.new {
         | 
| 92 | 
            +
            #   #   def should_generate_new_friendly_id?
         | 
| 93 | 
            +
            #   #     slug.blank? || <your_column_name_here>_changed?
         | 
| 94 | 
            +
            #   #   end
         | 
| 95 | 
            +
            #   # }
         | 
| 96 | 
            +
            #   #
         | 
| 97 | 
            +
            #   # FriendlyId uses Rails's `parameterize` method to generate slugs, but for
         | 
| 98 | 
            +
            #   # languages that don't use the Roman alphabet, that's not usually sufficient.
         | 
| 99 | 
            +
            #   # Here we use the Babosa library to transliterate Russian Cyrillic slugs to
         | 
| 100 | 
            +
            #   # ASCII. If you use this, don't forget to add "babosa" to your Gemfile.
         | 
| 101 | 
            +
            #   #
         | 
| 102 | 
            +
            #   # config.use Module.new {
         | 
| 103 | 
            +
            #   #   def normalize_friendly_id(text)
         | 
| 104 | 
            +
            #   #     text.to_slug.normalize! :transliterations => [:russian, :latin]
         | 
| 105 | 
            +
            #   #   end
         | 
| 106 | 
            +
            #   # }
         | 
| 107 | 
            +
            # end
         |