Rails app template
Bullet Train
Add Avo 3 to your Bullet Trains app blazing fast!
Run the following command to quickly apply this app template
If you think this template needs changes please submit a PR here.
Full template
# Template info:
# Link: https://avohq.io/templates/bullet-train
# Repository: https://github.com/avo-hq/bullet-train-app-template
# List of all Avo files with path and contents
files = {"app/avo/cards/users_count.rb"=>"class Avo::Cards::UsersCount < Avo::Cards::MetricCard\n self.id = \"users_count\"\n self.label = \"Users count\"\n self.description = \"Count of registered users\"\n\n def query\n result ::User.all.count\n end\nend\n", "app/avo/dashboards/overview.rb"=>"class Avo::Dashboards::Overview < Avo::Dashboards::BaseDashboard\n self.id = \"overview\"\n self.name = \"Overview\"\n self.grid_cols = 4\n\n def cards\n card Avo::Cards::UsersCount\n end\nend\n", "app/avo/resources/invitation.rb"=>"class Avo::Resources::Invitation < Avo::BaseResource\n self.title = :email\n self.includes = []\n self.search = {\n query: -> { query.ransack(id_eq: params[:q], email_cont: params[:q], m: \"or\").result(distinct: false) },\n item: -> {\n {\n title: record.title\n }\n }\n }\n\n def fields\n field :id, as: :id\n field :email, as: :text\n field :uuid, as: :text\n field :team, as: :belongs_to, searchable: true\n field :from_membership, as: :belongs_to, searchable: true\n field :membership, as: :has_one\n end\nend\n", "app/avo/resources/membership.rb"=>"class Avo::Resources::Membership < Avo::BaseResource\n self.title = :name\n self.includes = []\n self.search = {\n query: -> { query.ransack(id_eq: params[:q], name_cont: params[:q], user_email_cont: params[:q], role_cont: params[:q], m: \"or\").result(distinct: false) },\n item: -> {\n {\n title: record.name,\n description: \"Membership of \#{team.name}\"\n }\n }\n }\n\n def fields\n field :id, as: :id\n field :name, as: :text, hide_on: :forms\n field :user_profile_photo_id, as: :text\n field :user_email, as: :text\n field :added_by_id, as: :number\n field :role_ids, as: :tags\n field :user, as: :belongs_to, searchable: true\n field :team, as: :belongs_to, searchable: true\n field :invitation, as: :belongs_to, searchable: true\n field :added_by, as: :belongs_to, searchable: true\n end\nend\n", "app/avo/resources/team.rb"=>"class Avo::Resources::Team < Avo::BaseResource\n self.title = :name\n self.includes = []\n self.search = {\n query: -> { query.ransack(id_eq: params[:q], name_cont: params[:q], slug_cont: params[:q], m: \"or\").result(distinct: false) },\n item: -> {\n {\n title: record.name\n }\n }\n }\n\n def fields\n field :id, as: :id\n field :name, as: :text\n field :slug, as: :text\n field :being_destroyed, as: :boolean, hide_on: :forms\n field :time_zone, as: :select, options: -> { view_context.time_zone_options_for_select(Avo::Current.user.time_zone, nil, ActiveSupport::TimeZone) }\n field :locale, as: :text\n field :users, as: :has_many, through: :memberships\n field :memberships, as: :has_many\n field :invitations, as: :has_many\n end\nend\n", "app/avo/resources/user.rb"=>"class Avo::Resources::User < Avo::BaseResource\n self.title = :full_name\n self.includes = []\n self.search = {\n query: -> { query.ransack(id_eq: params[:q], first_name_cont: params[:q], last_name_cont: params[:q], email_cont: params[:q], m: \"or\").result(distinct: false) },\n item: -> {\n {\n title: record.full_name,\n }\n }\n }\n\n def fields\n field :id, as: :id\n field :email, as: :text\n field :first_name, as: :text\n field :last_name, as: :text\n field :time_zone, as: :text\n field :current_team, as: :belongs_to\n\n field :teams, as: :has_many, through: :teams\n field :memberships, as: :has_many\n end\nend\n", "app/controllers/avo/invitations_controller.rb"=>"# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::InvitationsController < Avo::ResourcesController\nend\n", "app/controllers/avo/memberships_controller.rb"=>"# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::MembershipsController < Avo::ResourcesController\nend\n", "app/controllers/avo/teams_controller.rb"=>"# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::TeamsController < Avo::ResourcesController\nend\n", "app/controllers/avo/users_controller.rb"=>"# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::UsersController < Avo::ResourcesController\nend\n", "config/initializers/avo.rb"=>"# For more information regarding these settings check out our docs https://docs.avohq.io\nAvo.configure do |config|\n ## == Routing ==\n config.root_path = \"/admin/avo\"\n # used only when you have custom `map` configuration in your config.ru\n # config.prefix_path = \"/internal\"\n\n # Where should the user be redirected when visting the `/avo` url\n # config.home_path = nil\n\n ## == Licensing ==\n # config.license_key = ENV['AVO_LICENSE_KEY']\n\n ## == Set the context ==\n config.set_context do\n # Return a context object that gets evaluated in Avo::ApplicationController\n end\n\n ## == Authentication ==\n config.current_user_method = :current_user\n # config.authenticate_with do\n # end\n\n ## == Authorization ==\n # config.authorization_methods = {\n # index: 'index?',\n # show: 'show?',\n # edit: 'edit?',\n # new: 'new?',\n # update: 'update?',\n # create: 'create?',\n # destroy: 'destroy?',\n # search: 'search?',\n # }\n # config.raise_error_on_missing_policy = false\n # config.authorization_client = :pundit\n\n ## == Localization ==\n # config.locale = 'en-US'\n\n ## == Resource options ==\n # config.resource_controls_placement = :right\n # config.model_resource_mapping = {}\n # config.default_view_type = :table\n # config.per_page = 24\n # config.per_page_steps = [12, 24, 48, 72]\n # config.via_per_page = 8\n config.id_links_to_resource = true\n # config.cache_resources_on_index_view = true\n ## permanent enable or disable cache_resource_filters, default value is false\n # config.cache_resource_filters = false\n ## provide a lambda to enable or disable cache_resource_filters per user/resource.\n # config.cache_resource_filters = ->(current_user:, resource:) { current_user.cache_resource_filters?}\n\n ## == Customization ==\n config.app_name = -> { I18n.t \"application.name\" }\n # config.timezone = 'UTC'\n # config.currency = 'USD'\n # config.hide_layout_when_printing = false\n # config.full_width_container = false\n # config.full_width_index_view = false\n # config.search_debounce = 300\n # config.view_component_path = \"app/components\"\n # config.display_license_request_timeout_error = true\n # config.disabled_features = []\n # config.buttons_on_form_footers = true\n # config.field_wrapper_layout = true\n\n ## == Branding ==\n # config.branding = {\n # colors: {\n # background: \"248 246 242\",\n # 100 => \"#CEE7F8\",\n # 400 => \"#399EE5\",\n # 500 => \"#0886DE\",\n # 600 => \"#066BB2\",\n # },\n # chart_colors: [\"#0B8AE2\", \"#34C683\", \"#2AB1EE\", \"#34C6A8\"],\n # logo: \"/avo-assets/logo.png\",\n # logomark: \"/avo-assets/logomark.png\",\n # placeholder: \"/avo-assets/placeholder.svg\",\n # favicon: \"/avo-assets/favicon.ico\"\n # }\n\n ## == Breadcrumbs ==\n # config.display_breadcrumbs = true\n # config.set_initial_breadcrumbs do\n # add_breadcrumb \"Home\", '/avo'\n # end\n\n ## == Menus ==\n # config.main_menu = -> {\n # section \"Dashboards\", icon: \"dashboards\" do\n # all_dashboards\n # end\n\n # section \"Resources\", icon: \"resources\" do\n # all_resources\n # end\n\n # section \"Tools\", icon: \"tools\" do\n # all_tools\n # end\n # }\n # config.profile_menu = -> {\n # link \"Profile\", path: \"/avo/profile\", icon: \"user-circle\"\n # }\nend\n"}
if ARGV.include? "--community-edition"
edition = "community"
elsif ARGV.include? "--pro-edition"
edition = "pro"
elsif ARGV.include? "--advanced-edition"
edition = "advanced"
end
unless edition
# === Fetch the Avo edition ===
question = <<~QUESTION
Which version of Avo would you like to install?
1. Avo Community (default)
2. Avo Pro
3. Avo Advanced
More information about version features here:
https://avohq.io/pricing
QUESTION
puts question
answer = ask("Which version of Avo would you like to install?", default: "1", limited_to: ["1", "2", "3"])
edition = case answer
when "1"
"community"
when "2"
"pro"
when "3"
"advanced"
end
end
# === Add gem to Gemfile ===
case edition
when "community"
gem "avo", ">= 3.2.3"
when "pro"
gem "avo-pro", source: "https://packager.dev/avo-hq"
when "advanced"
gem "avo-advanced", source: "https://packager.dev/avo-hq"
end
gem "ransack"
# === Run bundle install ===
Bundler.with_unbundled_env { run "bundle install" }
file "config/routes/avo.rb", "# Avo admin panel
if defined?(Avo::Engine)
authenticate :user, lambda { |u| u.developer? } do
mount Avo::Engine, at: Avo.configuration.root_path
end
end"
route "draw \"avo\""
# === Copy template files ===
files.each do |path, contents|
file path, contents
end