#192 Pagination des pages admin. On peut passer à la page précédente seulement si le numéro de page est >0 et la dernière page n'affiche pas de bouton pour la page suivante.

This commit is contained in:
josephine.vetu
2026-04-03 15:22:24 +02:00
parent 9e0a9751d1
commit 279fd75459
27 changed files with 346 additions and 77 deletions

View File

@@ -1,5 +1,7 @@
namespace Webzine.Business; namespace Webzine.Business;
using Microsoft.Extensions.Logging;
using Webzine.Business.Contracts; using Webzine.Business.Contracts;
using Webzine.Business.Contracts.Dto; using Webzine.Business.Contracts.Dto;
using Webzine.Entity; using Webzine.Entity;

View File

@@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Faker.Net" Version="2.0.163" /> <PackageReference Include="Faker.Net" Version="2.0.163" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.5" />
<PackageReference Include="NLog" Version="6.1.1" /> <PackageReference Include="NLog" Version="6.1.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118"> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View File

@@ -40,5 +40,11 @@ namespace Webzine.Repository.Contracts
/// <param name="limit">Le nombre maximum de commentaires à récupérer.</param> /// <param name="limit">Le nombre maximum de commentaires à récupérer.</param>
/// <returns>Une collection de commentaires paginée.</returns> /// <returns>Une collection de commentaires paginée.</returns>
IEnumerable<Commentaire> FindCommentaires(int offset, int limit); IEnumerable<Commentaire> FindCommentaires(int offset, int limit);
/// <summary>
/// Retourne le nombre total de commentaires dans la source de données.
/// </summary>
/// <returns>Le nombre total de commentaires.</returns>
int Count();
} }
} }

View File

@@ -43,5 +43,13 @@ namespace Webzine.Repository.Contracts
/// </summary> /// </summary>
/// <returns>Le nombre total de styles présents dans la liste.</returns> /// <returns>Le nombre total de styles présents dans la liste.</returns>
int Count(); int Count();
/// <summary>
/// Recherche les styles dans la liste des styles en fonction de l'offset et de la limite spécifiés, permettant ainsi une pagination des résultats.
/// </summary>
/// <param name="offset">Le nombre de styles à ignorer avant de commencer à retourner les résultats.</param>
/// <param name="limit">Le nombre maximum de styles à retourner.</param>
/// <returns>Une collection de styles correspondant au critère de pagination, triée par libellé.</returns>
IEnumerable<Style> FindStyles(int offset, int limit);
} }
} }

View File

@@ -208,28 +208,23 @@ namespace Webzine.Repository
} }
} }
/// <summary> /// <inheritdoc/>
/// Permet de paginer les artistes en fonction du numéro de page et de la taille de page spécifiés. public IEnumerable<Artiste> FindArtistes(int offset, int limit)
/// </summary>
/// <param name="pageNumber">Le numéro de la page à récupérer.</param>
/// <param name="pageSize">La taille de chaque page.</param>
/// <returns>Une liste d'artistes pour la page demandée.</returns>
public IEnumerable<Artiste> FindArtistes(int pageNumber, int pageSize)
{ {
try try
{ {
var artistes = this.context.Artistes var artistes = this.context.Artistes
.AsNoTracking() .AsNoTracking()
.OrderBy(a => a.Nom)
.Include(t => t.Titres) .Include(t => t.Titres)
.Skip((pageNumber - 1) * pageSize) .Skip(offset)
.Take(pageSize) .Take(limit);
.ToList(); this.logger.LogDebug("Page {PageNumber} d'artistes récupérée avec {PageSize} artistes par page.", offset, limit);
this.logger.LogDebug("Page {PageNumber} d'artistes récupérée avec {PageSize} artistes par page.", pageNumber, pageSize);
return artistes; return artistes;
} }
catch (Exception ex) catch (Exception ex)
{ {
this.logger.LogError(ex, "Erreur lors de la pagination des artistes. Page: {PageNumber}, Taille: {PageSize}", pageNumber, pageSize); this.logger.LogError(ex, "Erreur lors de la pagination des artistes. Page: {PageNumber}, Taille: {PageSize}", offset, limit);
throw; throw;
} }
} }

