Améliorez vos index en back office

Ismaël Boukhars, chef de projet web & mobile chez Capsens
Ismaël Boukhars10 févr. 2021

En tant que chef de projet dans une société de développement spécialisée dans les fintech (hi CapSens), j'ai vu des tas et des tas de back-offices de plateformes web.

Ces interfaces d'administration sont très communes et similaires surtout pour les index (liste de ressources) : un grand tableau paginé de 50 lignes, une barre latérale qui contient le filtre et un titre. Toujours la même interface. Cet article explore les moyens d'améliorer ces interfaces simples.

Etant dans une entreprise Ruby on Rails, cet article montrera des bouts de code Ruby et se concentrera sur le design d'ActiveAdmin mais il peut être appliqué à n'importe quel autre index Admin.

Voici un index ActiveAdmin de base. Pour l'exemple, j'ai créé un modèle de client et un index affichant les champs montrés à droite. La vue est celle par défaut du générateur d'AA, donc nous avons aussi un tas de filtres inutiles empilés dans une barre latérale sur la droite. Vous avez déjà vu ça, non ?

Le code de ce projet peut être trouvé sur ce dépôt Github. Vous y trouverez une branche git représentant chaque phase de cet article (ici "1_base_admin").

Code Ruby

Code Ruby

Maintenant que nous sommes configurés, passons à autre chose et explorons les moyens d'améliorer notre index d'administration.


Créer un thème pour votre administration

Il existe plusieurs thèmes open-source disponibles pour ActiveAdmin. Parmi tous les gains rapides que je vais vous montrer dans cet article, celui-ci est peut-être le plus important.

Tout d'abord, nous devons choisir le thème que nous souhaitons afin de personnaliser l'interface de notre administrateur. Ce wiki référence une liste de thèmes d'AA. En choisissant votre thème, vous voudrez qu'il soit fonctionnel, vous avez assez de bugs à gérer, vous ne voulez pas en ajouter de nouveaux grâce à votre thème, non ? Un bon indicateur est de s'assurer qu'il n'y a pas trop de problèmes ouverts et que le thème est toujours maintenu à jour (vérifiez le dernier commit sur la branche master). Enfin, si votre projet contient déjà de nombreuses pages AA, vous devriez opter pour une thématisation légère afin d'éviter les changements de rupture que vous pourriez manquer.

Parmi tous les thèmes disponibles sur ce wiki, mon préféré est Artic Admin mais pour les raisons que je vous ai données ci-dessus, nous allons opter pour un thème plus léger : ActiveMaterial. Pour l'implémenter, il suffit de suivre la doc sur la page Github, vous devriez être prêt en une minute (il ne nécessite que 3 lignes de code à ajouter).

L'index AA de nos clients avec le thème d'ActiveMaterial. Le code peut être trouvé ici.

L'index AA de nos clients avec le thème d'ActiveMaterial. Le code peut être trouvé ici.

L'interface de l'AA a changé et a maintenant un aspect différent. Avec un peu de configuration, nous pouvons facilement la personnaliser davantage. Le thème est fait en SASS (SCSS) donc nous pouvons rechercher des variables et modifier la configuration par défaut.


Personnalisation du thème

Si nous jetons un coup d'oeil aux variables de couleur disponibles, nous pouvons voir qu'il y en a 14. Pour cela, ajoutez un nouveau fichier app/assets/stylesheets/active_admin/variables/_colors.scss et exigez-le dans le fichier active_admin.scss avant les autres fichiers comme ceci.

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

Un exemple de code admin.scss


Maintenant, allons dans notre nouveau fichier _variables.scss et modifions un peu le thème ! Tout d'abord, nous devons définir notre palette de couleurs. ActiveMaterial étant un modèle de conception matérielle, j'ai utilisé un générateur de palette de couleurs matérielles pour cela. Il y en a plein disponibles sur le web, mais j'aime particulièrement Material.io.

La palette de couleurs de mon matériel

La palette de couleurs de mon matériel


Une fois que vous avez fini de définir votre modèle, il vous suffit de reporter la valeur dans notre fichier _variable.scss en réaffectant la valeur des variables SASS existantes :

$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%);

Voici mon fichier _variable.scss pour correspondre à la palette de couleurs ci-dessus.


Vous pouvez retrouver le code ici.

Bien sûr, il existe d'autres options pour une personnalisation plus poussée : polices, élévations, tailles, points d'arrêt. Pour ce faire, il suffit de répéter le même processus que pour la couleur.


Bascule de la barre latérale des filtres

Notre index thématique des clients AA avec une grande barre latérale de filtres sur la droite.

Notre index thématique des clients AA avec une grande barre latérale de filtres sur la droite.

Maintenant que nous avons ajouté quelques couleurs, nous pouvons voir que notre barre latérale de filtres occupe 20 % de l'écran. C'est un peu trop pour une fonctionnalité que vous n'utiliserez pas tout le temps, n'est-ce pas ? Trouvons un moyen de la faire apparaître uniquement en cas de besoin.

