Gestion des utilisateurs

Catégorie

Temps estimé :22 minutes 93 views

Introduction

Ce tutoriel vous guide à travers la création d’un module de gestion des catégories dans une application Vue.js. Ce module permet de gérer une liste de catégories de manière intuitive et efficace, offrant des fonctions essentielles telles que la recherche, l’ajout, l’édition et la suppression. Grâce à une interface utilisateur conviviale, les utilisateurs peuvent naviguer facilement dans une grande liste grâce à la fonctionnalité de pagination intégrée.

L’architecture du module repose sur Vue.js pour le développement de l’interface, Pinia pour une gestion d’état optimale, et Axios pour effectuer les appels API nécessaires à l’interaction avec les données. Les actions comme l’édition et la suppression sont déclenchées par des événements, garantissant une réactivité et une fluidité lors de l’utilisation. De plus, le système de filtres intégré permet une gestion efficace des catégories affichées, rendant la navigation et le suivi des catégories simples et rapides.

Dans ce tutoriel, nous explorerons le raisonnement derrière chaque étape, tout en expliquant comment nous avons structuré et implémenté les différentes fonctionnalités liées à la gestion des catégories. Vous apprendrez à créer un module puissant et adaptable, capable de répondre aux besoins variés des utilisateurs.

Prérequis

Pour utiliser ce composant dans votre projet, voici les prérequis nécessaires :

Yarn : Si nous avons utilisé Yarn dans le projet initialisé, assurons-nous qu’il est installé et configuré correctement dans notre environnement de développement.

Vue.js 3 : Ce composant est construit avec Vue.js 3. Assurez-vous que votre projet est bien configuré pour utiliser cette version.

Pinia:Vous devez installer et configurer Pinia dans votre projet.

Node.js version 18 ou supérieure : Assurons-nous d’utiliser Node.js version 18 ou ultérieure pour garantir la compatibilité avec les outils modernes et les bibliothèques que nous allons utiliser.

Familiarité avec la ligne de commande : Une compréhension de base des commandes en ligne est nécessaire pour gérer les opérations liées à la gestion des catégories et à l’utilisation de Pinia.

Découpage et Organisation du Projet

Voici à quoi devrait ressembler l’arborescence du projet:

├─ assets/     
  ├─ components/
  ├─ core/
      ├─ shared/
        ├─ apiformat/
          ├─ Pagination.ts
          ├─ category/
               └── apiformat.ts
      ├─ services/
         └── CategoryService.ts
  ├─ layouts/               
  ├─ views/ 
     ├─ crafted/ 
        ├─ settings/
          ├─ categories/
              └── TrueListeCategorie.vue
        ├─ widgets/
           ├─ tables/
              └── TruePartialCategoryTable.vue
        ├─ modals/  
           ├─ forms/  
             ├─ category/
                └── TrueAddCategoryModal.vue
                └── TrueEditCategoryModal.vue  
  ├─ router/ 
      └── clean.ts           
  ├─ stores/  
      └── trueCategory.ts                 
  ├─ App.vue            
  └─ main.ts  
  ├── .env 
  ├── .eslintrc.cjs 
  ├── .gitignore
  ├─ index.html

1. Configurer les Routes

Commencez par définir les routes pour accéder à la page de gestion des catégories.

Fichier router/clean.ts :

La route /categories est définie comme une sous-route qui charge un composant pour afficher la liste des catégories. Elle inclut également un titre de page pour apporter une meilleure expérience utilisateur. Ce composant est associé à la structure de navigation de l’application

import { createRouter,createWebHistory,type RouteRecordRaw,} from "vue-router";
import { useAuthStore } from "@/stores/auth";
import { useConfigStore } from "@/stores/config";