View File

@@ -114,4 +114,19 @@ public class DbCommentaireRepository : ICommentaireRepository
throw new Exception("Une erreur est survenue lors de la pagination des commentaires.", ex); throw new Exception("Une erreur est survenue lors de la pagination des commentaires.", ex);
} }
} }
/// <inheritdoc/>
public int Count()
{
try
{
this.logger.LogDebug("Comptage du nombre total de commentaires");
return Enumerable.Count(this.context.Commentaires);
}
catch (Exception ex)
{
this.logger.LogError(ex, "Erreur lors du comptage des commentaires");
throw new Exception("Une erreur est survenue lors du comptage des commentaires.", ex);
}
}
} }

View File

@@ -182,4 +182,27 @@ public class DbStyleRepository : IStyleRepository
throw; throw;
} }
} }
/// <inheritdoc/>
public IEnumerable<Style> FindStyles(int offset, int limit)
{
try
{
this.logger.LogDebug("Récupération paginée des styles (offset: {Offset}, limit: {Limit})", offset, limit);
var styles = this.context.Styles
.AsNoTracking()
.OrderBy(s => s.Libelle)
.Skip(offset)
.Take(limit);
this.logger.LogDebug("La liste paginée de styles a été récupérée.");
return styles;
}
catch (Exception ex)
{
this.logger.LogError(ex, "Erreur lors de la récupération paginée des styles (offset: {Offset}, limit: {Limit})", offset, limit);
throw;
}
}
} }

View File

@@ -233,17 +233,14 @@ public class DbTitreRepository : ITitreRepository
try try
{ {
this.logger.LogInformation("Recherche des titres avec le mot-clé: {Mot}", mot); this.logger.LogInformation("Recherche des titres avec le mot-clé: {Mot}", mot);
this.logger.LogDebug("Préparation de la requête de recherche avec les inclusions");
var titres = this.context.Titres var titres = this.context.Titres
.Include(t => t.Artiste) .Include(t => t.Artiste)
.Include(t => t.Styles) .Include(t => t.Styles)
.Where(t => t.Libelle.ToLower().Contains(mot.ToLower())) .Where(t => t.Libelle.ToLower().Contains(mot.ToLower()))
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.AsNoTracking() .AsNoTracking();
.ToList();
this.logger.LogDebug("{Count} titres trouvés correspondant à '{Mot}'", titres.Count, mot);
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)
@@ -264,7 +261,7 @@ public class DbTitreRepository : ITitreRepository
.Include(t => t.Artiste) .Include(t => t.Artiste)
.Include(t => t.Styles) .Include(t => t.Styles)
.Include(t => t.Commentaires) .Include(t => t.Commentaires)
.FirstOrDefault(t => t.IdTitre == idTitre); .SingleOrDefault(t => t.IdTitre == idTitre);
return titre; return titre;
} }
@@ -293,9 +290,9 @@ public class DbTitreRepository : ITitreRepository
.Include(t => t.Styles) .Include(t => t.Styles)
.Include(t => t.Commentaires) .Include(t => t.Commentaires)
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.ToList(); .AsNoTracking();
this.logger.LogDebug("{Count} titres récupérés", titres.Count); this.logger.LogDebug("{Count} titres récupérés", titres.Count());
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)
@@ -318,9 +315,9 @@ public class DbTitreRepository : ITitreRepository
.Include(t => t.Styles) .Include(t => t.Styles)
.Where(t => t.Styles.Any(s => s.Libelle.ToLower() == libelle.ToLower())) .Where(t => t.Styles.Any(s => s.Libelle.ToLower() == libelle.ToLower()))
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.ToList(); .AsNoTracking();
this.logger.LogDebug("{Count} titres trouvés pour le style '{Libelle}'", titres.Count, libelle); this.logger.LogDebug("{Count} titres trouvés pour le style '{Libelle}'", titres.Count(), libelle);
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -108,14 +108,12 @@ namespace Webzine.Repository
} }
/// <inheritdoc/> /// <inheritdoc/>
/// <param name="pageNumber">Le numéro de la page à récupérer.</param> public IEnumerable<Artiste> FindArtistes(int offset, int limit)
/// <param name="pageSize">La taille de chaque page.</param>
/// <returns>Une liste d'artistes pour la page demandée.</returns>
public IEnumerable<Artiste> FindArtistes(int pageNumber, int pageSize)
{ {
return this.dataStore.Artistes return this.dataStore.Artistes
.Skip((pageNumber - 1) * pageSize) .OrderBy(a => a.Nom)
.Take(pageSize) .Skip(offset)
.Take(limit)
.ToList(); .ToList();
} }
} }

