Skip to content

Commit

Permalink
Merge pull request #80 from avo-hq/updates
Browse files Browse the repository at this point in the history
Updates
  • Loading branch information
Paul-Bob authored Aug 7, 2023
2 parents b8f6066 + 803c741 commit 0c54f25
Show file tree
Hide file tree
Showing 13 changed files with 304 additions and 257 deletions.
46 changes: 23 additions & 23 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ const config = {
{text: "Fields", link: "/3.0/fields"},
{text: "Field options", link: "/3.0/field-options"},
{text: "Controller configuration", link: "/3.0/controllers"},
{text: "Record previews", link: "/3.0/records-previews"},
{text: "Record previews", link: "/3.0/record-previews"},
{text: "Scopes", link: "/3.0/scopes"},
// {text: "Records reordering", link: "/3.0/records-reordering"},
// {text: "Tabs and panels", link: "/3.0/tabs"},
// {text: "Resource sidebar", link: "/3.0/resource-sidebar"},
{text: "Records reordering", link: "/3.0/records-reordering"},
{text: "Tabs and panels", link: "/3.0/tabs"},
{text: "Resource sidebar", link: "/3.0/resource-sidebar"},
{text: "Customizable controls", link: "/3.0/customizable-controls"},
],
},
Expand All @@ -135,25 +135,25 @@ const config = {
collapsed: true,
items: fieldsMenuItems3,
},
// {
// text: "Associations",
// collapsible: true,
// collapsed: true,
// items: [
// {text: "Customization", link: "/3.0/associations"},
// {text: 'Belongs to', link: '/3.0/associations/belongs_to.md'},
// {text: 'Has one', link: '/3.0/associations/has_one.md'},
// {text: 'Has many', link: '/3.0/associations/has_many.md'},
// {text: 'Has and belongs to many', link: '/3.0/associations/has_and_belongs_to_many.md'},
// ],
// },
// {
// text: "Dashboards and cards",
// items: [
// {text: "Dashboards", link: "/3.0/dashboards"},
// {text: "Cards", link: "/3.0/cards"},
// ],
// },
{
text: "Associations",
collapsible: true,
collapsed: true,
items: [
{text: "Customization", link: "/3.0/associations"},
{text: 'Belongs to', link: '/3.0/associations/belongs_to.md'},
{text: 'Has one', link: '/3.0/associations/has_one.md'},
{text: 'Has many', link: '/3.0/associations/has_many.md'},
{text: 'Has and belongs to many', link: '/3.0/associations/has_and_belongs_to_many.md'},
],
},
{
text: "Dashboards and cards",
items: [
{text: "Dashboards", link: "/3.0/dashboards"},
{text: "Cards", link: "/3.0/cards"},
],
},
{
text: "Customize Avo",
items: [
Expand Down
132 changes: 74 additions & 58 deletions docs/3.0/associations/belongs_to.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,44 +78,48 @@ On the `Edit` and `New` views, Avo will generate a dropdown element with the ava

To use a polymorphic relation, you must add the `polymorphic_as` and `types` properties.

```ruby{12}
class CommentResource < Avo::BaseResource
```ruby{13}
class Avo::Resources::Comment < Avo::BaseResource
self.title = :id
field :id, as: :id
field :body, as: :textarea
field :excerpt, as: :text, show_on: :index do
ActionView::Base.full_sanitizer.sanitize(record.body).truncate 60
rescue
""
end
def fields
field :id, as: :id
field :body, as: :textarea
field :excerpt, as: :text, show_on: :index do
ActionView::Base.full_sanitizer.sanitize(record.body).truncate 60
rescue
""
end
field :commentable, as: :belongs_to, polymorphic_as: :commentable, types: [::Post, ::Project]
field :commentable, as: :belongs_to, polymorphic_as: :commentable, types: [::Post, ::Project]
end
end
```

## Polymorphic help

When displaying a polymorphic association, you will see two dropdowns. One selects the polymorphic type (`Post` or `Project`), and one for choosing the actual record. You may want to give the user explicit information about those dropdowns using the `polymorphic_help` option for the first dropdown and `help` for the second.

```ruby{16-17}
class CommentResource < Avo::BaseResource
```ruby{17-18}
class Avo::Resources::Comment < Avo::BaseResource
self.title = :id
field :id, as: :id
field :body, as: :textarea
field :excerpt, as: :text, show_on: :index do
ActionView::Base.full_sanitizer.sanitize(record.body).truncate 60
rescue
""
def fields
field :id, as: :id
field :body, as: :textarea
field :excerpt, as: :text, show_on: :index do
ActionView::Base.full_sanitizer.sanitize(record.body).truncate 60
rescue
""
end
field :reviewable,
as: :belongs_to,
polymorphic_as: :reviewable,
types: [::Post, ::Project, ::Team],
polymorphic_help: "Choose the type of record to review",
help: "Choose the record you need."
end
field :reviewable,
as: :belongs_to,
polymorphic_as: :reviewable,
types: [::Post, ::Project, ::Team],
polymorphic_help: "Choose the type of record to review",
help: "Choose the record you need."
end
```

Expand All @@ -127,14 +131,16 @@ end

There might be the case that you have a lot of records for the parent resource, and a simple dropdown won't cut it. This is where you can use the `searchable` option to get a better search experience for that resource.

```ruby{7}
class CommentResource < Avo::BaseResource
```ruby{8}
class Avo::Resources::Comment < Avo::BaseResource
self.title = :id
field :id, as: :id
field :body, as: :textarea
def fields
field :id, as: :id
field :body, as: :textarea
field :user, as: :belongs_to, searchable: true
field :user, as: :belongs_to, searchable: true
end
end
```

Expand All @@ -143,35 +149,41 @@ end

`searchable` works with `polymorphic` `belongs_to` associations too.

```ruby{7}
class CommentResource < Avo::BaseResource
```ruby{8}
class Avo::Resources::Comment < Avo::BaseResource
self.title = :id
field :id, as: :id
field :body, as: :textarea
def fields
field :id, as: :id
field :body, as: :textarea
field :commentable, as: :belongs_to, polymorphic_as: :commentable, types: [::Post, ::Project], searchable: true
field :commentable, as: :belongs_to, polymorphic_as: :commentable, types: [::Post, ::Project], searchable: true
end
end
```

:::info
Avo uses the [search feature](./../search) behind the scenes, so **make sure the target resource has the `search_query` option configured**.
Avo uses the [search feature](./../search) behind the scenes, so **make sure the target resource has the `query` option configured inside the `search` block**.
:::


```ruby
# app/avo/resources/post_resource.rb
class PostResource < Avo::BaseResource
self.search_query = -> do
query.ransack(id_eq: params[:q], name_cont: params[:q], body_cont: params[:q], m: "or").result(distinct: false)
end
# app/avo/resources/post.rb
class Avo::Resources::Post < Avo::BaseResource
self.search = {
query: -> {
query.ransack(id_eq: params[:q], name_cont: params[:q], body_cont: params[:q], m: "or").result(distinct: false)
}
}
end

# app/avo/resources/project_resource.rb
class ProjectResource < Avo::BaseResource
self.search_query = -> do
query.ransack(id_eq: params[:q], name_cont: params[:q], country_cont: params[:q], m: "or").result(distinct: false)
end
# app/avo/resources/project.rb
class Avo::Resources::Project < Avo::BaseResource
self.search = {
query: -> {
query.ransack(id_eq: params[:q], name_cont: params[:q], country_cont: params[:q], m: "or").result(distinct: false)
}
}
end
```

Expand All @@ -193,9 +205,11 @@ class User < ApplicationRecord
scope :non_admins, -> { where "(roles->>'admin')::boolean != true" }
end

# app/avo/resources/post_resource.rb
class PostResource < Avo::BaseResource
field :user, as: :belongs_to, attach_scope: -> { query.non_admins }
# app/avo/resources/post.rb
class Avo::Resources::Post < Avo::BaseResource
def fields
field :user, as: :belongs_to, attach_scope: -> { query.non_admins }
end
end
```

Expand All @@ -207,17 +221,19 @@ When you visit a record through an association, that `belongs_to` field is disab

You can instruct Avo to keep that field enabled in this scenario using `allow_via_detaching`.

```ruby{11}
class CommentResource < Avo::BaseResource
```ruby{12}
class Avo::Resources::Comment < Avo::BaseResource
self.title = :id
field :id, as: :id
field :body, as: :textarea
def fields
field :id, as: :id
field :body, as: :textarea
field :commentable,
as: :belongs_to,
polymorphic_as: :commentable,
types: [::Post, ::Project],
allow_via_detaching: true
field :commentable,
as: :belongs_to,
polymorphic_as: :commentable,
types: [::Post, ::Project],
allow_via_detaching: true
end
end
```
18 changes: 9 additions & 9 deletions docs/3.0/cards.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ All cards have some standard settings like `id`, which must be unique, `label` a
Each card has its own `cols` and `rows` settings to control the width and height of the card inside the dashboard grid. They can have values from `1` to `6`.

```ruby{2-7}
class UsersMetric < Avo::Dashboards::MetricCard
class Avo::Cards::UsersMetric < Avo::Dashboards::MetricCard
self.id = 'users_metric'
self.label = 'Users count'
self.description = 'Users description'
Expand All @@ -38,7 +38,7 @@ You can also set a default range using the `initial_range` attribute.
The ranges have been changed a bit since **version 2.8**. The parameter you pass to the `range` option will be directly passed to the [`options_for_select`](https://apidock.com/rails/v5.2.3/ActionView/Helpers/FormOptionsHelper/options_for_select) helper, so it behaves more like a regular `select_tag`.

```ruby{4-15}
class UsersMetric < Avo::Dashboards::MetricCard
class Avo::Cards::UsersMetric < Avo::Dashboards::MetricCard
self.id = 'users_metric'
self.label = 'Users count'
self.initial_range = 30
Expand All @@ -61,7 +61,7 @@ end
If this dashboard is something that you keep on the big screen, you need to keep the data fresh at all times. That's easy using `refresh_every`. You pass the number of seconds you need to be refreshed and forget about it. Avo will do it for you.

```ruby{3}
class UsersMetric < Avo::Dashboards::MetricCard
class Avo::Cards::UsersMetric < Avo::Dashboards::MetricCard
self.id = 'users_metric'
self.refresh_every = 10.minutes
end
Expand All @@ -72,7 +72,7 @@ end
In cases where you need to embed some content that should fill the whole card (like a map, for example), you can choose to hide the label and ranges dropdown.

```ruby{3}
class UsersMetric < Avo::Dashboards::MetricCard
class Avo::Cards::UsersMetric < Avo::Dashboards::MetricCard
self.id = 'users_metric'
self.display_header = false
end
Expand All @@ -92,7 +92,7 @@ To calculate your result, you may use the `query` method. After you make the que
In the `query` method you have access to a few variables like `context` (the [App context](./customization#context)), `params` (the request params), `range` (the range that was requested), `dashboard` (the current dashboard the card is on), and current `card`.

```ruby{23-47,36}
class UsersMetric < Avo::Dashboards::MetricCard
class Avo::Cards::UsersMetric < Avo::Dashboards::MetricCard
self.id = 'users_metric'
self.label = 'Users count'
self.description = 'Some tiny description'
Expand Down Expand Up @@ -147,7 +147,7 @@ end
Some metrics might want to add a `prefix` or a `suffix` to display the data better.

```ruby{3,4}
class UsersMetric < Avo::Dashboards::MetricCard
class Avo::Cards::UsersMetric < Avo::Dashboards::MetricCard
self.id = 'users_metric'
self.prefix = '$'
self.suffix = '%'
Expand All @@ -163,7 +163,7 @@ A picture is worth a thousand words. So maybe a chart a hundred? Who knows? But
You start by running `bin/rails g avo:card users_chart --type chartkick`.

```ruby
class UserSignups < Avo::Dashboards::ChartkickCard
class Avo::Cards::UserSignups < Avo::Dashboards::ChartkickCard
self.id = 'user_signups'
self.label = 'User signups'
self.chart_type = :area_chart
Expand Down Expand Up @@ -223,7 +223,7 @@ If you'd like to use [Groupdate](https://github.com/ankane/groupdate), [Hightop]
You can use a partial card to add custom content to a card. Generate one by running `bin/rails g avo:card custom_card --type partial`. That will create the card class and the partial for it.

```ruby{5}
class ExampleCustomPartial < Avo::Dashboards::PartialCard
class Avo::Cards::ExampleCustomPartial < Avo::Dashboards::PartialCard
self.id = "users_custom_card"
self.cols = 1
self.rows = 4
Expand All @@ -237,7 +237,7 @@ You can embed a piece of content from another app using an iframe. You can hide

```ruby{5}
# app/avo/cards/map_card.rb
class MapCard < Avo::Dashboards::PartialCard
class Avo::Cards::MapCard < Avo::Dashboards::PartialCard
self.id = "map_card"
self.label = "Map card"
self.partial = "avo/cards/map_card"
Expand Down
26 changes: 15 additions & 11 deletions docs/3.0/common/associations_searchable_option_common.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,28 @@

Turns the attach field/modal from a `select` input to a searchable experience

```ruby{4}
class CourseLink < Avo::BaseResource
field :links,
as: :has_many,
searchable: true
```ruby{5}
class Avo::Resources::CourseLink < Avo::BaseResource
def fields
field :links,
as: :has_many,
searchable: true
end
end
```

:::warning
Avo uses the **search feature** behind the scenes, so **make sure the target resource has the [`search_query`](./../search) option configured**.
:::

```ruby{3-5}
# app/avo/resources/course_link_resource.rb
class CourseLinkResource < Avo::BaseResource
self.search_query = -> do
query.ransack(id_eq: params[:q], link_cont: params[:q], m: "or").result(distinct: false)
end
```ruby{3-7}
# app/avo/resources/course_link.rb
class Avo::Resources::CourseLink < Avo::BaseResource
self.search = {
query: -> {
query.ransack(id_eq: params[:q], link_cont: params[:q], m: "or").result(distinct: false)
}
}
end
```

Expand Down
2 changes: 1 addition & 1 deletion docs/3.0/common/associations_use_resource_option_common.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ Sets a different resource to be used when displaying (or redirecting to) the ass

#### Possible values

`PostResource`, `PhotoCommentResource`, or any Avo resource class.
`Avo::Resources::Post`, `Avo::Resources::PhotoComment`, or any Avo resource class.
:::
Loading

0 comments on commit 0c54f25

Please sign in to comment.