Giter Club home page Giter Club logo

avo's Introduction

Gem Version Tests reviewdog codecov Maintainability Open Source Helpers

Ruby on Rails application building framework.

Avo is a beautiful next-generation framework that empowers you, the developer, to create fantastic admin panels for your Ruby on Rails apps with the flexibility to fit your needs as you grow.

Get started

⚡️ Install: docs.avohq.io/3.0/installation
Website: avohq.io
📚 Documentation: docs.avohq.io
🗺 Roadmap: GitHub Roadmap
🎸 Demo app: Avodemo
🐤 Twitter: avo_hq
💬 Community chat: discord
🔧 Issue tracker: GitHub issues
🎙 Discussions and feature requests: GitHub issues

Features

  • Powered by Hotwire - Rails ❤️ Hotwire
  • Code driven configuration - Configure your Rails dashboard entirely by writing Ruby code. docs
  • Resource Management - Create a CRUD interface for Active Record from one command. No more copy-pasting view and controller files around.
  • Dashboard widgets and metrics - Create metrics, charts, and custom cards amazingly fast. docs
  • Resource Search - Quickly run a search through one or more resources at once. docs
  • Associations enabled - Link your models together with all types of associations (belongs_to, has_many, polymorphic, etc.). docs
  • Fuzzy-searchable associations - Do you have a ton of records and don't want to scroll through a big dropdown? Avo's got you covered. docs
  • Active Storage support - Amazingly easy, one-line, single or multi-file integration with ActiveStorage. docs
  • Records Ordering - Sorting records is a breeze. docs
  • Grid view - Beautiful card layout to showcase your content. docs
  • Actions - Run custom actions to one or more of your resources with as little as pressing a button 💪   docs
  • Filters - Write your own custom filters to quickly segment your data. docs
  • 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 🙌 docs
  • Custom fields- No worries if we missed a field you need. Generate a custom field in a jiffy. docs
  • Custom tools - Break out of the CRUD. Do you need to add a page with something completely new? You've got it! docs
  • Authorization - Leverage Pundit policies to build a robust and scalable authorization system. docs
  • Localization - Have it available in any language you need. docs
  • No asset pipeline pollution - Bring your own asset pipeline. docs
  • Mobile interface - Check your data on the go from any mobile device.
  • Tabbed interface - Conditionally show the data you need
  • Menu builder - Group and surface information as you need to
  • Branding - Make it look

Some of the things we're going to focus on next

Theming ⭐️  notifications ⭐️  Resource segmentation ⭐️  filterable fields ⭐️  inline editing ⭐️  multilingual records ⭐️  keyboard shortcuts ⭐️  track resource changes ⭐️  smart resource generation ⭐️  live resources ⭐️  columns view ⭐️  list view ⭐️  custom action items ⭐️  command bar ⭐️   use fields DSL in your custom views

For more up-to-date info check out our 🗺 Roadmap.

Installation

Use this RailsBytes template to get started quick rails app:template LOCATION='https://avohq.io/app-template'. If you need a more detailed guide, follow this page.

Contributing

Please read CONTRIBUTING.MD

Upgrade Guide

Please read the UPGRADE_GUIDE.MD

Release schedule

Please read the RELEASE.MD

🥇 Sponsors

Greenhats Start-up Sponsor

Become a sponsor

Alt

Shoutouts

Get a box of waffles and some of the best app monitoring from Appsignal 🧇

Get $100 in credits from Digital Ocean 💸

avo's People

Contributors

adrianthedev avatar bear-in-mind avatar bryszard avatar calebuharrison avatar dependabot[bot] avatar depfu[bot] avatar dhnaranjo avatar elassadi avatar fastjames avatar gabrielgiroe1 avatar iainbeeston avatar jeremasposta avatar krystof-k avatar marcelobarreto avatar marianddev avatar mihaimdm22 avatar mrjoy avatar nicolascochin avatar nkriege avatar paul-bob avatar pedroaugustoramalhoduarte avatar rickychilcott avatar rockhalil avatar sarvaiyanidhi avatar sedubois avatar shiroemons avatar stevegeek avatar tersor avatar veelenga avatar yorch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

avo's Issues

Rails scopes as filters

At the moment Avo supports custom filters that are separate classes. That might get tedious at some point.
Rails already has scopes. We might be able to implement filters really quick as one-liners inside the Resource class without building that whole clunky-at-times Filter class.
The Filter class can still be present in the app for more complex filters that can't be configured from one scope.