const routes: Array<RouteRecordRaw> = [
  	  //autres codes ...
    children: [
      //autres codes ...
      {
        path: "/categories",
        name: "categories",
        component: () =>
          import("@/views/crafted/pages/categories/ListeCategorie.vue"),
        meta: {
          pageTitle: "Categories",
        },      
      },
    ],
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;
  • Les routes sont définies dans un tableau de type RouteRecordRaw. Chaque route a un chemin (path), un nom (name), et un composant associé qui est chargé dynamiquement.
  • Route / : Sert de point d’entrée principal et redirige vers /dashboard. Cette route utilise un layout par défaut (DefaultLayout.vue) et applique un middleware d’authentification.
  • Route /categories : Charge un composant pour la liste des catégories avec un titre de page.

2. Configurer le Menu Latéral

Ajoutez une entrée pour les catégories dans la configuration du menu latéral.

Fichier layouts/default-layout/config/CleanMainMenu.ts :

import type { MenuItem } from "@/layouts/default-layout/config/types";

const MainMenuConfig: Array<MenuItem> = [
  {
    pages: [
      {
        heading: "Dashboard",
        route: "/dashboard",
        keenthemesIcon: "element-11",
        bootstrapIcon: "bi-app-indicator",
      },
    ],
  },
  {
    heading: "craft",
    route: "/crafted",
    pages: [
      {
        sectionTitle: "pages",
        route: "/pages",
        keenthemesIcon: "element-plus",
        bootstrapIcon: "bi-archive",
        sub: [
          {
            heading: "categories",
            route: "/categories",
          },
        ],
      },
    ],
  },
];

export default MainMenuConfig;

3.Création du Service

Créer un fichier CategoryService dans le dossier core/services/

CategoryService est responsable des appels API liés à la gestion des catégories fournissant des méthodes faciles pour effectuer des opérations HTTP courantes telles que créer, mettre à jour, supprimer et récupérer des ressources à l’aide d’Axios.Il centralise toutes les interactions avec le serveur, ce qui permet de rendre le code plus maintenable et réutilisable.

//core/services/categoryService.ts  
import type  { App } from "vue";
import type { AxiosResponse } from "axios";
import axios from "axios";
import VueAxios from "vue-axios";

class CategoryService {
  public static vueInstance: App;

  public static init(app: App<Element>) {
    CategoryService.vueInstance = app;
    CategoryService.vueInstance.use(VueAxios, axios);
    CategoryService.vueInstance.axios.defaults.baseURL =
      import.meta.env.VITE_APP_API_URL;
  }
  
  public static async post(resource: string,params: any): Promise<AxiosResponse> {/* Envoie une requête POST à la ressource spécifiée avec les paramètres fournis */}

  public static async update(resource: string,slug: string,params: any): Promise<AxiosResponse> {/* Envoie une requête PUT pour mettre à jour une ressource*/}
  
  public static async put(resource: string,params: any): Promise<AxiosResponse> {/* Envoie une requête PUT pour mettre à jour la ressource.*/}

  public static async delete(resource: string): Promise<AxiosResponse> {/* Envoie une requête DELETE pour supprimer une ressource.*/}

  public static async getById(resource: string): Promise<AxiosResponse> {/*Récupère une ressource identifiée par l'ID spécifié. */ }

  public static async getAll(resource: string): Promise<AxiosResponse> {   /* Récupère toutes les ressources depuis le point de terminaison spécifié.*/}
}

export default CategoryService;

NB : N’oublions pas de créer un fichier .env à la racine du projet. Dans ce fichier, définissez l’URL de l’API comme suit :

VITE_APP_API_URL="https://vesper.applizethat.com/"

Cette variable d’environnement sera utilisée dans notre service pour effectuer les requêtes HTTP.

4.API Format : Formatage des Données

Situé dans le répertoire  core/shared/apiformat/category/apiformat.ts, ce fichier est responsable du formatage des données API, garantissant une manipulation cohérente et standardisée des données à travers l’application.

import type { CategoryAttributes } from "@/stores/truecategory";

export const formatItem = (item: any): CategoryAttributes => {
  if (!item || !item.attributes) {
    throw new Error("Invalid item format");
  }

  return {
    id: item.id,
    title: item.attributes.title || "Untitled",
    created: item.attributes.created || "Unknown date",
  };
};

export const formatCategoryData = (response: any): CategoryAttributes[] => {
  const dataArray = response.data;

  if (!Array.isArray(dataArray)) {
    throw new Error("Invalid response format");
  }

  return dataArray.map(formatItem);
};

5.Pagination 

Situé dans le répertoire  core/shared/apiformat/Pagination.ts, ce fichier gère toute la pagination de notre application, centralisant la logique de pagination pour faciliter son intégration et sa maintenance.

class Pagination<T> {
  // variables

  constructor(config?: Partial<Pagination<T>>) {
    // variables 
  }

  setItemsPerPage(count: number) { this.itemsPerPage = count; }
  
  setCurrentPage(page: number) { this.currentPage = page; }
  
  setTotalItems(total: number) { this.totalItems = total; }
  
  setItems(items: T[]) { this.items = items; }
  
  addFilter(field: string, operator: string, value: string | string[]) { /* Code pour ajouter un filtre */ }
  
  removeFilter(field: string) { delete this.filters[field]; }
  
  setSortField(field: string) { /* Code pour définir un champ de tri */ }
  
  get offset() { return (this.currentPage - 1) * this.itemsPerPage; }
  
  totalPages(): number { return Math.ceil(this.totalItems / this.itemsPerPage); }
  
  prevPage() { if (this.currentPage > 1) this.currentPage--; }
  
  nextPage() { if (this.currentPage < this.totalPages()) this.currentPage++; }
  
  goToPage(page: number) { if (page >= 1 && page <= this.totalPages()) this.currentPage = page; }
  
  get queryString() { /* Code pour générer une chaîne de requête */ }
}

export default Pagination;

Classe de Pagination
La classe Pagination<T> est un outil générique utilisé pour gérer la pagination, le tri, et les filtres d’un ensemble de données dans une application. Cette classe vous permet de définir des paramètres de pagination, d’appliquer des filtres dynamiques sur les données, de définir un champ de tri, et de générer une chaîne de requête pour faire des appels API compatibles avec ces paramètres.


Attributs principaux

  • itemsPerPage : Nombre d’éléments affichés par page. Par défaut, il est initialisé à 5.
  • currentPage : Numéro de la page actuelle. Par défaut, il est initialisé à 1.
  • totalItems : Nombre total d’éléments dans l’ensemble de données. Cela permet de calculer le nombre total de pages.
  • items : Un tableau d’éléments de type générique T, représentant les données actuelles à afficher.
  • filters : Un objet représentant les filtres appliqués sur les données. Les filtres sont définis par des champs, des opérateurs (comme eq, contains, etc.), et des valeurs. Chaque champ peut avoir plusieurs conditions de filtre.
  • sortField : Champ utilisé pour trier les données. Par défaut, il n’y a pas de tri appliqué.
  • sortOrder : Ordre de tri, soit « asc » (ascendant) ou « desc » (descendant). Par défaut, c’est « asc ».

Méthodes disponibles :

  • setItemsPerPage(count: number):Définit le nombre d’éléments affichés par page.
  • setCurrentPage(page: number):Change la page actuelle.
  • setTotalItems(total: number):Définit le nombre total d’éléments (utilisé pour calculer le nombre de pages).
  • setItems(items: T[]):Associe les éléments actuels à afficher dans la pagination.
  • addFilter(field: string, operator: string, value: string | string[]):Ajoute un filtre sur un champ donné avec un opérateur spécifique (ex: eq, contains) et une valeur.
  • removeFilter(field: string):Supprime le filtre appliqué sur un champ donné.
  • setSortField(field: string):Définit le champ de tri et change l’ordre entre ascendant et descendant.
  • prevPage():Passe à la page précédente si elle existe.
  • nextPage():Passe à la page suivante si elle existe.
  • goToPage(page: number):Va à une page spécifique si elle est dans la plage de pages disponibles.
  • get offset:Retourne l’offset actuel, calculé à partir de la page courante et du nombre d’éléments par page.
  • totalPages(): number:Retourne le nombre total de pages.
  • get queryString:Génère une chaîne de requête pour les filtres, la pagination et le tri, à utiliser dans les appels API.

6.Création du Store

Commencons par ouvrir le fichier main.ts et importer createPinia pour pouvoir l'utiliser après dans le store.

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

Créer un fichier trueCategory dans le dossier stores/

Le store Pinia centralise la gestion de l’état des catégories, les erreurs, et les actions CRUD.

import { defineStore } from "pinia";
import CategoryService from "@/core/services/CategoryService";
import Pagination from "@/core/shared/apiformat/Pagination";
import { ref } from "vue";

export interface CategoryAttributes {
  id: string;
  title: string;
  created: string;
}

export const useTrueCategoryStore = defineStore("categoryStore", () => {
  const pagination = ref(new Pagination<CategoryAttributes>()), errors = ref({});

  const setError = (error: any) => (errors.value = { ...error }),
    addCategory = async (label: string) => { /* Ajout d'une catégorie */ },
    deleteCategory = async (id: string) => { /* Suppression d'une catégorie */ },
    getCategoryById = async (id: string) => { /* Récupération d'une catégorie */ },
    editCategory = async (id: string, title: string) => { /* Modification d'une catégorie */ },
    getAllCategories = async (params = {}) => { /* Récupération de toutes les catégories */ };

  return {
    pagination, errors, addCategory, deleteCategory, getCategoryById, getAllCategories, editCategory
  };
});

Ce code implémente un store Pinia qui gère les catégories dans notre application Vue.js. Le store utilise des services API pour effectuer des opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) sur les catégories, ainsi que pour gérer la pagination et les erreurs. Voici une explication détaillée de chaque section du code :

