EasyAdmin 3 premier pas – Personalisation de la page du dashboard

EasyAdmin 3 premier pas – Personalisation de la page du dashboard

Attention à l’heure de l’écriture, EasyAdmin3 est en Alpha. Certaine choses peuvent changer.

Comme dit dans la documentation, un dashboard est un controlleur Symfony standard.

En lieu et place de la page vide du dashboard nous allons afficher nos informations.

La première est d’utiliser notre template twig et de lui passre les valeurs qui nous intéressent et d’étendre le template de base d’EasyAdmin3

public function index(): Response
    {
        $accounts = $this->getDoctrine()->getRepository(Account::class)->count([]);
        $contacts = $this->getDoctrine()->getRepository(Contact::class)->count([]);

        return $this->render('Admin/dashboard.html.twig', [
            'accounts' => $accounts,
            'contacts' => $contacts,
        ]);
    }
{% extends '@EasyAdmin/layout.html.twig' %}

{% block main %}
You have {{ accounts }} accounts and {{ contacts }} contacts.
{% endblock %}

Pour la suite nous ajoutons le bundle suivant

 composer require stof/doctrine-extensions-bundle

Nous configurons l’extension pour utiliser timestampable dans le fichier stof_doctrine_extensions.yaml

stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            tree: true
            timestampable: true

Nous rajoutons dans nos entitées les champs created et updated a l’aide de la commande « bin/console make:entity » puis nous ajoutons l’annotation timestampable:

/**
 * @ORM\Column(type="datetime")
 * @Gedmo\Timestampable(on="create")
  */
private $created;

/**
 * @ORM\Column(type="datetime")
 * @Gedmo\Timestampable(on="update")
 */
private $updated;

Dans AccountRepository nous rajoutons la fonction getAccountsLastDays

public function getAccountsLastDays() {
        $stmt  = $this->getEntityManager()->getConnection()->prepare('SELECT COUNT(id) num, DATE(created) d FROM account GROUP BY DATE(created)');
        $stmt->execute();
        return $stmt->fetchAll(FetchMode::STANDARD_OBJECT);
    }

Si vous savez comment faire la même chose avec Doctrine plutôt qu’avec du SQL je suis preneur 🙂

Nous pouvons dorenavant utiliser cette fonctions dans notre DashboardController

private function getAccountsLastDays()
    {
        $accountLast30Days = $this->getDoctrine()->getRepository(Account::class)->getAccountsLastDays();
        $r = [];
        $begin = new \DateTime('-'.$days.' day');
        $end = new \DateTime();

        $interval = \DateInterval::createFromDateString('1 day');
        $period = new \DatePeriod($begin, $interval, $end);

        foreach ($period as $dt) {
            $r[$dt->format("Y-m-d")] = 0;
        }
        foreach ($accountLast30Days as $accountLast30Day) {
            $r[$accountLast30Day->d] = $accountLast30Day->num;
        }

        ksort($r);

        return $r;
    }

public function index(): Response
    {
        $accounts = $this->getDoctrine()->getRepository(Account::class)->count([]);
        $accountLast30Days = $this->getAccountsLastDays();
        $contacts = $this->getDoctrine()->getRepository(Contact::class)->count([]);

        return $this->render('Admin/dashboard.html.twig', [
            'accounts' => $accounts,
            'contacts' => $contacts,
            'accountLast30Days' => $accountLast30Days,
            'accountLast30DaysSum' => array_sum($accountLast30Days),
        ]);
    }

En utilisant apexcharts nous pouvons alors afficher un beau widget:

EasyAdmin 3 premier pas – Création d’entités et relation

EasyAdmin 3 premier pas – Création d’entités et relation

Attention à l’heure de l’écriture, EasyAdmin3 est en Alpha. Certaine choses peuvent changer.

Première étape, mettre EasyAdmin3 à jour, la version alpha4 corrige la création des entités.

Nous créons ensuite une entité Account avec entre autre une relation avec l’entité Contact et nous mettons à jour la base de données.

Et pour finir créons le CRUD pour notre nouvelle entité.

composer require easycorp/easyadmin-bundle:v3.0.0-alpha4
bin/console make:entity
bin/console doctrine:schema:update --force
bin/console make:admin:crud

Nous configurons le CRUD Account de la façon suivante:

public function configureFields(string $pageName): iterable
    {
        return [
            TextField::new('name'),
            TextEditorField::new('description'),
            CountryField::new('country'),
            UrlField::new('website'),
            AssociationField::new('contacts'),
            CurrencyField::new('currency'),
        ];
    }

Afin d’obtenir le résultat suivant lors de la création d’un Account:

Sur la vue liste des Account on peut voir :

Pour la partie Contact, afin de pouvoir ajouter un contact il faut ajouter la fonction __toString a l’entité Account:

