Enhance your admin indexes

Ismaël Boukhars, project manager web and mobile at Capsens
Ismaël BoukharsFeb 10, 2021

As a project manager in a fintech specialized development company (hi CapSens), I’ve seen loads and loads of web platforms’ back-offices.

These administration interfaces are very common and similar especially for the indexes (list of ressources) : a big paginated table of 50 lines, a sidebar that contains the filter and a title. Always the same interface. This article explores ways to enhance these simple interface designs.

Being in a Ruby on Rails company, this article will be showing bits of Ruby code and focused on ActiveAdmin design but it can be applied to any other Admin index.

Screenshot of a basic ActiveAdmin index.

Screenshot of a basic ActiveAdmin index.

Here is a a basic ActiveAdmin index. For the example, I came up with a Customer model and an index displaying the fields shown on the right. The view is default from AA’s generator so we also have a bunch of useless filters stacked in a sidebar on the right. Already seen this, right ?

The code of this project can be found on this Github repository. You’ll find a git branch representing each phase of this article (here “1_base_admin”).

Ruby Code

Ruby Code

Now that we are set up, let’s move on and explore ways to enhance our admin index.


Theme up your Admin

There are several open-source themes available for ActiveAdmin. Amongst all the quick wins I’ll show you in this article, this one might be the biggest.

First of all, we need to pick the theme we’d like in order to customize our admin’s interface. This wiki references a list of AA’s themes. When choosing your theme, you’ll want it to be functionnal, you have enough bugs to deal with, don’t wan’t to add up new ones thanks to your theming, right ? A good indicator is to ensure that there are not too much opened issues and that the theme is still kept up to date (check the last commit on the master branch). Last but not least, if your project already contains numerous AA pages, you should go for a light theming in order to avoid breaking changes that you might miss.

Amongst all the available themes of this wiki, my favorite one is Artic Admin but for the reasons I gave you above, we’ll go for a lighter theming: ActiveMaterial. To implement it, just follow the doc on the Github’s page, you should be good to go in a minute (it only requires 3 lines of code to add).


Our same AA customers’ index with ActiveMaterial’s theming. Code can be found here.


The AA’s interface changed and now look different. With a bit of configuration we can easily customize it more. The theme is made in SASS (SCSS) so we can look up for variables and modify the default configuration.


Customizing the theming

If we take a look at the color variables available we can see there are 14 of them. For this, add up a new file app/assets/stylesheets/active_admin/variables/_colors.scss and require it in active_admin.scss file before the other files like this.

// Customization
@import ‘active_admin/variables/variables’;
@import ‘active_admin/variables/fonts’;
// Libraries
@import “active_admin/mixins”;
@import “active_material”;

An example of admin.scss code


Now let’s go in our new _variables.scss file and tweak the theme a bit! First we need to define our color palette. ActiveMaterial being a material design template, I used a material color palette generator for this. There are plenty of them available on the web, but I particularly like Material.io.

My material color’s palette

My material color’s palette

Once you are done defining your template, you just have to report the value in our _variable.scss file by re-assigning the value of existing SASS variables:

$am-theme-primary: #42a5f5;
// A darker primary theme color for contrast when overlaying 
// important items containers that are already treated 
// with primary color.
$am-theme-primary-700: #0077c2;
//  Used for primary action button and components 
$am-theme-accent: #673ab7;
// The background color of the document.
$am-theme-backdrop: #eeeeee;
// Background color of “paper” elements such as cards.
$am-theme-paper: #F5F5F6;
// Color used to separate elements such as table's lines
$am-theme-divider: darken($am-theme-backdrop, 2.5%);

Here is my _variable.scss file to match the color palette above.

Here is my _variable.scss file to match the color palette above. You can find the code here.

Of course, there are other options for further customization: fonts, elevations, sizes, breakpoints. To do that, just repeat the same process than for the color.

Filter sidebar toggle

Our themed AA customers’ index with a big filter sidebar on the right.

Our themed AA customers’ index with a big filter sidebar on the right.

Now that we added some colors, we can see that our filters sidebar is taking 20% of the screen. It’s a bit much for a feature that you won’t use all the time, isn’t it? Let’s find a way to make it appear only when needed.

By finding a solution for this matter, I stepped upon this article from Emanuele Tozzato that shows a simple way to sort it out. With a little bit of Jquery and Css, he allows to toggle in and out the filters sidebar thanks to an action item.

Our AA customers’ index with the filters sidebar hidden and a top right action item that allows to toggle filtrs.

Our AA customers’ index with the filters sidebar hidden and a top right action item that allows to toggle filtrs.

We’ll just push a little bit further his approach because I’m not a big fan of adding an action item. These should be used for admins CRUD actions. So I just tweaked the code a little bit to move the toggle filters button on the top right of the indexes’ table.

Same index, but we moved out the toggle filters’ sidebar button on the indexes’ table.

Same index, but we moved out the toggle filters’ sidebar button on the indexes’ table.


If you’re interested, you can find the code here.


Stripping up the table

Sometimes, it can be complexe for an administrator to distinguish elements from one lines to another. One solution is to strip the table. To do this, I just need to create a new scss component :

// app/assets/active_admin/components/_tables.scss
$table-striping-color: $am-theme-paper;
.index_content table {
  tr.odd {
    background: $table-striping-color;
  }
  tr.even {
    background: lighten($table-striping-color, 10%);
  }
}

How to colour every other row in a table in SAS


For the striping color, I used the value of our $am-theme-paper (the background color of components such as cards or tables) and I just darkened the even columns. Easy right ? You can find the full code here.