Attributs principaux

  • pagination : Utilise le modèle de pagination pour gérer une collection de catégories paginées.
  • errors : Stocke les erreurs potentielles lors des opérations API.

Methodes

  • setError : Cette fonction met à jour l’objet errors pour capturer les erreurs survenues lors des requêtes API.
  • addCategory : Cette fonction envoie une requête POST pour ajouter une nouvelle catégorie :
    • Le payload contient le nom de la catégorie.
    • En cas de succès, la nouvelle catégorie est ajoutée en haut de la liste paginée.
    • En cas d’erreur, elle est capturée par setError.
  • deleteCategory : Cette fonction supprime une catégorie par son id :
    • La catégorie est supprimée à l’aide d’une requête DELETE.
    • La liste paginée est mise à jour pour retirer la catégorie supprimée.
    • Si la page actuelle est vide après suppression, la pagination passe à la page précédente.
  • getCategoryById : Cette fonction récupère une catégorie spécifique par son id via une requête GET.
  • editCategory : Cette fonction met à jour une catégorie en fonction de son id :
    • Elle envoie une requête PUT à l’API.
    • Si la mise à jour réussit, la catégorie est mise à jour dans la liste paginée.
  • getAllCategories : Cette fonction récupère toutes les catégories avec pagination :
    • Les filtres et autres paramètres sont appliqués à la requête.
    • Les données reçues sont formatées et la pagination est mise à jour avec les nouvelles catégories.