En cherchant une solution à ce problème, je suis tombé sur cet article d'Emanuele Tozzato qui montre une façon simple de régler le problème. Avec un peu de Jquery et de Css, il permet d'activer et de désactiver la barre latérale des filtres grâce à un élément d'action.

L'index de nos clients AA avec la barre latérale des filtres cachée et un élément d'action en haut à droite qui permet de basculer les filtres.

L'index de nos clients AA avec la barre latérale des filtres cachée et un élément d'action en haut à droite qui permet de basculer les filtres.

Nous allons juste pousser un peu plus loin son approche car je ne suis pas un grand fan de l'ajout d'un élément d'action. Ceux-ci devraient être utilisés pour les actions CRUD des administrateurs. J'ai donc modifié un peu le code pour déplacer le bouton de basculement des filtres en haut à droite de la table des index.

Même index, mais nous avons déplacé le bouton latéral de basculement des filtres sur le tableau des index.

Même index, mais nous avons déplacé le bouton latéral de basculement des filtres sur le tableau des index.

Si vous êtes intéressé, vous pouvez trouver le code ici.


Ajouter des bandes

Parfois, il peut être complexe pour un administrateur de distinguaer les éléments d'une ligne à l'autre. Une solution consiste à dépouiller le tableau. Pour ce faire, il suffit de créer un nouveau composant scss :

// 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%);
  }
}

Comment colorer une ligne sur deux d'un tableau en SAS


Pour la couleur des rayures, j'ai utilisé la valeur de notre $am-theme-paper (la couleur de fond des composants tels que les cartes ou les tables) et j'ai juste assombri les colonnes paires. Facile, non ? Vous pouvez trouver le code complet ici.

L'index de nos clients AA avec la table rayée.

L'index de nos clients AA avec la table rayée.


Décorez vos données

Parfois, vous pouvez trouver dans vos index des colonnes qui n'ont aucun intérêt à être séparées. Par exemple le prénom et le nom ou chaque partie d'une adresse. Vous pouvez alors rapidement les fusionner dans une nouvelle colonne "nom" ou "adresse complète".

Par ailleurs, lorsque vous affichez un montant, vous pouvez ajouter le formatage de la devise et des chiffres pour faciliter la lecture.

Vous pouvez utiliser un décorateur comme Draper pour cela. Cela évite de surcharger la logique d'administration.

__# 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

Un exemple de décorateur pour un client


Ensuite, pour chaque colonne décorée utilisée, n'oubliez pas de spécifier comment le tri doit se comporter comme ceci :

# 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

Exemple d'index AA pour un client

l'index des clients AA avec des données décorées.

l'index des clients AA avec des données décorées.


Améliorer l'affichage de l'état

Les ressources affichées dans un index d'administration sont souvent accompagnées d'un état. Dans notre index des clients, il s'agit d'un pipeline de vente de base. En effet, un client est d'abord dans l'état "nouveau" avant d'être contacté, puis il peut entrer dans la phase de négociation et enfin il devient signé. Il peut ensuite passer à la phase de résiliation (lorsqu'il annule le contrat).


Étiquettes d'état

Bien sûr, nous pouvons ajouter un peu de couleur en utilisant la fonction très simple status_tag d'ActiveAdmin.

Tout d'abord, nous ajoutons la logique status_tag dans la vue index de nos clients AA :

# 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

Ajouter un label sur un statut client AA


Nous pouvons ensuite utiliser une "map" SASS pour personnaliser la couleur de fond du status_tag :

// 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.


Convertir les étiquettes en progression

Le résultat est plus visuel mais d'un autre côté les états de nos clients sont linéaires ce qui signifie que pour chaque client, son premier état sera nouveau et enfin il entrera dans la phase terminée.

Notez que j'ai utilisé un enum pour cela car ces états n'ont pas besoin de transitions ou de gardes mais vous pouvez obtenir le même résultat avec une machine à états comme AASM ou Statesman.

Une façon de représenter graphiquement cette linéarité est d'afficher l'état dans une barre de progression. Lorsqu'elle est vide, cela signifie que le client est dans le nouvel état et lorsqu'elle est pleine, cela signifie que le client est soit signé soit terminé. Nous allons également réutiliser les schémas de couleurs définis précédemment pour rendre le tout plus visuel.

Tout d'abord, ajoutons une méthode dans notre décorateur client qui retournera l'état d'achèvement en pourcentage pour notre barre de progression :

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


Ensuite, nous rendrons un partial .html.erb dans notre colonne customer.state :

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


Maintenant nous pouvons créer notre partiel material_progress_bar  :


<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>


Enfin, un petit peu de style (n'oubliez pas de l'exiger dans votre fichier application.scss) :

@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, chef de projet web & mobile chez Capsens
Ismaël Boukhars10 févr. 2021

Blog de Capsens

Capsens est une agence spécialisée dans le développement de solutions fintech. Nous aimons les startups, la méthodologie scrum, le Ruby et le React.