Our AA customers’ index with the table striped.

Our AA customers’ index with the table striped.


Decorate your datas

Sometimes you may find columns in your indexes that don’t have any interest in being separated. For instance the first name and the last name or each part of an address. Then you can quickly merge them into a new column “name” or “full address”.

Moreover, when showing an amount, you may want to add the currency and number formatting to ease the reading.

You can use a decorator like Draper for this. This avoid to overload the admin logic.

__# app/decorators/customer_decorator.rb__
class CustomerDecorator < Draper::Decorator
delegate_all
  def name
#{firstname&.capitalize} #{lastname&.upcase}”
  end
  def membership_amount_in_dollars
    h.number_to_currency(membership_amount, locale: :en)
  end
end

An example of a decorator for a client


Then for each decorate column used, don’t forget to specify how the sorting should behave like this:

# app/admin/customers.rb
ActiveAdmin.register Customer do
  decorate_with CustomerDecorator
  index do
    selectable_column
    column :id
    column :name, sortable: :lastname
    column :email
    column :phone_number
    column :city
    column :language
    column :membership_amount_in_dollars, sortable: :membership_amount
    column :state
    column :created_at
    column :updated_at
    actions
  end
end

Example of an AA index for a client

the AA customers’ index with decorated datas.

the AA customers’ index with decorated datas.


Enhance the state display

The ressources displayed in an admin index often comes with a state. In our customers’ index, it’s a basic sales’ pipeline. Indeed, a customer is first in the “new” state before being contacted, then it might enter in the negociating phase and finally he becomes signed. He might change later to the terminated phase (when he cancels the contract).


Status Labels

Of course, we could just add up a bit of color using the very simple status_tag feature of ActiveAdmin.
First of all, we add the status_tag logic in our AA customers’ index view :

# app/admin/customers.rb
ActiveAdmin.register Customer do
  decorate_with CustomerDecorator
  index do
    # [... others columns]
    column :state do |customer|
      status_tag customer.state
    end
    # [... others columns]
  end
end


Then we can use a SASS’map to customize the status_tag background color :

// app/assets/stylesheets/active_admin/components/_status_tags.scss
$customers_states_colors: (
  new:         #BBC6C3, 
  contacted:   #70C0C6, 
  negociating: #9DEA4F, 
  signed:      #329932, 
  terminated:  #FF320E
);
.status_tag {
  @each $state, $color in $customers_states_colors {
    &.#{$state} {
      background: $color;
    }
  }
}

AA customers’ index with colored status_tags.


Convert labels to progress

The results is more visual but on the other hand our customers’ states are linear which means that for each customers, its first state will be new and at last he will go into the terminated phase.

Note that I used an enum for this because these states didn’t need any transitions or guards but you can achieve the same result with a state machine like AASM or Statesman.

One way to graphically represent this linearity is to display the state in a progress bar. Whenever it’s empty means that the customer is in the new state and full means that the customer is either signed or terminated. We will also reuse the color schemes defined before to make it more visual.

First, let’s add a method in our customer decorator that will return the completion state in percent for our progress bar :

class CustomerDecorator < Draper::Decorator
  delegate_all
  # [ other decorator logic here ... ]
  def state_completition_in_percent
    customer_state_index = Customer.state.values.index(state).to_f + 1
    return 100 if state == :terminated
    total_states_count_without_terminated_state = Customer.state.values.length -1
    completion = customer_state_index / total_states_count_without_terminated_state
    (completion * 100).round(0)
  end
end


Then we will render an .html.erb partial in our customer.state column :

ActiveAdmin.register Customer do
  decorate_with CustomerDecorator

  index do
    [ other columns logic here ... ]
    column :state do |customer|
      render partial: 'admin/customers/material_progress_bar', locals: { customer: customer }
    end
    actions
  end
end


Now we can create our material_progress_bar partial :


<div class="progress-wrapper <%= customer.state %>">
  <span class="state"><%= customer.state %></span>
  <div class="progress">
    <div class="bar" style="width: <%= customer.state_completition_in_percent %>%"></div>
  </div>
</div>


At last, a little bit of styling (don’t forget to require it in your application.scss file) :

@import 'active_admin/variables/colors';

$customers_states_colors: (
  new:         #BBC6C3, 
  contacted:   #70C0C6, 
  negociating: #9DEA4F, 
  signed:      #329932,  
  terminated:  #FF320E
);

$progress-bar-bg: #acece6;
$state-text-color: #707675;
$progress-bar-border-color: $state-text-color;

.progress-wrapper {
  .progress {
    position: relative;
    height: 10px;
    display: block;
    width: 100%;
    min-width: 100px;
    background-color: $progress-bar-bg;
    border-radius: 2px;
    background-clip: padding-box;
    margin: 0.15rem 0 1rem 0;
    overflow: hidden;

    .bar {
      position: absolute;
      top: 0;
      bottom: 0;
      transition: width 1s expandWidth;    
    }
  }

  @each $state, $color in $customers_states_colors {
    &.#{$state} {
      color: $state-text-color;

      .progress {
        border: 0.5px solid $progress-bar-border-color;
        background-color: transparent;

        .bar {
          background: $color;
        }
      }
    }
  }
}
view raw



Et voilà ! 🎉


Our redesigned AA customers’ index. You can find the full code here.

Partager
Ismaël Boukhars, project manager web and mobile at Capsens
Ismaël BoukharsFeb 10, 2021

Capsens' blog

Capsens is an agency specialized in the development of fintech solutions. We love startups, scrum methodology, Ruby and React.