7.Création des Vues

Pour faciliter la lecture et la compréhension, nous allons diviser la section “Création des vues” en plusieurs sous-parties distinctes. Cette approche nous permettra de suivre chaque étape de manière claire et organisée, en nous concentrant sur un aspect spécifique à chaque étape du processus.

Création de la vue PartialCategoryTable

Créer un fichier TruePartialCategoryTable dans le dossier views/crafted/widgets/Tables/

<template>
  <div class="card" :class="widgetClasses">
 	<!-- codes... -->
      
  </div>
</template>

<script lang="ts">
import {defineComponent,ref,computed,onMounted,getCurrentInstance,watch} from "vue";
import { Toast } from "bootstrap";
import { useI18n } from "vue-i18n";
import { useTrueCategoryStore } from "@/stores/truecategory";
import DateRangeFilter from "@/views/crafted/widgets/filter/DateRangeFilter.vue";
import ToastNotification from "@/views/crafted/widgets/Toast/ToastNotification.vue";

export default defineComponent({
  name: "TruePartialCategoryTable",
  components: {
    DateRangeFilter,
    ToastNotification,
  },
  props: {
    widgetClasses: String,
  },
  setup() {
    const { t } = useI18n();
    const checkedRows = ref<number[]>([]);
    const categoryStore = useTrueCategoryStore();
    const toastMessage = ref<string>("");
    //autres Variables réactives

    watch(itemsPerPage, (newCount) => { /* surveiller les changements d'une variable réactive */});

    onMounted(async () => {/*exécuter du code lorsque le composant est monté */});

    const updateTitleQuery = (e: Event) => {/*  filtrer des categories */};

    const updateItemsPerPage = (e: Event) => {/*changement du nombre d'éléments par page */ };

    const currentPage = computed(() => categoryStore.pagination.currentPage);
    const totalPages = computed(() => categoryStore.pagination.totalPages());
    const sortField = computed(() => categoryStore.pagination.sortField);
    const sortOrder = computed(() => categoryStore.pagination.sortOrder);

    const emitPrevPage = async () => {/* naviguer vers la page précédente */};

    const emitNextPage = async () => {/* navigation vers la page suivante */};

    const emitGoToPage = async (page: number) => {/* naviguer vers une page donnée */};

    const handleEditClick = (id: string) => {/* edition d'une categorie */};

    const showToast = (message, color, icon, iconColor, title) => {/* afficher une notification */};
    
    const handleDeleteClick = async (id: string) => { /* edition d'une categorie */  };

    const changeSort = (field: string) => { /*  gérer le tri des données en fonction du champ spécifié */  };

    const handleDateRangeChange = ({/* gérer les changements de plage de dates */ };
    
    return {t,checkedRows,emitNextPage,emitGoToPage,handleEditClick,handleDeleteClick,toggleAllCheckedRows,
      //autres ...
    };
  },
});
</script>
<style scoped>
/* style ...*/
</style>

Ce composant Vue.js offre une interface interactive pour la gestion des catégories, avec des fonctionnalités comme la recherche, le tri, la pagination, et des actions CRUD (ajout, modification, suppression). Il utilise des modales, des icônes personnalisées et des composants comme DateRangeFilter pour le filtrage par date, ainsi que des notifications visuelles via Bootstrap Toast. Le store Pinia est utilisé pour la gestion centralisée des données.

Variables réactives

  • Réactivité : Les variables comme checkedRows (pour les lignes sélectionnées), titleQuery (pour la recherche par titre), et itemsPerPage (pour la pagination) sont déclarées avec ref pour les rendre réactives.
  • Toast : Plusieurs variables (toastMessage, toastColor, etc.) sont utilisées pour gérer l’affichage des notifications toast.

Methodes

  • onMounted : Lors du montage du composant, toutes les catégories sont récupérées via categoryStore.getAllCategories(). Si une erreur se produit, elle est loggée dans la console.
  • Recherche par titre(updateTitleQuery) : est déclenchée lorsque l’utilisateur saisit une recherche par titre. Elle applique un filtre "CONTAINS" sur le titre et récupère les catégories filtrées.
  • updateItemsPerPage : est déclenchée lorsque l’utilisateur change le nombre d’éléments par page. La pagination est mise à jour, et les catégories sont récupérées.
  • Propriétés calculées : currentPage, totalPages, sortField, et sortOrder sont des propriétés calculées qui surveillent les valeurs dans categoryStore et réagissent aux changements.
  • Pagination : emitPrevPage et emitNextPage permettent de naviguer entre les pages et de récupérer les catégories correspondantes.
  • Tri : changeSort modifie le champ de tri (par exemple, tri par titre ou par date) et récupère les catégories triées.
  • handleDeleteClick : Lorsqu’une catégorie est supprimée, une notification toast de succès est affichée et les catégories sont de nouveau récupérées pour mettre à jour la table.
  • handleDateRangeChange : Le filtre par date (startDate, endDate) est ajouté ou supprimé en fonction de la sélection, et les catégories sont récupérées avec les filtres appropriés.

Création des Modales

Dans cette sous-partie, nous allons créer plusieurs composants modales, notamment TrueAddCategoryModal.vue et TrueEditCategoryModal.vue dans le répertoire crafted/modals/forms/category/.

Les modals permettent d’ajouter et de modifier des catégories sans changer de page.

TrueAddCategoryModal.vue
<template>
  <div>
    <!-- codes ... -->
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import { Modal, Toast } from "bootstrap";
import { useI18n } from "vue-i18n";
import { useTrueCategoryStore } from "@/stores/truecategory"; // Assurez-vous d'importer le store correct
import ToastNotification from "@/views/crafted/widgets/Toast/ToastNotification.vue";

export default defineComponent({
  name: "AddCategoryModal",
  components: {
    ToastNotification,
  },
  setup(_, { emit }) {
    const storeCategory = useTrueCategoryStore();
    const addCategoryModalRef = ref<null | HTMLElement>(null);
    const { t } = useI18n();
    const toastMessage = ref<string>("");
    //autres  Variables
    

    const formData = ref({ label: "",});

    const rules = ref({label: [{ required: true,message: t("messageLabel"),trigger: "change",},],});

    const hideModal = (modalRef: HTMLElement | null) => {/* masquer un modal */};

    const showToast = (message, color, icon, iconColor, title) => {/* afficher une notification */};

    const submit = async () => {/* fonction ajouter une nouvelle catégorie.*/};
    
    return {t,formRef,submit,rules,loading,addCategoryModalRef,toastMessage,
      //autres ...
    };
  },
});
</script>

<style>

   /* style ... */

</style>

Ce composant TrueAddCategoryModal.vue gère l’ajout de nouvelles catégories via un formulaire dans un modal. Voici une explication détaillée de son fonctionnement :

Références et État :

  • formRef, addCategoryModalRef, et toastRef sont des références pour manipuler respectivement le formulaire, le modal et le toast.
  • loading est une variable booléenne qui indique si une action est en cours (pour désactiver certaines interactions pendant le traitement).
  • formData contient les données du formulaire, ici avec un seul champ label pour le nom de la catégorie.
  • rules définit des règles de validation pour s’assurer que le champ label soit obligatoire.

Fonctionnalités Principales :

  • hideModal : Cette fonction cache le modal lorsque l’action est terminée ou en cas d’erreur.
  • showToast : Affiche une notification pour informer l’utilisateur du succès ou de l’échec de l’opération.
  • submit :
    • C’est la fonction principale qui soumet le formulaire pour ajouter une nouvelle catégorie.
    • Elle utilise le store useTrueCategoryStore pour appeler la fonction d’ajout.
    • En cas de succès, elle réinitialise le formulaire, affiche un toast de succès, et ferme le modal.
    • En cas d’erreur (comme un titre déjà existant), elle affiche un toast d’erreur avec des messages traduits (grâce à vue-i18n).
TrueEditCategoryModal.vue
<template>
  <div>
    <!-- codes ... -->
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch, reactive, onMounted } from "vue";
import type { ElForm } from "element-plus";
import { useI18n } from "vue-i18n";
import { Modal, Toast } from "bootstrap";
import { useTrueCategoryStore,type CategoryAttributes,} from "@/stores/truecategory";
import { hideModal } from "@/core/helpers/modal";
import ToastNotification from "@/views/crafted/widgets/Toast/ToastNotification.vue";

