Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add search_result_path and search? authorization method #1634

Merged
merged 5 commits into from Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions CONTRIBUTING.MD
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
12 changes: 10 additions & 2 deletions app/controllers/avo/search_controller.rb
Expand Up @@ -27,7 +27,9 @@ def search_resources(resources)
resources
.map do |resource|
# Apply authorization
next unless @authorization.set_record(resource.model_class).authorize_action(:index, raise_exception: false)
action = Avo.configuration.authorization_methods.stringify_keys['search'] || :search
next unless @authorization.set_record(resource.model_class).authorize_action(action, raise_exception: false)

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

Expand Down Expand Up @@ -120,10 +122,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
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
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
9 changes: 6 additions & 3 deletions spec/dummy/app/avo/resources/city_resource.rb
@@ -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
Expand Up @@ -26,6 +26,10 @@ def update?
false
end

def search?
false
end

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

def search?
true
end

def upload_attachments?
true
end
Expand Down
4 changes: 4 additions & 0 deletions spec/dummy/app/policies/post_policy.rb
Expand Up @@ -31,6 +31,10 @@ def act_on?
true
end

def search?
true
end

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

def search?
true
end

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

def search?
true
end

def attach_post?
true
end
Expand Down
4 changes: 2 additions & 2 deletions spec/features/avo/hidden_from_global_search_spec.rb
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
39 changes: 39 additions & 0 deletions spec/features/avo/search_with_custom_path.rb
@@ -0,0 +1,39 @@
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
# wait_for_loaded # -> didn't work, had to use sleep above

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
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
glaucocustodio marked this conversation as resolved.
Show resolved Hide resolved

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

Expand Down