Some inspiration here:

https://www.graphiti.dev/guides/concepts/resources

[Feature request] Allow custom view component directory

From #414

The custom field generator generates several view components that are used to render the field. It would be nice if the generator could make use of a configuration option that allows the directory of these generated components to change. Currently, it places the components in app/components, but in my apps, I put components in different directories, such as app/view_components or app/frontend/components.

Refresh all tests

Refresh previous Vue tests

  • fields
  • relations
  • filters
  • actions
  • components

Hotwire rewrite

We're rewriting Avo with Hotwire. This should make it a lot easier to update & extend.

To do

Fields

  • Trix field
  • KeyValue field
  • DateTime field
  • Currency field
  • Country field
  • Boolean field
  • BooleanGroup field
  • Hidden field

Misc

  • Refresh all tests (fields, relations, actions & filters)

Wrong inheritance

Hi,

The Avo::ApplicationMailer should inherits ::ActionMailer::Base (missing the ::)

class ApplicationMailer < ActionMailer::Base

This is failing some tools such as erd (https://github.com/voormedia/rails-erd) as the Avo::ApplicationMailer can't be loaded

irb(main):004:0> Avo::ApplicationMailer
Traceback (most recent call last):
        2: from (irb):3
        1: from (irb):4:in `rescue in irb_binding'
NameError (uninitialized constant Avo::ActionMailer)
Did you mean?  ActionView

Regards,

Nicolas

Custom fields

Add the ability for devs to add their own custom fields to Avo

[BUG] Array enums not displaying properly

Describe the bug

When using array enums Avo won't display them properly

Steps to Reproduce

Steps to reproduce the behavior:

  1. Add an Array enum enum status: [:draft, :published, :archived]
  2. Add a select field feeding off of that enum field :status, as: :select, enum: ::Product.statuses
  3. Update a record on that field.
  4. Check that the field to see the empty dash

Expected behavior

See the enum

Actual behavior

See the empty dash

System configuration

Avo version: 1.1.0

Screenshots

image
image

[BUG] After you click cancel on the has many attach modal you cannot interact with that button again

Describe the bug

It's related to hotwired/turbo#249.

Steps to Reproduce

Steps to reproduce the behavior:

  1. Go to the show view of a resource with a has many relation
  2. Click Attach
  3. Click Cancel
  4. Now you can't interact with that attach button

Expected behavior

TO be able to click the attach button

Actual behavior

Button is disabled

System configuration

Avo version: 1.3.5

Rails version:

Ruby version:

Screenshots

Additional context

has_and_belongs_to_many does not find the model if option class_name is specified

Hi,

Imagine you have a resource has_and_belongs_to_many with option class_name
At the moment, the linked resource can't be found.
Resource should be found the same way the has_many field

App.get_resources.find { |r| r.class == "Avo::Resources::#{model._reflections[id.to_s].plural_name.to_s.camelcase.singularize}".safe_constantize }

it should be like this

class_name = model._reflections[id.to_s].options[:class_name].present? ? model._reflections[id.to_s].options[:class_name] : model._reflections[id.to_s].klass.name
App.get_resource_by_model_name class_name

Regards,

Nicolas

v1.0

We're working towards v1.0 coming mid/late march.

Features

  • Custom fields
  • Custom tools

Use packed assets in production

Right now we have a webpacker pipeline that plugs into the asset pipeline of the app.

The issue with this that when the app's asset pipeline is triggered it also triggers avo's pipeline and we don't want that. We need to allow the customer to enable this behaviour when he needs it.

AC:

Have an independent webpacker asset pipeline that we can trigger it when we want it when we build for release and have the dev server for dev.

Fields tier 1

For our initial release we should have a few fields available out of the box.

This is a list of good initial fields. Let's just add them.

  • Avatar (depends on image)
  • Boolean
  • Date
  • DateTime (similar to date) use flatpickr
  • File
  • ID
  • Image (depends on file)
  • Number
  • Select
  • Text
  • TextArea
  • Password

Hotwire fields

Fields left for the Hotwire rewrite

  • Trix field
  • KeyValue field
  • DateTime field
  • Currency field
  • Country field
  • Boolean field
  • BooleanGroup field
  • Hidden field #71

Fields tier 2

Let's start on the next tier of fields:

  • Boolean group
  • Heading
  • KeyValue - this should be nice to have
  • Gravatar - fetch gravatar for that field. we can use the email field. Let's add some gravatar options on this field
  • Markdown - let's find a good library. TBD. this seems like a good fit. see if it works
  • Trix WYSIWYG
  • Status - waiting, running, or finished
  • Code - library TBD
  • Hidden
  • Badge
  • Country (Search for IsoCountryCodes)
  • Currency - just a formatter
  • Graphs library. We'll see if sparkline or not.

[BUG] Avo causes Cucumber test to fail

Avo depends on Webpacker in test environment, which causes normal app without Webpacker installation to fail.

Puma caught this error: undefined method `javascript_pack_tag' for #<ActionView::Base:0x00000000026ef8>
Did you mean?  javascript_path
               javascript_tag (ActionView::Template::Error)
/Users/thachchau/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/manifester-0.1.7/lib/manifester/helper.rb:109:in `javascript_manifest_tag'
/Users/thachchau/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/avo-1.3.4/app/views/layouts/avo/application.html.erb:12:in `___sers_thachchau__asdf_installs_ruby_______lib_ruby_gems_______gems_avo_______app_views_layouts_avo_application_html_erb___3104381627434387194_79640'

Manually update this code snippet helps the test to pass

    def manifester
      @manifester ||= ::Manifester::Instance.new(
        root_path: ROOT_PATH,
        public_output_dir: "avo-packs",
        cache_manifest: Rails.env.production?,
        fallback_to_webpacker: -> { false }
      )
    end

Development works well, as expected. Please have a look if you have time 💯
And thanks for the awesome work 👍

Compatibility with Friendly IDs

We are using Friendly IDs gem to make friendly URLs for one of our model - Page. So we have:

class Page < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
end

However if we try to manage Page resource using Avo it fails to find page id.

We tried to create a class and add extend as follows:

class Avo::ApplicationController < ActionController::Base
extend FriendlyId
friendly_id :name, use: :slugged
end

But this throwas an error.

Eventually I found a temporary solution to hack one of the avo classes as follows:

def set_model
@model = if @resource.model_class.name == 'Page'
eager_load_files(@resource, @resource.model_class).friendly.find params[:id]
else
eager_load_files(@resource, @resource.model_class).find params[:id]
end
end

Please can we have a proper solution so we can use both your gem and Friendly IDs gem in a number of our commercial applications? Many thanks in advance.

Client side validation

We need to add some client side validations to our fields.

Reference

The rules are:

  • required which will not allow the user to submit the form if the field is not filled and
  • readonly. The field will not show up in the create or update views.
  • nullable. Not a validation rule per se, but we can do it in this ticket. This should convert empty values '' to null in the db.

[RFC] Actions support optional fields based on a property of the passed model

Background

The initial field declaration API on actions was the block notation.

fields do
  boolean :notify_user
  textarea :message, default: 'Your account has been marked as inactive.'
end

The second iteration (that wasn't really published at all) got the def treatment.

def fields(request)
  f.boolean :notify_user, default: true
  f.text :message, default: 'Your account has been marked as inactive.'
end

After talking with Thomas Klemm, he suggested we use a different type, more familiar type of declaration.

fields do |field|
  field.boolean :notify_user, default: true
  field.text :message, default: 'Your account has been marked as inactive.'

This 👆 looks very familiar to rails developers (kind of like form do |f|).

There are some caveats though. Because the fields method is being run only at boot time, you don't have any control over it on runtime.

Example: Let's say you have a TicketResource that can have multiple types of attributes, and some are optional. You might not have all tickets with all the data filled in. Let's say the ticket might/might not have the email attribute.
You might have an action that marks the ticket as resolved and if the ticket has an email attribute present you might want to send a message to it.
The requirement here is to show the textarea field on the action if the ticket has the email attribute present and have it hidden (or disabled) if that attribute is missing.

You can't really implement that requirement if the fields registration is being done on boot time. You can only do that at runtime when you have access to that model object.

Proposal

Go back to the def fields API. This way we can instantiate the fields on runtime. This API also allows us to pass in more than just that model. We can pass the params, request, or a custom context object and build the fields based on those objects if we want to.

the action might look something like this.

class MarkResolved < Avo::BaseAction
  self.name = 'Mark ticket resolved'

  def handle(models:, fields:)
    models.each do |model|
      model.update resolved: true

      model.send_resolved_notification fields[:message] if fields[:notify_user]
    end

    succeed 'Perfect!'
  end

  def fields(field, model:, **args)
	# Show the fields only if it was accessed on one model and that model has the `email` attribute present
    if models.blank? && model.email.present?
      field.boolean :notify_user, default: true
      field.text :message, default: 'The ticket was resolved.'
    end
  end
end

The args can hold multiple named arguments like the request, params, context, models (if multiple were selected).

How does this affect the fields API for Resource objects?

I don't think it's wise to use different APIs for declaring fields on Resources and Actions. They have to be implemented the same way in both classes, so I'm proposing to change it there as well, bringing the advantages of runtime updates too.

attaching image to post

When I attach an image to a post (even on your demo site) it appears as clickable one and also inserts the hyperlink as well.

That hyperlink can be then edited as caption, otherwise it stays and shows as a link to image.

However we do not need that caption or link. Indeed, we do not want to have image clickable either.

How can this be fixed?

Your default images in demo are not clickable and do not show any hyperlinks or captions - we want to replicate exactly the same behaviour but failed to do that locally on our own app as well as in your online demo as stated above.

Please help.

Search for pivot tables is not working

.or operator doesn't work for queries that use joins. The following error is thrown.

Relation passed to #or must be structurally compatible. Incompatible values: [:joins]

Field `belongs_to` is using the name to find the resource

Hi,

The belongs_to field relation is not working.
Looking at the code, I think the error is right here:

target_resource = App.get_resources.find { |r| r.class == "Avo::Resources::#{name}".safe_constantize }

As we can see, the name is used to find the resource. I think this is a mistake as the name could be anything.
The relation's class name should be used (as it is for the has_many field)

Something like this :

class_name = model._reflections[id.to_s].options[:class_name].present? ? model._reflections[id.to_s].options[:class_name] : model._reflections[id.to_s].name
App.get_resources.find { |r| r.class == "Avo::Resources::#{class_name.to_s.camelcase.singularize}".safe_constantize }

Relations

  • belongs_to
  • has_one
  • has_many
  • has_many_through
  • has_one_through
  • has_and_belongs_to_many
  • has_many polymorphic

Wrong module

Hi,

The Avo configuration uses the iso gem.
In the locale_tag method, this gem is used but should use the global scope
cf

ISO::Tag.new(locale)

example :

irb(main):007:0> Avo.configuration.locale_tag
Traceback (most recent call last):
        1: from (irb):7
NameError (uninitialized constant Avo::Configuration::ISO)
irb(main):008:0> 

The result is that the default locale is changed to en

[BUG] Multi-word resources generate bad controller class name

Describe the bug

I have a model named business_places. The class name of the generated controller is wrong and crashes the app.

Steps to Reproduce

Steps to reproduce the behavior:

  1. bin/rails generate avo:resource business_place
  2. open app/controllers/avo/business_places_controller.rb
  3. First line reads as class Avo::Business placesController < Avo::ResourcesController which is obviously wrong.

Expected behavior

First line should read class Avo::BusinessPlacesController < Avo::ResourcesController

Actual behavior

First line reads as class Avo::Business placesController < Avo::ResourcesController which is obviously wrong.

System configuration

Avo version: 1.2.8

Rails version: 6.1.3

Ruby version: 2.7.2

Can This Work With Shrine / Carrierwave etc?

Hi,

I'm trying to use the file field with a shrine column and I keep getting an error of

undefined method 'attached?' for nil class.

I'm not sure if it's a problem on my end or if it's because of the gem.

Setup is straight forward, installed shrine gem, did a database migration to add image_data as a json column to my Post model and then used the file field on the shrine virtual attribute (column is :image_data)

file :image, is_image: true

[BUG] Avo shows license warning banner if used on root path `/`

Describe the bug

Avo shows custom tools license warning banner if used on root path / even if it's not using custom tools.

Steps to Reproduce

Steps to reproduce the behavior:

  1. In avo.rb initializer edit the root_path to /
  2. Go to /avo
  3. You will see the license banner

Expected behavior

You should not see the banner.

Actual behavior

You will see the banner.

System configuration

Avo version:

Rails version:

Ruby version:

Screenshots

Additional context

Missing dependency

Hi,

The avo gem depends on the ISO gem. If I’m not mistaken, the dependency is missing in the gemspec file.

regards,

Nicolas

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.