export default defineComponent({
  name: "EditCategoryModal",
  components: {
    ToastNotification,
  },
  props: {
    editCategoryId: {
      type: String,
      required: true,
    },
  },
  setup(props, { emit }) {
    const formRef = ref<InstanceType<typeof ElForm>>();
    const toastRef = ref<HTMLElement | null>(null);
    const { t } = useI18n();
    const categoryStore = useTrueCategoryStore();
    const toastMessage = ref<string>("");
    //autres variables 

    const formData = reactive<CategoryAttributes>({ id: "", title: "",created: "", });

    const rules = { title: [{ required: true, message: t("titleRequired"), trigger: "blur" }],};

    const loadCategoryData = async () => {/*  charger les données de la catégorie. nécessaires concernant une catégorie.*/ };

    watch(
      () => props.editCategoryId,
      () => {
        loadCategoryData();
      },
      { immediate: true }
    );
    const showToast = (message, color, icon, iconColor, title) => {/* afficher une notification*/ };

    const submit = async () => {/* modification categorie*/};

    return { formData,submit,formRef,editCategoryModalRef, t,toastMessage,
      //autres ...
    };
  },
});
</script>

<style scoped>

  /* code style ... */

</style>

EditCategoryModal.vue est conçu pour gérer la modification d’une catégorie existante dans l’application . Il s’appuie sur un formulaire réactif, valide les entrées utilisateur, et met à jour les données en temps réel via le store, tout en assurant une gestion robuste des erreurs et une expérience utilisateur améliorée avec des notifications visuelles.Voici une explication détaillée de son fonctionnement :

