Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CONTRIBUTING.MD
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ gem 'avo', path: '../avo'

Avo's assets will not show up by default, resulting in 404 errors on `/avo-assets/avo.base.js` and `/avo-assets/avo.base.css`. To avoid this, you need to compile the asset bundles, and symlink them into `public/avo-assets`.

First, make sure you have `yarn` installed and then install Avo's dependencies:
```bash
yarn install
```

Run the first build to generate the files `app/assets/builds/avo.base.js` and `app/assets/builds/avo.base.css`:

```bash
yarn build
```

Create symlinks for compiled assets into the `public` directory. You'll only need to do this once.

```bash
Expand Down
2 changes: 1 addition & 1 deletion app/components/avo/views/resource_index_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<% end %>
<% c.body do %>
<div class="flex flex-col xs:flex-row xs:justify-between space-y-2 xs:space-y-0 py-4 <%= 'hidden' if @resource.search_query.nil? && @filters.empty? && available_view_types.count <= 1 %>">
<% unless hide_search_input %>
<% if show_search_input %>
<div class="flex items-center px-4 w-64">
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key, via_reflection: via_reflection} %>
</div>
Expand Down
15 changes: 12 additions & 3 deletions app/components/avo/views/resource_index_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,19 @@ def description
@resource.resource_description
end

def hide_search_input
return true unless @resource.search_query.present?
def show_search_input
return false unless authorized_to_search?
return false unless @resource.search_query.present?
return false if field&.hide_search_input

field&.hide_search_input || false
true
end

def authorized_to_search?
# Hide the search if the authorization prevents it
return true unless @resource.authorization.has_action_method?("search")

@resource.authorization.authorize_action("search", raise_exception: false)
end

private
Expand Down
11 changes: 9 additions & 2 deletions app/controllers/avo/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def search_resources(resources)
resources
.map do |resource|
# Apply authorization
next unless @authorization.set_record(resource.model_class).authorize_action(:index, raise_exception: false)
next unless @authorization.set_record(resource.model_class).authorize_action(:search, raise_exception: false)

# Filter out the models without a search_query
next if resource.search_query.nil?

Expand Down Expand Up @@ -120,10 +121,16 @@ def apply_search_metadata(models, avo_resource)
models.map do |model|
resource = avo_resource.dup.hydrate(model: model).hydrate_fields(model: model)

record_path = if resource.search_result_path.present?
Avo::Hosts::ResourceRecordHost.new(block: resource.search_result_path, resource: resource, record: model).handle
else
resource.record_path
end

result = {
_id: model.id,
_label: resource.label,
_url: resource.record_path,
_url: record_path
}

if App.license.has_with_trial(:enhanced_search_results)
Expand Down
1 change: 1 addition & 0 deletions lib/avo/base_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class BaseResource
class_attribute :description, default: :id
class_attribute :search_query, default: nil
class_attribute :search_query_help, default: ""
class_attribute :search_result_path
class_attribute :includes, default: []
class_attribute :authorization_policy
class_attribute :translation_key
Expand Down
2 changes: 2 additions & 0 deletions lib/avo/hosts/base_host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class BaseHost
option :params, default: proc { Avo::App.params }
option :view_context, default: proc { Avo::App.view_context }
option :current_user, default: proc { Avo::App.current_user }
option :main_app, default: proc { view_context.main_app }
option :avo, default: proc { view_context.avo }
# This is optional because we might instantiate the `Host` first and later hydrate it with a block.
option :block, optional: true

Expand Down
8 changes: 8 additions & 0 deletions lib/avo/services/authorization_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,16 @@ def defined_methods(model, **args)
end

def has_method?(method, **args)
method = "#{method}?" unless method.to_s.end_with? "?"
defined_methods(args[:record] || record, **args).include? method.to_sym
end

# Check the received method to see if the user overrode it in their config and then checks if it's present on the policy.
def has_action_method?(method, **args)
method = Avo.configuration.authorization_methods.stringify_keys[method.to_s] || method

has_method? method, **args
end
end
end
end
1 change: 1 addition & 0 deletions lib/generators/avo/templates/initializer/avo.tt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Avo.configure do |config|
# update: 'update?',
# create: 'create?',
# destroy: 'destroy?',
# search: 'search?',
# }
# config.raise_error_on_missing_policy = false
# config.authorization_client = :pundit
Expand Down
9 changes: 6 additions & 3 deletions spec/dummy/app/avo/resources/city_resource.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
class CityResource < Avo::BaseResource
self.title = :name
self.includes = []
# self.search_query = ->(params:) do
# scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
# end
self.search_query = -> do
scope.ransack(name_eq: params[:q]).result(distinct: false)
end
self.search_result_path = -> do
avo.resources_city_path record, custom: "yup"
end
self.extra_params = [:fish_type, :something_else, properties: [], information: [:name, :history]]

field :id, as: :id
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/application_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ def update?
false
end

def avo_search?
false
end

def edit?
update?
end
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/course_link_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def act_on?
true
end

def avo_search?
true
end

def upload_attachments?
true
end
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/course_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def reorder_links?
false
end

def avo_search?
true
end

class Scope < Scope
def resolve
scope.all
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/post_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ def act_on?
true
end

def avo_search?
true
end

def upload_attachments?
true
end
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/team_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def destroy?
true
end

def avo_search?
true
end

# Attachments
def upload_attachments?
true
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/user_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def act_on?
true
end

def avo_search?
true
end

def attach_post?
true
end
Expand Down
3 changes: 3 additions & 0 deletions spec/dummy/config/initializers/avo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
params: request.params
}
end
config.authorization_methods = {
search: "avo_search?" # override this method
}
# config.raise_error_on_missing_policy = true
# config.authorization_client = "Avo::Services::AuthorizationClients::ExtraPunditClient"

Expand Down
4 changes: 2 additions & 2 deletions spec/features/avo/hidden_from_global_search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
let!(:team_membership) { team.team_members << user }

describe "global search" do
it "does not return the ream membership" do
it "does not return the team membership" do
get :index

expect(json['users']['count']).to eq 1
Expand All @@ -17,7 +17,7 @@
end

describe "resource search" do
it "does not return the ream membership" do
it "does not return the team membership" do
get :show, params: {
resource_name: 'memberships'
}
Expand Down
38 changes: 38 additions & 0 deletions spec/features/avo/search_with_custom_path.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require "rails_helper"

RSpec.feature "Search with custom path", type: :system do
let(:url) { "/admin/resources/cities" }

subject do
visit url
page
end

describe "global search" do
let!(:city) { create :city, name: "São Paulo" }

context "when search result path has been changed" do
it "can find the city" do
visit url
open_global_search_box
expect_search_panel_open

write_in_search "São Paulo"
expect(page).to have_content "São Paulo"
find(".aa-Panel").find(".aa-Item div", text: "São Paulo", match: :first).click
sleep 0.8

expect(page.current_url).to include("custom=yup")
end
end
end
end

def open_global_search_box
find(".global-search").click
end

def expect_search_panel_open
expect(page).to have_css ".aa-InputWrapper .aa-Input"
expect(page).to have_selector(".aa-Input:focus")
end
1 change: 1 addition & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def driver_options(headless: false)
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
config.filter_run_when_matching :focus

config.before(:each, type: :system) { driven_by test_driver }

Expand Down