public function __toString()
    {
        return $this->name;
    }

Pour le code direction https://gitlab.com/dayo/easy3firststeps

EasyAdmin 3 premier pas – 1

EasyAdmin 3 premier pas – 1

Attention à l’heure de l’écriture, EasyAdmin3 est en Alpha. Certaine choses peuvent changer.

Commençons par créer notre projet symfony, puis ajoutons easyadmin:

composer create-project symfony/website-skeleton easy3
composer require easycorp/easyadmin-bundle:v3.0.0-alpha3

Si vous avez une erreur avec des fichiers yaml faites ce qui suit:

Supprimer config/packages/easy_admin.yaml et config/routes/easy_admin.yaml

Configurez ensuite la connexion a la base de donnée puis crée la table:

bin/console doctrine:schema:create

Afin d’utiliser l’admin, créons une entité Contact avec comme champs: email, phone, country, lastName, firstName.

Passons maintenant a EasyAdmin, il nous faut créer un dashboard et un crud avec les commandes suivantes:

bin/console make:admin:dashboard
bin/console make:admin:crud

Lorsque l’on vous le demande, sélectionnez l’entité Contact.

Dans la fonction configureMenuItems du fichier DashboardController.php ajoutez:

yield MenuItem::linkToCrud('Contact', 'fa fa-user', Contact::class);

Dans la classe ContactCrudController ajouter les champs a la fonction configureFields:

TextField::new('email'),
TextField::new('phone'),
TextField::new('lastName'),
TextField::new('firstName'),
TextField::new('country'),

Rendez vous sur l’url de votre projet /admin et vous devriez voir cela:

Vue.js et localstorage

Vue.js et localstorage

Afin d’utiliser les données https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data/csse_covid_19_time_series nous allons les récupérés a la création de notre application.

Pour ce faire nous regardons si nous avons dans le localstorage une date de défini ou de moins d’une heure. Si non, nous récupérons à l’aide de fetch les données, convertissons le csv a l’aide de papaparse puis stockons le résultats sous forme de JSON dans le localstorage.

Une fois les 3 fichiers chargés grâce à Promise.all, nous allons vers la route /single.

if (localStorage.date === undefined || localStorage.date < Date.now() - 3600) {
                this.$router.push('/');
                localStorage.date = Date.now();
                Promise.all([
                    fetch('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv')
                        .then((resp) => resp.text())
                        .then((data) => {
                            localStorage.confirmed = JSON.stringify(Papa.parse(data));
                        }),
                    fetch('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv')
                        .then((resp) => resp.text())
                        .then((data) => {
                            localStorage.recovered = JSON.stringify(Papa.parse(data));
                        }),
                    fetch('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv')
                        .then((resp) => resp.text())
                        .then((data) => {
                            localStorage.death = JSON.stringify(Papa.parse(data));
                        }),
                ])
                    .then(() => this.$router.push('/single'));
            }

Le dépôt est accessible sur: https://gitlab.com/dayo/covid19 et l’application: https://dayo.gitlab.io/covid19/single

for en JavaScript sur un tableau

for en JavaScript sur un tableau

Une grande partie viens de MDN.

for

for ([initialisation]; [condition]; [expression_finale]) {
   instruction
}

Permet d’initialiser des variables, de spécifier une condition pour finir la boucle, une expression final exécuté a la fin de chaque boucle et enfin les instructions a effectuer.

let str = "";

for (let i = 0; i < 9; i++) {
  str = str + i;
}

console.log(str);
// "012345678"

for…in

for (variable in objet) {
  instructions
}

Utile pour parcourir les propriété d’un objet. Attention avec les tableau car l’ordre de parcours n’est pas garantie.

var obj = {a:1, b:2, c:3};
    
for (var prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}

// Affiche dans la console :
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

for…of

for (variable of iterable) {
  instruction
}

Permet de parcourir tout objet itérable et d’exécuter les instructions.

let iterable = new Map([['a', 1], ['b', 2], ['c', 3]]);

for (let element of iterable) {
  console.log(element);
}
// ['a', 1]
// ['b', 2]
// ['c', 3]

for (let [clef, valeur] of iterable) {
  console.log(clef + ':' + valeur);
}
// a:1
// b:2
// c:3

Array.forEach

arr.forEach(callback);
arr.forEach(callback, thisArg);

Exécute la fonction callback sur chacun des éléments.

const array1 = ['a', 'b', 'c'];

array1.forEach(element => console.log(element));
// "a"
// "b"
// "c"

[2, 5, , 9].forEach(function(element, index, array) {
    console.log("a[" + index + "] = " + element);
});
// a[0] = 2
// a[1] = 5
// a[3] = 9

Sources:

  • https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/for
  • https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/for…in
  • https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/for…of
  • https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/forEach