Propriétés et Réactivité :

  • editCategoryId est une propriété passée au composant, elle représente l’ID de la catégorie à modifier.
  • formData est un objet réactif qui contient les informations de la catégorie en cours d’édition (comme id, title, et created).
  • Les règles de validation (rules) assurent que le champ title soit obligatoire.

Fonctionnalités Principales :

  • Chargement des Données de la Catégorie :
    • loadCategoryData est appelée pour récupérer les données de la catégorie correspondant à editCategoryId depuis le store.
    • Si les données sont valides (c’est-à-dire que l’ID et le titre existent), elles sont assignées à formData.
  • Validation et Soumission du Formulaire
    • La fonction submit est appelée lorsque l’utilisateur soumet le formulaire.
    • Avant d’envoyer les données modifiées, le formulaire est validé via formRef.value.validate. Si les données sont valides, la catégorie est mise à jour dans le store à l’aide de editCategory.
  • Affichage des Notifications (Toasts)
    • La fonction showToast est utilisée pour afficher des notifications de succès ou d’erreur après la soumission du formulaire.
    • Les toasts sont personnalisés avec des couleurs, icônes, et messages traduits.
  • Gestion des Modales
    • Après la soumission réussie, la modale est fermée à l’aide de la fonction hideModal et un événement categoryUpdated est émis pour informer les composants parents que la catégorie a été mise à jour.
  • Gestion des Erreurs :
    • Si une erreur survient lors du chargement ou de l’édition des données de la catégorie, un message d’erreur est affiché via les toasts et l’erreur est loguée dans la console.

