Create admin panel for your application FAST!
Usage
How to use my plugin.
1. Add this gems to Gemfile
Gemfile
gem 'tramway-admin'
gem 'tramway-user'
gem 'bcrypt'
gem 'haml-rails'
gem 'bootstrap'
gem 'jquery-rails'
gem 'copyright_mafa'
gem 'trap'
gem 'kaminari'
gem 'bootstrap-kaminari-views', github: 'kalashnikovisme/bootstrap-kaminari-views', branch: :master
gem 'state_machine_buttons'
gem 'ckeditor', '4.2.4'
gem 'ransack'
gem 'smart_buttons'
gem 'carrierwave'
gem 'validates'
2. You should remove gem turbolinks
from your application and from app/assets/javascripts/application.js
3. Update your routes
config/routes.rb
Rails.application.routes.draw do
mount Tramway::Auth::Engine, at: '/auth'
mount Tramway::Admin::Engine, at: '/admin'
end
4. Then make tramway-core
installation. How-to
5. And then execute:
$ rails g tramway:user:install
$ rails db:migrate
6. Create your first admin user
$ rails c
$> Tramway::User::User.create! email: 'your@email.com', password: '123456789', role: :admin
7. Add models to your admin
app/config/initializers/tramway.rb
# set available models for your admin
::Tramway::Admin.set_available_models YourModel, AnotherYourModel, project: #{project_name_which_you_used_in_application_name}
# set singleton models for your admin
::Tramway::Admin.set_singleton_models YourSingletonModel, AnotherYourSingletonModel, project: #{project_name_which_you_used_in_application_name}
::Tramway::Auth.root_path = '/admin' # you need it to redirect in the admin panel after admin signed_in
8. Configurate navbar
config/initializers/tramway.rb
Tramway::Admin.navbar_structure(
YourModel, # this line will create first-level link in your navbar, which will send you to the YourModel management
{
my_dropdown: [ # this line contains dropdown link name
AnotherYourModel # this line will create 2nd-level link in your navbar, which will send you to the YourModel management,
:divider # this line adds bootstrap divider to the dropdown list
]
},
project: :your_application_name
)
9. Create decorators and forms for all available_models.
You can run generator that will create all necessary files
$ rails g tramway:admin:install
Or generate decorator and form for only one model
$ rails g tramway:admin:model Coworking
If you're using several user roles in your admin dashboard, then you can specify scope for the form(default scope is admin
)
$ rails g tramway:admin:install --user-role=partner
Or you can create forms and decorators manually as it written below:
9a. Create decorator for models [manual option]
app/decorators/your_model_decorator.rb
class YourModelDecorator < Tramway::Core::ApplicationDecorator
decorate_associations :messages, :posts
class << self
def collections
[ :all, :scope1, :scope2 ]
end
def list_attributes
[ :begin_date, :end_date ]
end
def show_attributes
[ :begin_date, :end_date ]
end
def show_associations
[ :messages ]
end
def list_filters
{
filter_name: {
type: :select,
select_collection: filter_collection,
query: lambda do |list, value|
list.where some_attribute: value
end
},
date_filter_name: {
type: :dates,
query: lambda do |list, begin_date, end_date|
list.where 'created_at > ? AND created_at < ?', begin_date, end_date
end
}
}
end
end
delegate_attributes :title
end
NOTES:
-
collections
method must return array of scopes ofYourModel
. Every collection will be a tab in a list of your model in admin panel -
list_filters
method returns hash of filters where:- select_collection - collection which will be in the select of filter. It must be compatible with options_for_select method
- query - some Active Record query which be used as a filter of records
-
list_attributes
method returns array of attributes which will be shown in index page. If empty onlyname
will be shown -
show_attributes
method returns array of attributes which will be shown in show page. If empty all attributes of the model will be shown -
show_associations
method returns array of decorated associations which will be show in show page. If empty no associations will be shown
Filters naming:
Select filters
en:
tramway:
admin:
filters:
model_name:
filter_name: Your Filter
Date filters
en:
tramway:
admin:
filters:
model_name:
date_filter_name:
begin_date: Your Begin date filter
end_date Your end date filter
9b. Create Admin::YourModelForm
[manual option]
*app/forms/admin/your_model_form.rb
class Admin::YourModelForm < Tramway::Core::ApplicationForm
properties :title, :description, :text, :date, :logo
association :associated
association :another_polymorphic_associated
def initialize(object)
super(object).tap do
form_properties title: :string,
logo: :file,
description: :ckeditor,
date: :date_picker,
text: :text,
associated: :association,
another_polymorphic_association: :polymorphic_association,
birth_date: {
type: :default,
input_options: {
hint: 'It should be more than 18'
}
}
end
end
end
NOTE If you want fill inputs of this form, just send query params
params = {
your_model: {
logo: '/file/url',
description: 'some text',
text: 'some another text',
associated_id: 5,
another_polymorphic_associated: 56,
another_polymorphic_associated_type: 'AnotherModel'
}
}
10. Add inheritance to YourModel
app/models/your_model.rb
class YourModel < Tramway::Core::ApplicationRecord
end
11. You can add search to your index page
Tramway use gem PgSearch as search engine
Just add search
method to YourModel
like this
search_by *attributes, **associations # `attributes` and `associations` should be the same syntax as in PgSearch
Example:
class YourModel < Tramway::Core::ApplicationRecord
search_by :my_attribute, :another_attribute, my_association: [ :my_association_attribute, :another_my_association_attribute ]
12. Run server rails s
13. Launch localhost:3000/admin
CRUDs for models
By default users with role admin
have access to all models used as arguments in method ::Tramway::Admin.set_available_models
. If you want specify models by roles, use them as keys
::Tramway::Admin.set_available_models ::Tramway::Event::Event, ::Tramway::Event::ParticipantFormField,
::Tramway::Event::Participant, ::Tramway::Landing::Block, ::Tramway::User::User,
::Tramway::Profiles::SocialNetwork, project: #{project_name_which_you_used_in_application_name}, role: :admin
::Tramway::Admin.set_available_models ::Tramway::Event::Event, ::Tramway::Event::ParticipantFormField,
::Tramway::Event::Participant, project: #{project_name_which_you_used_in_application_name}, role: :another_role
You can set functions which are available by default some CRUD functions for any role:
# this line gives access only index page to YourModel for partner role
::Tramway::Admin.set_available_models YourModel => [ :index ], role: :partner
You can set conditions for functions which are available for any role:
# this line gives access to destroy only record with name `Elon Musk`
::Tramway::Admin.set_available_models YourModel => [
destroy => lambda do |record|
record.name == 'Elon Musk'
end
], role: :partner
Here docs about changing roles of Tramway::User::User
model Readme
Associations management
has_many
We have models Game and Packs.
app/models/game.rb
class Game < Tramway::Core::ApplicationRecord
has_many :packs
end
app/models/pack.rb
class Pack < Tramway::Core::ApplicationRecord
belongs_to :game
end
You want to manage packs in the Game show admin page
1. Add association to PackDecorator
app/decorators/pack_decorator.rb
class GameDecorator < Tramway::Core::ApplicationDecorator
decorate_association :packs, as: :game # we recommend you to add association name in Pack model. You need it if association name of Game in Pack is not `game`
end
has_and_belongs_to_many
We have models Game and Packs.
app/models/game.rb
class Game < Tramway::Core::ApplicationRecord
has_and_belongs_to_many :packs
end
app/models/pack.rb
class Pack < Tramway::Core::ApplicationRecord
has_and_belongs_to_many :games
end
You want to manage games in the Pack show admin page
1. Add association to PackDecorator
app/decorators/pack_decorator.rb
class PackDecorator < Tramway::Core::ApplicationDecorator
decorate_association :games
end
2. Create Admin::Packs::AddGameForm
and Admin::Packs::RemoveGameForm
app/forms/admin/packs/add_game_form.rb
class Admin::Packs::AddGameForm < Tramway::Core::ApplicationForm
properties :game_ids
association :games
def initialize(object)
super(object).tap do
form_properties games: :association
end
end
def submit(params)
params[:game_ids].each do |id|
model.games << Game.find(id) if id.present?
end
model.save!
end
end
app/forms/admin/packs/remove_game_form.rb
class Admin::Packs::RemoveGameForm < Tramway::Core::ApplicationForm
properties :id
def submit(params)
model.games -= [Game.find(params)] if id.present?
model.save!
end
end
3. Add this forms to initializer
config/initializers/tramway/admin/forms.rb
Tramway::Admin.forms = 'packs/add_game', 'packs/remove_game'
Date Picker locale
DatePicker provides ru
, en
locales. To set needed locale, just add
window.current_locale = window.i18n_locale('en');
to the app/assets/javascripts/admin/application.js
file
OR
window.current_locale = window.i18n_locale 'en'
to the app/assets/javascripts/admin/application.js.coffee
file
Decorator Helper methods
date_view
Returns a date in the format depending on localization
app/decorators/*_decorator.rb
def created_at
date_view object.created_at
end
datetime_view
Returns a date and time in the format depending on localization
app/decorators/_decorator.rb*
def created_at
datetime_view object.created_at
end
state_machine_view
Returns the state of an object according to a state machine
app/decorators/_decorator.rb*
def state
state_machine_view object, :state
end
It takes locales from I18n.t("state_machines.#{model_name}.#{state_machine_name}.states.#{state_value}")
image_view
Returns an image in a particular format depending on the parameters of the original image file
app/decorators/*_decorator.rb
def avatar
image_view object.avatar
end
enumerize_view
Returns object enumerations as text
app/decorators/*_decorator.rb
def field_type
enumerize_view object.field_type
end
file_view
Returns file name and button to download it
app/decorators/*_decorator.rb
def file_download
file_view object.file
end
Notifications
You can add notification to your admin panel to the navbar.
To add notification to application, you need just set queries in initializers.
config/initializers/tramway.rb
::Tramway::Admin.set_notificable_queries :"#{your_title}" => -> { your_query }
# Example from tramway-event gem (you also can push context variables here)
::Tramway::Admin.set_notificable_queries new_participants: -> (current_user) do
::Tramway::Event::Participant.where(participation_state: :requested).send "#{current_user}_scope", current_user.id
end
NOTE: Proc with current_user
argument is expecting. If you don't need current_user
, just name do something like that:
::Tramway::Admin.set_notificable_queries new_participants: -> (_current_user) do
# some code which does not need current_user
end
Admin Main Page management
Start page of admin panel contains only application.name
by default. To manage it just set Tramway::Admin.welcome_page_actions
with some lambda and set @content
variable with HTML.
Example:
config/initializers/tramway/admin.rb
::Tramway::Admin.welcome_page_actions = lambda do
@content = '<a href="http://it-way.pro">IT Way</a>'
end
Navbar management
Navbar structure
You can manage your navbar easy
config/initializers/tramway.rb
Tramway::Admin.navbar_structure(
YourModel, # this line will create first-level link in your navbar, which will send you to the YourModel management
{
my_dropdown: [ # this line contains dropdown link name
AnotherYourModel # this line will create 2nd-level link in your navbar, which will send you to the YourModel management,
:divider # this line adds bootstrap divider to the dropdown list
]
},
project: :your_application_name
)
NOTE: navbar structure is the same for all roles, but users will see only available models for them
Dropdown localization
To set human-read name for dropdown link you can use i18n:
config/locales/admin.yml
en:
admin:
navbar:
links:
my_dropdown: Very important dropdown
Additional buttons to the show view
You can additional buttons to the header of show view of your model. Just add its configuration to the decorator
app/decorators/your_model_decorator.rb
class YourModelDecorator < Tramway::Core::ApplicationDecorator
def additional_buttons
{
show: [ # means that this buttons will be shown on show view only
{
url: ::Tramway::Export::Engine.routes.url_helpers.export_path(object.id, model: object.class, collection: :tasks),
inner: lambda do # inner HTML you want to see in the button
fa_icon 'file-excel'
end,
color: :success, # bootstrap button color
method: :get # HTTP method. get method is a default. Available: :post, :patch: delete
}
]
}
end
end
Errors
-
Model or Form is not available -
params[:model]
orparams[:form]
is empty OR current user does not have access to model or form inparams[:model]
orparams[:form]
Change admin user base model
config/initializers/tramway.rb
::Tramway::Admin.auth_config = { user_model: User, auth_attributes: %i[email username] }
Good features
Get actions log in admin panel
Tramway uses audited to log actions of models. That's why all we need it's creating view for model Audited::Audit
1. Add Audited::Audit model to available models
config/initializers/tramway.rb
Tramway::Admin.set_available_models(
Audited::Audit,
project: :your_project_name
)
2. Add this model to navbar
Tramway::Admin.set_navbar_structure(
Audited::Audit,
project: :your_project_name
)
3. Generate decorator for Audited::Audit
rails g tramway:admin:model Audited::Audit
License
The gem is available as open source under the terms of the MIT License.