avo 1.4.4 → 1.4.5.pre.1
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 +2 -0
- data/Gemfile.lock +7 -1
- data/README.md +4 -4
- data/app/components/avo/views/resource_index_component.html.erb +3 -3
- data/app/controllers/avo/application_controller.rb +14 -7
- data/app/controllers/avo/relations_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +50 -35
- data/app/packs/entrypoints/application.css +2 -1
- data/app/packs/entrypoints/application.js +3 -0
- data/app/packs/js/controllers/search_controller.js +120 -0
- data/app/packs/js/helpers/debounce_promise.js +13 -0
- data/app/packs/stylesheets/search.css +79 -0
- data/app/views/avo/partials/_global_search.html.erb +17 -0
- data/app/views/avo/partials/_profile_dropdown.html.erb +8 -12
- data/app/views/avo/partials/_resource_search.html.erb +10 -0
- data/app/views/layouts/avo/application.html.erb +2 -4
- data/avo.gemspec +1 -0
- data/config/routes.rb +2 -6
- data/lib/avo/app.rb +3 -1
- data/lib/avo/base_resource.rb +83 -7
- data/lib/avo/configuration.rb +2 -0
- data/lib/avo/fields/base_field.rb +6 -0
- data/lib/avo/fields/file_field.rb +4 -0
- data/lib/avo/licensing/license.rb +10 -0
- data/lib/avo/licensing/pro_license.rb +3 -1
- data/lib/avo/services/authorization_service.rb +1 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +1 -0
- data/lib/generators/avo/templates/resource/resource.tt +3 -0
- data/lib/generators/avo/templates/tool/sidebar_item.tt +1 -1
- data/public/avo-packs/css/{application-68691c73.css → application-d69fe930.css} +183 -6
- data/public/avo-packs/css/application-d69fe930.css.br +0 -0
- data/public/avo-packs/css/application-d69fe930.css.gz +0 -0
- data/public/avo-packs/css/application-d69fe930.css.map +1 -0
- data/public/avo-packs/css/application-d69fe930.css.map.br +0 -0
- data/public/avo-packs/css/application-d69fe930.css.map.gz +0 -0
- data/public/avo-packs/js/application-7b3d507875f4bc1f6677.js +26 -0
- data/public/avo-packs/js/{application-6a0b9e58526ae6bef242.js.LICENSE.txt → application-7b3d507875f4bc1f6677.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-7b3d507875f4bc1f6677.js.br +0 -0
- data/public/avo-packs/js/application-7b3d507875f4bc1f6677.js.gz +0 -0
- data/public/avo-packs/js/application-7b3d507875f4bc1f6677.js.map +1 -0
- data/public/avo-packs/js/application-7b3d507875f4bc1f6677.js.map.br +0 -0
- data/public/avo-packs/js/application-7b3d507875f4bc1f6677.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +15 -15
- metadata +36 -17
- data/public/avo-packs/css/application-68691c73.css.br +0 -0
- data/public/avo-packs/css/application-68691c73.css.gz +0 -0
- data/public/avo-packs/css/application-68691c73.css.map +0 -1
- data/public/avo-packs/css/application-68691c73.css.map.br +0 -0
- data/public/avo-packs/css/application-68691c73.css.map.gz +0 -0
- data/public/avo-packs/js/application-6a0b9e58526ae6bef242.js +0 -26
- data/public/avo-packs/js/application-6a0b9e58526ae6bef242.js.br +0 -0
- data/public/avo-packs/js/application-6a0b9e58526ae6bef242.js.gz +0 -0
- data/public/avo-packs/js/application-6a0b9e58526ae6bef242.js.map +0 -1
- data/public/avo-packs/js/application-6a0b9e58526ae6bef242.js.map.br +0 -0
- data/public/avo-packs/js/application-6a0b9e58526ae6bef242.js.map.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46a795d39c0e6c43399df4c10b3a75891557f6e1d525ec737420573e3042521a
|
4
|
+
data.tar.gz: 970f8657291f6b9a0d1338265e9253120135128eb3a248c88ca4a457f7273d64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0886bf3479f6eaf19d674b60e81906714666433d3b90d5b3685fac16ed558a18aeb099826ffc8e8ba798fa4149586ee36b4c447c6c05ce1141effd0c144a5a8
|
7
|
+
data.tar.gz: d8afee4446cef7180453beb74ef91cdf68f860e59ae8baa62c660075c4de8656ecabf2c6668318a21a85ca410112caa3b39b43b5f88cbaea5fbe3d1bd6b8ea21
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (1.4.
|
4
|
+
avo (1.4.5.pre.1)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
@@ -14,6 +14,7 @@ PATH
|
|
14
14
|
pagy
|
15
15
|
pundit
|
16
16
|
rails (>= 6.0)
|
17
|
+
ransack
|
17
18
|
view_component
|
18
19
|
zeitwerk
|
19
20
|
|
@@ -235,6 +236,10 @@ GEM
|
|
235
236
|
thor (>= 0.20.3, < 2.0)
|
236
237
|
rainbow (3.0.0)
|
237
238
|
rake (13.0.3)
|
239
|
+
ransack (2.4.2)
|
240
|
+
activerecord (>= 5.2.4)
|
241
|
+
activesupport (>= 5.2.4)
|
242
|
+
i18n
|
238
243
|
rb-fsevent (0.10.4)
|
239
244
|
rb-inotify (0.10.1)
|
240
245
|
ffi (~> 1.0)
|
@@ -390,6 +395,7 @@ DEPENDENCIES
|
|
390
395
|
pundit
|
391
396
|
rails (~> 6.0.2, >= 6.0.2.2)
|
392
397
|
rails-controller-testing
|
398
|
+
ransack
|
393
399
|
rspec-rails (~> 4.0.0)
|
394
400
|
ruby-debug-ide
|
395
401
|
sass-rails (>= 6)
|
data/README.md
CHANGED
@@ -29,13 +29,13 @@ Avo is a beautiful next-generation framework that empowers you, the developer, t
|
|
29
29
|
- **Actions** - Run custom actions to one or more of your resources with as little as pressing a button 💪
|
30
30
|
- **Filters** - Write your own custom filters to quickly segment your data.
|
31
31
|
- **Keeps your app clean** - You don't need to change your app to use Avo. Drop it in your existing app or add it to a new one and you're done 🙌
|
32
|
-
- **Custom fields
|
33
|
-
- **Dashboard widgets and metrics*** - Customize your dashboard with the tools and analytics you need.
|
32
|
+
- **Custom fields**- No worries if we missed a field you need. Generate a custom field in a jiffy.
|
34
33
|
- **Custom tools** - You need to add a page with something completely new, you've got it!
|
35
34
|
- **Authorization** - Leverage Pundit policies to build a robust and scalable authorization system.
|
36
|
-
- **
|
37
|
-
- **Localization*** - Have it available in any language you need.
|
35
|
+
- **Localization** - Have it available in any language you need.
|
38
36
|
- **No asset pipeline pollution** - Bring your own asset pipeline.
|
37
|
+
- **Dashboard widgets and metrics*** - Customize your dashboard with the tools and analytics you need.
|
38
|
+
- **Themable*** - Dress it up into your own colors.
|
39
39
|
|
40
40
|
*Features still under development
|
41
41
|
|
@@ -22,12 +22,12 @@
|
|
22
22
|
<% end %>
|
23
23
|
|
24
24
|
<% c.body do %>
|
25
|
-
<div class="flex justify-between
|
25
|
+
<div class="flex justify-between pt-2 pb-2 min-h-16"
|
26
26
|
data-selected-resources-name="<%= @resource.plural_name.downcase %>"
|
27
27
|
data-selected-resources="[]"
|
28
28
|
>
|
29
29
|
<div class="flex items-center px-6 w-64">
|
30
|
-
|
30
|
+
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key} if @resource.search_query.present? %>
|
31
31
|
</div>
|
32
32
|
<div class="flex justify-end items-center px-6 space-x-3">
|
33
33
|
<%= render partial: 'avo/partials/view_toggle_button', locals: { available_view_types: available_view_types, view_type: view_type, turbo_frame: @turbo_frame } if @models.present? %>
|
@@ -36,7 +36,7 @@
|
|
36
36
|
</div>
|
37
37
|
|
38
38
|
<% if view_type.to_sym == :table %>
|
39
|
-
<div class="w-full overflow-auto flex flex-col">
|
39
|
+
<div class="w-full overflow-auto flex flex-col mt-4">
|
40
40
|
<div class="relative flex-1 flex">
|
41
41
|
<%= render(Avo::Index::ResourceTableComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model)) %>
|
42
42
|
</div>
|
@@ -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
|
20
|
+
Avo::App.init request: request, context: context, current_user: _current_user
|
21
21
|
|
22
22
|
@license = Avo::App.license
|
23
23
|
end
|
@@ -38,18 +38,25 @@ module Avo
|
|
38
38
|
def render(*args)
|
39
39
|
raise Avo::LicenseVerificationTemperedError, "License verification mechanism tempered with." unless method(:check_avo_license).source_location.first.match?(/.*\/app\/controllers\/avo\/application_controller\.rb/)
|
40
40
|
|
41
|
+
if params[:controller] == "avo/search" && params[:action] == "index"
|
42
|
+
raise Avo::LicenseVerificationTemperedError, "License verification mechanism tempered with." unless method(:index).source_location.first.match?(/.*\/app\/controllers\/avo\/search_controller\.rb/)
|
43
|
+
end
|
44
|
+
|
41
45
|
super(*args)
|
42
46
|
end
|
43
47
|
|
44
48
|
def check_avo_license
|
49
|
+
# Check to see if the path is on a custom tool
|
45
50
|
unless on_root_path || on_resources_path || on_api_path
|
46
|
-
if
|
47
|
-
|
51
|
+
# Display alert on custom tool page if in development.
|
52
|
+
if @license.lacks(:custom_tools) || @license.invalid?
|
53
|
+
if Rails.env.development? || Rails.env.test?
|
48
54
|
@custom_tools_alert_visible = true
|
49
|
-
else
|
50
|
-
raise Avo::LicenseInvalidError, "Your license is invalid or doesn't support custom tools."
|
51
55
|
end
|
52
56
|
end
|
57
|
+
|
58
|
+
# Raise error in non-development environments.
|
59
|
+
raise Avo::LicenseInvalidError, "Your license is invalid or doesn't support custom tools." if @license.lacks_with_trial(:custom_tools)
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
@@ -157,9 +164,9 @@ module Avo
|
|
157
164
|
|
158
165
|
def authorize_action
|
159
166
|
if @model.present?
|
160
|
-
@authorization.set_record(@model).authorize_action
|
167
|
+
@authorization.set_record(@model).authorize_action action_name.to_sym
|
161
168
|
else
|
162
|
-
@authorization.set_record(@resource.model_class).authorize_action
|
169
|
+
@authorization.set_record(@resource.model_class).authorize_action action_name.to_sym
|
163
170
|
end
|
164
171
|
end
|
165
172
|
|
@@ -17,7 +17,7 @@ module Avo
|
|
17
17
|
@resource = @related_resource
|
18
18
|
@parent_model = @parent_resource.model_class.find(params[:id])
|
19
19
|
@parent_resource.hydrate(model: @parent_model)
|
20
|
-
@query = @parent_model.public_send(params[:related_name])
|
20
|
+
@query = @authorization.apply_policy @parent_model.public_send(params[:related_name])
|
21
21
|
|
22
22
|
super
|
23
23
|
end
|
@@ -2,56 +2,71 @@ require_dependency "avo/application_controller"
|
|
2
2
|
|
3
3
|
module Avo
|
4
4
|
class SearchController < ApplicationController
|
5
|
-
|
5
|
+
before_action :set_resource_name, only: [:show]
|
6
|
+
before_action :set_resource, only: [:show]
|
6
7
|
|
7
8
|
def index
|
8
|
-
|
9
|
-
resources = []
|
10
|
-
|
11
|
-
App.resources
|
12
|
-
.select { |resource| resource.search.present? }
|
13
|
-
.select { |resource| AuthorizationService.authorize_action _current_user, resource.model, "index" }
|
14
|
-
.each do |resource_model|
|
15
|
-
found_resources = add_link_to_search_results(search_resource(resource_model), resource_model)
|
16
|
-
resources.push({
|
17
|
-
label: resource_model.name,
|
18
|
-
resources: found_resources
|
19
|
-
})
|
20
|
-
end
|
9
|
+
raise ActionController::BadRequest.new("This feature requires the pro license https://avohq.io/purchase/pro") if App.license.lacks_with_trial(:global_search)
|
21
10
|
|
22
|
-
render json:
|
23
|
-
resources: resources
|
24
|
-
}
|
11
|
+
render json: search_resources(Avo::App.resources)
|
25
12
|
end
|
26
13
|
|
27
|
-
def
|
28
|
-
render json:
|
29
|
-
resources: add_link_to_search_results(search_resource(avo_resource), avo_resource)
|
30
|
-
}
|
14
|
+
def show
|
15
|
+
render json: search_resources([resource])
|
31
16
|
end
|
32
17
|
|
33
18
|
private
|
34
19
|
|
35
|
-
def
|
36
|
-
resources.map do |
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
20
|
+
def search_resources(resources)
|
21
|
+
resources.map do |resource|
|
22
|
+
# Apply authorization
|
23
|
+
next unless @authorization.set_record(resource.model_class).authorize_action(:index, raise_exception: false)
|
24
|
+
# Filter out the models without a search_query
|
25
|
+
next if resource.search_query.nil?
|
26
|
+
|
27
|
+
search_resource resource
|
42
28
|
end
|
29
|
+
.select do |payload|
|
30
|
+
payload.present?
|
31
|
+
end
|
32
|
+
.sort do |payload|
|
33
|
+
payload.last[:count]
|
34
|
+
end
|
35
|
+
.reverse
|
36
|
+
.to_h
|
43
37
|
end
|
44
38
|
|
45
|
-
def search_resource(
|
46
|
-
|
39
|
+
def search_resource(resource)
|
40
|
+
results = apply_search_metadata(resource.search_query.call(params: params).limit(8), resource)
|
41
|
+
|
42
|
+
result_object = {
|
43
|
+
header: resource.name.pluralize,
|
44
|
+
results: results,
|
45
|
+
count: results.length
|
46
|
+
}
|
47
|
+
|
48
|
+
[resource.name.pluralize.downcase, result_object]
|
47
49
|
end
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
+
def apply_search_metadata(models, avo_resource)
|
52
|
+
models.map do |model|
|
53
|
+
resource = avo_resource.dup.hydrate(model: model).hydrate_fields(model: model)
|
51
54
|
|
52
|
-
|
55
|
+
result = {
|
56
|
+
_id: model.id,
|
57
|
+
_label: resource.label,
|
58
|
+
_url: resource.avo_path,
|
59
|
+
model: model
|
60
|
+
}
|
53
61
|
|
54
|
-
|
55
|
-
|
62
|
+
if App.license.has_with_trial(:enhanced_search_results)
|
63
|
+
result[:_description] = resource.description
|
64
|
+
result[:_avatar] = resource.avatar
|
65
|
+
result[:_avatar_type] = resource.avatar_type
|
66
|
+
end
|
67
|
+
|
68
|
+
result
|
69
|
+
end
|
70
|
+
end
|
56
71
|
end
|
57
72
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
@import './../../../node_modules/tippy.js/themes/light.css';
|
5
5
|
@import './../../../node_modules/trix/dist/trix.css';
|
6
6
|
@import './../../../node_modules/flatpickr/dist/flatpickr.css';
|
7
|
-
|
7
|
+
@import './../../../node_modules/@algolia/autocomplete-theme-classic/dist/theme.css';
|
8
8
|
|
9
9
|
@import './../stylesheets/tailwindcss/base.css';
|
10
10
|
|
@@ -15,6 +15,7 @@
|
|
15
15
|
@import './../stylesheets/loader.css';
|
16
16
|
@import './../stylesheets/pagination.css';
|
17
17
|
@import './../stylesheets/breadcrumbs.css';
|
18
|
+
@import './../stylesheets/search.css';
|
18
19
|
|
19
20
|
@import './../stylesheets/components/status.css';
|
20
21
|
@import './../stylesheets/components/code.css';
|
@@ -45,6 +45,9 @@ document.addEventListener('turbo:load', () => {
|
|
45
45
|
})
|
46
46
|
document.addEventListener('turbo:visit', () => document.body.classList.add('turbo-loading'))
|
47
47
|
document.addEventListener('turbo:submit-start', () => document.body.classList.add('turbo-loading'))
|
48
|
+
document.addEventListener('turbo:before-cache', () => {
|
49
|
+
document.querySelectorAll('[data-turbo-remove-before-cache]').forEach((element) => element.remove())
|
50
|
+
})
|
48
51
|
|
49
52
|
// Uncomment to copy all static images under ../images to the output folder and reference
|
50
53
|
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
2
|
+
import * as Mousetrap from 'mousetrap'
|
3
|
+
import { Controller } from 'stimulus'
|
4
|
+
import { Turbo } from '@hotwired/turbo-rails'
|
5
|
+
import { autocomplete } from '@algolia/autocomplete-js'
|
6
|
+
import debouncePromise from '@/js/helpers/debounce_promise'
|
7
|
+
|
8
|
+
export default class extends Controller {
|
9
|
+
static targets = ['autocomplete', 'button']
|
10
|
+
|
11
|
+
debouncedFetch = debouncePromise(fetch, this.debounceTimeout)
|
12
|
+
|
13
|
+
get translationKeys() {
|
14
|
+
let keys
|
15
|
+
try {
|
16
|
+
keys = JSON.parse(this.autocompleteTarget.dataset.translationKeys)
|
17
|
+
} catch (error) {
|
18
|
+
keys = {}
|
19
|
+
}
|
20
|
+
|
21
|
+
return keys
|
22
|
+
}
|
23
|
+
|
24
|
+
get debounceTimeout() {
|
25
|
+
return this.autocompleteTarget.dataset.debounceTimeout
|
26
|
+
}
|
27
|
+
|
28
|
+
get searchResource() {
|
29
|
+
return this.autocompleteTarget.dataset.searchResource
|
30
|
+
}
|
31
|
+
|
32
|
+
get isGlobalSearch() {
|
33
|
+
return this.searchResource === 'global'
|
34
|
+
}
|
35
|
+
|
36
|
+
get searchUrl() {
|
37
|
+
return this.isGlobalSearch ? '/avo/avo_api/search' : `/avo/avo_api/${this.searchResource}/search`
|
38
|
+
}
|
39
|
+
|
40
|
+
addSource(resourceName, data) {
|
41
|
+
const that = this
|
42
|
+
|
43
|
+
return {
|
44
|
+
sourceId: resourceName,
|
45
|
+
getItems: () => data.results,
|
46
|
+
onSelect({ item }) {
|
47
|
+
Turbo.visit(item._url, { action: 'replace' })
|
48
|
+
},
|
49
|
+
templates: {
|
50
|
+
header() {
|
51
|
+
return data.header
|
52
|
+
},
|
53
|
+
item({ item, createElement }) {
|
54
|
+
let element = ''
|
55
|
+
|
56
|
+
if (item._avatar) {
|
57
|
+
let classes
|
58
|
+
|
59
|
+
switch (item._avatar_type) {
|
60
|
+
default:
|
61
|
+
case 'circle':
|
62
|
+
classes = 'rounded-full'
|
63
|
+
break
|
64
|
+
case 'rounded':
|
65
|
+
classes = 'rounded'
|
66
|
+
break
|
67
|
+
}
|
68
|
+
|
69
|
+
element += `<img src="${item._avatar}" alt="${item._label}" class="flex-shrink-0 w-8 h-8 my-[2px] inline mr-2 ${classes}" />`
|
70
|
+
}
|
71
|
+
element += `<div>${item._label}`
|
72
|
+
|
73
|
+
if (item._description) {
|
74
|
+
element += `<div class="aa-ItemDescription">${item._description}</div>`
|
75
|
+
}
|
76
|
+
|
77
|
+
element += '</div>'
|
78
|
+
|
79
|
+
return createElement('div', {
|
80
|
+
class: 'flex',
|
81
|
+
dangerouslySetInnerHTML: {
|
82
|
+
__html: element,
|
83
|
+
},
|
84
|
+
})
|
85
|
+
},
|
86
|
+
noResults() {
|
87
|
+
return that.translationKeys.no_item_found.replace('%{item}', resourceName)
|
88
|
+
},
|
89
|
+
},
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
showSearchPanel() {
|
94
|
+
this.autocompleteTarget.querySelector('button').click()
|
95
|
+
}
|
96
|
+
|
97
|
+
connect() {
|
98
|
+
const that = this
|
99
|
+
|
100
|
+
this.buttonTarget.onclick = () => this.showSearchPanel()
|
101
|
+
|
102
|
+
if (this.isGlobalSearch) {
|
103
|
+
Mousetrap.bind(['command+k', 'ctrl+k'], () => this.showSearchPanel())
|
104
|
+
}
|
105
|
+
|
106
|
+
autocomplete({
|
107
|
+
container: this.autocompleteTarget,
|
108
|
+
placeholder: 'Search',
|
109
|
+
openOnFocus: true,
|
110
|
+
detachedMediaQuery: '',
|
111
|
+
getSources: ({ query }) => {
|
112
|
+
const endpoint = `${that.searchUrl}?q=${query}`
|
113
|
+
|
114
|
+
return that.debouncedFetch(endpoint)
|
115
|
+
.then((response) => response.json())
|
116
|
+
.then((data) => Object.keys(data).map((resourceName) => that.addSource(resourceName, data[resourceName])))
|
117
|
+
},
|
118
|
+
})
|
119
|
+
}
|
120
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
:root {
|
2
|
+
--aa-primary-color: --tw-ring-color;
|
3
|
+
--aa-selected-color: --tw-ring-color;
|
4
|
+
--aa-primary-color-rgb: 5, 150, 105;
|
5
|
+
}
|
6
|
+
|
7
|
+
.global-search {
|
8
|
+
.aa-DetachedSearchButton:focus,
|
9
|
+
.aa-DetachedSearchButton {
|
10
|
+
border: none !important;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
.resource-search {
|
15
|
+
.aa-Autocomplete {
|
16
|
+
@apply w-full;
|
17
|
+
}
|
18
|
+
|
19
|
+
.aa-DetachedSearchButton {
|
20
|
+
@apply rounded-full border-gray-300;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
.aa-SourceHeader {
|
25
|
+
@apply uppercase text-xs font-semibold;
|
26
|
+
}
|
27
|
+
|
28
|
+
.aa-DetachedFormContainer,
|
29
|
+
.aa-DetachedContainer .aa-Panel {
|
30
|
+
@apply bg-blue-gray-100 border-b-0;
|
31
|
+
}
|
32
|
+
|
33
|
+
.aa-Form {
|
34
|
+
&:focus-within {
|
35
|
+
@apply ring-0 !important;
|
36
|
+
}
|
37
|
+
|
38
|
+
input {
|
39
|
+
@apply focus:ring-0 !important;
|
40
|
+
}
|
41
|
+
&:focus-within {
|
42
|
+
.aa-InputWrapperPrefix{
|
43
|
+
.aa-SubmitButton {
|
44
|
+
@apply ring-0;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
.aa-Input {
|
50
|
+
@apply focus:ring-green-600;
|
51
|
+
}
|
52
|
+
|
53
|
+
.aa-DetachedContainer {
|
54
|
+
.aa-PanelLayout {
|
55
|
+
@apply pt-0 space-y-3;
|
56
|
+
}
|
57
|
+
|
58
|
+
.aa-Source {
|
59
|
+
.aa-List {
|
60
|
+
@apply space-y-1;
|
61
|
+
|
62
|
+
.aa-Item {
|
63
|
+
@apply bg-white rounded-md px-3 py-4 shadow;
|
64
|
+
|
65
|
+
.aa-ItemDescription {
|
66
|
+
@apply text-gray-500 text-sm;
|
67
|
+
}
|
68
|
+
|
69
|
+
&[aria-selected=true]{
|
70
|
+
@apply bg-blue-700 text-white;
|
71
|
+
|
72
|
+
.aa-ItemDescription {
|
73
|
+
@apply text-white;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|