8. Créer la Vue TrueListeCategorie

Créer un fichier TrueListeCategorie.vue dans le dossier views/crafted/settings/categories/

<template>
  <div>
    <TablesWidget9
      @editCategory="handleEditCategory"
      @categoryAdded="getAllCategories"
      @categoryUpdated="getAllCategories"
      widget-classes="mb-5 mb-xl-8"
    ></TablesWidget9>
    <AddCategory @categoryAdded="getAllCategories" />
    <EditCategory
      :editCategoryId="selectedCategoryId"
      @categoryUpdated="getAllCategories"
    />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, computed } from "vue";
import TablesWidget9 from "@/views/crafted/widgets/Tables/TruePartialCategoryTable.vue";
import AddCategory from "@/views/crafted/modals/forms/category/TrueAddCategoryModal.vue";
import EditCategory from "@/views/crafted/modals/forms/category/TrueEditEditCategoryModal.vue";
import { useI18n } from "vue-i18n";
import { useTrueCategoryStore } from "@/stores/truecategory";

export default defineComponent({
  name: "TrueListeCategorie",
  components: {
    TablesWidget9,
    AddCategory,
    EditCategory,
  },
  setup() {
    const selectedCategoryId = ref<string>("");
    const categoryStore = useTrueCategoryStore();
    const { getAllCategories, pagination } = categoryStore;
    const toastRef = ref<null | HTMLElement>(null);
    //autres variables ...

    onMounted(async () => {
     //codes...
    });

    const handleEditCategory = (id: string) => {selectedCategoryId.value = id;};

    return { getAllCategories,handleEditCategory,
      //autres ...
    };
  },
});
</script>

CONTENTS