View File

@@ -66,5 +66,11 @@ namespace Webzine.Repository
.Skip(offset) .Skip(offset)
.Take(limit); .Take(limit);
} }
/// <inheritdoc/>
public int Count()
{
return this.dataStore.Commentaires.Count;
}
} }
} }

View File

@@ -71,4 +71,14 @@ public class LocalStyleRepository : IStyleRepository
{ {
return this.dataStore.Styles.Count; return this.dataStore.Styles.Count;
} }
/// <inheritdoc/>
public IEnumerable<Style> FindStyles(int offset, int limit)
{
return this.dataStore.Styles
.OrderBy(s => s.Libelle)
.Skip(offset)
.Take(limit)
.ToList();
}
} }

View File

@@ -12,9 +12,9 @@ using Webzine.WebApplication.Areas.Administration.ViewModels.Artiste;
[Area("Administration")] [Area("Administration")]
public class ArtisteController : Controller public class ArtisteController : Controller
{ {
// Injection du logger via le constructeur
private readonly ILogger<ArtisteController> logger; private readonly ILogger<ArtisteController> logger;
private readonly IArtisteRepository artisteRepository; private readonly IArtisteRepository artisteRepository;
private readonly IConfiguration configuration;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ArtisteController"/> class. /// Initializes a new instance of the <see cref="ArtisteController"/> class.
@@ -22,25 +22,39 @@ public class ArtisteController : Controller
/// </summary> /// </summary>
/// <param name="logger">Logger.</param> /// <param name="logger">Logger.</param>
/// <param name="artisteRepository">Repository pour les artistes.</param> /// <param name="artisteRepository">Repository pour les artistes.</param>
/// <param name="configuration">Configuration.</param>
public ArtisteController( public ArtisteController(
ILogger<ArtisteController> logger, ILogger<ArtisteController> logger,
IArtisteRepository artisteRepository) IArtisteRepository artisteRepository,
IConfiguration configuration)
{ {
this.logger = logger; this.logger = logger;
this.artisteRepository = artisteRepository; this.artisteRepository = artisteRepository;
this.configuration = configuration;
} }
/// <summary> /// <summary>
/// Affiche la liste des artistes. /// Affiche la liste des artistes paginée.
/// </summary> /// </summary>
/// <param name="page">Le numéro de page pour la pagination des artistes (par défaut à 0).</param>
/// <returns>Redirection.</returns> /// <returns>Redirection.</returns>
public IActionResult Index() public IActionResult Index(int page = 0)
{ {
IEnumerable<Artiste> artistes = this.artisteRepository.FindAll(); int artistes_par_page = this.configuration.GetValue<int>("Webzine:NombreDeLignesAdministration");
var artistes_ordre = artistes.OrderBy(t => t.Nom).ToList(); IEnumerable<Artiste> artistes = this.artisteRepository.FindArtistes(page * artistes_par_page, artistes_par_page);
return this.View(artistes_ordre); int totalArtistes = this.artisteRepository.Count();
int totalPages = (int)Math.Ceiling((double)totalArtistes / artistes_par_page);
var model = new ArtisteIndexViewModel
{
Artistes = artistes.ToList(),
Page = page,
TotalPages = totalPages,
};
return this.View(model);
} }
/// <summary> /// <summary>

View File

@@ -13,6 +13,7 @@ namespace Webzine.WebApplication.Areas.Administration.Controllers
{ {
private readonly ILogger<CommentaireController> logger; private readonly ILogger<CommentaireController> logger;
private readonly ICommentaireRepository commentaireRepository; private readonly ICommentaireRepository commentaireRepository;
private readonly IConfiguration configuration;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CommentaireController"/> class. /// Initializes a new instance of the <see cref="CommentaireController"/> class.
@@ -21,10 +22,15 @@ namespace Webzine.WebApplication.Areas.Administration.Controllers
/// </summary> /// </summary>
/// <param name="logger">Service de journalisation injecté.</param> /// <param name="logger">Service de journalisation injecté.</param>
/// <param name="commentaireRepository">Le repository des commentaires injecté.</param> /// <param name="commentaireRepository">Le repository des commentaires injecté.</param>
public CommentaireController(ILogger<CommentaireController> logger, ICommentaireRepository commentaireRepository) /// <param name="configuration">Service de configuration injecté pour accéder aux paramètres de configuration.</param>
public CommentaireController(
ILogger<CommentaireController> logger,
ICommentaireRepository commentaireRepository,
IConfiguration configuration)
{ {
this.logger = logger; this.logger = logger;
this.commentaireRepository = commentaireRepository; this.commentaireRepository = commentaireRepository;
this.configuration = configuration;
this.logger.LogInformation("Initialisation du contrôleur CommentaireController."); this.logger.LogInformation("Initialisation du contrôleur CommentaireController.");
} }
@@ -32,16 +38,23 @@ namespace Webzine.WebApplication.Areas.Administration.Controllers
/// <summary> /// <summary>
/// Affiche la liste des commentaires dans la vue Index. /// Affiche la liste des commentaires dans la vue Index.
/// </summary> /// </summary>
/// <param name="page">Le numéro de page pour la pagination des commentaires (par défaut à 0).</param>
/// <returns>La vue Index avec le ViewModel contenant la liste des commentaires.</returns> /// <returns>La vue Index avec le ViewModel contenant la liste des commentaires.</returns>
public IActionResult Index() public IActionResult Index(int page = 0)
{ {
int commentaires_par_page = this.configuration.GetValue<int>("Webzine:NombreDeLignesAdministration");
// Récupération des commentaires depuis le repository // Récupération des commentaires depuis le repository
var commentaires = this.commentaireRepository.FindAll(); var commentaires = this.commentaireRepository.FindCommentaires(page * commentaires_par_page, commentaires_par_page);
int totalCommentaires = this.commentaireRepository.Count();
// Initialisation du ViewModel // Initialisation du ViewModel
var viewModel = new CommentaireViewModel var viewModel = new CommentaireIndexViewModel
{ {
Commentaires = commentaires, Commentaires = commentaires,
Page = page,
TotalPages = (int)Math.Ceiling((double)totalCommentaires / commentaires_par_page),
}; };
return this.View(viewModel); return this.View(viewModel);

View File

@@ -14,18 +14,22 @@ public class StyleController : Controller
{ {
private readonly ILogger<StyleController> logger; private readonly ILogger<StyleController> logger;
private readonly IStyleRepository styleRepository; private readonly IStyleRepository styleRepository;
private readonly IConfiguration configuration;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="StyleController"/> class. /// Initializes a new instance of the <see cref="StyleController"/> class.
/// </summary> /// </summary>
/// <param name="logger">Service de journalisation injecte.</param> /// <param name="logger">Service de journalisation injecte.</param>
/// <param name="styleRepository">Repository des styles injecte.</param> /// <param name="styleRepository">Repository des styles injecte.</param>
/// <param name="configuration">Service de configuration injecte pour acceder aux parametres de configuration.</param>
public StyleController( public StyleController(
ILogger<StyleController> logger, ILogger<StyleController> logger,
IStyleRepository styleRepository) IStyleRepository styleRepository,
IConfiguration configuration)
{ {
this.logger = logger; this.logger = logger;
this.styleRepository = styleRepository; this.styleRepository = styleRepository;
this.configuration = configuration;
this.logger.LogInformation("Initialisation du controleur StyleController."); this.logger.LogInformation("Initialisation du controleur StyleController.");
} }
@@ -33,12 +37,22 @@ public class StyleController : Controller
/// <summary> /// <summary>
/// Affiche la liste des styles dans la vue Index. /// Affiche la liste des styles dans la vue Index.
/// </summary> /// </summary>
/// <param name="page">Le numero de page pour la pagination des styles (par defaut a 0).</param>
/// <returns>La vue Index avec la liste des styles.</returns> /// <returns>La vue Index avec la liste des styles.</returns>
public IActionResult Index() public IActionResult Index(int page = 0)
{ {
IEnumerable<Style> listeStyles = this.styleRepository.FindAll().Take(10); int styles_par_page = this.configuration.GetValue<int>("Webzine:NombreDeLignesAdministration");
IEnumerable<Style> listeStyles = this.styleRepository.FindStyles(page * styles_par_page, styles_par_page);
return this.View(listeStyles); int totalStyles = this.styleRepository.Count();
var model = new StyleIndexViewModel
{
Styles = listeStyles,
Page = page,
TotalPages = (int)Math.Ceiling((double)totalStyles / styles_par_page),
};
return this.View(model);
} }
/// <summary> /// <summary>

View File

@@ -17,6 +17,7 @@ using Webzine.WebApplication.Areas.Administration.ViewModels.Titre;
public class TitreController : Controller public class TitreController : Controller
{ {
private readonly ILogger<TitreController> logger; private readonly ILogger<TitreController> logger;
private readonly IConfiguration configuration;
private readonly ITitreRepository titreRepository; private readonly ITitreRepository titreRepository;
private readonly IArtisteRepository artisteRepository; private readonly IArtisteRepository artisteRepository;
private readonly IStyleRepository styleRepository; private readonly IStyleRepository styleRepository;
@@ -31,9 +32,17 @@ public class TitreController : Controller
/// <param name="artisteRepository">Repository des artistes injecté pour accéder aux données des artistes, nécessaires pour les associations avec les titres.</param> /// <param name="artisteRepository">Repository des artistes injecté pour accéder aux données des artistes, nécessaires pour les associations avec les titres.</param>
/// <param name="styleRepository">Repository des styles injecté pour accéder aux données des styles, nécessaires pour les associations avec les titres.</param> /// <param name="styleRepository">Repository des styles injecté pour accéder aux données des styles, nécessaires pour les associations avec les titres.</param>
/// <param name="titreAdminService">Service Titre Administration injecté gérant Edit et Crée.</param> /// <param name="titreAdminService">Service Titre Administration injecté gérant Edit et Crée.</param>
public TitreController(ILogger<TitreController> logger, ITitreRepository titreRepository, IArtisteRepository artisteRepository, IStyleRepository styleRepository, ITitreAdminService titreAdminService) /// <param name="configuration">Service de configuration injecté pour accéder aux paramètres de configuration.</param>
public TitreController(
ILogger<TitreController> logger,
IConfiguration configuration,
ITitreRepository titreRepository,
IArtisteRepository artisteRepository,
IStyleRepository styleRepository,
ITitreAdminService titreAdminService)
{ {
this.logger = logger; this.logger = logger;
this.configuration = configuration;
this.titreRepository = titreRepository; this.titreRepository = titreRepository;
this.artisteRepository = artisteRepository; this.artisteRepository = artisteRepository;
this.styleRepository = styleRepository; this.styleRepository = styleRepository;
@@ -43,12 +52,16 @@ public class TitreController : Controller
/// <summary> /// <summary>
/// Affiche la liste des titres dans la vue Index. /// Affiche la liste des titres dans la vue Index.
/// </summary> /// </summary>
/// <param name="page">Le numéro de page pour la pagination des titres (par défaut à 0).</param>
/// <returns>La vue Index avec le ViewModel contenant la liste des titres.</returns> /// <returns>La vue Index avec le ViewModel contenant la liste des titres.</returns>
public IActionResult Index() public IActionResult Index(int page = 0)
{ {
IEnumerable<Titre> titres = this.titreRepository.FindAll().Take(10); int titres_par_page = this.configuration.GetValue<int>("Webzine:NombreDeLignesAdministration");
IEnumerable<Titre> titres = this.titreRepository.FindTitres(page * titres_par_page, titres_par_page);
var model = titres.Select(t => new AdminTitreList int totalTitres = this.titreRepository.Count();
var adminListeModel = titres.Select(t => new AdminTitreList
{ {
Id = t.IdTitre, Id = t.IdTitre,
Nom = t.Artiste.Nom, Nom = t.Artiste.Nom,
@@ -58,9 +71,15 @@ public class TitreController : Controller
NbLectures = t.NbLectures, NbLectures = t.NbLectures,
NbLikes = t.NbLikes, NbLikes = t.NbLikes,
NbCommentaires = t.Commentaires?.Count ?? 0, NbCommentaires = t.Commentaires?.Count ?? 0,
}).ToList(); });
return this.View(model); var vm = new TitreIndexViewModel
{
Titres = adminListeModel.ToList(),
Page = page,
TotalPages = (int)Math.Ceiling((double)totalTitres / titres_par_page),
};
return this.View(vm);
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,25 @@
namespace Webzine.WebApplication.Areas.Administration.ViewModels.Artiste
{
using Webzine.Entity;
/// <summary>
/// ViewModel pour la page d'index des artistes dans l'administration, contenant la liste des artistes à afficher et les informations de pagination.
/// </summary>
public class ArtisteIndexViewModel
{
/// <summary>
/// Définit la liste des artistes à afficher dans la page d'index de l'administration.
/// </summary>
public IEnumerable<Artiste> Artistes { get; set; }
/// <summary>
/// Définit le numéro de page pour la pagination des artistes dans l'administration.
/// </summary>
public int Page { get; set; }
/// <summary>
/// Définit le nombre total de pages disponibles pour la pagination des artistes dans l'administration.
/// </summary>
public int TotalPages { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
namespace Webzine.WebApplication.Areas.Administration.ViewModels.Commentaire
{
using Webzine.Entity;
/// <summary>
/// ViewModel pour la page d'index des commentaires dans l'administration, contenant la liste des commentaires à afficher et les informations de pagination.
/// </summary>
public class CommentaireIndexViewModel
{
/// <summary>
/// Définit la liste des commentaires à afficher dans la page d'index de l'administration.
/// </summary>
public IEnumerable<Commentaire> Commentaires { get; set; }
/// <summary>
/// Définit le numéro de page pour la pagination des commentaires dans l'administration.
/// </summary>
public int Page { get; set; }
/// <summary>
/// Définit le nombre total de pages disponibles pour la pagination des commentaires dans l'administration.
/// </summary>
public int TotalPages { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
// <copyright file="CommentaireViewModel.cs" company="Equipe 1 - BOBIN, MASI, NODON, VETU">
// Copyright (c) Equipe 1 - BOBIN, MASI, NODON, VETU. All rights reserved.
// </copyright>
namespace Webzine.WebApplication.Areas.Administration.ViewModels.Commentaire
{
/// <summary>
/// ViewModel pour afficher la liste des commentaires en administration.
/// </summary>
public class CommentaireViewModel
{
/// <summary>
/// Obtient ou définit la liste des commentaires.
/// </summary>
public IEnumerable<Entity.Commentaire> Commentaires { get; set; } = new List<Entity.Commentaire>();
}
}

View File

@@ -0,0 +1,25 @@
namespace Webzine.WebApplication.Areas.Administration.ViewModels.Style
{
using Webzine.Entity;
/// <summary>
/// ViewModel pour la page d'index des styles dans l'administration, contenant la liste des styles à afficher et les informations de pagination.
/// </summary>
public class StyleIndexViewModel
{
/// <summary>
/// Définit la liste des styles à afficher dans la page d'index de l'administration.
/// </summary>
public IEnumerable<Style> Styles { get; set; }
/// <summary>
/// Définit le numéro de page pour la pagination des styles dans l'administration.
/// </summary>
public int Page { get; set; }
/// <summary>
/// Définit le nombre total de pages disponibles pour la pagination des styles dans l'administration.
/// </summary>
public int TotalPages { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace Webzine.WebApplication.Areas.Administration.ViewModels.Titre
{
/// <summary>
/// ViewModel pour la page d'index des titres dans l'administration, contenant la liste des titres à afficher et les informations de pagination.
/// </summary>
public class TitreIndexViewModel
{
/// <summary>
/// Définit la liste des titres à afficher dans la page d'index de l'administration.
/// </summary>
public IEnumerable<AdminTitreList> Titres { get; set; }
/// <summary>
/// Définit le numéro de page pour la pagination des titres dans l'administration.
/// </summary>
public int Page { get; set; }
/// <summary>
/// Définit le nombre total de pages disponibles pour la pagination des titres dans l'administration.
/// </summary>
public int TotalPages { get; set; }
}
}

View File

@@ -1,4 +1,4 @@
@model IEnumerable<Webzine.Entity.Artiste> @model Webzine.WebApplication.Areas.Administration.ViewModels.Artiste.ArtisteIndexViewModel;
@{ @{
ViewData["Title"] = "Artiste"; ViewData["Title"] = "Artiste";
@@ -21,7 +21,7 @@
</thead> </thead>
<tbody> <tbody>
@foreach (var artiste in Model) @foreach (var artiste in Model.Artistes)
{ {
<tr class="align-middle"> <tr class="align-middle">
<td class="p-2"> <td class="p-2">
@@ -44,5 +44,21 @@
} }
</tbody> </tbody>
</table> </table>
</div>
<div class="row justify-content-between">
@if (Model.Page > 0)
{
<a asp-action="Index" asp-route-page="@(Model.Page - 1)"
class="btn btn-secondary col-auto mt-3">
&lt;&lt; Page précédente
</a>
}
@if (Model.Page < Model.TotalPages - 1)
{
<a asp-action="Index" asp-route-page="@(Model.Page + 1)"
class="btn btn-secondary col-auto mt-3 ms-auto">
Page suivante &gt;&gt;
</a>
}
</div> </div>
</div> </div>

View File

@@ -1,4 +1,4 @@
@model Webzine.WebApplication.Areas.Administration.ViewModels.Commentaire.CommentaireViewModel @model Webzine.WebApplication.Areas.Administration.ViewModels.Commentaire.CommentaireIndexViewModel;
@{ @{
ViewData["Title"] = "Commentaires"; ViewData["Title"] = "Commentaires";
@@ -47,5 +47,21 @@
} }
</tbody> </tbody>
</table> </table>
</div>
<div class="row justify-content-between">
@if (Model.Page > 0)
{
<a asp-action="Index" asp-route-page="@(Model.Page - 1)"
class="btn btn-secondary col-auto mt-3">
&lt;&lt; Page précédente
</a>
}
@if (Model.Page < Model.TotalPages - 1)
{
<a asp-action="Index" asp-route-page="@(Model.Page + 1)"
class="btn btn-secondary col-auto mt-3 ms-auto">
Page suivante &gt;&gt;
</a>
}
</div> </div>
</div> </div>

View File

@@ -1,4 +1,4 @@
@model IEnumerable<Webzine.Entity.Style> @model Webzine.WebApplication.Areas.Administration.ViewModels.Style.StyleIndexViewModel;
@{ @{
ViewData["Title"] = "Styles"; ViewData["Title"] = "Styles";
@@ -24,9 +24,9 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@if ( Model.Any()) @if (Model.Styles.Any())
{ {
@foreach (Webzine.Entity.Style style in Model) @foreach (Webzine.Entity.Style style in Model.Styles)
{ {
<tr > <tr >
<td class="p-2 w-75"> <td class="p-2 w-75">
@@ -52,4 +52,19 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="row justify-content-between">
@if (Model.Page > 0)
{
<a asp-action="Index" asp-route-page="@(Model.Page - 1)"
class="btn btn-secondary col-auto mt-3">
&lt;&lt; Page précédente
</a>
}
@if (Model.Page < Model.TotalPages - 1)
{
<a asp-action="Index" asp-route-page="@(Model.Page + 1)"
class="btn btn-secondary col-auto mt-3 ms-auto">
Page suivante &gt;&gt;
</a>
}
</div> </div>

View File

@@ -1,4 +1,4 @@
@model IEnumerable<Webzine.WebApplication.Areas.Administration.ViewModels.Titre.AdminTitreList> @model Webzine.WebApplication.Areas.Administration.ViewModels.Titre.TitreIndexViewModel;
@{ @{
ViewData["Title"] = "Titres"; ViewData["Title"] = "Titres";
@@ -30,7 +30,7 @@
<tbody> <tbody>
@foreach (var item in Model) @foreach (var item in Model.Titres)
{ {
<tr> <tr>
<td>@item.Nom</td> <td>@item.Nom</td>
@@ -59,5 +59,21 @@
} }
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="row justify-content-between">
@if (Model.Page > 0)
{
<a asp-action="Index" asp-route-page="@(Model.Page - 1)"
class="btn btn-secondary col-auto mt-3">
&lt;&lt; Page précédente
</a>
}
@if (Model.Page < Model.TotalPages - 1)
{
<a asp-action="Index" asp-route-page="@(Model.Page + 1)"
class="btn btn-secondary col-auto mt-3 ms-auto">
Page suivante &gt;&gt;
</a>
}
</div>
</div> </div>

View File

@@ -46,14 +46,14 @@
var derniereChronique = this.configuration.GetValue<int>("Webzine:NombreDerniereChronique"); var derniereChronique = this.configuration.GetValue<int>("Webzine:NombreDerniereChronique");
var nbTopTitres = this.configuration.GetValue<int>("Webzine:NombreDeTopTitres"); var nbTopTitres = this.configuration.GetValue<int>("Webzine:NombreDeTopTitres");
var titres_paginé = this.titreRepository.FindTitres(page * derniereChronique, derniereChronique); var titres_paginés = this.titreRepository.FindTitres(page * derniereChronique, derniereChronique);
var top_titres = this.titreRepository.FindAll() var top_titres = this.titreRepository.FindAll()
.OrderByDescending(t => t.NbLikes) .OrderByDescending(t => t.NbLikes)
.Take(nbTopTitres); .Take(nbTopTitres);
var vm = new AccueilIndexViewModel var vm = new AccueilIndexViewModel
{ {
DerniersTitres = titres_paginé.ToList(), DerniersTitres = titres_paginés.ToList(),
TopTitres = top_titres.ToList(), TopTitres = top_titres.ToList(),
Page = page, Page = page,
}; };

View File

@@ -25,5 +25,8 @@ public class TitreStyleItem
/// </summary> /// </summary>
public string? UrlJaquette { get; set; } public string? UrlJaquette { get; set; }
/// <summary>
/// Définit la durée du titre en secondes.
/// </summary>
public int Duree { get; set; } public int Duree { get; set; }
} }

View File

@@ -7,7 +7,8 @@
}, },
"Webzine": { "Webzine": {
"NombreDerniereChronique": 3, "NombreDerniereChronique": 3,
"NombreDeTopTitres": 3 "NombreDeTopTitres": 3,
"NombreDeLignesAdministration": 10
}, },
"ConnectionStrings": { "ConnectionStrings": {
"SqliteConnection": "Data Source=Data/webzine.sqlite", "SqliteConnection": "Data Source=Data/webzine.sqlite",